⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 update.c

📁 MUD服务器程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	    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 + -