/*
....[@@@..[@@@..............[@.................. MUD++ is a written from
....[@..[@..[@..[@..[@..[@@@@@....[@......[@.... scratch multi-user swords and
....[@..[@..[@..[@..[@..[@..[@..[@@@@@..[@@@@@.. sorcery game written in C++.
....[@......[@..[@..[@..[@..[@....[@......[@.... This server is an ongoing
....[@......[@..[@@@@@..[@@@@@.................. development project. All
................................................ contributions are welcome.
....Copyright(C).1995.Melvin.Smith.............. Enjoy.
------------------------------------------------------------------------------
Melvin Smith (aka Fusion) msmith@hom.net
MUD++ development mailing list mudpp@van.ml.org
------------------------------------------------------------------------------
pulse.cc
*/
#include "config.h"
#include "string.h"
#include "llist.h"
#include "room.h"
#include "hash.h"
#include "area.h"
#include "pc.h"
#include "npc.h"
#include "object.h"
#include "env.h"
#include "global.h"
Environment envir;
const int MAX_IDLE = 100;
const int PULSE_NPC = 8;
const int PULSE_OBJ = 8;
const int PULSE_VM = PULSE_PER_SEC;
const int PULSE_PC = 10;
const int PULSE_COMBAT = 3;
const int PULSE_UPDATE = 45;
void pulseArea();
void pulseIdle();
void pulsePC();
void pulseNPC();
void pulseObj();
void pulseCombat();
void pulseVM();
void wakeSleepingVM();
// Heartbeat of the game.
// This is what makes the MUD run.
void heartbeat()
{
static int combat_timer = PULSE_COMBAT;
static int npc_timer = PULSE_NPC;
static int obj_timer = PULSE_OBJ;
static int vm_timer = PULSE_VM;
static int pc_timer = PULSE_PC;
static int update_timer = PULSE_UPDATE;
if( ! combat_timer-- )
{
pulseCombat();
combat_timer = PULSE_COMBAT;
}
if( ! npc_timer-- )
{
pulseNPC();
npc_timer = PULSE_NPC;
}
if( ! obj_timer-- )
{
pulseObj();
obj_timer = PULSE_OBJ;
}
if( ! pc_timer-- )
{
pulsePC();
pc_timer = PULSE_PC;
}
if( ! vm_timer-- )
{
pulseVM();
vm_timer = PULSE_VM;
}
if( ! update_timer-- )
{
wakeSleepingVM();
envir.update();
pulseArea();
pulseIdle();
update_timer = PULSE_UPDATE;
}
}
void action_heartbeat()
{
Action *act;
actions.reset();
while ( ( act = actions.peek() ) )
{
actions.next();
if ( act->getType() == 0 )
act->update();
}
Cout.flush();
}
void pulseArea()
{
Area * area;
for_each( areas, area )
area->tick();
}
void pulsePC()
{
PC *pc;
LList<PC> tlist = pcs;
for_each( tlist, pc )
pc->pulse();
}
void pulseIdle()
{
PC *pc;
LList<PC> tlist = pcs;
for_each( tlist, pc )
{
pc->idle();
// Wizzes can idle all they want.
if( pc->authorized( WIZARD ) )
continue;
if( pc->getIdle() > MAX_IDLE )
pc->setState( STATE_BOOT );
else if( pc->getIdle() == MAX_IDLE )
pc->out( "You have been idle. Autologout next pulse.\n\r" );
}
}
void pulseNPC()
{
NPC *npc;
LList<NPC> tlist = npcs;
for_each( tlist, npc )
{
if ( npc->TgUpdate() )
continue;
if ( npc->isBusy() )
continue;
if( randgen.get( 0, 4 ) )
continue;
npc->moveDir( randgen.get( 0, 5 ) );
}
}
void pulseObj()
{
Object *obj;
objects.reset();
while( ( obj = objects.peek() ) )
{
if ( obj->TgUpdate() )
{
objects.next();
continue;
}
if( obj->getTimer() > 0 )
{
if( obj->tick() )
{
objects.next();
continue;
}
if ( obj->TgTimerOut() )
{
objects.next();
continue;
}
if( obj->inRoom() )
{
obj->inRoom()->out( obj->getShort() );
obj->inRoom()->out( " decays into dust.\n\r" );
if( obj->isCorpse() )
{
obj->setName( "pile bones" );
obj->setShort( "a pile of old bones" );
obj->setLong( "A pile of old bones is here." );
objects.next();
continue;
}
obj->inRoom()->rmObjInv( obj );
}
else if( obj->carriedBy() )
{
obj->carriedBy()->out( obj->getShort() );
obj->carriedBy()->out( " crumbles in your hands.\n\r" );
obj->carriedBy()->rmObjInv( obj );
}
else if( obj->inObj() )
{
obj->inObj()->rmObjInv( obj );
}
// call to remove expects obj to be current.
// after remove current points to the next node so no ++
objects.remove();
obj->fordelete();
}
else
{
objects.next();
}
}
}
void pulseCombat()
{
Char *ch;
Char *vict;
// Run through npc list first
// Do somethin here with isBusy()
for_each( npcs, ch )
{
vict = ch->getFighting();
if( !vict )
continue;
ch->attack( vict, -1 );
}
for_each( pcs, ch )
{
vict = ch->getFighting();
if( !vict )
continue;
ch->attack( vict, -1 );
}
}