#include <sys/types.h>
#include <stdio.h>
#include "define.h"
#include "struct.h"
bool obj_compiled = FALSE;
bool mob_compiled = FALSE;
bool room_compiled = FALSE;
void affect_update ( char_data* );
void char_update ( void );
void drunk_update ( char_data* );
void light_update ( char_data* );
void obj_update ( void );
bool plague_update ( char_data* );
void poison_update ( char_data* );
void room_update ( void );
/*
* MAIN UPDATE FUNCTION
*/
void update_handler( void )
{
static int pulse_area;
static int pulse_mobile;
static int pulse_violence;
static int pulse_point;
static int pulse_room;
struct timeval start;
gettimeofday( &start, NULL );
event_update( );
delete_list( extracted );
if( --pulse_area <= 0 ) {
pulse_area = number_range( PULSE_AREA/2, 3*PULSE_AREA/2 );
area_update( );
}
if( --pulse_mobile <= 0 ) {
pulse_mobile = PULSE_MOBILE;
action_update( );
auction_update( );
regen_update( );
time_update( );
}
if( --pulse_point <= 0 ) {
pulse_point = number_range( PULSE_TICK/2, 3*PULSE_TICK/2 );
char_update( );
obj_update( );
}
if( --pulse_room <= 0 ) {
pulse_room = number_range( PULSE_ROOM/2, 3*PULSE_ROOM/2 );
room_update( );
w3_who( );
}
if( --pulse_violence <= 0 ) {
pulse_violence = PULSE_VIOLENCE;
update_queue( );
}
pulse_time[ TIME_UPDATE ] = stop_clock( start );
}
/*
* UPDATE CHARACTERS
*/
inline void update( char_data* ch )
{
light_update( ch );
affect_update( ch );
if( !plague_update( ch ) )
poison_update( ch );
return;
}
inline void update( mob_data* mob )
{
// mprog_data* mprog;
if( mob->position == POS_EXTRACTED || mob->in_room == NULL )
return;
/*
if( mob->timer > 0 && --mob->timer == 0 )
for( mprog = mob->species->mprog; mprog != NULL; mprog = mprog->next )
if( mprog->trigger == MPROG_TRIGGER_TIMER ) {
var_mob = mob;
var_room = mob->in_room;
execute( mprog );
return;
}
*/
update( (char_data*) mob );
}
inline void update( player_data* player )
{
int idle;
if( !player->In_Game( ) )
return;
if( player->save_time+600 < current_time ) {
if( is_set( &player->pcdata->message, MSG_AUTOSAVE ) )
send( player, "Autosaving...\n\r" );
write( player );
reference( player, player->contents, -1 );
}
idle = current_time-player->timer;
if( player->shdata->level < LEVEL_BUILDER
&& idle > ( player->link == NULL ? 30 : 300 ) ) {
if( player->was_in_room == NULL && player->in_room != NULL ) {
if( player->switched != NULL )
do_return( player->switched, "" );
player->was_in_room = player->in_room;
send( player, "You are pulled into nothingness.\n\r" );
send_seen( player, "%s is pulled into nothingness.\n\r", player );
write( player );
player->From( );
player->To( get_room_index( ROOM_LIMBO ) );
}
else if( idle > 900 ) {
forced_quit( player );
return;
}
}
if( player->was_in_room != NULL )
return;
if( player->gossip_pts < 1000
&& number_range( 0, player->pcdata->trust >= LEVEL_AVATAR ? 3 : 5 ) == 0 )
player->gossip_pts++;
player->shdata->fame = max( --player->shdata->fame, 0 );
player->whistle = max( --player->whistle, 0 );
player->prayer = min( ++player->prayer, 1000 );
condition_update( player );
update( (char_data*) player );
}
void char_update( void )
{
struct timeval start;
gettimeofday( &start, NULL );
for( int i = 0; i < mob_list; i++ )
update( mob_list[i] );
for( int i = 0; i < player_list; i++ )
update( player_list[i] );
pulse_time[ TIME_CHAR_LOOP ] = stop_clock( start );
return;
}
/*
* CHARACTER UPDATE SUBROUTINES
*/
void affect_update( char_data* ch )
{
affect_data* aff;
for( int i = ch->affected.size-1; i >= 0; i-- ) {
aff = ch->affected[i];
if( aff->leech == NULL ) {
if( aff->duration-- == 1 && aff->type == AFF_FIRE_SHIELD
&& ch->position > POS_SLEEPING ) {
send( ch, "The flames around you begin to fade.\n\r" );
}
else if( aff->type == AFF_DEATH ) {
update_max_hit( ch );
update_max_move( ch );
}
if( aff->duration <= 0 )
remove_affect( ch, aff );
}
}
return;
}
void light_update( char_data* ch )
{
// obj_data* obj;
// oprog_data* oprog;
/*
if( ( obj = get_eq_char( ch, WEAR_LIGHT ) ) == NULL
|| ( obj->pIndexData->item_type != ITEM_LIGHT
&& obj->pIndexData->item_type != ITEM_LIGHT_PERM )
|| obj->value[2] < 0 )
return;
if( obj->pIndexData->vnum == OBJ_BALL_OF_LIGHT
&& IS_AFFECTED( ch, AFF_CONTINUAL_LIGHT ) )
return;
if( --obj->value[2] == 1 ) {
if( ch->position > POS_SLEEPING )
send( ch, "%s you are carrying flickers briefly.\n\r", obj );
send( *ch->array, "%s carried by %s flickers briefly.\n\r", obj, ch );
return;
}
if( obj->value[2] != 0 || ch->in_room == NULL )
return;
send( ch, "%s you are carrying extinguishes.\n\r", obj );
send( *ch->array, "%s carried by %s extinguishes.\n\r", obj, ch );
--ch->in_room->light;
for( oprog = obj->pIndexData->oprog; oprog != NULL; oprog = oprog->next )
if( oprog->trigger == OPROG_TRIGGER_TIMER ) {
var_obj = obj;
var_ch = ch;
var_room = ch->in_room;
execute( oprog );
break;
}
if( oprog == NULL && obj->pIndexData->item_type == ITEM_LIGHT )
obj->Extract( );
*/
return;
}
bool plague_update( char_data* ch )
{
affect_data* aff;
int con;
if( !is_set( ch->affected_by, AFF_PLAGUE ) )
return FALSE;
for( int i = 0; ; i++ ) {
if( i >= ch->affected ) {
bug( "%s has the plague with no affect??", ch->real_name( ) );
return FALSE;
}
aff = ch->affected[i];
if( aff->type == AFF_PLAGUE )
break;
}
con = ch->Constitution( );
ch->mod_con--;
aff->level++;
update_max_hit( ch );
update_max_move( ch );
if( con == 3 ) {
death( ch, NULL, "the plague" );
return TRUE;
}
if( aff->level < 3 ) {
send( *ch->array, "%s coughs violently.\n\r", ch );
if( aff->level == 1 )
send( ch, "You cough violently.\n\r" );
else
send( "You cough, your throat burning in pain.\n\rThis is much worse than any cold, you have the plague!\n\r", ch );
return FALSE;
}
send( "The plague continues to destroy your body.\n\r", ch );
send( *ch->array,
"%s coughs violently, %s has obviously contracted the plague!\n\r",
ch, ch->He_She( ) );
return FALSE;
}
void poison_update( char_data* ch )
{
if( is_set( ch->affected_by, AFF_POISON ) ) {
send( ch, "Your condition deteriorates from a poison affliction.\n\r" );
send_seen( ch,
"%s's condition deteriorates from a poison affliction.\n\r", ch );
inflict( ch, NULL, 2, "poison" );
return;
}
if( ch->position == POS_INCAP )
inflict( ch, NULL, 1, "[BUG] incap??" );
else
if( ch->position == POS_MORTAL )
inflict( ch, NULL, 2, "bleeding to death" );
return;
}
/*
* TIMED ACTIONS
*/
void room_update( void )
{
// action_data* action;
// area_data* area;
// char_data* rch;
// room_data* room;
struct timeval start;
gettimeofday( &start, NULL );
/*
for( area = area_list; area != NULL; area = area->next )
for( room = area->room_first; room != NULL; room = room->next ) {
for( rch = room->people; rch != NULL && IS_NPC( rch );
rch = rch->next_in_room );
for( action = room->action; action != NULL; action = action->next )
if( ( ( rch != NULL && action->trigger == TRIGGER_RANDOM )
|| action->trigger == TRIGGER_RANDOM_ALWAYS )
&& number_range( 0, 999 ) < action->value ) {
var_room = room;
var_ch = NULL;
var_victim = NULL;
var_mob = NULL;
execute( action );
}
}
*/
pulse_time[ TIME_RNDM_ACODE ] = stop_clock( start );
return;
}
/*
* RESETTING OF AREAS
*/
void area_update( void )
{
area_data* area;
room_data* room;
struct timeval start;
bool save = TRUE;
gettimeofday( &start, NULL );
for( int i = 0; i < max_clan; i++ )
if( clan_list[i]->modified )
save_clans( clan_list[i] );
for( area = area_list; area != NULL; area = area->next ) {
if( ++area->age < 15 && ( area->nplayer != 0 || area->age < 5 ) )
continue;
for( room = area->room_first; room != NULL; room = room->next )
if( !player_in_room( room ) ) {
reset_room( room );
save_room_items( room );
}
area->age = number_range( 0, 3 );
if( save && area->modified ) {
save_area( area );
save = FALSE;
}
}
shop_update( );
pulse_time[ TIME_RESET ] = stop_clock( start );
return;
}
/*
* OBJECT UPDATE
*/
void obj_update( void )
{
// affect_data* affect;
// obj_data* obj;
// obj_data* content = NULL;
// obj_data* content_next;
// obj_clss_data* fire;
// oprog_data* oprog;
// room_data* room;
// char* message;
struct timeval start;
gettimeofday( &start, NULL );
/*
for( obj = obj_list; obj != NULL; obj = obj->next ) {
if( obj->valid != OBJ_DATA || obj->array == NULL )
continue;
for( oprog = obj->pIndexData->oprog; oprog != NULL;
oprog = oprog->next ) {
if( ( oprog->trigger == TRIGGER_RANDOM )
&& number_range( 0, 999 ) < oprog->value ) {
var_ch = character( obj->array );
var_room = room( obj->array );
var_obj = obj;
var_mob = NULL;
execute( oprog );
break;
}
}
}
*/
/*
for( obj = obj_list; obj != NULL; obj = obj->next ) {
if( obj->valid != OBJ_DATA )
continue;
for( int i = obj->affected.size-1; i >= 0; i-- ) {
affect = obj->affected[i];
if( affect->duration > 0 && --affect->duration == 0 )
remove_affect( obj, affect );
}
room = ( obj->array == NULL ? NULL : obj->array->room( ) );
if( room == NULL || obj->timer <= 0 || --obj->timer > 0 )
continue;
for( oprog = obj->pIndexData->oprog; oprog != NULL; oprog = oprog->next )
if( oprog->trigger == OPROG_TRIGGER_TIMER ) {
var_obj = obj;
var_room = room;
execute( oprog );
break;
}
if( oprog != NULL )
continue;
if( obj->pIndexData->item_type == ITEM_FIRE ) {
if( ( fire = get_obj_index( obj->value[1] ) ) != NULL
&& ( content = create( fire ) ) != NULL )
put_obj( content, room );
obj->Extract( );
return;
}
switch( obj->pIndexData->item_type ) {
default:
message = "%s vanishes.";
break;
case ITEM_FOUNTAIN:
message = "%s dries up.";
break;
case ITEM_CORPSE_NPC:
case ITEM_CORPSE_PC:
message = "%s rots, and is quickly eaten by a grue.";
break;
case ITEM_FOOD:
message = "%s decomposes.";
break;
}
fsend_room( room, message, obj );
*/
/*
if( obj->pIndexData->item_type == ITEM_CORPSE_PC ) {
for( content = obj->contents; content != NULL;
content = content_next ) {
content_next = content->next_content;
if( number_range( 1, 3 ) != 3 ) {
remove( content, content->number );
put_obj( content, room );
}
}
}
obj->Extract( );
}
*/
pulse_time[ TIME_OBJ_LOOP ] = stop_clock( start );
return;
}