📄 update.c
字号:
weather_info.sky = SKY_LIGHTNING;
}
if ( weather_info.mmhg > 1030
|| ( weather_info.mmhg > 1010 && number_bits( 2 ) == 0 ) )
{
strcat( buf, "The rain stopped.\n\r" );
weather_info.sky = SKY_CLOUDY;
}
break;
case SKY_LIGHTNING:
if ( weather_info.mmhg > 1010
|| ( weather_info.mmhg > 990 && number_bits( 2 ) == 0 ) )
{
strcat( buf, "The lightning has stopped.\n\r" );
weather_info.sky = SKY_RAINING;
break;
}
break;
}
if ( buf[0] != '\0' )
{
for ( d = descriptor_list; d != NULL; d = d->next )
{
if ( d->connected == CON_PLAYING
&& IS_OUTSIDE(d->character)
&& IS_AWAKE(d->character) )
send_to_char( buf, d->character );
}
}
return;
}
/*
* Update all chars, including mobs.
* This function is performance sensitive.
*/
void char_update( void )
{
CHAR_DATA *ch;
CHAR_DATA *ch_next;
CHAR_DATA *ch_save;
CHAR_DATA *ch_quit;
time_t save_time;
save_time = current_time;
ch_save = NULL;
ch_quit = NULL;
for ( ch = char_list; ch != NULL; ch = ch_next )
{
AFFECT_DATA *paf;
AFFECT_DATA *paf_next;
ch_next = ch->next;
/*
* Find dude with oldest save time.
*/
if ( !IS_NPC(ch)
&& ( ch->desc == NULL || ch->desc->connected == CON_PLAYING )
&& ch->level >= 2
&& ch->save_time < save_time )
{
ch_save = ch;
save_time = ch->save_time;
}
if ( ch->position >= POS_STUNNED )
{
if ( ch->hit < ch->max_hit )
ch->hit += hit_gain(ch);
if ( ch->mana < ch->max_mana )
ch->mana += mana_gain(ch);
if ( ch->move < ch->max_move )
ch->move += move_gain(ch);
}
if ( ch->position == POS_STUNNED )
update_pos( ch );
if ( !IS_NPC(ch) && ch->level < LEVEL_IMMORTAL )
{
OBJ_DATA *obj;
if ( ( obj = get_eq_char( ch, WEAR_LIGHT ) ) != NULL
&& obj->item_type == ITEM_LIGHT
&& obj->value[2] > 0 )
{
if ( --obj->value[2] == 0 && ch->in_room != NULL )
{
--ch->in_room->light;
act( "$p goes out.", ch, obj, NULL, TO_ROOM );
act( "$p goes out.", ch, obj, NULL, TO_CHAR );
extract_obj( obj );
}
}
if ( ++ch->timer >= 12 )
{
if ( ch->was_in_room == NULL && ch->in_room != NULL )
{
ch->was_in_room = ch->in_room;
if ( ch->fighting != NULL )
stop_fighting( ch, TRUE );
act( "$n disappears into the void.",
ch, NULL, NULL, TO_ROOM );
send_to_char( "You disappear into the void.\n\r", ch );
save_char_obj( ch );
char_from_room( ch );
char_to_room( ch, get_room_index( ROOM_VNUM_LIMBO ) );
}
}
if ( ch->timer > 30 )
ch_quit = ch;
gain_condition( ch, COND_DRUNK, -1 );
gain_condition( ch, COND_FULL, -1 );
gain_condition( ch, COND_THIRST, -1 );
}
for ( paf = ch->affected; paf != NULL; paf = paf_next )
{
paf_next = paf->next;
if ( paf->duration > 0 )
paf->duration--;
else if ( paf->duration < 0 )
;
else
{
if ( paf_next == NULL
|| paf_next->type != paf->type
|| paf_next->duration > 0 )
{
if ( paf->type > 0 && skill_table[paf->type].msg_off )
{
send_to_char( skill_table[paf->type].msg_off, ch );
send_to_char( "\n\r", ch );
}
}
affect_remove( ch, paf );
}
}
/*
* Careful with the damages here,
* MUST NOT refer to ch after damage taken,
* as it may be lethal damage (on NPC).
*/
if ( IS_AFFECTED(ch, AFF_POISON) )
{
act( "$n shivers and suffers.", ch, NULL, NULL, TO_ROOM );
send_to_char( "You shiver and suffer.\n\r", ch );
damage( ch, ch, 2, gsn_poison );
}
else if ( ch->position == POS_INCAP )
{
damage( ch, ch, 1, TYPE_UNDEFINED );
}
else if ( ch->position == POS_MORTAL )
{
damage( ch, ch, 2, TYPE_UNDEFINED );
}
}
/*
* Autosave and autoquit.
* Check that these chars still exist.
*/
if ( ch_save != NULL || ch_quit != NULL )
{
for ( ch = char_list; ch != NULL; ch = ch_next )
{
ch_next = ch->next;
if ( ch == ch_save )
save_char_obj( ch );
if ( ch == ch_quit )
do_quit( ch, "" );
}
}
return;
}
/*
* Update all objs.
* This function is performance sensitive.
*/
void obj_update( void )
{
OBJ_DATA *obj;
OBJ_DATA *obj_next;
for ( obj = object_list; obj != NULL; obj = obj_next )
{
CHAR_DATA *rch;
char *message;
obj_next = obj->next;
if ( obj->timer <= 0 || --obj->timer > 0 )
{
#if 1 // @@@
if (obj->in_room &&
obj->in_room->sector_type == SECT_AIR &&
(obj->wear_flags & ITEM_TAKE) &&
obj->in_room->exit[5] &&
obj->in_room->exit[5]->to_room)
{
ROOM_INDEX_DATA *new_room = obj->in_room->exit[5]->to_room;
if (( rch = obj->in_room->people ) != NULL )
{
act( "$p falls away.", rch, obj, NULL, TO_ROOM );
act( "$p falls away.", rch, obj, NULL, TO_CHAR );
}
obj_from_room(obj);
obj_to_room(obj, new_room);
if (( rch = obj->in_room->people ) != NULL )
{
act( "$p floats by.", rch, obj, NULL, TO_ROOM );
act( "$p floats by.", rch, obj, NULL, TO_CHAR );
}
}
#endif
continue;
}
switch ( obj->item_type )
{
default: message = "$p vanishes."; break;
case ITEM_FOUNTAIN: message = "$p dries up."; break;
case ITEM_CORPSE_NPC: message = "$p decays into dust."; break;
case ITEM_CORPSE_PC: message = "$p decays into dust."; break;
case ITEM_FOOD: message = "$p decomposes."; break;
}
if ( obj->carried_by != NULL )
{
act( message, obj->carried_by, obj, NULL, TO_CHAR );
}
else if ( obj->in_room != NULL
&& ( rch = obj->in_room->people ) != NULL )
{
act( message, rch, obj, NULL, TO_ROOM );
act( message, rch, obj, NULL, TO_CHAR );
}
// Sands fix... Corpse stuff stays in the room
if (obj->item_type == ITEM_CORPSE_PC && obj->contains)
/* save the contents */
{
OBJ_DATA *t_obj, *next_obj;
for (t_obj = obj->contains; t_obj != NULL; t_obj = next_obj)
{
next_obj = t_obj->next_content;
obj_from_obj(t_obj);
if (obj->in_obj) /* in another object */
obj_to_obj(t_obj,obj->in_obj);
if (obj->carried_by) /* carried */
obj_to_char(t_obj,obj->carried_by);
if (obj->in_room == NULL) /* destroy it */
extract_obj(t_obj);
else /* to a room */
obj_to_room(t_obj,obj->in_room);
}
}
extract_obj( obj );
}
return;
}
/*
* Aggress.
*
* for each mortal PC
* for each mob in room
* aggress on some random PC
*
* This function takes 25% to 35% of ALL Merc cpu time.
* Unfortunately, checking on each PC move is too tricky,
* because we don't the mob to just attack the first PC
* who leads the party into the room.
*
* -- Furey
*/
void aggr_update( void )
{
CHAR_DATA *wch;
CHAR_DATA *wch_next;
CHAR_DATA *ch;
CHAR_DATA *ch_next;
CHAR_DATA *vch;
CHAR_DATA *vch_next;
CHAR_DATA *victim;
// CHAR_DATA *prev = 0; // @@@
// int nCount = 0;
for ( wch = char_list; wch != NULL; wch = wch_next )
{
#if 0 // @@@
if (IsBadWritePtr(wch, sizeof *wch))
DebugBreak();
nCount++;
if (nCount > 5000)
DebugBreak();
#endif
wch_next = wch->next;
/* MOBProgram ACT_PROG trigger */
if ( IS_NPC( wch ) && wch->mpactnum > 0
&& wch->in_room->area->nplayer > 0 )
{
MPROG_ACT_LIST * tmp_act, *tmp2_act;
for ( tmp_act = wch->mpact; tmp_act != NULL;
tmp_act = tmp_act->next )
{
mprog_wordlist_check( tmp_act->buf, wch, tmp_act->ch,
tmp_act->obj, tmp_act->vo, ACT_PROG );
free_string( tmp_act->buf );
}
for ( tmp_act = wch->mpact; tmp_act != NULL; tmp_act = tmp2_act )
{
tmp2_act = tmp_act->next;
free_mem( tmp_act, sizeof( MPROG_ACT_LIST ) );
}
wch->mpactnum = 0;
wch->mpact = NULL;
}
if ( IS_NPC( wch )
|| wch->level >= LEVEL_IMMORTAL
|| wch->in_room == NULL )
continue;
for ( ch = wch->in_room->people; ch != NULL; ch = ch_next )
{
int count;
ch_next = ch->next_in_room;
if ( !IS_NPC(ch)
|| !IS_SET(ch->act, ACT_AGGRESSIVE)
|| ch->fighting != NULL
|| IS_AFFECTED(ch, AFF_CHARM)
|| !IS_AWAKE(ch)
|| ( IS_SET(ch->act, ACT_WIMPY) && IS_AWAKE(wch) )
|| !can_see( ch, wch ) )
continue;
/*
* Ok we have a 'wch' player character and a 'ch' npc aggressor.
* Now make the aggressor fight a RANDOM pc victim in the room,
* giving each 'vch' an equal chance of selection.
*/
count = 0;
victim = NULL;
for ( vch = wch->in_room->people; vch != NULL; vch = vch_next )
{
vch_next = vch->next_in_room;
// There are two commented-out ch->level + 5s from the Sands Patch. I
// didn't like them.
if ( !IS_NPC(vch)
&& vch->level < LEVEL_IMMORTAL
// && ch->level + 5 >= vch->level
&& ( !IS_SET(ch->act, ACT_WIMPY) || !IS_AWAKE(vch) )
&& can_see( ch, vch ) )
{
if ( number_range( 0, count ) == 0 )
victim = vch;
count++;
}
}
if ( victim == NULL /*&& ch->level + 5 < vch->level */ )
{
bug( "Aggr_update: null victim.", count );
continue;
}
multi_hit( ch, victim, TYPE_UNDEFINED );
}
// prev = wch;
}
return;
}
/*
* Handle all kinds of updates.
* Called once per pulse from game loop.
* Random times to defeat tick-timing clients and players.
*/
void update_handler( void )
{
static int pulse_area;
static int pulse_mobile;
static int pulse_violence;
static int pulse_point;
// HDC hDC;
if ( --pulse_area <= 0 )
{
pulse_area = number_range( PULSE_AREA / 2, 3 * PULSE_AREA / 2 );
// hDC = GetDC(0);
// TextOut(hDC, 0, 0, "area_update", 11);
// ReleaseDC(0, hDC);
area_update ( );
}
if ( --pulse_violence <= 0 )
{
pulse_violence = PULSE_VIOLENCE;
// hDC = GetDC(0);
// TextOut(hDC, 0, 0, "violence_update", 15);
// ReleaseDC(0, hDC);
violence_update ( );
}
if ( --pulse_mobile <= 0 )
{
pulse_mobile = PULSE_MOBILE;
// hDC = GetDC(0);
// TextOut(hDC, 0, 0, "mobile_update", 13);
// ReleaseDC(0, hDC);
mobile_update ( );
}
if ( --pulse_point <= 0 )
{
pulse_point = number_range( PULSE_TICK / 2, 3 * PULSE_TICK / 2 );
// hDC = GetDC(0);
// TextOut(hDC, 0, 0, "weather_update", 14);
weather_update ( );
// TextOut(hDC, 0, 0, "char_update", 11);
char_update ( );
// TextOut(hDC, 0, 0, "obj_update", 10);
// ReleaseDC(0, hDC);
obj_update ( );
}
// hDC = GetDC(0);
// TextOut(hDC, 0, 0, "aggr_update", 11);
// ReleaseDC(0, hDC);
aggr_update( );
tail_chain( );
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -