legend/
legend/area/
legend/player/
/****************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,         *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.    *
 *                                                                          *
 *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael           *
 *  Chastain, Michael Quan, and Mitchell Tse.                               *
 *                                                                          *
 *  In order to use any part of this Merc Diku Mud, you must comply with    *
 *  both the original Diku license in 'license.doc' as well the Merc        *
 *  license in 'license.txt'.  In particular, you may not remove either of  *
 *  these copyright notices.                                                *
 *                                                                          *
 *  Much time and thought has gone into this software and you are           *
 *  benefitting.  We hope that you share your changes too.  What goes       *
 *  around, comes around.                                                   *
 ***************************************************************************/
/****************************************************************************
 *  God Wars Mud copyright (C) 1994, 1995, 1996 by Richard Woolcock         *
 *                                                                          *
 *  Legend of Chrystancia copyright (C) 1999, 2000, 2001 by Matthew Little  *
 *  This mud is NOT to be copied in whole or in part, or to be run without  *
 *  the permission of Matthew Little. Nobody else has permission to         *
 *  authorise the use of this code.                                         *
 ***************************************************************************/

/* One minute before MidNight */
#define NEWDAYTIME "23:59"
#define MIN_KINGDOM_RENT 1000

#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include "merc.h"
#include "psycho.h"

/* local variables */
int iDelete = 0;

char *set_comma (long long init);
void call_all args ((CHAR_DATA * ch));
void call_bags args ((CHAR_DATA * ch));
void tick_restore args ((void));
void check_newday args ((void));
void update_xpqp args ((void));
void update_wartimer args ((void));
void minute_update args ((void));
void tick_update args ((void));
void gain_exp args ((CHAR_DATA * ch, int gain));
void show_combined_exp args ((CHAR_DATA * ch));
int hit_gain args ((CHAR_DATA * ch));
int mana_gain args ((CHAR_DATA * ch));
int move_gain args ((CHAR_DATA * ch));
void werewolf_regen args ((CHAR_DATA * ch, int multi));
void gain_condition args ((CHAR_DATA * ch, int iCond, int value));
void update_orgasm args ((CHAR_DATA * ch));
void mobile_update args ((void));
void moon_update args ((void));
void weather_update args ((void));
void event_update args ((void));
void regen_update args ((void));
void char_update args ((void));
void obj_update args ((void));
void aggr_update args ((void));
void embrace_update args ((void));
void quest_update args ((void));
void aquest_update    args( ( void ) ); /* Vassago - quest.c */
void hint_update args ((void));
void ww_update args ((void));
void ftag_update args ((void));
void update_handler args ((void));
void update_gametime args ((void));
bool check_social    args( ( CHAR_DATA *ch, char *command,
                            char *argument ) );

void vote_update args ((void));
extern OBJ_DATA *aquest_object;
EVENT_DATA *events;

#define kill_event						\
			if (!ev_next)				\
			{							\
				free_event(ev);			\
				return;					\
			}			  				\
			if (ev_last!=NULL)			\
				ev_last->next=ev_next;	\
			else						\
				events=ev_next;			\
			free_event(ev);  			\
			continue;

void tick_restore (void)
{
   int i;
   CHAR_DATA *ch;

   for (ch = char_list; ch != NULL; ch = ch->next)
   {
      if (IS_NPC (ch))
	 continue;

      if (ch->level < 3 && ch->class == 0)
      {
	 ch->hit = ch->max_hit;
	 ch->mana = ch->max_mana;
	 ch->move = ch->max_move;
	 for (i = 0; i < 6; i++)
	    ch->loc_hp[i] = 0;
	 update_pos (ch);
	 if (!IS_SET (ch->more, MORE_NOHINT))
	    send_to_char ("#y-Mortal Tick Restore-#n\n\r", ch);
      }
   }
   return;
}

void do_randarea (CHAR_DATA * ch, char *argument)
{
   AREA_DATA *area;
   int tog = 0;

   for (area = area_first; area; area = area->next)
   {
          tog = number_range(1,2);
          if (IS_SET(area->aflags, AFLAG_NOAREA) && (tog == 1)) continue;
          if (!IS_SET(area->aflags, AFLAG_NOAREA) && (tog == 2)) continue;
          if ((tog == 1) && (!IS_SET(area->aflags, AFLAG_NOAREA))) SET_BIT(area->aflags, AFLAG_NOAREA);
          else if ((tog == 2) && (IS_SET(area->aflags, AFLAG_NOAREA))) REMOVE_BIT(area->aflags, AFLAG_NOAREA);
          else continue;

          if (!str_cmp(area->filename, "spirallabyrinth.are") && IS_SET(area->aflags, AFLAG_NOAREA))
             REMOVE_BIT(area->aflags, AFLAG_NOAREA);
          if (!str_cmp(area->filename, "knighttemplar.are") && IS_SET(area->aflags, AFLAG_NOAREA))
             REMOVE_BIT(area->aflags, AFLAG_NOAREA);
          if (!str_cmp(area->filename, "ATControl.are") && IS_SET(area->aflags, AFLAG_NOAREA))
             REMOVE_BIT(area->aflags, AFLAG_NOAREA);
          if (!str_cmp(area->filename, "Asylum.are") && IS_SET(area->aflags, AFLAG_NOAREA))
             REMOVE_BIT(area->aflags, AFLAG_NOAREA);
          if (!str_cmp(area->filename, "darkwood.are") && IS_SET(area->aflags, AFLAG_NOAREA))
             REMOVE_BIT(area->aflags, AFLAG_NOAREA);

   }
    do_asave(NULL,"changed");
    return;
}

void check_newday (void)
{
   time_t nowtime;
   struct tm *t;
   char buf[MIL];
   nowtime = time (&current_time);
   t = localtime (&nowtime);

   strftime (buf, 100, "%H:%M", t);
   if (!strcmp (buf, NEWDAYTIME))
   {
      WizConfig->paradoxlimit = number_range(5, 30);
      do_randarea(NULL,"");

   }
   return;
}

void update_xpqp (void)
{
   char buf[MSL];
   int choose = number_range (1, 2);
   int times = number_range (1, 50);
   int duration = number_range (15, 45);
   int modifier = 0;

  switch(times)
  {
	case 1: case 6: case 11: case 16: case 21: case 26: case 31: case 36: case 41: case 46:
        modifier = 2;
        break;
	case 2: case 7: case 12: case 17: case 22: case 27: case 32: case 37: case 42: case 47:
        modifier = 3;
        break;
	case 3: case 8: case 13: case 18: case 23: case 28: case 33: case 38: case 43: case 48:
        modifier = 4;
        break;
	case 4: case 9: case 14: case 19: case 24: case 29: case 34: case 39: case 44: case 49:
        modifier = 5;
        break;
	case 5: case 10: case 15: case 20: case 25: case 30: case 35: case 40: case 45: case 50:
        modifier = 3;
        break;
  }
   if (--WizConfig->modtimer <= 1)
   {
      switch (choose)
      {
      case 1:
	 if (WizConfig->xpbonus == 1)
	 {
	    WizConfig->xpbonus = modifier;
	    WizConfig->xptimer = duration;
	    sprintf (buf, "A %d minute x%d experience multiplier has begun!",
		     duration, modifier);
	    do_info (NULL, buf);
	 }
	 break;
      case 2:
	 if (WizConfig->qpbonus == 1)
	 {
	    WizConfig->qpbonus = modifier;
	    WizConfig->qptimer = duration;
	    sprintf (buf, "A %d minute x%d quest point multiplier has begun!",
		     duration, modifier);
	    do_info (NULL, buf);
	 }
	 break;
      }
      WizConfig->modtimer = number_range (60, 300);
      save_wizconfig ();
   }
   return;
}

void update_wartimer (void)
{
   char buf[MSL];
   char buf2[MSL];
   int wartype = number_range (1, 2);
   int jackpot = number_range (50, 250);

   if (--pulse_arena <= 1)
   {
      if (war->bits == 0)
      {
	 war->jackpot[JPP] = jackpot;
	 war->type = wartype;
	 war->countdown = 5;

	 switch (wartype)
	 {
	 case 1:
	    sprintf (buf2, "#yFREE FOR ALL");
	    break;
	 case 2:
	    sprintf (buf2, "#cTEAM WAR");
	    break;
	 }

	 SET_BIT (war->bits, COUNTING);
	 sprintf (buf, "A %s#w is about to begin! To take part type 'join'", buf2);
	 warinfo (buf);
      }
        pulse_arena = number_range (60, 300);
   }
   return;
}

void minute_update (void)
{
   check_newday ();
   update_parasite ();
   //update_triviatime ();
   xptick ();
   wartick ();
   qptick ();
   update_xpqp ();
   return;
}

void tick_update (void)
{
   CHAR_DATA *ch;

   for (ch = char_list; ch != NULL; ch = ch->next)
   {
      if (IS_NPC (ch))
	 continue;
      if (IS_SET (ch->act, PLR_AUTOTICK))
	 send_to_char ("#2(#1Tick#2)#n\n\r", ch);
   }
   return;
}

void gain_exp (CHAR_DATA * ch, int gain)
{
   CHAR_DATA *mount = NULL;
   CHAR_DATA *master = NULL;

   if (IS_SET (ch->extra2, NHELPER))
   return;

   if (IS_NPC (ch) && ((mount = ch->mount) != NULL) && !IS_NPC (mount))
   {
      if (((master = ch->master) == NULL) || (master != mount))
	 mount->exp += gain;
   }

   if (!IS_NPC (ch))
      ch->exp += gain;

   if (!IS_NPC (ch))
      ch->pcdata->score[SCORE_TOTAL_XP] += gain;
   return;
}

// Empties combined exp in exp-pool into players exp pool -- Serenity
void show_combined_exp (CHAR_DATA * ch)
{
   if (IS_NPC(ch) )
       return;
   if (IS_SET (ch->extra2, NHELPER))
   return;
        
   if (ch->combined_exp > 0)
      stcf (ch, "#r<[#wYou gain #r%s #cpooled #wexperience points#r]>\n\r",
	    set_comma (ch->combined_exp));

   if (IS_CLASS (ch, CLASS_DEMON) && ch->combined_cp > 0)
   {
      stcf (ch, "#wYou receive #r%d #cpooled #eDemon Points#w.\n\r",
	    ch->combined_cp);
      ch->pcdata->stats[DEMON_CURRENT] += ch->combined_cp;
      ch->pcdata->stats[DEMON_TOTAL] += ch->combined_cp;
   }

   if (IS_CLASS (ch, CLASS_DROW) && ch->combined_cp > 0)
   {
      stcf (ch, "#wYou receive #r%d #cpooled #eDrow Points#w.\n\r",
	    ch->combined_cp);
      ch->pcdata->stats[DROW_POWER] += ch->combined_cp;
   }
   if (!IS_NPC (ch))
      ch->exp += ch->combined_exp;
   ch->pcdata->score[SCORE_TOTAL_XP] += ch->combined_exp;
   ch->combined_exp = 0;
   ch->combined_cp = 0;
   return;
}

// HP regeneration -- rebuilt by Serenity
int hit_gain (CHAR_DATA * ch)
{
   int gain;
   int conamount;

   if (IS_NPC (ch))
   {
      gain = ch->level;
      gain = UMIN (gain, ch->max_hit - ch->hit);
      return gain;
   }				// Get out of the LOOP now and save time -- Serenity

   if (IS_CLASS (ch, CLASS_VAMPIRE))
   {
      if (ch->hit < 0)
      {				// If mortally wounded, natural regeneration takes over
	 if (ch->pcdata->condition[COND_THIRST] > 10)
	 {
            ch->pcdata->condition[COND_THIRST] -= number_range(5, 10);   // charge blood for the regen
	    return dice (2, 2);
	 }
	 else if (ch->pcdata->condition[COND_THIRST] > 0)
	 {
	    ch->pcdata->condition[COND_THIRST] = 0;	// charge blood for the regen
	    return dice (1, 2);
	 }
      }				// Otherwise Vampires get 0 hp back during a normal regen tick.
      return 0;
   }

   gain = number_range (10, 20);

   if (ch->pcdata->condition[COND_FULL] < 1 && !IS_HERO (ch))
      gain /= 2;

   if (ch->pcdata->condition[COND_THIRST] < 1 && !IS_HERO (ch))
      gain /= 2;

   if (IS_AFFECTED (ch, AFF_POISON))
      gain /= 4;

   if (IS_AFFECTED (ch, AFF_FLAMING))
      gain /= 4;

   if ((conamount = (get_curr_con (ch) + 1)) > 1)
   {
      switch (ch->position)
      {
      case POS_MEDITATING:
	 gain *= (conamount * 2);
	 break;
      case POS_SLEEPING:
	 gain *= conamount;
	 break;
      case POS_RESTING:
	 gain *= (conamount / 2);
	 break;
      }
   }

   gain = UMIN (gain, ch->max_hit - ch->hit);	// Stop it at 0 -- Serenity

   if (IS_SET (ch->more, PLR_SEE_REGEN))
   {
      if (gain > 0)
	 stcf (ch,
	       "#rHG#wYour body repairs the damage you have suffered. #g[ #c+%d hp #g]#n\n\r",
	       gain);
   }
   return gain;
}

// MANA regeneration -- rebuilt by Serenity
int mana_gain (CHAR_DATA * ch)
{
   int gain;
   int intamount;

   if (IS_NPC (ch))
   {
      gain = ch->level;
      gain = UMIN (gain, ch->max_mana - ch->mana);
      return gain;
   }

   if (IS_CLASS (ch, CLASS_VAMPIRE))
      return 0;

   gain = number_range (10, 20);

   if ((intamount = (get_curr_int (ch) + 1)) > 1)
   {
      switch (ch->position)
      {
      case POS_MEDITATING:
	 gain *= number_range ((intamount * 10.0), (intamount * 13));
	 break;
      case POS_SLEEPING:
	 gain *= intamount;
	 break;
      case POS_RESTING:
	 gain *= (intamount / 2);
	 break;
      }
   }

   if (ch->pcdata->condition[COND_FULL] < 1 && !IS_HERO (ch))
      gain /= 2;

   if (ch->pcdata->condition[COND_THIRST] < 1 && !IS_HERO (ch))
      gain /= 2;

   if (IS_AFFECTED (ch, AFF_POISON))
      gain /= 4;

   if (IS_AFFECTED (ch, AFF_FLAMING))
      gain /= 4;

   gain = UMIN (gain, ch->max_mana - ch->mana);

   if (IS_SET (ch->more, PLR_SEE_REGEN))
   {
      if (gain > 0)
	 stcf (ch,
	       "#cMG#wYour mind harnesses nearby latent energy. #g[ #c+%d mana #g]#n\n\r",
	       gain);
   }

   return gain;
}

// Move regeneration -- rebuilt by Serenity
int move_gain (CHAR_DATA * ch)
{
   int gain;
   int dexamount;

   if (IS_NPC (ch))
   {
      gain = ch->level;
      gain = UMIN (gain, ch->max_move - ch->move);
      return gain;
   }

   if (IS_CLASS (ch, CLASS_VAMPIRE))
      return 0;

   gain = number_range (10, 20);

   if ((dexamount = (get_curr_dex (ch) + 1)) > 1)
   {
      switch (ch->position)
      {
      case POS_MEDITATING:
	 gain *= ((dexamount * ch->race) * 10);
	 break;
      case POS_SLEEPING:
	 gain *= (dexamount * ch->race);
	 break;
      case POS_RESTING:
	 gain *= ((dexamount * ch->race) / 2);
	 break;
      }
   }

   if (ch->pcdata->condition[COND_FULL] < 1 && !IS_HERO (ch))
      gain /= 2;

   if (ch->pcdata->condition[COND_THIRST] < 1 && !IS_HERO (ch))
      gain /= 2;

   if (IS_AFFECTED (ch, AFF_POISON))
      gain /= 4;

   if (IS_AFFECTED (ch, AFF_FLAMING))
      gain /= 4;

   gain = UMIN (gain, ch->max_move - ch->move);

   if (IS_SET (ch->more, PLR_SEE_REGEN))
   {
      if (gain > 0)
	 stcf (ch,
	       "#gMG#wYou slowly regain your stamina. #g[ #c+%d move #g]#n\n\r",
	       gain);
   }

   return gain;
}

void werewolf_regen (CHAR_DATA * ch, int multi)
{
   int a, b, c, gain;
   int gained_a;		// Used to monitor how much was actually gained.  --Serenity
   int gained_b;		// Used to monitor how much was actually gained.  --Serenity
   int gained_c;		// Used to monitor how much was actually gained.  --Serenity
   int conamount;
   int intamount=0;
   int dexamount=0;
   int max = 200000;
   int position = ch->position;

   if (IS_NPC (ch) && !IS_SUPER_NPC (ch))
      return;

   if (IS_NPC(ch)) max = ch->max_hit;

   if (!IS_NPC (ch))
   {
      if (ch->pcdata->obj_vnum > 0)
      {
	 return;
      }
   }

   if ((conamount = (get_curr_con (ch) + 1)) > 1)
      if ((intamount = (get_curr_int (ch) + 1)) > 1)
	 if ((dexamount = (get_curr_dex (ch) + 1)) > 1)

	    if (multi < 1)
	       multi = 1;

   if (ch->hit < 1)
   {
      gained_a = number_range (1, 3);
      gained_b = number_range (1, 3);
      gained_c = number_range (1, 3);
   }
   else if (!IS_NPC(ch) && IS_CLASS (ch, CLASS_DEMON) && ch->in_room->vnum == ROOM_VNUM_HELL)
   {
      gained_a = (((max * 4) * multi) / 200);
      gained_b = (((max * 4) * multi) / 200);
      gained_c = (((max * 4) * multi) / 200);
   }
   else if (ch->position == POS_SLEEPING)
   {
      gained_a = (((max * 3) * multi) / 200);
      gained_b = (((max * 1) * multi) / 200);
      gained_c = (((max * 2) * multi) / 200);
   }
   else if (ch->position == POS_RESTING)
   {
      gained_a = (((max * 1) * multi) / 200);
      gained_b = (((max * 2) * multi) / 200);
      gained_c = (((max * 3) * multi) / 200);
   }

   else if (ch->position == POS_MEDITATING)
   {
      gained_a = (((max * 1) * multi) / 200);
      gained_b = (((max * 3) * multi) / 200);
      gained_c = (((max * 2) * multi) / 200);
   }
   else if (!IS_NPC(ch) && IS_CLASS (ch, CLASS_DROW)
	    && (ch->in_room->vnum == 29701 || ch->in_room->vnum == 29702))
   {
      gained_a = (((max * 4) * multi) / 200);
      gained_b = (((max * 4) * multi) / 200);
      gained_c = (((max * 4) * multi) / 200);
   }
   else
   {
      a = max / 800;
      b = max / 800;
      c = max / 800;
      if (a < 1)
	 a = 1;
      if (b < 1)
	 b = 1;
      if (c < 1)
	 c = 1;
      a *= multi;
      b *= multi;
      c *= multi;
      gain = a * number_range (1, 5);
      if (gain <= 5)
	 gain = 5;
      gained_a = gain;
      gain = b * number_range (1, 5);
      if (gain <= 5)
	 gain = 5;
      gained_b = gain;
      gain = c * number_range (1, 5);
      if (gain <= 5)
	 gain = 5;
      gained_c = gain;
   }

   gain = 100;

   if (ch->hit > 0)
   {
      gained_a += ((conamount - (conamount % 10)) * dice (3, 25));
      gained_b += ((intamount - (intamount % 10)) * dice (3, 25));
      gained_c += ((dexamount - (dexamount % 10)) * dice (3, 25));

      if (!IS_NPC (ch))
      {
         if (ch->pcdata->condition[COND_FULL] < 1 && !IS_HERO (ch))
	    gain /= 2;
         if (ch->pcdata->condition[COND_THIRST] < 1 && !IS_HERO (ch))
	    gain /= 2;
      }
      if (IS_AFFECTED (ch, AFF_POISON))
	 gain /= 4;
      if (IS_AFFECTED (ch, AFF_FLAMING))
	 gain /= 4;
      if (ch->fight_timer > 0 )
	 gain /= 4;
   }

   gained_a *= gain;
   gained_a /= 100;

   gained_b *= gain;
   gained_b /= 100;

   gained_c *= gain;
   gained_c /= 100;

   if (ch->in_room != NULL && IS_SET( ch->in_room->room_flags, ROOM_COLOUR_ROOM ))
   {
      int sleeping = 1;
      if (ch->position == POS_SLEEPING) sleeping = 2;
      if (ch->in_room->vnum == ROOM_VNUM_PLANAR_G || ch->in_room->vnum == ROOM_VNUM_CRYSTAL_R)
         gained_a = 10000 * sleeping;
      if (ch->in_room->vnum == ROOM_VNUM_PLANAR_B || ch->in_room->vnum == ROOM_VNUM_CRYSTAL_B)
         gained_b = 10000 * sleeping;
      if (ch->in_room->vnum == ROOM_VNUM_PLANAR_R || ch->in_room->vnum == ROOM_VNUM_CRYSTAL_G)
         gained_c = 10000 * sleeping;
   }

   if ((gained_a + ch->hit) > ch->max_hit)
      gained_a = (ch->max_hit - ch->hit);
   if ((gained_b + ch->mana) > ch->max_mana)
      gained_b = (ch->max_mana - ch->mana);
   if ((gained_c + ch->move) > ch->max_move)
      gained_c = (ch->max_move - ch->move);

   ch->hit += gained_a;
   ch->mana += gained_b;
   ch->move += gained_c;

   if (ch->hit < -10)
      ch->hit = -10;
   if (ch->move < 0)
      ch->move = 0;
   if (ch->mana < 0)
      ch->mana = 0;

   if (position < POS_STUNNED) update_pos (ch);

   if (IS_SET (ch->more, PLR_SEE_REGEN))
   {
      if (gained_a > 0)
	 stcf (ch,
	       "#wYour body repairs the damage you have suffered. #g[ #c+%d hp #g]#n\n\r",
	       gained_a);
      if (gained_b > 0)
	 stcf (ch,
	       "#wYour mind harnesses nearby latent energy. #g[ #c+%d mana #g]#n\n\r",
	       gained_b);
      if (gained_c > 0)
	 stcf (ch,
	       "#wYou slowly regain your stamina. #g[ #c+%d move #g]#n\n\r",
	       gained_c);
   }
   if ((gained_a + gained_b + gained_c) > 0)
   {
      if ((ch->hit >= ch->max_hit) && (ch->mana >= ch->max_mana)
	  && (ch->move >= ch->max_move))
         if (IS_SET (ch->more, PLR_SEE_REGEN))
	    send_to_char ("#cYou are completely energized and healed.#n\n\r",
		       ch);
   }

   return;
}

// modifies thirst/hunger values -- Serenity
void gain_condition (CHAR_DATA * ch, int iCond, int value)
{
   int condition;
   bool is_obj=FALSE;
   if (value == 0 || IS_NPC (ch))
      return;

   // no longer need to check for NPC we already did.

   if ((IS_HEAD (ch, LOST_HEAD) || IS_EXTRA (ch, EXTRA_OSWITCH)))
      is_obj = TRUE;
   else if (ch->pcdata->obj_vnum != 0)
   {
      is_obj = TRUE;
      SET_BIT (ch->extra, EXTRA_OSWITCH);
   }
   if (IS_HERO (ch))
   {
      if ((!IS_CLASS (ch, CLASS_VAMPIRE))
	  && (!IS_CLASS (ch, CLASS_DRAGON)) && (iCond != COND_DRUNK))
	 return;
      // Hero's ignore conditions unless they are either
      // A) a vampire, B) a Dragon or C) Dealing with Alcohol
   }

   condition = ch->pcdata->condition[iCond];
   if (iCond == COND_FULL)
   {
      if (IS_CLASS (ch, CLASS_DRAGON))
      {
	 ch->pcdata->condition[iCond] =
            URANGE (0, condition + value, 100 * GET_AGE(ch));
         if (ch->pcdata->condition[iCond] < (25 * GET_AGE(ch)))
	    stcf (ch, "%s Dragon #nneeds #ofood #Rbadly#n.\n\r",
		  dcolor[ch->pcdata->disc_a[DRAGON_COLOR]]);
         else if (ch->pcdata->condition[iCond] < (50 * GET_AGE(ch)))
	    stcf (ch, "%s Dragon #nneeds #ofood#n.\n\r",
		  dcolor[ch->pcdata->disc_a[DRAGON_COLOR]]);
         else if (ch->pcdata->condition[iCond] < (75 * GET_AGE(ch)))
	    stc ("You feel the gnawing teeth of hunger ripping at your strength.\n\r", ch);
      }
      else if (!IS_CLASS (ch, CLASS_VAMPIRE))
	 ch->pcdata->condition[iCond] = URANGE (0, condition + value, 48);
   }

   if (iCond == COND_THIRST)
   {
      if (IS_CLASS (ch, CLASS_VAMPIRE) && !IS_IMMORTAL(ch))
      {
	 int chargen = ch->pcdata->stats[UNI_GEN];
	 int maxblood;
	 if (chargen > 12)
	    chargen = 12;
	 maxblood = (13 - chargen) * 100;
	 ch->pcdata->condition[iCond] =
	    URANGE (0, condition + value, maxblood);
	 if (ch->pcdata->condition[iCond] < (maxblood / 10))
	 {
	    send_to_char ("You are DYING from lack of blood!\n\r", ch);
	 }

      }
   }

   if (ch->pcdata->condition[iCond] < 1)
   {
      switch (iCond)
      {
      case COND_FULL:
	 if (IS_CLASS (ch, CLASS_DRAGON) && !is_obj)
	 {
	    stcf (ch,
		  "%s Dragon #nhas #rD#RI#rE#RD#n for lack of #ofood#n!\n\r",
		  dcolor[ch->pcdata->disc_a[DRAGON_COLOR]]);
	    dragon_sleep (ch);
	 }
	 if (!IS_CLASS (ch, CLASS_VAMPIRE))
	 {
	    send_to_char ("You are REALLY hungry.\n\r", ch);
	    act ("You hear $n's stomach growling, hmm $e must be hungry.", ch,
		 NULL, NULL, TO_ROOM);
	 }
	 break;
      case COND_THIRST:
	 if (!IS_CLASS (ch, CLASS_VAMPIRE) && !IS_CLASS (ch, CLASS_DRAGON))
	 {
	    send_to_char ("You are REALLY thirsty.\n\r", ch);
	 }
	 else if (ch->hit > 0)
	 {
	    if (IS_CLASS (ch, CLASS_VAMPIRE) && !is_obj)
	    {
	       send_to_char ("You are DYING from lack of blood!\n\r", ch);
	       act ("$n gets a bloodthirsty look in $s eyes.", ch, NULL, NULL,
		    TO_ROOM);
	       ch->hit = ch->hit - number_range (2, 5);
	       if ((number_percent () <= ch->beast) && (ch->beast > 0))
		  vamp_rage (ch);
	       if (!IS_VAMPAFF (ch, VAM_FANGS))
		  do_fangs (ch, "");
	    }
	 }
	 break;
      case COND_DRUNK:
	 if (condition != 0)
	    send_to_char ("You are sober.\n\r", ch);
	 break;
      }
   }
   else if (ch->pcdata->condition[iCond] < 10)
   {
      switch (iCond)
      {
      case COND_FULL:
	 if (IS_CLASS (ch, CLASS_DRAGON) && !is_obj)
	 {
	    stcf (ch, "%s Dragon #nis about to #rD#RI#rE#n!\n\r",
		  dcolor[ch->pcdata->disc_a[DRAGON_COLOR]]);
	    if (number_percent () < 25)
	       dragon_sleep (ch);
	 }
	 if (!IS_CLASS (ch, CLASS_VAMPIRE))
	 {
	    send_to_char ("You feel hungry.\n\r", ch);
	 }
	 break;
      case COND_THIRST:
	 if (!IS_CLASS (ch, CLASS_VAMPIRE) && !IS_CLASS (ch, CLASS_DRAGON))
	    send_to_char ("You feel thirsty.\n\r", ch);
	 else
	 {
	    if (IS_CLASS (ch, CLASS_VAMPIRE) && !is_obj)
	    {
	       send_to_char ("You feel the need to bleed.\n\r", ch);
	       if ((number_range (1, 1000) <= ch->beast) && (ch->beast > 0))
		  vamp_rage (ch);
	       if ((number_percent () >
		    (ch->pcdata->condition[COND_THIRST] + 75))
		   && (!IS_VAMPAFF (ch, VAM_FANGS)))
		  do_fangs (ch, "");
	    }
	 }
	 break;
      }
   }
   return;
}

// Stupid xsocial orgasm crap -- Serenity
// GET A LIFE FOLKS FIND A REAL ONE! -- Serenity
void update_orgasm (CHAR_DATA * ch)
{
   CHAR_DATA *vch;
     if (ch->sex == SEX_FEMALE || ch->sex == SEX_MALE)
         {
	    int stage = XS_READY;

	    vch = ch->pcdata->partner;
	    if (vch == NULL || ch->in_room != vch->in_room)
	    {
	       if (ch->pcdata->stage[1] > 0)
		  ch->pcdata->stage[1]--;
               if (ch->pcdata->stage[0] != XS_RECOVERING)
		  ch->pcdata->stage[0] = XS_NONE;
	    }
	    else if (ch->pcdata->stage[1] > ((ch->sex - 1) ? 85 : 200)
		     && ch != vch && ch->pcdata->stage[0] > XS_READY)
	    {
	       if (ch->sex - 1)
		  stage = vch->pcdata->stage[0];
	       else
		  stage = ch->pcdata->stage[0];
               if ((ch->sex - 1) || (!IS_NPC(ch) && ch->in_room->vnum == 3))
	       {
		  switch (stage)
		  {
		  case XS_BREASTS:
		     act ("You hold your breasts together for $N, $S cock stroking you near orgasm.", ch, NULL, vch, TO_CHAR);
		     act ("$n holds $s breasts together for you, panting quietly.", ch, NULL, vch, TO_VICT);
		     act ("$n holds $s breasts together for $N, panting quietly.", ch, NULL, vch, TO_NOTVICT);
		     break;
		  case XS_BJ:
		     act ("You finger yourself hard, imagining $N's cock buried deep in your wet pussy.", ch, NULL, vch, TO_CHAR);
		     act ("$n fingers $mself hard, almost cumming $e sucks on your hard cock.", ch, NULL, vch, TO_VICT);
		     act ("$n fingers $mself almost as enthusiastically as $e sucks on $N's cock, $s orgasm not far off.", ch, NULL, vch, TO_NOTVICT);
		     break;
		  case XS_BJDEEP:
                     if (ch->in_room->vnum == 3)
                     {
                        act ("You rock in place, almost cumming from $N's rough use of your throat.", ch, NULL, vch, TO_CHAR);
                        act ("$n rocks in place as fast as $e can, almost cumming from your rough use of $s throat.", ch, NULL, vch, TO_VICT);
                        act ("$n rocks in place as fast as $e can, almost cumming from $N's rough use of $s throat.", ch, NULL, vch, TO_NOTVICT);
                     }
                     else
                     {
                        act ("You knead your clit as hard as you can, almost cumming from $N's rough use of your throat.", ch, NULL, vch, TO_CHAR);
                        act ("$n kneads $s clit as hard as $e can, almost cumming from your rough use of $s throat.", ch, NULL, vch, TO_VICT);
                        act ("$n kneads $s clit as hard as $e can, almost cumming from $N's rough use of $s throat.", ch, NULL, vch, TO_NOTVICT);
                     }
		     break;
		  case XS_PUSSY:
		     act ("You writhe passionately, grinding down on $N's cock as hard as you can.", ch, NULL, vch, TO_CHAR);
		     act ("$n writhes passionately, grinding down on your cock as hard as $e can.", ch, NULL, vch, TO_VICT);
		     act ("$n writhes passionately, grinding down on $N's cock as hard as $e can.", ch, NULL, vch, TO_NOTVICT);
		     break;
		  case XS_ASS:
		     act ("You groan ecstatically, helpless as $N fucks your ass.", ch, NULL, vch, TO_CHAR);
		     act ("$n groans ecstatically, helpless as you fuck $s ass.", ch, NULL, vch, TO_VICT);
		     act ("$n groans ecstatically, helpless as $N fucks $s ass.", ch, NULL, vch, TO_NOTVICT);
		     break;
		  }
	       }
	       else
	       {
		  switch (stage)
		  {
		  case XS_BREASTS:
		     act ("You squash $N's breasts tight around your cock, fucking them hard.", ch, NULL, vch, TO_CHAR);
		     act ("$n squashes your breasts tight around $s cock, fucking them hard.", ch, NULL, vch, TO_VICT);
		     act ("$n squashes $N's breasts tight around $s cock, fucking them hard.", ch, NULL, vch, TO_NOTVICT);
		     break;
		  case XS_BJ:
		     act ("You hold $N's head firmly, fucking $S mouth as your orgasm approaches.", ch, NULL, vch, TO_CHAR);
		     act ("$n holds your head firmly, fucking your mouth as $s orgasm approaches.", ch, NULL, vch, TO_VICT);
		     act ("$n holds $N's head firmly, fucking $S mouth as $s orgasm approaches.", ch, NULL, vch, TO_NOTVICT);
		     break;
		  case XS_BJDEEP:
		     act ("You pound deep into $N's throat, grunting with every ecstatic thrust.", ch, NULL, vch, TO_CHAR);
		     act ("$n pounds deep into your throat, almost choking you.", ch, NULL, vch, TO_VICT);
		     act ("$n pounds deep into $N's throat, almost choking $M.", ch, NULL, vch, TO_NOTVICT);
		     break;
		  case XS_PUSSY:
		     act ("You thrust deep into $N's pussy, groaning with ecstasy.", ch, NULL, vch, TO_CHAR);
		     act ("$n thrusts deep into your pussy, groaning with ecstasy.", ch, NULL, vch, TO_VICT);
		     act ("$n thrusts deep into $N's pussy, groaning with ecstasy.", ch, NULL, vch, TO_NOTVICT);
		     break;
		  case XS_ASS:
		     act ("You hold $N's hair, holding $M helpless as you pull $S hot, tight ass back around your cock.", ch, NULL, vch, TO_CHAR);
		     act ("$n holds your hair, holding you helpless as $e pulls your hot, tight ass back around $s cock.", ch, NULL, vch, TO_VICT);
		     act ("$n holds $N's hair, holding $M helpless as $e pulls $S ass back around $s cock.", ch, NULL, vch, TO_NOTVICT);
		     break;
		  }
	       }
	       if (ch->sex - 1)
		  ch->pcdata->stage[1] += 30;
	       else
		  ch->pcdata->stage[1] += 10;

	       stage_update (ch, vch, stage);
	    }
	 }
         if (ch->sex == SEX_MALE &&
	     ch->pcdata->stage[0] == XS_RECOVERING)
	 {
	    if (ch->pcdata->stage[2] <= 0)
	    {
	       ch->pcdata->stage[0] = XS_NONE;
	       send_to_char ("You feel fully recovered.\n\r", ch);
	    }
	    else
	       ch->pcdata->stage[2]--;
	 }

	 if (ch->pcdata->stage[0] != XS_RECOVERING)
	 {
	    if (IS_SET (ch->pcdata->stage[3], XF_PUSSYON))
	    {
	       if (number_percent () < 20)
	       {
		  act ("You groan quietly with pleasure, the vibrations in your pussy bringing you nearer and nearer to orgasm.", ch, NULL, NULL, TO_CHAR);
		  act ("$n groans gently.", ch, NULL, NULL, TO_ROOM);
	       }
	       ch->pcdata->stage[1] += 4;
	       stage_update (ch, ch, XS_PUSSY);
	    }
	    if (IS_SET (ch->pcdata->stage[3], XF_CLITON))
	    {
	       if (number_percent () < 30)
	       {
		  act ("You whimper as the butterfly enflames your clit.", ch,
		       NULL, NULL, TO_CHAR);
		  act ("$n whimpers quietly.", ch, NULL, NULL, TO_ROOM);
	       }
	       ch->pcdata->stage[1] += 7;
	       stage_update (ch, ch, XS_CLIT);
	    }
	    if (IS_SET (ch->pcdata->stage[3], XF_ASSON))
	    {
	       if (number_percent () < 20)
	       {
		  act ("You pant slightly, the butt plug thrusting hard in your ass.", ch, NULL, NULL, TO_CHAR);
		  act ("$n pants slightly.", ch, NULL, NULL, TO_ROOM);
	       }
	       ch->pcdata->stage[1] += 1;
	       stage_update (ch, ch, XS_ASS);
	    }
	 }
	 if (ch->pcdata->stage[0] > XS_NONE && ch->pcdata->stage[1] < 25)
	 {
	    ch->pcdata->stage[0] = XS_NONE;
	 }


}

/*
 * Mob autonomous action.
 * This function takes 25% to 35% of ALL Merc cpu time.
 * -- Furey
 */
 // Updated -- Serenity
void mobile_update (void)
{
   CHAR_DATA *ch;
   EXIT_DATA *pexit;
   int door;

   /* Examine all mobs. */
   for (ch = char_list; ch != NULL; ch = ch->next)
   {
      if (ch->in_room == NULL)
	 continue;		// Only process mobs if they are in a room -- Serenity

      // Super NPC's Attempt to fight back!!
      if (IS_SUPER_NPC (ch) && ch->position == POS_FIGHTING)
	 do_kick (ch, "");

      if (!IS_NPC (ch))
	 continue;		// THIS IS A MOBILE FUNCTION, not a PLAYER FUNCTION -- Serenity

      if (IS_NPC(ch) && ch->hit < 1) ch->hit = 1;

      /* Examine call for special procedure */
      if (ch->spec_fun != 0 && !IS_SET (ch->tag_flags, TAG_PLAYING))
      {
	 if ((*ch->spec_fun) (ch))
	    continue;
	 if (ch == NULL)
	    continue;
      }

        if ( (ch->position == POS_FIGHTING
        &&      ch->stance[0] < 1 )
        ||      ( ch->level > 74 && number_bits( 2 ) == 0 && ch->stance[0] < 1 ))
        {
            switch (number_range(1,10))
            {
                case 1: do_stance(ch,"viper"); break;   
                case 2: do_stance(ch,"crane"); break;   
                case 3: do_stance(ch,"mongoose"); break;
                case 4: do_stance(ch,"bull"); break;
                case 5: do_stance(ch,"crab"); break;
                case 6: do_stance(ch, "mantis"); break;
                case 7: do_stance(ch, "dragon"); break;
                case 8: do_stance(ch, "tiger"); break;
                case 9: do_stance(ch, "monkey"); break;
                case 10: do_stance(ch, "dragon"); break;
                continue;
            }
        }

      /* That's all for sleeping / busy monster */
      if (ch->position != POS_STANDING)
	 continue;

      /* Scavengers */
      if (IS_SET (ch->act, ACT_SCAVENGER) && ch->in_room->contents != NULL
	  && number_bits (2) == 0)
      {
	 OBJ_DATA *obj;
	 OBJ_DATA *obj_best;
	 int max;

	 max = 1;
	 obj_best = 0;
	 for (obj = ch->in_room->contents; obj; obj = obj->next_content)
	 {
	    if ((obj->item_type == ITEM_CORPSE_NPC)
		|| (obj->item_type == ITEM_CORPSE_PC))
	       continue;	// Do NOT take corpses into account.  -- Serenity
            if (OBJ_ARTIFACT(obj)) continue;
	    if (CAN_WEAR (obj, ITEM_TAKE) && obj->cost > max)
	    {
	       obj_best = obj;
	       max = obj->cost;
	    }
	 }

	 if (obj_best)
	 {
	    obj_from_room (obj_best);
	    obj_to_char (obj_best, ch);
	    act ("$n picks $p up.", ch, obj_best, NULL, TO_ROOM);
	    act ("You pick $p up.", ch, obj_best, NULL, TO_CHAR);
	 }
      }

      /* Wandering mobs */
      if (!IS_SET (ch->act, ACT_SENTINEL)
	  && (door = number_bits (5)) <= 5
	  && (pexit = ch->in_room->exit[door]) != NULL
	  && pexit->to_room != NULL
	  && !IS_SET (pexit->exit_info, EX_CLOSED)
	  && !IS_SET (pexit->to_room->room_flags, ROOM_NO_MOB)
	  && (ch->hunting == NULL || strlen (ch->hunting) < 2)
	  && ((!IS_SET (ch->act, ACT_STAY_AREA) && ch->level < 900)
	      || pexit->to_room->area == ch->in_room->area))
	 move_char (ch, door);
      else if (ch->pIndexData->vnum == 25 && number_percent() < 2)
      {
         check_social( ch, "yawn", ch->name );
         do_say(ch, "Time to move on.");
         act ("You heft your backpack over your shoulder and wander out of the room.", ch, NULL, NULL,
            TO_CHAR);
         act ("$n hefts $s backpack over $s shoulder and wanders out of the room.", ch, NULL, NULL,
            TO_ROOM);
         move_oaka (ch);
      }

      /* Fleeing mobs */
      if (ch->hit < ch->max_hit / 2
	  && (door = number_bits (3)) <= 5
	  && (pexit = ch->in_room->exit[door]) != NULL
	  && pexit->to_room != NULL
	  && !IS_AFFECTED (ch, AFF_WEBBED)
	  && ch->level < 900
	  && !IS_SET (pexit->exit_info, EX_CLOSED)
	  && !IS_SET (pexit->to_room->room_flags, ROOM_NO_MOB))
      {
	 do_flee (ch, "auto");	//      Force the mob to use flee command
      }
   }
   return;
}

/*
 * Update the moonphases
 */
/*
 * Updated for the NEW static RL days
 * -Tijer 2/1/2004
 */
void moon_update (void)
{
        if ((time_info.minutelist % (36145440/850)) < (36145440/850/8))
           weather_info.moonphase = MOON_NEW;
        else if ((time_info.minutelist % (36145440/850)) < (36145440/850/8*2))
           weather_info.moonphase = MOON_CRESCENT;
        else if ((time_info.minutelist % (36145440/850)) < (36145440/850/8*3))
           weather_info.moonphase = MOON_HALF;
        else if ((time_info.minutelist % (36145440/850)) < (36145440/850/8*4))
           weather_info.moonphase = MOON_GIBBOUS;
        else if ((time_info.minutelist % (36145440/850)) < (36145440/850/8*5))
           weather_info.moonphase = MOON_FULL;
        else if ((time_info.minutelist % (36145440/850)) < (36145440/850/8*6))
           weather_info.moonphase = MOON_GIBBOUS + MOON_WANING;
        else if ((time_info.minutelist % (36145440/850)) < (36145440/850/8*7))
           weather_info.moonphase = MOON_HALF + MOON_WANING;
        else if ((time_info.minutelist % (36145440/850)) < (36145440/850))
           weather_info.moonphase = MOON_CRESCENT + MOON_WANING;
}

/*
 * Update the weather.
 */
 // Updated -- Serenity
void weather_update (void)
{
   char buf[MAX_STRING_LENGTH];
   char ybuf[MAX_STRING_LENGTH];
   DESCRIPTOR_DATA *d;
   CHAR_DATA *ch = NULL;
   int diff;
   int length;
   bool char_up;
   bool mes_all = FALSE;

   strcpy (buf, "Bug - Please inform KaVir.\n\r");

   if (IS_SET (world_affects, WORLD_ECLIPSE))
   {
      strcpy (buf, "The sun emerges from behind the moon.\n\r");
      REMOVE_BIT (world_affects, WORLD_ECLIPSE);
      mes_all = TRUE;
   }
   else if (IS_SET (world_affects, WORLD_FOG) && number_range (1, 5) == 1)
   {
      strcpy (buf, "The fog disperses.\n\r");
      REMOVE_BIT (world_affects, WORLD_FOG);
      mes_all = TRUE;
   }
   else if (IS_SET (world_affects, WORLD_RAIN) && number_range (1, 5) == 1)
   {
      strcpy (buf, "It is no longer raining quite so heavily.\n\r");
      REMOVE_BIT (world_affects, WORLD_RAIN);
      mes_all = TRUE;
   }
   else if (IS_SET (world_affects, WORLD_SNOW) && number_range (1, 5) == 1)
   {
      strcpy (buf, "It is no longer snowing quite so heavily.\n\r");
      REMOVE_BIT (world_affects, WORLD_SNOW);
      mes_all = TRUE;
   }

   if (mes_all)
   {
      for (d = first_descriptor; d != NULL; d = d->next)
      {
	 if (d->connected == CON_PLAYING
	     && (ch = d->character) != NULL
	     && !IS_NPC (ch)
	     && !IS_EXTRA (ch, EXTRA_OSWITCH)
	     && !IS_HEAD (ch, LOST_HEAD)
	     && ch->in_room != NULL
	     && ch->in_room->sector_type != SECT_INSIDE && IS_OUTSIDE (ch))
	    send_to_char (buf, ch);
      }
   }

   buf[0] = '\0';

   time_info.minutelist += 60 - (time_info.minutelist % 60);

   switch (++time_info.hour)
   {
   case 4:
      weather_info.moonlight = MOON_SET;
      strcat (buf, "The moon slowly slides below the horizon.\n\r");
      break;
   case 5:
      weather_info.moonlight = MOON_DOWN;
      weather_info.time_of_day = MORNING;
      for (d = first_descriptor; d != NULL; d = d->next)
      {
	 if (d->connected == CON_PLAYING
	     && (ch = d->character) != NULL
	     && !IS_NPC (ch)
	     && !IS_EXTRA (ch, EXTRA_OSWITCH)
	     && !IS_HEAD (ch, LOST_HEAD) && IS_CLASS (ch, CLASS_VAMPIRE))
	    send_to_char
	       ("You feel weary as the night begins to come to an end.\n\r",
		ch);
      }
      break;
   case 6:
      weather_info.sunlight = SUN_RISE;
      strcat (buf, "The sun ascends the eastern horizon.\n\r");
      break;
   case 10:
      weather_info.time_of_day = DAY;
      strcat (buf, "As the sun rises, a new day commences.\n\r");
      break;
   case 12:
      strcat (buf,
	      "You hear chimes in the distance announcing midday.\n\r");
      break;
   case 17:
      weather_info.time_of_day = EVENING;
      strcat (buf,
	      "The sun begins its descent towards the western horizon.\n\r");
      break;
   case 19:
      weather_info.sunlight = SUN_SET;
      strcat (buf, "The sun is lost to the western horizon.\n\r");
      break;
   case 20:
      weather_info.sunlight = SUN_DARK;
      strcat (buf, "Darkness now complete, night sweeps over the land.\n\r");
      for (d = first_descriptor; d != NULL; d = d->next)
      {
	 if (d->connected == CON_PLAYING && (ch = d->character) != NULL
	     && IS_OUTSIDE (d->character) && IS_AWAKE (d->character)
	     && !IS_NPC (ch))
	 {
	    send_night (d->character);
	 }
      }
      break;
   case 21:
      weather_info.moonlight = MOON_RISE;
      weather_info.time_of_day = NIGHT;
      if (weather_info.moonphase == MOON_CRESCENT)
	 strcat (buf, "A crescent moon slowly rises above the horizon.\n\r");
      if (weather_info.moonphase == MOON_HALF)
	 strcat (buf,
		 "You see the moon, half tonight, slowly rising from the horizon.\n\r");
      if (weather_info.moonphase == MOON_GIBBOUS)
	 strcat (buf,
		 "The gibbous moon ascends, starting its nocturnal journey.\n\r");
      if (weather_info.moonphase == MOON_FULL)
	 strcat (buf,
		 "The full moon slowly ascends from its cradle, preparing to journey across the night sky.\n\r");
      if (weather_info.moonphase == MOON_WANING)
	 strcat (buf,
		 "The quickly waning moon slowly climbs to its nightly throne.\n\r");
      if (weather_info.moonphase == MOON_NEW)
	 strcat (buf,
		 "Hardly visible, the moon still ascends the horizon.\n\r");
      break;
   case 22:
      weather_info.moonlight = MOON_UP;
      break;
   case 23:
      strcat (buf,
	      "The moon starts its slow journey across the night sky. Stars glinting like tears trailing behind it.\n\r");
      break;
   case 24:
      time_info.hour = 0;
      time_info.day++;
      time_info.daylist++;

      if (time_info.full700 < 2 && time_info.day >= 255675)
      {
	 time_info.full700++;
	 time_info.day -= 255675;
      }
      else if (time_info.part182 < 1 && time_info.day >= 66707)
      {
	 time_info.part182++;
	 time_info.day -= 66707;
	 time_info.day += 10;	// To make up for October 5-14th 
      }
      else if (time_info.part018 < 1 && time_info.day >= 6287)
      {
	 time_info.part018++;
	 time_info.day -= 6287;
      }
      else if (time_info.day >= 146097)
      {
	 time_info.full400++;
	 time_info.day -= 146097;
      }
      for (d = first_descriptor; d != NULL; d = d->next)
      {
	 char_up = FALSE;
	 if (d->connected == CON_PLAYING && (ch = d->character) != NULL
	     && !IS_NPC (ch))
	 {
	    stc ("An ancient bell tolls somewhere in the distance, declaring the witching hour.\n\r", ch);

	    if (ch->fighting == NULL && !IS_SET (ch->newbits, NEW_NATURAL)
		&& ch->monkab[SPIRIT] >= 2)
	       SET_BIT (ch->newbits, NEW_NATURAL);
	    if (IS_SET (ch->newbits, NEW_NOPAIN))
	    {
	       REMOVE_BIT (ch->newbits, NEW_NOPAIN);
	       send_to_char ("You no longer feel so oblivious to pain.\n\r",
			     ch);
	    }
	    if (IS_SET (ch->garou1, GAROU_WHELP1)
		&& IS_SET (ch->garou1, GAROU_WHELP2))
	    {
	       stc ("The Whelps Curse Leaves your body!\n\r", ch);
	       REMOVE_BIT (ch->garou1, GAROU_WHELP1);
	       REMOVE_BIT (ch->garou1, GAROU_WHELP2);
	       ch->max_hit = ch->max_hit + 3000;
	    }
	    if (IS_SET (ch->flag2, AFF2_ROT)
		&& !IS_SET (ch->warp, WARP_INFIRMITY))
	    {
	       send_to_char ("Your flesh feels better.\n\r", ch);
	       REMOVE_BIT (ch->flag2, AFF2_ROT);
	    }
	    if (IS_SET (ch->flag2, AFF2_ROT))
	    {
	       send_to_char ("Your flesh feels better.\n\r", ch);
	       REMOVE_BIT (ch->flag2, AFF2_ROT);
	    }
	    if (IS_SET (ch->flag2, AFF2_BALOR))
	    {
	       stc ("You no longer feel the pain of Balor's Gaze.\n\r", ch);
	       REMOVE_BIT (ch->flag2, AFF2_BALOR);
	    }
	    if (IS_SET (ch->in_room->added_flags, ROOM2_SILENCE))
	    {
	       send_to_char ("The silence leaves the room.\n\r", ch);
	       act ("The silence leaves the room.", ch, NULL, NULL, TO_ROOM);
	       REMOVE_BIT (ch->in_room->added_flags, ROOM2_SILENCE);
	    }
	    if (IS_SET (ch->in_room->added_flags, ROOM2_FLAMING))
	    {
	       send_to_char ("The flames in the room die down.\n\r", ch);
	       act ("The flames in the room die down.", ch, NULL, NULL,
		    TO_ROOM);
	       REMOVE_BIT (ch->in_room->added_flags, ROOM2_FLAMING);
	    }
	    if (IS_CLASS (ch, CLASS_VAMPIRE))
	    {
	       int loopvar = 0;
	       if (IS_EXTRA (ch, EXTRA_POTENCY))
	       {
		  send_to_char ("You feel your blood potency fade away.\n\r",
				ch);
		  ch->pcdata->stats[UNI_GEN]++;
		  REMOVE_BIT (ch->extra, EXTRA_POTENCY);
	       }
	       if (IS_SET (ch->newbits, NEW_TIDE))
	       {
		  REMOVE_BIT (ch->newbits, NEW_TIDE);
		  send_to_char ("The tide of vitae leaves you.\n\r", ch);
	       }
               if (ch->position != POS_FIGHTING)
               {    
	       if ((ch->hit < ch->max_hit) && (ch->fight_timer < 1))
	       {
		  ch->hit = ch->max_hit;
		  char_up = TRUE;
	       }
	       if ((ch->mana < ch->max_mana) && (ch->fight_timer < 1))
	       {
		  ch->mana = ch->max_mana;
		  char_up = TRUE;
	       }
	       if ((ch->move < ch->max_move) && (ch->fight_timer < 1))
	       {
		  ch->move = ch->max_move;
		  char_up = TRUE;
	       }
	       for (loopvar = 0; loopvar < 6; loopvar++)
		  ch->loc_hp[loopvar] = 0;
	       if (char_up)
	       {
		  send_to_char
		     ("You feel the strength of the kindred flow through your veins!\n\r",
		      ch);
		  update_pos (ch);
	       }
               }
	    }
	 }
      }
      if (time_info.day == 22) switch (time_info.month)
      {
          case 2:
              weather_info.season = SPRING;
              break;

          case 5:
              weather_info.season = SUMMER;
              break;

          case 8:
              weather_info.season = AUTUMN;
              break;

          case 11:
              weather_info.season = WINTER;
              break;

          default:
              break;
      }
      break;
   }
   length = 0;

   if (time_info.month == 0)
      length = 31;
   if (time_info.month == 1)
   {
      if (time_info.part182 != 0
	  && ((time_info.year) !=
	      (((time_info.year) * 400) / ((time_info.year % 400) + 1))
	      || ((time_info.year) !=
		  (((time_info.year) * 100) / ((time_info.year % 100) + 1))
		  && (time_info.year) ==
		  (((time_info.year) * 4) / ((time_info.year % 4) + 1)))))
	 length = 29;
      else if (time_info.part182 == 0
	       && time_info.year ==
	       (((time_info.year) * 4) / ((time_info.year % 4) + 1)))
	 length = 29;
      else
	 length = 28;
   }
   if (time_info.month == 2)
      length = 31;
   if (time_info.month == 3)
      length = 30;
   if (time_info.month == 4)
      length = 31;
   if (time_info.month == 5)
      length = 30;
   if (time_info.month == 6)
      length = 31;
   if (time_info.month == 7)
      length = 31;
   if (time_info.month == 8)
      length = 30;
   if (time_info.month == 9)
      length = 31;
   if (time_info.month == 10)
      length = 30;
   if (time_info.month == 11)
      length = 31;
   if (time_info.day >= length)
   {
      time_info.day = 0;
      time_info.month++;
   }

   if (time_info.month >= 12)
   {
      time_info.month = 0;
      time_info.year++;
      sprintf (ybuf, "It is now the Year %d.\n\r", time_info.year);
      strcat (buf, ybuf);
   }


   /*
    * Weather change.
    */
   if (time_info.month >= 9 && time_info.month <= 16)
      diff = weather_info.mmhg > 985 ? -2 : 2;
   else
      diff = weather_info.mmhg > 1015 ? -2 : 2;

   weather_info.change += diff * dice (1, 4) + dice (2, 6) - dice (2, 6);
   weather_info.change = UMAX (weather_info.change, -12);
   weather_info.change = UMIN (weather_info.change, 12);

   weather_info.mmhg += weather_info.change;
   weather_info.mmhg = UMAX (weather_info.mmhg, 960);
   weather_info.mmhg = UMIN (weather_info.mmhg, 1040);

   switch (weather_info.sky)
   {
   default:
      bug ("Weather_update: bad sky %d.", weather_info.sky);
      weather_info.sky = SKY_CLOUDLESS;
      break;
   case SKY_CLOUDLESS:
      if (weather_info.mmhg < 990
	  || (weather_info.mmhg < 1010 && number_bits (2) == 0))
      {
	 strcat (buf, "The sky is getting cloudy.\n\r");
	 weather_info.sky = SKY_CLOUDY;
      }
      break;
   case SKY_CLOUDY:
      if (weather_info.mmhg < 970
	  || (weather_info.mmhg < 990 && number_bits (2) == 0))
      {
	 strcat (buf, "It starts to rain.\n\r");
	 weather_info.sky = SKY_RAINING;
      }

      if (weather_info.mmhg > 1030 && number_bits (2) == 0)
      {
	 strcat (buf, "The clouds disappear.\n\r");
	 weather_info.sky = SKY_CLOUDLESS;
      }
      break;
   case SKY_RAINING:
      if (IS_SET (world_affects, WORLD_RAIN))
      {
	 if (weather_info.mmhg < 970)
	    weather_info.mmhg += 10;
	 else if (weather_info.mmhg > 1010)
	    weather_info.mmhg -= 10;
	 strcat (buf, "The rain pours down heavily from the sky.\n\r");
	 break;
      }
      if (weather_info.mmhg < 970 && number_bits (2) == 0)
      {
	 strcat (buf, "Lightning flashes in the sky.\n\r");
	 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 = first_descriptor; 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;
}

/*
 * Handle events.
 */
void event_update (void)
{
   EVENT_DATA *ev = NULL, *ev_next, *ev_last = ev;

   if (!events)
      return;
   for (ev = events; ev; ev = ev_next)
   {
      ev_next = ev->next;
      if (ev->delay-- <= 0)
      {
	 switch (ev->action)
	 {
	 case ACTION_PRINT:
	    if ((!ev->args[0]) || (!ev->argv[0]))
	    {
	    kill_event}
	    send_to_char (ev->args[0], ev->argv[0]);
	    break;
	 case ACTION_FUNCTION:
	    if (!ev->args[0])
	    {
	    kill_event}
	    do_function (ev->argv[0], ev->do_fun, ev->args[0]);
	    break;
	 case ACTION_WAIT:
	    if (!ev->argv[0])
	    {
	    kill_event}
	    WAIT_STATE (ev->to, PULSE_PER_SECOND * ev->argi[0]);
	    break;
	 case ACTION_ACT:
	    if (!ev->args[0] || !ev->argv[0])
	    {
	    kill_event}
	    act (ev->args[0], ev->argv[0], ev->argv[1], ev->argv[2],
		 ev->argi[0]);
	    break;
	 }
	 if (!ev_next)
	 {
	    if ((ev != events) && (ev_last != NULL))
	    {
	       if (ev_last->next == ev)
		  ev_last->next = NULL;
	    }
	    else
	    {
	       if (ev == events)
		  events = NULL;
	    }
	    free_event (ev);
	    return;
	 }
	 if (ev_last != NULL)
	    ev_last->next = ev_next;
	 else
	    events = ev_next;
	 free_event (ev);
	 continue;
      }				/* end delay */
      ev_last = ev;
   }				/* end loop */
   return;
}

// New function - Blood_update  -- Serenity
void blood_update (void)
{
   CHAR_DATA *ch;

   // begin regeneration functions -- Serenity
   for (ch = char_list; ch != NULL; ch = ch->next)
   {
      gain_condition (ch, COND_DRUNK, -1);
      if (!IS_CLASS (ch, CLASS_VAMPIRE))
      {
	 gain_condition (ch, COND_FULL, -1);
	 gain_condition (ch, COND_THIRST, -1);
      }
      else
      {
	 int blood;
	 blood = -1;

	 if (ch->beast > 0)
	 {
	    if (IS_VAMPAFF (ch, VAM_CLAWS))
	       blood -= 1;
	    if (IS_VAMPAFF (ch, VAM_FANGS))
	       blood -= 1;
	    if (IS_VAMPAFF (ch, VAM_NIGHTSIGHT))
	       blood -= 1;
	    if (IS_VAMPAFF (ch, AFF_SHADOWSIGHT))
	       blood -= number_range (1, 3);
	    if (IS_SET (ch->act, PLR_HOLYLIGHT))
	       blood -= 1;
	    if (IS_VAMPAFF (ch, VAM_DISGUISED))
	       blood -= number_range (5, 10);
	    if (IS_VAMPAFF (ch, VAM_CHANGED))
	       blood -= number_range (5, 10);
	    if (IS_VAMPAFF (ch, IMM_SHIELDED))
	       blood -= number_range (1, 3);
	    if (IS_POLYAFF (ch, POLY_SERPENT))
	       blood -= number_range (1, 3);
	    if (ch->beast == 100)
	       blood *= 2;
	 }
	 gain_condition (ch, COND_THIRST, blood);
      }
   }
}

// New Function - Regen_update, controls regen rate -- Serenity
void regen_update (void)
{
   CHAR_DATA *ch;
   int clot_sn;
   bool SPEC_REGEN = FALSE;
   int regen_multi = 1;
   bool is_obj=FALSE;
   bool drop_out = FALSE;
   int start_position;

   clot_sn = skill_lookup ("clot");

   // begin regeneration functions -- Serenity
   for (ch = char_list; ch != NULL; ch = ch->next)
   {
      if (IS_SUPER_NPC(ch))
         update_orgasm (ch);
      else if (!IS_NPC (ch))
      {
	 if ((IS_HEAD (ch, LOST_HEAD) || IS_EXTRA (ch, EXTRA_OSWITCH)))
	    is_obj = TRUE;
	 else if (ch->pcdata->obj_vnum != 0)
	 {
	    is_obj = TRUE;
	    SET_BIT (ch->extra, EXTRA_OSWITCH);
	 }

	 if ((ch->pcdata->condition[COND_DRUNK] > 10)
	     && (number_range (1, 10) == 1))
	 {
	    send_to_char ("You hiccup loudly.\n\r", ch);
	    act ("$n hiccups.", ch, NULL, NULL, TO_ROOM);
	 }
	 // Ya know xsocials are a waste of time, space, and ram?
	 // Just thought I'd express my opinion -- Serenity
	update_orgasm (ch);	// waste of time..see above comment.. -- Seren  

	 if (IS_HERO (ch))
	 {
	    if (IS_CLASS (ch, CLASS_HIGHLANDER))
	    {
	       if ((number_range (1, 100) < 5) && (ch->quickening[0] > 0))
		  ch->quickening[0] -= 1;

	       if (ch->hempower > 1)
		  ch->hempower = 1;	// set it to 1 use new system
	       // Highlander Empower Update - Krynn
	       if (ch->hempower > -1)
	       {
		  if (ch->quickening[0] < 1)
		  {
		     ch->hempower -= 1;
		     if (ch->hempower == 0)
			send_to_char
			   ("#rAs your empowerment wears off, the sparkles of energy fade from your body.\n\r",
			    ch);
		     if (ch->hempower == -1)
			send_to_char
			   ("#cYou may now recharge your quickening once more.\n\r",
			    ch);
		  }
	       }
	    }
	    if (IS_CLASS (ch, CLASS_MONK))
	    {
               if (ch->chi[CURRENT] > 0)
	       {
                  if (ch->move > ch->chi[CURRENT] * 500)
                  {
                     ch->move -= ch->chi[CURRENT] * 500;

                     if ((ch->position != POS_FIGHTING)
                         && (number_range (1, 8) == 2))
                     {
                        ch->chi[CURRENT]--;
                        stc ("You feel more relaxed.\n\r", ch);
                        act ("$n looks more relaxed.", ch, NULL, NULL, TO_ROOM);
                     }
                  }
                  else
                  {
                     ch->chi[CURRENT]--;
                     stc ("You feel more relaxed.\n\r", ch);
                     act ("$n looks more relaxed.", ch, NULL, NULL, TO_ROOM);
                  }
	       }
	       if ((ch->fighting == NULL) && (number_percent () <= 50))
	       {
		  if (ch->monkblock > 0)
		     ch->monkblock -= 1;
	       }

	       if ((ch->focus[MAXIMUM] > 0)
		   && (ch->focus[MAXIMUM] > ch->focus[CURRENT]))
	       {
		  if (ch->position == POS_SLEEPING)
		     ch->focus[CURRENT] += number_range (2, 3);
		  else if (ch->position == POS_MEDITATING)
		     ch->focus[CURRENT] += number_range (4, 5);
		  else if (ch->position == POS_RESTING)
		     ch->focus[CURRENT] += number_range (1, 2);
		  else if (ch->position == POS_FIGHTING)
		     ch->focus[CURRENT] += 0;
		  else
		     ch->focus[CURRENT] += number_range (1, 2);
	       }
	    }
	    // Update rage/ki etc
	    if (IS_CLASS (ch, CLASS_NINJA))
	    {
	       if (ch->pcdata->powers[NINJAKI] > 150)
		  ch->pcdata->powers[NINJAKI] = 150;
	       if (ch->position == POS_MEDITATING)
		  ch->pcdata->powers[NINJAKI] += number_range (30, 70);
	       else
		  ch->pcdata->powers[NINJAKI] += number_range (15, 22);

	       if (ch->pcdata->powers[HARA_KIRI] > 0)
		  ch->pcdata->powers[HARA_KIRI]--;

	       if ((ch->position == POS_FIGHTING)
		   && (ch->pcdata->stats[UNI_RAGE] > 0)
		   && (ch->pcdata->stats[UNI_RAGE] < 250)
		   && (!IS_ITEMAFF (ch, ITEMA_RAGER)))
		  ch->pcdata->stats[UNI_RAGE] += 1;
	       else if ((ch->pcdata->stats[UNI_RAGE] > 0)
			&& (!IS_ITEMAFF (ch, ITEMA_RAGER)))
		  ch->pcdata->stats[UNI_RAGE] -= 1;
	    }
	    if (IS_CLASS (ch, CLASS_VAMPIRE))
	    {
	       if ((ch->position == POS_FIGHTING)
		   && (ch->pcdata->stats[UNI_RAGE] > 0)
		   && (ch->pcdata->stats[UNI_RAGE] < 25)
		   && (!IS_ITEMAFF (ch, ITEMA_RAGER)))
		  ch->pcdata->stats[UNI_RAGE] += 1;
	       else if ((ch->pcdata->stats[UNI_RAGE] > 0)
			&& (!IS_ITEMAFF (ch, ITEMA_RAGER)))
		  ch->pcdata->stats[UNI_RAGE] -= 1;

	       if ((ch->beast > 0)
		   && (ch->pcdata->condition[COND_THIRST] <= 15))
	       {
		  act ("You bare your fangs and scream in rage from lack of blood.", ch, NULL, NULL, TO_CHAR);
		  act ("$n bares $s fangs and screams in rage.", ch, NULL,
		       NULL, TO_ROOM);
		  do_beastlike (ch, "");
	       }
	    }
	    if (IS_CLASS (ch, CLASS_WEREWOLF))
	    {
	       if ((ch->position == POS_FIGHTING)
		   && (ch->pcdata->stats[UNI_RAGE] < 350)
		   && (!IS_ITEMAFF (ch, ITEMA_RAGER)))
	       {
		  if (ch->gifts[GETOFFENRIS] > 4)
		     ch->pcdata->stats[UNI_RAGE] += number_range (15, 30);
		  else
		     ch->pcdata->stats[UNI_RAGE] += number_range (5, 10);
	       }
	       else if ((ch->pcdata->stats[UNI_RAGE] > 0)
			&& (!IS_ITEMAFF (ch, ITEMA_RAGER)))
		  ch->pcdata->stats[UNI_RAGE] -= 1;

	       if ((ch->pcdata->stats[UNI_RAGE] >= 100)
		   && (!IS_SET (ch->special, SPC_WOLFMAN)))
		  do_werewolf (ch, "");
	       if ((ch->pcdata->stats[UNI_RAGE] < 100)
		   && (IS_SET (ch->special, SPC_WOLFMAN)))
		  do_unwerewolf (ch, "");

	       if (ch->gifts[UKTENA] >= 2 && !IS_AFFECTED (ch, AFF_FLYING))
		  SET_BIT (ch->affected_by, AFF_FLYING);

	       if (ch->gnosis[GMAXIMUM] > 0)
	       {
		  int current_gain = 0;
		  if (ch->position == POS_SLEEPING)
		     current_gain += number_range (2, 10);
		  else if (ch->position == POS_RESTING)
		     current_gain += number_range (3, 5);
		  else if (ch->position == POS_FIGHTING)
		     current_gain += 0;
		  else
		     current_gain += number_range (2, 3);

		  if ((current_gain + ch->gnosis[GCURRENT]) >
		      ch->gnosis[GMAXIMUM])
		     current_gain =
			(ch->gnosis[GMAXIMUM] - ch->gnosis[GCURRENT]);

		  ch->gnosis[GCURRENT] += current_gain;
		  if (current_gain > 0)
		     stcf (ch,
			   "#gYou feel your gnosis recharging slowly. #y[ #w+%d #y]#n\n\r",
			   current_gain);
	       }
	    }
	    if (IS_CLASS (ch, CLASS_MAGE))
	    {
	       if (ch->spheres[MPRI] > 0)
	       {
		  int quint_ava_gain =
		     number_range (1, (ch->spheres[MPRI] / 2));
		  int quint_bod_gain =
		     number_range (1, (ch->spheres[MPRI] / 2));
		  int max_quint = ch->spheres[MPRI];

		  if ((quint_ava_gain + ch->quint[AVATAR]) > max_quint)
		     quint_ava_gain = max_quint - ch->quint[AVATAR];
		  if ((quint_bod_gain + ch->quint[BODY]) > max_quint)
		     quint_bod_gain = max_quint - ch->quint[BODY];

		  ch->quint[AVATAR] =
		     UMIN ((quint_ava_gain + ch->quint[AVATAR]), max_quint);
		  ch->quint[BODY] =
		     UMIN ((quint_bod_gain + ch->quint[BODY]), max_quint);
		  if ((quint_ava_gain + quint_bod_gain) > 0)
		     stcf (ch,
			   "#yYou feel the quintessence in your body recharge slowly. #g[ #cAva-#y%d #cBod-#y%d #g]#n\n\r",
			   quint_ava_gain, quint_bod_gain);
	       }
	    }
	 }

	 // Default regen for being alive and in the world is 1 point.
	 regen_multi = 1;	// Controls amount of regeneration. -- Serenity
	 if (IS_CLASS (ch, CLASS_NINJA) && (ch->pcdata->stats[UNI_RAGE] > 0))
	 {
	    SPEC_REGEN = TRUE;	// x1 regen for ninjas
	    regen_multi += 1;	// Controls amount of regeneration. -- Serenity
	 }
         if (IS_CLASS (ch, CLASS_VAMPIRE))
	 {
	    if (ch->pcdata->stats[UNI_RAGE] > 0)
            {
               regen_multi += 1; // Controls amount of regeneration. -- Serenity
               SPEC_REGEN = TRUE;  // x1 regen for vampires
            }
	    else
               regen_multi -= 1;        // Controls amount of regeneration. -- Serenity
	 }
	 if (IS_CLASS (ch, CLASS_WEREWOLF))
	 {
	    SPEC_REGEN = TRUE;	// x4 regen for werewolves while asleep
	    if (ch->position == POS_SLEEPING)
	       regen_multi += 4;	// Controls amount of regeneration. -- Serenity
	    else
	       regen_multi += 1;	// Controls amount of regeneration. -- Serenity                                                         
	 }
	 if (IS_CLASS (ch, CLASS_DRAGON))
	 {
	    SPEC_REGEN = TRUE;	// x4 regen for werewolves while asleep
	    if (ch->position == POS_SLEEPING)
	       regen_multi += 4;	// Controls amount of regeneration. -- Serenity
	    else
	       regen_multi += 1;	// Controls amount of regeneration. -- Serenity
	 }
	 if (IS_CLASS (ch, CLASS_FAE))
	 {
	    SPEC_REGEN = TRUE;	// x4 regen for fae while dreaming
	    if (IS_SET (ch->extra2, EXTRA2_DREAMING))
	       regen_multi += 4;	// Controls amount of regeneration. -- Serenity
	    else
	       regen_multi += 1;	// Controls amount of regeneration. -- Serenity
	 }
	 if (IS_CLASS (ch, CLASS_DROW)
	     && (IS_SET (ch->pcdata->powers[1], DPOWER_REGEN)))
	 {
	    SPEC_REGEN = TRUE;	// x5 regen for drow at altar, or x1 with regen power
	    if (ch->in_room != NULL)
	    {
	       if ((ch->in_room->vnum == 29701)
		   || (ch->in_room->vnum == 29702))
		  regen_multi += 8;	// Controls amount of regeneration. -- Serenity
	       else
		  regen_multi += 1;	// Controls amount of regeneration. -- Serenity
	    }
	 }
	 if (IS_CLASS (ch, CLASS_WRAITH))
	 {
	    SPEC_REGEN = TRUE;	// x1 regen for wraiths, x3 in shadow, x5 in tempest
	    if (ch->in_room != NULL)
	    {
	       if ((ch->in_room->vnum == ROOM_VNUM_TEMPEST))
		  regen_multi += 5;	// Controls amount of regeneration. -- Serenity
	       else
		  regen_multi += 1;	// Controls amount of regeneration. -- Serenity
	    }
	 }
	 if (IS_CLASS (ch, CLASS_DEMON) || IS_SET (ch->special, SPC_CHAMPION))
	 {
	    SPEC_REGEN = TRUE;	// x4 regen for demons in hell
	    if (ch->in_room != NULL)
	    {
	       if ((ch->in_room->vnum == 30000))
		  regen_multi += 7;	// Controls amount of regeneration. -- Serenity
               else if (IS_SET (ch->warp, WARP_REGEN))
                  regen_multi += 2;     // Controls amount of regeneration. -- Serenity
               else
		  regen_multi += 1;	// Controls amount of regeneration. -- Serenity
	    }
	 }
	 if (IS_CLASS (ch, CLASS_MAGE))
	 {
	    SPEC_REGEN = TRUE;	// x4 regen for mages while meditating
	    if (ch->position == POS_MEDITATING)
	       regen_multi += 4;	// Controls amount of regeneration. -- Serenity
	    else
	       regen_multi += 1;	// Controls amount of regeneration. -- Serenity
	 }
	 if (IS_CLASS (ch, CLASS_MONK))
	 {
	    SPEC_REGEN = TRUE;	// x1 regen for Monk
	    regen_multi += 1;	// Controls amount of regeneration. -- Serenity
	 }
	 if (IS_CLASS (ch, CLASS_HIGHLANDER))
	 {
	    SPEC_REGEN = TRUE;	// x1 regen for highlanders
	    regen_multi += 1;	// Controls amount of regeneration. -- Serenity
	 }
	 if (IS_ITEMAFF (ch, ITEMA_REGENERATE))
	 {			// Auto sets SPEC_REGEN even if not set before
	    SPEC_REGEN = TRUE;	// +1 regen for regeneration item
	    regen_multi += 3;	// Controls amount of regeneration. -- Serenity
	 }
         if (IS_ITEMAFF (ch, ITEMA_RAREREGEN))
	 {			// Auto sets SPEC_REGEN even if not set before
	    SPEC_REGEN = TRUE;	// +1 regen for regeneration item
            if (regen_multi < 2) regen_multi = 1;   // Controls amount of regeneration. -- Serenity
	 }

	 if (IS_EXTRA2 (ch, EXTRA2_INFECTED) && IS_PARA (4))
	 {			// Auto sets SPEC_REGEN even if not set before
	    SPEC_REGEN = TRUE;	// +1 regen for regeneration parasite infection
	    regen_multi += 1;	// Controls amount of regeneration. -- Serenity
	 }
      }

      if (IS_NPC (ch) && IS_SUPER_NPC (ch))	// Super mobs are tuff as hell -- Serenity
      {				// Auto sets SPEC_REGEN even if not set before
	 SPEC_REGEN = TRUE;	// x1 regen for being alove
	 regen_multi += 1;	// Controls amount of regeneration. -- Serenity
      }

      if (SPEC_REGEN)
      {
	 if (ch->loc_hp[6] > 0)
	 {
	    (*skill_table[clot_sn].spell_fun) (clot_sn, ch->level, ch, ch);
	 }
	 else
	 {
	    if ((ch->loc_hp[0] + ch->loc_hp[1] + ch->loc_hp[2] +
		 ch->loc_hp[3] + ch->loc_hp[4] + ch->loc_hp[5]) != 0)
	       reg_mend (ch);
	 }
      }

      start_position = ch->position;
      if (regen_multi > 0)
      {
	 if ((ch->move < ch->max_move)
	     || (ch->mana < ch->max_mana) || (ch->hit < ch->max_hit))
	    werewolf_regen (ch, regen_multi);
      }
      if (IS_AFFECTED (ch, AFF_POISON) && !is_obj)
      {
	 if (!IS_CLASS (ch, CLASS_VAMPIRE) && !IS_CLASS(ch, CLASS_DRAGON))
	 {
	    act ("$n shivers and suffers.", ch, NULL, NULL, TO_ROOM);
            if (ch->hit < 1000 && !IS_NPC(ch))
            {
              stcf (ch, "You shiver and suffer. #g[ #r0 #g]#n\n\r");
            }
            else
            {
	    stcf (ch, "You shiver and suffer. #g[ #r%d #g]#n\n\r",
		  (ch->max_hit / 80));
	    damage (ch, ch, (ch->max_hit / 80), gsn_poison);
            }
	 }
      }
      if (IS_AFFECTED (ch, AFF_FLAMING) && WORN_ARTIFACT (ch, ARTI_DEMONS_HEART))
         REMOVE_BIT (ch->affected_by, AFF_FLAMING);
      if (IS_AFFECTED (ch, AFF_FLAMING) && !is_obj && !drop_out
	  && ch->in_room != NULL)
      {
	 int dam;
	 if (IS_IMMUNE (ch, IMM_HEAT) && !IS_CLASS (ch, CLASS_VAMPIRE))
	 {
	    act ("$n is wreathed in a glowing halo of fire.", ch, NULL, NULL,
		 TO_ROOM);
	    act ("You are wreathed in a glowing halo of fire.", ch, NULL,
		 NULL, TO_CHAR);
	    break;
	 }
	 act ("$n's flesh burns and crisps.", ch, NULL, NULL, TO_ROOM);
	 dam = number_range (250, 500);
	 if (!IS_NPC (ch) && IS_CLASS (ch, CLASS_VAMPIRE))
	    dam *= 2;
         if (ch->hit < 1000 && !IS_NPC(ch))
         {
           stcf (ch, "Your flesh burns and crisps. #g[ #r0 #g]#n\n\r");
         }
         else 
         {
	 stcf (ch, "Your flesh burns and crisps. #g[ #r%d #g]#n\n\r", dam);
	 ch->hit = ch->hit - dam;
         }
	 update_pos (ch);
	 if (ch->hit <= -11)
	 {
	    do_killperson (ch, ch->name);
	    drop_out = TRUE;
	    continue;
	 }
      }
      if (IS_CLASS (ch, CLASS_VAMPIRE)
	  && (!IS_AFFECTED (ch, AFF_SHADOWPLANE)) && (!IS_NPC (ch) && !IS_IMMUNE (ch,IMM_SUNLIGHT))
	  && ch->in_room != NULL && (!ch->in_room->sector_type == SECT_INSIDE)
	  && !is_obj && (!room_is_dark (ch->in_room))
	  && (weather_info.sunlight != SUN_DARK))
      {
	 act ("$n's flesh smolders in the sunlight!", ch, NULL, NULL,
	      TO_ROOM);
	 send_to_char ("Your flesh smolders in the sunlight!\n\r", ch);
	 if (IS_POLYAFF (ch, POLY_SERPENT))
	    ch->hit = ch->hit - number_range (125, 250);
	 else
	    ch->hit = ch->hit - number_range (250, 500);
	 update_pos (ch);
	 if (ch->hit <= -11)
	 {
	    ch->form = 15;
	    do_killperson (ch, ch->name);
	    drop_out = TRUE;
	    continue;
	 }
      }
   }
   return;
}

/*
 * Update all chars, including mobs.
 * This function is performance sensitive.
 */
// Updated -- Serenity
void char_update (void)
{
   CHAR_DATA *ch;
   CHAR_DATA *ch_save;
   CHAR_DATA *ch_quit;
   bool is_obj;
   bool drop_out = FALSE;
   time_t save_time;
   int i;

   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;
      is_obj = FALSE;

      if (!IS_NPC (ch)
	  && (IS_HEAD (ch, LOST_HEAD) || IS_EXTRA (ch, EXTRA_OSWITCH)))
	 is_obj = TRUE;
      else if (!IS_NPC (ch) && ch->pcdata->obj_vnum != 0)
      {
	 is_obj = TRUE;
	 SET_BIT (ch->extra, EXTRA_OSWITCH);
      }

      if (!IS_NPC (ch))
	 ch->pcdata->online++;

      /*
       * 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 (IS_SET (ch->mflags, MAGE_EMBRACED2) && (number_range (1, 100) < 40))
      {
	 stc ("The earth surrounding you starts to slowly crack.\n\r", ch);
	 SET_BIT (ch->mflags, MAGE_EMBRACED1);
	 REMOVE_BIT (ch->mflags, MAGE_EMBRACED2);
      }
      else if (IS_SET (ch->mflags, MAGE_EMBRACED1)
	       && (number_range (1, 100) < 60))
      {
	 stc ("The earth surrounding you falls away.\n\r", ch);
	 REMOVE_BIT (ch->mflags, MAGE_EMBRACED1);
      }

      // Char Timers
      if (!IS_NPC (ch))
      {
	 if (ch->pcdata->tick_timer[TIMER_DSLEEP] == 1)
	 {
	    stc ("You awaken from your deep sleep.\n\r", ch);
	    do_stand (ch, "");
	    ch->pcdata->condition[COND_FULL] = 100;
	 }
	 for (i = 0; i < MAX_TIMER; i++)
	 {
	    if (ch->pcdata->tick_timer[i] > 0)
	       ch->pcdata->tick_timer[i] -= 1;
	 }
      }

      if (IS_SET (ch->flag2, AFF_SEVERED))
      {
	 REMOVE_BIT (ch->flag2, AFF_SEVERED);
	 sprintf (log_buf,
		  "With a last gasp of breath, %s dies due to massive lower body trauma!",
		  ch->name);
	 do_fatality (ch, log_buf);
	 act ("With a last gasp of breath, $n dies due to massive lower body trauma.", ch, NULL, NULL, TO_ROOM);
	 if (!IS_NPC (ch))
	    send_to_char ("Your injuries prove too much, and you die.\n\r",
			  ch);
	 raw_kill (ch, ch);
	 continue;
      }
      /*Be sure to define raw_kill up top of update.c */

      if (ch->position == POS_STUNNED && !is_obj)
      {
	 if (ch->hit < 1)
	    ch->hit += number_range (2, 4);
	 update_pos (ch);
      }
/*

      if (IS_IMMORTAL (ch) && (++ch->timer > 120)
	  && (!IS_SET (ch->flag2, EXTRA_AFK)))
      {
	 SET_BIT (ch->flag2, EXTRA_AFK);
	 sprintf (log_buf, "#y%s #ris now AFK! (Due to Idle Timer)#n", ch->name);
	 do_info (ch, log_buf);
      }
*/

      if (!IS_NPC (ch) && ((ch->level < LEVEL_IMMORTAL && !is_obj) || !ch->desc))
      {
	 OBJ_DATA *obj;

	 if (((obj = get_eq_char (ch, WEAR_WIELD)) != NULL
	      && obj->item_type == ITEM_LIGHT
	      && obj->value[2] > 0)
	     || ((obj = get_eq_char (ch, WEAR_HOLD)) != 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 (!IS_SET (ch->newbits, NEW_NOTEWRITE))

	 {

	    if (++ch->timer >= 12)
	    {
               if (ch->was_in_room == NULL && ch->in_room != NULL
                   && ch->position != POS_FIGHTING && !IS_IMMORTAL (ch) && !IS_SET(ch->flag2, EXTRA_AFK))
	       {
		  ch->was_in_room = ch->in_room;
		  act ("$n disappears into the void.", ch, NULL, NULL,
		       TO_ROOM);
		  if (IS_IMMUNE (ch, IMM_SUMMON))
		     REMOVE_BIT (ch->immune, IMM_SUMMON);
                  //herematt
                  if (!IS_SET(ch->more, MORE_JAIL))
                  {
		  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));
                  WAIT_STATE(ch, 36);
                  }
	       }
	    }
	    if ((ch->timer > 30) )
	    {
              
	       ch->fight_timer = 0;
	       ch->pcdata->login_timer = 0;
	       ch_quit = ch;
	    }
 	    if ( ch->fight_timer > 240 )
		ch->fight_timer = 240;
	    if ( ch->pcdata->login_timer > 240 )
		ch->pcdata->login_timer = 240;
	 }
      }

      for (paf = ch->affected; paf != NULL; paf = paf_next)
      {
	 paf_next = paf->next;
	 if (paf->duration > 0)
	 {
	    paf->duration--;
	 }
	 else
	 {
	    if (paf_next == NULL || paf_next->type != paf->type
		|| paf_next->duration > 0)
	    {
	       if (paf->type > 0 && skill_table[paf->type].msg_off && !is_obj)
	       {
		  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 (ch->loc_hp[6] > 0 && !is_obj && ch->in_room != NULL)
      {
	 int dam = 0;
	 int minhit = 0;
	 if (!IS_NPC (ch))
	    minhit = -11;
	 if (IS_BLEEDING (ch, BLEEDING_HEAD) && (ch->hit - dam) > minhit)
	 {
	    act ("A spray of blood shoots from the stump of $n's neck.", ch,
		 NULL, NULL, TO_ROOM);
	    send_to_char
	       ("A spray of blood shoots from the stump of your neck.\n\r",
		ch);
	    dam += number_range (20, 50);
	 }
	 if (IS_BLEEDING (ch, BLEEDING_THROAT) && (ch->hit - dam) > minhit)
	 {
	    act ("Blood pours from the slash in $n's throat.", ch, NULL, NULL,
		 TO_ROOM);
	    send_to_char ("Blood pours from the slash in your throat.\n\r",
			  ch);
	    dam += number_range (10, 20);
	 }
	 if (IS_BLEEDING (ch, BLEEDING_ARM_L) && (ch->hit - dam) > minhit)
	 {
	    act ("A spray of blood shoots from the stump of $n's left arm.",
		 ch, NULL, NULL, TO_ROOM);
	    send_to_char
	       ("A spray of blood shoots from the stump of your left arm.\n\r",
		ch);
	    dam += number_range (10, 20);
	 }
	 else if (IS_BLEEDING (ch, BLEEDING_HAND_L)
		  && (ch->hit - dam) > minhit)
	 {
	    act ("A spray of blood shoots from the stump of $n's left wrist.",
		 ch, NULL, NULL, TO_ROOM);
	    send_to_char
	       ("A spray of blood shoots from the stump of your left wrist.\n\r",
		ch);
	    dam += number_range (5, 10);
	 }
	 if (IS_BLEEDING (ch, BLEEDING_ARM_R) && (ch->hit - dam) > minhit)
	 {
	    act ("A spray of blood shoots from the stump of $n's right arm.",
		 ch, NULL, NULL, TO_ROOM);
	    send_to_char
	       ("A spray of blood shoots from the stump of your right arm.\n\r",
		ch);
	    dam += number_range (10, 20);
	 }
	 else if (IS_BLEEDING (ch, BLEEDING_HAND_R)
		  && (ch->hit - dam) > minhit)
	 {
	    act ("A spray of blood shoots from the stump of $n's right wrist.", ch, NULL, NULL, TO_ROOM);
	    send_to_char
	       ("A spray of blood shoots from the stump of your right wrist.\n\r",
		ch);
	    dam += number_range (5, 10);
	 }
	 if (IS_BLEEDING (ch, BLEEDING_LEG_L) && (ch->hit - dam) > minhit)
	 {
	    act ("A spray of blood shoots from the stump of $n's left leg.",
		 ch, NULL, NULL, TO_ROOM);
	    send_to_char
	       ("A spray of blood shoots from the stump of your left leg.\n\r",
		ch);
	    dam += number_range (10, 20);
	 }
	 else if (IS_BLEEDING (ch, BLEEDING_FOOT_L)
		  && (ch->hit - dam) > minhit)
	 {
	    act ("A spray of blood shoots from the stump of $n's left ankle.",
		 ch, NULL, NULL, TO_ROOM);
	    send_to_char
	       ("A spray of blood shoots from the stump of your left ankle.\n\r",
		ch);
	    dam += number_range (5, 10);
	 }
	 if (IS_BLEEDING (ch, BLEEDING_LEG_R) && (ch->hit - dam) > minhit)
	 {
	    act ("A spray of blood shoots from the stump of $n's right leg.",
		 ch, NULL, NULL, TO_ROOM);
	    send_to_char
	       ("A spray of blood shoots from the stump of your right leg.\n\r",
		ch);
	    dam += number_range (10, 20);
	 }
	 else if (IS_BLEEDING (ch, BLEEDING_FOOT_R)
		  && (ch->hit - dam) > minhit)
	 {
	    act ("A spray of blood shoots from the stump of $n's right ankle.", ch, NULL, NULL, TO_ROOM);
	    send_to_char
	       ("A spray of blood shoots from the stump of your right ankle.\n\r",
		ch);
	    dam += number_range (5, 10);
	 }
	 if (IS_HERO (ch))
	 {
	    ch->hit = ch->hit - dam;
	    if (ch->hit < 1)
	       ch->hit = 1;
	 }
	 else
	    ch->hit = ch->hit - dam;
	 update_pos (ch);
	 ch->in_room->blood += dam;
	 if (ch->in_room->blood > 1000)
	    ch->in_room->blood = 1000;
	 if (ch->hit <= -11 || (IS_NPC (ch) && ch->hit < 0))
	 {
	    do_killperson (ch, ch->name);
	    drop_out = TRUE;
	 }
      }

      if (IS_SET (ch->flag2, AFF2_ROT) && !is_obj && !drop_out)
      {
	 int dam;
	 act ("$n's flesh shrivels and tears.", ch, NULL, NULL, TO_ROOM);
	 send_to_char ("Your flesh shrivels and tears.\n\r", ch);
	 dam = number_range (250, 500);
	 ch->hit = ch->hit - dam;
	 update_pos (ch);
	 if (ch->hit < -11)
	 {
	    do_killperson (ch, ch->name);
	    drop_out = TRUE;
	 }
      }

      if (IS_SET (ch->flag2, AFF2_BALOR) && !is_obj && !drop_out)
      {
	 int dam;
	 act ("$n screams in pain as $s body is torn apart from the inside out!", ch, NULL, NULL, TO_ROOM);
	 send_to_char
	    ("You scream in pain as your body is torn apart from the inside out.\n\r",
	     ch);
	 dam = number_range (250, 500);
	 ch->hit = ch->hit - dam;
	 update_pos (ch);
	 if (ch->hit < -11)
	 {
	    do_killperson (ch, ch->name);
	    drop_out = TRUE;
	 }
      }

      if (!IS_NPC (ch) && ch->paradox[1] > 0)
      {
	 if (ch->paradox[1] > 50)
	    paradox (ch);
	 else if (ch->paradox[2] == 0 && ch->paradox[1] > 0)
	 {
	    ch->paradox[1]--;
	    ch->paradox[2] = PARADOX_TICK;
	 }
	 else
	    ch->paradox[3]--;
      }

      if (ch->position == POS_INCAP && !is_obj && !drop_out)
      {
	 if (IS_HERO (ch))
	    ch->hit = ch->hit + number_range (2, 4);
	 else
	    ch->hit = ch->hit - number_range (1, 2);
	 update_pos (ch);
	 if (ch->position > POS_INCAP)
	 {
	    act ("$n's wounds stop bleeding and seal up.", ch, NULL, NULL,
		 TO_ROOM);
	    send_to_char ("Your wounds stop bleeding and seal up.\n\r", ch);
	 }
	 if (ch->position > POS_STUNNED)
	 {
	    send_to_char ("You clamber back to your feet.\n\r", ch);
	 }
      }
      else if (ch->position == POS_MORTAL && !is_obj && !drop_out)
      {
	 drop_out = FALSE;

	 if (IS_HERO (ch))
	    ch->hit = ch->hit + number_range (2, 4);
	 else
	 {
	    ch->hit = ch->hit - number_range (1, 2);
	    if (!IS_NPC (ch) && (ch->hit <= -11))
	    {
	       ch->form = 16;
               death_cry( ch );
	       do_killperson (ch, ch->name);
	       continue;
	    }
	    drop_out = TRUE;
	 }
	 if (!drop_out)
	 {
	    update_pos (ch);
	    if (ch->position == POS_INCAP)
	    {
	       act ("$n's wounds begin to close, and $s bones pop back into place.", ch, NULL, NULL, TO_ROOM);
	       send_to_char
		  ("Your wounds begin to close, and your bones pop back into place.\n\r",
		   ch);
	    }
	 }
      }
      else if (ch->position == POS_DEAD && !is_obj && !drop_out)
      {
	 update_pos (ch);
	 if (!IS_NPC (ch))
	 {
	    ch->form = 16;
               death_cry( ch );
	    do_killperson (ch, ch->name);
	    continue;
	 }
      }
      drop_out = FALSE;
   }

   /*
    * 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)
      {
	 if (ch == ch_save)
	 {
	    save_char_obj (ch);
	    adjust_hiscore ("pkill", ch, ch->pkill);
	    adjust_hiscore ("status", ch, ch->race);
	    adjust_hiscore ("pdeath", ch, ch->pdeath);
	    adjust_hiscore ("mkill", ch, ch->mkill);
	    adjust_hiscore ("mdeath", ch, ch->mdeath);
	    adjust_hiscore ("awins", ch, ch->awins);
	    adjust_hiscore ("alosses", ch, ch->alosses);
	    adjust_hiscore ("exp", ch, ch->pcdata->score[SCORE_TOTAL_XP]);
	    adjust_hiscore ("quest", ch, ch->pcdata->score[SCORE_QUEST]);
	    adjust_hiscore ("tier", ch, ch->tier);
	    adjust_hiscore ("hours", ch, get_hours (ch));
	 }
	 if (ch == ch_quit)
	 {
	    do_quit (ch, "");

	 }
      }
   }
   return;
}

// Updated -- Serenity
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)
	 continue;

      switch (obj->item_type)
      {
      default:
	 message = "$p vanishes.";
	 break;
      case ITEM_FOUNTAIN:
	 message = "$p dries up.";
	 break;
      case ITEM_CORPSE_NPC:
      case ITEM_CORPSE_PC:
	 message = "$p decays into dust.";
	 break;
      case ITEM_FOOD:
	 message = "$p decomposes.";
	 break;
      case ITEM_TRASH:
	 message = "$p crumbles into dust.";
	 break;
      case ITEM_EGG:
	 message = "$p cracks open.";
	 break;
      case ITEM_WEAPON:
	 message = "The poison on $p melts through it.";
	 break;
      case ITEM_WALL:
	 message = "$p flows back into the ground.";
	 break;
      }

      if (obj->carried_by != NULL && !IS_SET (obj->quest, QUEST_DAEMONSEED))
      {
	 act (message, obj->carried_by, obj, NULL, TO_CHAR);
      }
      else if (obj->in_room != NULL
	       && (rch = obj->in_room->people) != NULL
	       && !IS_SET (obj->quest, QUEST_DAEMONSEED))
      {
	 act (message, rch, obj, NULL, TO_ROOM);
	 act (message, rch, obj, NULL, TO_CHAR);
      }

      /* If the item is an egg, we need to create a mob and shell!
       * KaVir
       */
      if ((obj->item_type == ITEM_EGG)
	  && (!IS_SET (obj->quest, QUEST_DAEMONSEED)))
      {
	 CHAR_DATA *creature;
	 OBJ_DATA *egg;
	 if (get_mob_index (obj->value[0]) != NULL)
	 {
	    if (obj->carried_by != NULL && obj->carried_by->in_room != NULL)
	    {
	       creature = create_mobile (get_mob_index (obj->value[0]));
	       char_to_room (creature, obj->carried_by->in_room);
	    }
	    else if (obj->in_room != NULL)
	    {
	       creature = create_mobile (get_mob_index (obj->value[0]));
	       char_to_room (creature, obj->in_room);
	    }
	    else
	    {
	       creature = create_mobile (get_mob_index (obj->value[0]));
	       char_to_room (creature, get_room_index (ROOM_VNUM_HELL));
	    }
	    egg = create_object (get_obj_index (OBJ_VNUM_EMPTY_EGG), 0);
	    egg->timer = 2;
	    obj_to_room (egg, creature->in_room);
	    act ("$n clambers out of $p.", creature, obj, NULL, TO_ROOM);
	 }
	 else if (obj->in_room != NULL)
	 {
	    egg = create_object (get_obj_index (OBJ_VNUM_EMPTY_EGG), 0);
	    egg->timer = 2;
	    obj_to_room (egg, obj->in_room);
	 }
      }
      if ((IS_SET (obj->quest, QUEST_DAEMONSEED)
	   && (obj != NULL)
	   && (obj->in_obj == NULL) && (locate_obj (obj))->people))
      {
	 char buf[MAX_STRING_LENGTH];
	 CHAR_DATA *vch;
	 int wdam;

	 sprintf (buf,
		  "%s suddenly explodes in a ball of flame, incinerating you!\n\r",
		  obj->short_descr);
	 buf[0] = UPPER (buf[0]);
	 if ((locate_obj (obj))->people == NULL)
	    break;
	 for (vch = (locate_obj (obj))->people; vch != NULL;
	      vch = vch->next_in_room)
	 {
            if (IS_CLASS
               (vch, CLASS_DEMON) || WORN_ARTIFACT (vch, ARTI_DEMONS_HEART))
	    {
	       stc ("Your powers of EVIL protect you from the blast!\n\r",
		    vch);
	       continue;
	    }

	    if (vch->class == 0 || (!IS_NPC (vch) && vch->level < 3))
	       continue;
	    if (IS_SET (vch->in_room->room_flags, ROOM_SAFE))
	    {
	       stc ("You are unaffected by the blast.\n\r", vch);
	       continue;
	    }
	    wdam = obj->level + dice (75, 125);
	    damage (vch, vch, obj->level + dice (75, 125), gsn_inferno);
	    send_to_char (buf, vch);
	    sprintf (buf,
		     "The flames strike you incredibly hard![#r%d]#n\n\r",
		     wdam);
	    stc (buf, vch);
	 }
      }
      /*
       * BUGFIX : The famous extract_obj bug....
       *                      basicly we just make sure that we don't skip into the obj_free list
       *                      by accident. (That's what caused it).
       */

      if (obj == object_list)
      {
	 extract_obj (obj);
	 obj_next = object_list;
      }
      else
      {
	 OBJ_DATA *bugObj;
	 for (bugObj = object_list; bugObj; bugObj = bugObj->next)
	 {
	    if (bugObj->next == obj)
	       break;
	 }

	 /*
	  * This shouldn't happen, but if it does, I want to make sure we never see that object again,
	  * so we let extract_obj() try and handle it, terminating to avoid further corruption.
	  */
	 if (!bugObj)
	 {
//                              bug("obj_update: obj %d not in object_list. Terminating obj_update.", obj->pIndexData->vnum);
	    return;
	 }
	 extract_obj (obj);
	 obj_next = bugObj->next;
      }

      /*
       * The old simple line that caused the bug... It's a long story, just rejoice.
       * Keeping the line - always nice to scare people with.
       */
      //if (obj != NULL) 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 want the mob to just attack the first PC
 *   who leads the party into the room.
 *
 * -- Furey
 */
// Updated -- Serenity
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 = NULL;

   OBJ_DATA *obj = NULL;
   OBJ_DATA *chobj = NULL;
   ROOM_INDEX_DATA *objroom = NULL;
   DESCRIPTOR_DATA *d;
//int max_dam = 1000;
   for (d = first_descriptor; d != NULL; d = d->next)
   {
      if ((d->connected == CON_PLAYING)
	  && ((ch = d->character) != NULL)
	  && (!IS_NPC (ch))
	  && (ch->pcdata != NULL) && ((obj = ch->pcdata->chobj) != NULL))
      {
	 if (obj->in_room != NULL)
	    objroom = obj->in_room;
	 else if (obj->in_obj != NULL)
	    objroom = get_room_index (ROOM_VNUM_IN_OBJECT);
	 else if (obj->carried_by != NULL)
	 {
	    if (obj->carried_by != ch && obj->carried_by->in_room != NULL)
	       objroom = obj->carried_by->in_room;
	    else
	       continue;
	 }
	 else
	    continue;
	 if (ch->in_room != objroom && objroom != NULL)
	 {
	    char_from_room (ch);
	    char_to_room (ch, objroom);
	    do_look (ch, "auto");
	 }
      }
      else if ((d->connected == CON_PLAYING)
	       && ((ch = d->character) != NULL)
	       && (!IS_NPC (ch))
	       && (ch->pcdata != NULL)
	       && ((IS_HEAD (ch, LOST_HEAD)
		    || (IS_EXTRA (ch, EXTRA_OSWITCH)))
		   || (ch->pcdata->obj_vnum != 0)))
      {
	 if (ch->pcdata->obj_vnum != 0)
	 {
	    bind_char (ch);
	    continue;
	 }
	 if (IS_HEAD (ch, LOST_HEAD))
	 {
	    REMOVE_BIT (ch->loc_hp[0], LOST_HEAD);
	    send_to_char ("You are able to regain a body.\n\r", ch);
	    ch->position = POS_RESTING;
	    ch->hit = 1;
	 }
	 else
	 {
	    send_to_char ("You return to your body.\n\r", ch);
	    REMOVE_BIT (ch->extra, EXTRA_OSWITCH);
	 }
	 REMOVE_BIT (ch->affected_by, AFF_POLYMORPH);
	 free_string (ch->morph);
	 ch->morph = str_dup ("");
	 char_from_room (ch);
	 char_to_room (ch, get_room_index (ROOM_VNUM_ALTAR));
	 if ((chobj = ch->pcdata->chobj) != NULL)
	    chobj->chobj = NULL;
	 ch->pcdata->chobj = NULL;
	 do_look (ch, "auto");
      }
      continue;
   }

   for (wch = char_list; wch != NULL; wch = wch_next)
   {
      wch_next = wch->next;
      if (IS_NPC (wch)
	  || ((wch->desc != NULL && wch->desc->connected != CON_PLAYING))
	  || (wch->position <= POS_STUNNED)
	  || (wch->level >= LEVEL_IMMORTAL)
	  || (wch->pcdata == NULL)
	  || (((chobj = wch->pcdata->chobj) != NULL))
	  || (wch->in_room == NULL)
	  || (IS_SET (wch->in_room->room_flags, ROOM_SAFE)))
	 continue;

      if ( wch->hunting != NULL && wch->hunting != '\0' && 
          strlen(wch->hunting) > 1)
      {
         check_hunt( wch );
         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))
	     || (no_attack (ch, wch))
	     || (ch->fighting != NULL)
	     || (IS_AFFECTED (ch, AFF_CHARM))
	     || (!IS_AWAKE (ch))
	     || ((IS_SET (ch->act, ACT_WIMPY) && IS_AWAKE (wch)))
	     || (IS_SET (ch->in_room->room_flags, ROOM_SAFE))
	     || (!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;

	    if (!IS_NPC (vch)
		&& (!no_attack (ch, vch))
		&& (vch->pcdata != NULL)
		&& (((chobj = vch->pcdata->chobj) == NULL))
		&& (vch->level < LEVEL_IMMORTAL)
		&& (vch->position > POS_STUNNED)
		&& ((!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)
	    continue;
/* Testing */
	 if (ch->damcap[DAM_CHANGE] == 1)
	 {
	    update_damcap (ch, victim);
	 }
	 multi_hit (ch, victim, TYPE_UNDEFINED);
      }
   }
   return;
}

void embrace_update( void )
{  
    DESCRIPTOR_DATA *d;
    CHAR_DATA       *ch;
    CHAR_DATA       *victim;
    int blpr;  /* variable to check for amout of blood sucked. Shakti */
    char buf[MAX_STRING_LENGTH];
               int chargen;
                int maxblood=0;

    for ( d = first_descriptor; d != NULL; d = d->next )
    {

      if ( ( ch = d->character) == NULL )
        continue;

      if ( IS_CLASS(ch, CLASS_MONK) && ch->fighting == NULL )
        ch->monkblock = 0;
    
      if ( !IS_NPC(ch) && IS_CLASS(ch, CLASS_MONK)
          && ch->focus[MAXIMUM] > 0 && ch->focus[MAXIMUM]
           > ch->focus[CURRENT] )
        {
          if ( ch->position == POS_SLEEPING )
            ch->focus[CURRENT] += number_range(1, 10);
          else if ( ch->position == POS_MEDITATING )
            ch->focus[CURRENT] += number_range( 4, 5 );
          else if ( ch->position == POS_RESTING )
            ch->focus[CURRENT] += number_range(1,9);
          else if ( ch->position == POS_FIGHTING )
            ch->focus[CURRENT] += 0;
          else
            ch->focus[CURRENT] += number_range( 1, 8 );
        }
      if ( IS_CLASS(ch, CLASS_MONK) && ch->focus[CURRENT] > ch->focus[MAXIMUM])
         ch->focus[CURRENT] = ch->focus[MAXIMUM];
    
      if ( IS_NPC(ch) || ch->embracing == NULL )
        continue;
               
        if (!IS_CLASS(ch,CLASS_VAMPIRE))
          stop_embrace(ch,NULL);
    
        victim=ch->embracing;

      
        if (IS_NPC(victim) )
        {
                if (victim->level > 75 )
                {
                        stop_embrace(ch,victim);
                        send_to_char("You cannot embrace someone so powerful!\n\r",ch);
                        return;
                }
         
        if (ch->in_room != victim->in_room)  
            stop_embrace (ch, victim);
          
         // To keep how much blood was sucked, and how much gained the same. Shakti
         blpr = number_range (10, 20);
           victim->practice -= blpr;
//         victim->practice -= UMAX (3, (blpr / victim->level));  // larger mobs have stronger blood, min of 3 drawn-- Serenity
         ch->pcdata->condition[COND_THIRST] += blpr;
                ch->pcdata->condition[COND_THIRST] +=blpr;
                   act("You shudder with ecstacy as you drain $N's lifeblood from $S throat.",ch,NULL,victim,TO_CHAR);
                    act("The gentle motion of $n's lips on your throat sends electric shivers through your body.",ch,NULL,victim,TO_VICT);
                    act("$n drinks deeply from $N's throat.",ch,NULL,victim,TO_NOTVICT);
    
               chargen =  ch->pcdata->stats[UNI_GEN];
/*
                if (chargen > 12)
                        chargen = 12;   
                maxblood = (13 - chargen) * 100;
*/  
switch (chargen)
    {
        default:
            maxblood = 100; 
            break;
        case 1:
            maxblood = 5000;
        case 2:
            maxblood = 2000;
            break;
        case 3:  
            maxblood = 1000;
            break;
        case 4:
            maxblood = 500;
            break;
        case 5:
            maxblood = 400;
            break;
        case 6:
            maxblood = 300;
            break;
        case 7:
            maxblood = 200;
            break;
        case 8:
            maxblood = 150;
            break;
        case 9:
            maxblood = 140;
            break;
        case 10:
            maxblood = 130;
            break;
        case 11:
            maxblood = 120; 
            break;
        case 12:
            maxblood = 110; 
            break;
        case 13:
            maxblood = 100;
            break;
    }
            
               if (ch->pcdata->condition[COND_THIRST] >= maxblood)
               {
                        send_to_char( "Your blood thirst is sated.\n\r", ch);
                       ch->pcdata->condition[COND_THIRST] = maxblood;
                }
                if (victim->practice < 0)
                {
                        victim->practice = 0;
                } 
        
                if (victim->practice == 0)
            
                {
                        act("Your body falls limply to the ground.",victim,NULL,NULL,TO_CHAR);
                        act("$n's body falls limply to the ground.",victim,NULL,NULL,TO_ROOM);
                        stop_embrace(ch,victim);
                        raw_kill(victim, ch);
                 return;
                }
            
                continue;
        }
            
            
        
        if (get_char_world(ch,victim->name) == NULL)
          {stop_embrace(ch,NULL);continue;}
        if (ch->in_room != victim->in_room)
          stop_embrace(ch,victim);
        if (victim->pcdata->condition[COND_THIRST] < 0)
          victim->pcdata->condition[COND_THIRST] = 0;
            
        ch->pcdata->condition[COND_THIRST] += number_range(30,40); 
    sprintf(buf, "%s shudders in ecstacy as he drinks blood from %s's neck.\n\r", ch->name,victim->name);
        act(buf,ch,NULL,NULL,TO_ROOM);
        sprintf(buf, "You shudder in ecstacy as you drink blood from %s's neck.\n\r",victim->name);
        send_to_char(buf,ch);
        sprintf(buf, "You feel some of your life slip away as %s drinks from your neck.\n\r", ch->name);
        send_to_char(buf,victim);

        if (is_garou (victim) && victim->gifts[GETOFFENRIS] >= 4)
        {
           stc ("Their blood is a deadly venom!\n\r", ch);
           ch->hit -= number_range (400, 500);
           victim->pcdata->condition[COND_THIRST] -= 30;
        }
        else if (IS_SET (victim->act, PLR_ACID))
        {
           send_to_char ("Their blood is a deadly acid!\n\r", ch);
           ch->hit -= 300;
           victim->pcdata->condition[COND_THIRST] -= 30;
        }
        else
        {
           ch->pcdata->condition[COND_THIRST] += number_range(35,40);
           victim->pcdata->condition[COND_THIRST] -= number_range(40,42);
           if (ch->pcdata->condition[COND_THIRST] > maxblood)
           {ch->pcdata->condition[COND_THIRST]=maxblood;
           send_to_char("Your bloodlust is sated.\n\r",ch);}
        }
        if (victim->pcdata->condition[COND_THIRST] < 0)
          victim->pcdata->condition[COND_THIRST]=0;
        if (victim->pcdata->condition[COND_THIRST] == 0)
        {
          sprintf(buf,"You have been diablerized!\n\r");
          send_to_char(buf,victim);
          victim->form = 3;
          raw_kill(victim, ch);
          sprintf(buf,"%s's body falls lifeless to the ground.\n\r",victim->name);
          act(buf,ch,NULL,NULL,TO_ROOM);
          send_to_char(buf,ch);
          stop_embrace(ch,victim);
          if (IS_EXTRA (victim, EXTRA_POTENCY))
          {
             victim->pcdata->stats[UNI_GEN]++;
             REMOVE_BIT (victim->extra, EXTRA_POTENCY);
          }
          if (IS_CLASS(victim, CLASS_VAMPIRE) && victim->pcdata->stats[UNI_GEN] <= ch->pcdata->stats[UNI_GEN] && ch->pcdata->stats[UNI_GEN] > 3 && victim->pcdata->stats[UNI_GEN] < 13)
          {
            sprintf(buf,"%s has been diablerized by %s.",victim->name,ch->name);
            ch->pcdata->stats[UNI_GEN] -= 1;
            victim->pcdata->stats[UNI_GEN] += 1;
            victim->pcdata->condition[COND_THIRST] = 0;
            do_info(ch,buf);

            if (IS_SET (ch->more, GOT_GOLCONDA))
            {
               send_to_char ("You have lost Golconda!\n\r", ch);
               REMOVE_BIT (ch->more, GOT_GOLCONDA);
               REMOVE_BIT (ch->immune, IMM_SUNLIGHT);
            }
            else if (ch->beast < 100)
               send_to_char ("You feel your beast take more control over your actions.\n\r",
                             ch);

            if (ch->beast < 100)
            {
               ch->beast += 10;
               if (ch->beast > 100)
               {
                  ch->beast = 100;
                  send_to_char
                     ("Your beast has fully taken over control of your actions!\n\r",
                       ch);
               }
            }
          } 
          else
          {
            sprintf(buf,"%s has been diablerized by %s for no generation.", victim->name,ch->name);
            victim->pcdata->condition[COND_THIRST] = 0;
            do_info(ch,buf); 
          }
    }
    continue;
  }
  
  return;

}               

      

/*added by sage for embrace*/
// Updated -- Serenity

//Updated -- Serenity
void quest_update ()
{
   extern bool auto_quest;
   extern bool quest;
   extern CHAR_DATA *quest_mob;
   extern OBJ_DATA *aquest_object;
   extern int quest_timer;
   extern int quest_wait;

   if (!quest && !auto_quest)
      return;

   if (quest)
   {
      /* Make sure the mobile and obj still exist! */
      if (quest_mob == NULL || aquest_object == NULL)
      {
	 quest_cancel ();
	 return;
      }

      /* Needs Something here */
      quest_inform ();
      if (quest_timer > 15)
	 quest_cancel ();
      return;
   }

   if (!quest)
   {
      if (quest_wait > 0)
      {
	 quest_wait--;
	 return;
      }

      if (auto_quest)
	 generate_auto_quest ();
   }
   return;
}


//Updated Serenity
void hint_update (void)
{
   CHAR_DATA *ch;
   CHAR_DATA *ch_next;
   char buf[MSL];

   for (ch = char_list; ch != NULL; ch = ch_next)
   {
      ch_next = ch->next;

      if (!IS_NPC (ch) && (get_hours (ch) < 6)
	  && !IS_SET (ch->more, MORE_NOHINT))
      {

	 cent_to_char
	    ("#r-=-=-=-=-=[ #yLegend of Chrystancia Hints #r]=-=-=-=-=-", ch);
	 switch (number_range (0, 25))
	 {
	 default:
	 case 0:
	    sprintf (buf,
		     "You receive 3 times experience for your first 6 hrs");
	    break;
	 case 1:
	    sprintf (buf,
		     "Please check the helpfiles before asking a question");
	    break;
	 case 2:
	    sprintf (buf,
		     "Set your autostance, these stance you before combat making it easier to improve your stances, Syntax is autostance <stance>,  see help stance for information on stances.");
	    break;
	 case 3:
	    sprintf (buf,
		     "Train your weapon resistances to reduce the damage taken in combat");
	    break;
	 case 4:
	    sprintf (buf,
		     "You will occasionally gain quest pieces, see 'help piece' for further details");
	    break;
	 case 5:
	    sprintf (buf,
		     "One you reach the requirements you will be able to class yourself, see 'help classme' for details");
	    break;
	 case 6:
	    sprintf (buf,
		     "Once you reach 6 hours you will be able to use all channels");
	    break;
	 case 7:
	    sprintf (buf,
		     "You are safe from PKILL for your first 10 hrs of playing time");
	    break;
	 case 8:
	    sprintf (buf,
		     "If you wish to partake in PK before your 10 hrs type pkready <password> this will remove your safe status");
	    break;
	 case 9:
	    sprintf (buf,
		     "You will be unable to gain experience from mobkills, until agree to this muds rules, Rules <agree|decline> <password>");
	    break;
	 case 10:
	    sprintf (buf,
		     "You can quest trust yourself once you have 500 earned quest points, 2000 mana and 1500 move, by typing 'q trust'. After you have been quest trusted you can create your own equipment using the quest command");
	    break;
	 case 11:
	    sprintf (buf,
		     "To see your weapon, spell and stance levels type 'exp'");
	    break;
	 case 12:
	    sprintf (buf, "To stop seeing these hint type 'hint'");
	    break;
	 case 13:
	    sprintf (buf,
		     "While you are a mortal or under 10 hrs old you will be unable to use artifacts");
	    break;
	 case 14:
	    sprintf (buf,
		     "This mud has several classes, to see what they are type 'help class'");
	    break;
	 case 15:
	    sprintf (buf,
		     "Please check your notes regularly for rule updates");
	    break;
	 case 16:
	    sprintf (buf,
		     "You are required to know the rules whilst playing here");
	    break;
	 case 17:
	    sprintf (buf,
		     "Annoying the immortals is generally not a good thing to do");
	    break;
	 case 18:
	    sprintf (buf,
		     "Type 'changes' to see any new changes made to the mud.");
	    break;
	 case 20:
	    sprintf (buf,
		     "To condense your attacks and damge into 2 lines type 'config +short'");
	    break;
	 case 21:
	    sprintf (buf,
		     "To turn off room descriptions type 'config -desc'");
	    break;
	 case 22:
	    sprintf (buf,
		     "Type 'pray' at the temple altar to get a full heal as an unclassed mortal");
	    break;
	 case 23:
	    sprintf (buf,
		     "To class yourself once you have the reqs go up from altar and type 'classme <class>'");
	    break;
	 case 24:
	 case 25:
	    sprintf (buf,
		     "We have a WEBForum located at www.godwars.net/, to post there you will need to register");
	    break;
//         case 26: 
//            sprintf (buf,
//                     "If you see Hannah or Houdini on please see: HELP HANNAHREQS or HELP HOUDINI for things they can do.");
//           break;
	 }
	 cent_format (ch, buf, 50);
	 cent_to_char
	    ("#r-=-=-=-=-=[ #yLegend of Chrystancia Hints #r]=-=-=-=-=-", ch);
      }
   }
   return;
}

//Updated -- Just controls Blade barriers in a room
void ww_update (void)
{
   DESCRIPTOR_DATA *d;
   CHAR_DATA *victim;
   int dam = 0;

   for (d = first_descriptor; d != NULL; d = d->next)
   {
      if (!IS_PLAYING (d) || (victim = d->character) == NULL
	  || IS_NPC (victim) || IS_IMMORTAL (victim)
	  || victim->in_room == NULL || victim->pcdata->chobj != NULL)
      {
	 continue;
      }
      if (!IS_SET (d->character->in_room->room_flags, ROOM_BLADE_BARRIER))
	 continue;

      act ("The scattered blades on the ground fly up into the air ripping into you.", d->character, NULL, NULL, TO_CHAR);
      act ("The scattered blades on the ground fly up into the air ripping into $n.", d->character, NULL, NULL, TO_ROOM);
      act ("The blades drop to the ground inert.", d->character, NULL, NULL,
	   TO_CHAR);
      act ("The blades drop to the ground inert.", d->character, NULL, NULL,
	   TO_ROOM);

      dam = number_range (7, 14);
      dam = ((d->character->hit * dam) / 100);
      if (dam < 100)
	 dam = 100;
      d->character->hit -= -dam;

      if (d->character->hit < -10)
      {
	 if ((number_percent () < 35) && !IS_NPC (d->character))
	 {
	    char mov_buf[MSL];
	    d->character->pdeath++;
	    stc ("You have only a moment to see the blade aiming for your neck before a spasm of blinding pain ends your life.\n\r", d->character);
	    act ("You see one of the many shiny blades in the room slice through $n's neck severing $s head.", d->character, NULL, NULL, TO_ROOM);
	    raw_kill (d->character, d->character);
	    sprintf (mov_buf,
		     "%s has lost their head to a blade barrier.\n\r",
		     d->character->name);
	    do_info (NULL, mov_buf);
	 }
	 else
	 {
	    d->character->hit = -10;
	 }
      }
      update_pos (victim);
   }
   return;
}

// Updated -- Serenity
bool spec_tagbot (CHAR_DATA * ch);
void ftag_update (void)
{
   CHAR_DATA *vch;

   if (ftag.round == 0 && ftag.timer == 0)
      return;

   for (vch = char_list; vch; vch = vch->next)
   {
      if (!IS_NPC (vch) || !IS_SET (vch->tag_flags, TAG_PLAYING))
	 continue;
      spec_tagbot (vch);
   }

   if (ftag.timer == 0)
      return;

   ftag.timer--;

   if (ftag.timer <= 0)
      next_round ();
   return;
}

/*
 * Handle all kinds of updates.
 * Called once per pulse from game loop.
 * Random times to defeat tick-timing clients and players.
 */
//Updated --Serenity
void update_handler (void)
{
   bool is_obj = FALSE;
   CHAR_DATA *gch;
   static int pulse_mudinfo;
   static int pulse_gain_exp;
   static int pulse_area;
   static int pulse_mobile;
   static int pulse_violence;
   static int pulse_point;
   static int pulse_ww;
   static int pulse_event;
   static int pulse_auction;
   static int pulse_hint;
   static int pulse_ftag = 0;
   static int pulse_minute = 0;
   static int pulse_regen;
static  int     pulse_embrace;
   //recycle_descriptors();
   extern int pulse_weather;
   if (is_tick_info)
   {
      char buf[MSL];
      sprintf (buf,
	       "Pulse_Gain_Exp %d\n\r"
	       "Pulse_Area     %d\n\r"
	       "Pulse_Mobile   %d\n\r"
	       "Pulse_Violence %d\n\r"
	       "Pulse_Point    %d\n\r"
	       "Pulse_WW       %d\n\r"
	       "Pulse_Event    %d\n\r"
	       "Pulse_Auction  %d\n\r"
	       "Pulse_Hint     %d\n\r"
	       "Pulse_Ftag     %d\n\r"
	       "Pulse_Minute   %d\n\r"
	       "Pulse_Regen    %d\n\r",
	       pulse_gain_exp, pulse_area, pulse_mobile, pulse_violence,
	       pulse_point, pulse_ww, pulse_event, pulse_auction, pulse_hint,
	       pulse_ftag, pulse_minute, pulse_regen);
      log_string (buf, NULL);
   }
/* timed events */

   if (--pulse_minute <= 0)
   {
      minute_update ();
      update_wartimer ();
      pulse_minute = PULSE_PER_SECOND * 60;
   }

   if (--pulse_mudinfo <= 0)
   {
      pulse_mudinfo = 30 * PULSE_PER_SECOND;
      update_mudinfo ();
      update_polls ();
   }

   if (--pulse_ftag <= 0)
   {
      pulse_ftag = 3;
      ftag_update ();
   }

   if (--pulse_event <= 0)
   {
      pulse_event = PULSE_EVENT;
      event_update ();
   }

   if (--pulse_hint <= 0)
   {
      pulse_hint = PULSE_HINT;
      hint_update ();
   }

   if (--pulse_auction <= 0)
   {
      pulse_auction = PULSE_AUCTION;
      auction_update ();
   }

   if (--pulse_regen <= 0)
   {
      pulse_regen = PULSE_REGEN;
      regen_update ();		// Yes we are adding this to make a fast regen  -- Seren
   }

   if (--pulse_gain_exp <= 0)
   {
      char buf[MAX_STRING_LENGTH];
      DESCRIPTOR_DATA *d;
      DESCRIPTOR_DATA *d_next;
      CHAR_DATA *ch = NULL;
      CHAR_DATA *ch_next = NULL;
      //extern int dailycount;
      extern int bootcount;
      extern int copycount;
      extern int doublecount;
      extern int nosafecount;

      pulse_gain_exp = PULSE_GAIN_EXP;
      check_dns();

      //update_gametime();

      if (doublecount > 0)
      {
	 doublecount--;
	 switch (doublecount)
	 {
	 default:
	    strcpy (buf, " ");
	    break;
	 case 3600:
	    strcpy (buf, "Double Exp will last for 1 more hour");
	    break;
	 case 1800:
	    strcpy (buf, "Double Exp will last for 30 more minutes");
	    break;
	 case 900:
	    strcpy (buf, "Double EXP will last for 15 more minutes");
	    break;
	 case 60:
	    strcpy (buf, "Double Exp will last for 1 more minute");
	    break;
	 case 0:
	    strcpy (buf, "Double Exp is now off (AutoShutoff)");
	    break;
	 }
	 if (strlen (buf) > 2)
	    do_info (NULL, buf);
	 if (doublecount <= 0)
	 {
	    global_exp = FALSE;
	 }
      }
      if (nosafecount > 0)
      {
	 nosafecount--;
	 switch (nosafecount)
	 {
	 default:
	    strcpy (buf, " ");
	    break;
	 case 3600:
	    strcpy (buf, "Safe Rooms will be out for 1 more Hour");
	    break;
	 case 1800:
	    strcpy (buf, "Safe Rooms will be out for 30 more minutes");
	    break;
	 case 900:
	    strcpy (buf, "Safe Rooms will be out for 15 more minutes");
	    break;
	 case 60:
	    strcpy (buf, "Safe Rooms will be out for 1 more minute");
	    break;
	 case 0:
	    strcpy (buf, "Safe Rooms are now Back in!");
	    break;
	 }
	 if (strlen (buf) > 2)
	    do_info (NULL, buf);
	 if (nosafecount <= 0)
	 {
	    nosafe = FALSE;
	 }
      }
      if (bootcount > 0)
      {
	 char T_BUF[500];
	 bootcount--;
	 if (bootcount <= 600 && bootcount % 60 == 0 && bootcount > 60)
	 {
	    sprintf (T_BUF, "Reboot in %d minutes", bootcount / 60);
	    strcpy (buf, T_BUF);
	 }

	 else
	 {

	    switch (bootcount)
	    {
	    default:
	       strcpy (buf, " ");
	       break;
	    case 86400:
	       strcpy (buf, "Reboot in 1 day");
	       break;
	    case 36000:
	       strcpy (buf, "Reboot in 10 hours");
	       break;
	    case 18000:
	       strcpy (buf, "Reboot in 5 hours");
	       break;
	    case 14400:
	       strcpy (buf, "Reboot in 4 hours");
	       break;
	    case 10800:
	       strcpy (buf, "Reboot in 3 hours");
	       break;
	    case 7200:
	       strcpy (buf, "Reboot in 2 hours");
	       break;

	    case 3600:
	       strcpy (buf, "Reboot in 1 hour");
	       break;

	    case 90:
	       strcpy (buf, "Reboot in 90 seconds");
	       break;
	    case 60:
	       strcpy (buf, "Reboot in 1 minute");
	       break;

	    case 30:
	    strcpy (buf, "Reboot in 30 seconds");
	    break;
	    case 10:
	    strcpy (buf, "Reboot in 10 seconds");
	    break;
	 case 5:
	    strcpy (buf, "Reboot in 5 seconds");
	    break;
	 case 4:
	    strcpy (buf, "Reboot in 4 seconds");
	    break;
	 case 3:
	    strcpy (buf, "Reboot in 3 seconds");
	    break;
	 case 2:
	    strcpy (buf, "Reboot in 2 seconds");
	    break;
	 case 1:
	    strcpy (buf, "Reboot in 1 second");
	    break;
	    case 0:
	       strcpy (buf, "Rebooting, will be right back");
	       break;
	    }
	    if (strlen (buf) > 2)
	       sysmes (buf);
	    if (bootcount <= 0)
	    {
	       extern bool merc_down;
	       for (ch = char_list; ch != NULL; ch = ch_next)
	       {
		  ch_next = ch->next;
		  if (!IS_NPC (ch))
		  {

		     do_autosave (ch, "");
		     do_peace (ch, "");
		     do_restore (ch, "self");
		     do_wake (ch, "");
		     do_call (ch, "all");
		  }
	       }
	       sprintf (log_buf, "Timed reboot.");
	       log_string (log_buf, ch);
	       merc_down = TRUE;
	    }
	 }
      }
      if (copycount > 0)
      {  
         //dailycount--;
	 copycount--;
	 switch (copycount)
	 {
	 default:
	    strcpy (buf, " ");
	    break;
	 case 86400:
	    strcpy (buf, "Copyover in 1 day");
	    break;
	 case 36000:
	    strcpy (buf, "Copyover in 10 hours");
	    break;
	 case 18000:
	    strcpy (buf, "Copyover in 5 hours");
	    break;
	 case 14400:
	    strcpy (buf, "Copyover in 4 hours");
	    break;
	 case 10800:
	    strcpy (buf, "Copyover in 3 hours");
	    break;
	 case 7200:
	    strcpy (buf, "Copyover in 2 hours");
	    break;
	 case 3600:
	    strcpy (buf, "Copyover in 1 hour");
	    break;
	 case 1800:
	    strcpy (buf, "Copyover in 30 minutes");
	    break;
	 case 900:
	    strcpy (buf, "Copyover in 15 minutes");
	    break;
	 case 600:
	    strcpy (buf, "Copyover in 10 minutes");
	    break;
	 case 300:
	    strcpy (buf, "Copyover in 5 minutes");
	    break;
	 case 120:
	    strcpy (buf, "Copyover in 2 minutes");
	    break;
	 case 60:
	    strcpy (buf, "Copyover in 1 minute");
	    break;
	 case 30:
	    strcpy (buf, "Copyover in 30 seconds");
	    break;
	 case 10:
	    strcpy (buf, "Copyover in 10 seconds");
	    break;
	 case 5:
	    strcpy (buf, "Copyover in 5 seconds");
	    break;
	 case 4:
	    strcpy (buf, "Copyover in 4 seconds");
	    break;
	 case 3:
	    strcpy (buf, "Copyover in 3 seconds");
	    break;
	 case 2:
	    strcpy (buf, "Copyover in 2 seconds");
	    break;
	 case 1:
	    strcpy (buf, "Copyover in 1 second");
	    break;
	 case 0:
	    strcpy (buf, "Automatic Copyover!");
	    break;
	 }
	 if (strlen (buf) > 2)
	    sysmes (buf);
	 if (copycount <= 0)
	 {
	    for (gch = char_list; gch != NULL; gch = gch->next)
	    {
	       if (IS_NPC (gch))
		  continue;
               undo_arena2(gch);
               call_bags (gch);
	       call_all (gch);
	       restore_char (gch);
	       save_char_obj (gch);

	    }
	    sprintf (log_buf, "Timed copyover.");
	    do_copyover (NULL, "");
            log_string (log_buf, NULL);
	 }
      }

      for (d = first_descriptor; d != NULL; d = d_next)
      {
            d_next = d->next;
            if ( d->total_login > 0 && d->connected > CON_PLAYING
            &&  d->connected < CON_NOTE_TO )
	    {
		d->total_login--;
	    	if ( d->total_login <= 0 )
	    	{
		    write_to_buffer( d, "\n\rYour connection has timed out, please reconnect...\n\r", 0 );
//		    close_socket( d );
		    continue;
	    	}
	    }

	    if ( d->login > 0 && d->connected > CON_PLAYING
            &&  d->connected < CON_NOTE_TO )
	    {
		d->login--;
	    	if ( d->login <= 0 )
	    	{
		    write_to_buffer( d, "\n\rYour connection has timed out, please reconnect...\n\r", 0 );
//		    close_socket( d );
		    continue;
	    	}
	    }

	 if (d->connected == CON_PLAYING && (ch = d->character) != NULL
	     && !IS_NPC (ch))
	 {
	    if (IS_SET (ch->act, PLR_FREEZE))
	       unfreeze (ch);
	    if (IS_SET (ch->act, PLR_SILENCE))
	       unsilence (ch);
            if (!IS_NPC(ch) && IS_EXTRA (ch, EXTRA_OSWITCH))
               is_obj = TRUE;

	    if (ch->position <= POS_STUNNED && ch->hit >= 1)
	    {
	       ch->position = POS_STANDING;
	       act ("You flip back to your feet.", ch, NULL, NULL, TO_CHAR);
	       act ("$n flips back to $s feet.", ch, NULL, NULL, TO_ROOM);
	    }

	    ch->exp += ch->beast ? 1 : 10;

            if (ch->pcdata->get_exp > 0 && !is_safe_silent(ch, ch))
	    {
	       if (--ch->pcdata->get_exp == 0)
	       {
		  int ch_gen = ch->pcdata->stats[UNI_GEN];
		  int max_gen = 2;
		  int gen_cost = 0;
		  int rev_gen = 0;
		  int xp_cost = 0;
		  gen_cost = 16 - ch_gen;

		  if (ch_gen == 13)
		     rev_gen = 1;
		  else if (ch_gen == 12)
		     rev_gen = 2;
		  else if (ch_gen == 11)
		     rev_gen = 3;
		  else if (ch_gen == 10)
		     rev_gen = 4;
		  else if (ch_gen == 9)
		     rev_gen = 5;
		  else if (ch_gen == 8)
		     rev_gen = 6;
		  else if (ch_gen == 7)
		     rev_gen = 7;
		  else if (ch_gen == 6)
		     rev_gen = 8;
		  else if (ch_gen == 5)
		     rev_gen = 9;
		  else if (ch_gen == 4)
		     rev_gen = 10;
		  else if (ch_gen == 3)
		     rev_gen = 11;
		  else if (ch_gen == 2)
		     rev_gen = 12;
		  else if (ch_gen == 1)
		     rev_gen = 13;

		  xp_cost = rev_gen * 100000;
//better place for the vote thing.
  if (USE_MXP(ch))
  {
  stc("^1#yVote for us on the mudconnector by clicking on the following link                                   #n\n\r", ch);
  mxp_to_char(ch, "<A href=\"http://www.mudconnect.com/cgi-bin/vote_rank.cgi?mud=Legend+of+Chrystancia\">#whttp://www.mudconnect.com/cgi-bin/vote_rank.cgi?mud=Legend+of+Chrystancia</A>\n\r", MXP_ALL);
  stc("^1#yThis will help us raise our mudconnector ranking                                                    #n\n\r", ch);
  }
  else
  {
  stc("^1#yVote for us on the mudconnector by going to the following link                                   #n\n\r", ch); 
  stc("#whttp://www.mudconnect.com/cgi-bin/vote_rank.cgi?mud=Legend+of+Chrystancia\n\r", ch);
  stc("^1#yThis will help us raise our mudconnector ranking                                                 #n\n\r", ch);
  }
                  if (ch_gen > max_gen && ch->pcdata->gpoints < gen_cost)
		  {
		     if (ch->pcdata->gpoints < gen_cost )
			ch->pcdata->gpoints++;

		     stc ("You receive your daily generation point!\n\r", ch);
		     if (ch->pcdata->gpoints >= gen_cost)
		     {
			sprintf (buf,
				 "You may lower your generation for %d exp by typing 'lowergen'.\n\r",
				 xp_cost);
			send_to_char (buf, ch);
		     }
		  }
		  if (IS_SET (ch->more, MORE_NOKING))
		  {
		     ch->pcdata->outcast++;
		     if (ch->pcdata->outcast >= 30)
		     {
			REMOVE_BIT (ch->more, MORE_NOKING);
			ch->pcdata->outcast = 0;
		     }
		  }
	       }
	    }
            if (ch->pcdata->login_timer > 0)
	    {
//HEREMATTT
              
               if (ch->in_room->vnum != 3054 && !is_obj)
	           ch->pcdata->login_timer--;
	       if (ch->pcdata->login_timer < 1)
	       {
		  if (!IS_IMMORTAL (ch))
		     stc ("#yYour login timer is now cleared.#n\n\r", ch);
		  ch->pcdata->login_timer = 0;
	       }
	    }

				if (ch->pcdata->pkill_timer > 0)
				{
					ch->pcdata->pkill_timer--;
					if (ch->pcdata->pkill_timer < 1)
					{
						if (!IS_IMMORTAL (ch) && ( get_hours (ch) > 10 ) && ( ch->level > 2 ) )
							stc ("#w#FYou can be Pkilled again!!#n\n\r", ch);
						ch->pcdata->pkill_timer = 0;
					}
				}

	    if (ch->chat_timer > 0)
	    {
	       if (--ch->chat_timer < 1)
	       {
		  ch->chat_timer = 0;
		  if (get_hours (ch) < 6)
		     stc ("#wYou may now newbie again.#n\n\r", ch);
	       }
	    }
	    if (ch->pcdata->schallenge > 0)
	    {
	       ch->pcdata->schallenge--;
	       if (ch->pcdata->schallenge == 0)
		  stc ("You may now challenge for status again, if you so wish!\n\r", ch);
	    }
	    if (ch->pcdata->jailed > 0 && IS_SET (ch->more, MORE_JAIL))
	    {
	       ch->pcdata->jailed--;
	       if (ch->pcdata->jailed < 1)
		  unjail (ch);
	    }
	    if (ch->pcdata->majesty > 0)
	    {
	       ch->pcdata->majesty--;
	       if (IS_CLASS (ch, CLASS_MAGE))
	       {
		  if (ch->pcdata->majesty == 0)
		     stc ("You can now raise your magickal shield.\n\r", ch);
	       }
	       if (IS_CLASS (ch, CLASS_VAMPIRE))
	       {
		  if ((IS_AFFECTED (ch, AFF_STEELSHIELD))
		      && (!WORN_ARTIFACT (ch, ARTI_RING_AURELIUS)))
		  {
		     switch (ch->pcdata->majesty)
		     {
		     default:
			break;
		     case 0:
			do_majesty (ch, "");
			break;
		     case 5:
			send_to_char
			   ("You have FIVE seconds of Majesty remaining.\n\r",
			    ch);
			break;
		     case 10:
			send_to_char
			   ("You have TEN seconds of Majesty remaining.\n\r",
			    ch);
			break;
		     }
		  }
		  else
		  {
		     if (ch->pcdata->majesty == 0)
			stc ("You can now raise your Majesty again if you wish\n\r", ch);
		  }
	       }
	       if (IS_CLASS (ch, CLASS_FAE))
	       {
		  if IS_AFFECTED
		     (ch, AFF_STEELSHIELD)
		  {
		     switch (ch->pcdata->majesty)
		     {
		     default:
			break;
		     case 0:
			do_grandeur (ch, "");
			break;
		     case 5:
			send_to_char
			   ("You have FIVE seconds of Grandeur remaining.\n\r",
			    ch);
			break;
		     case 10:
			send_to_char
			   ("You have TEN seconds of Grandeur remaining.\n\r",
			    ch);
			break;
		     }
		  }
		  else
		  {
		     if (ch->pcdata->majesty == 0)
			stc ("You can now raise your Grandeur again if you wish\n\r", ch);
		  }
	       }
	    }
	    if (ch->wgrasp > 0 && ch->position != POS_FIGHTING)
	    {
	       ch->wgrasp--;
	       if (ch->wgrasp < 1)
	       {
		  stc ("You fade back into the Material Plane\n\r", ch);
		  REMOVE_BIT (ch->flag2, AFF_SHADOWREALM);
		  act ("$n fades back into the Material plane.", ch, NULL,
		       NULL, TO_ROOM);
		  do_look (ch, "auto");
	       }
	    }
	    if (ch->materialize > 0)
	    {
	       ch->materialize--;
	       if (ch->materialize < 1)
	       {
		  if (ch->position == POS_FIGHTING)
		  {
		     stc ("You try to fade into the Shadow Realm but fail\n\r", ch);
		     ch->materialize = 3;
		     act ("$n starts to shimmer slightly.", ch, NULL, NULL,
			  TO_ROOM);
		  }
		  else
		  {
		     stc ("You fade back into the Shadow Realm\n\r", ch);
		     SET_BIT (ch->flag2, AFF_SHADOWREALM);
		     act ("$n fades back into the Shadow Realm.", ch, NULL,
			  NULL, TO_ROOM);
		     do_look (ch, "auto");
		  }
	       }
	    }
	    if (ch->qtimer > 0)
	    {
	       ch->qtimer--;
	       if (ch->qtimer < 1)
		  stc ("You can now attempt to answer again\n\r", ch);
	       ch->qtimer = 0;
	    }

	    if (ch->pcdata->obeah > 0)
	    {
	       ch->pcdata->obeah--;
	       if (ch->pcdata->obeah < 1)
	       {
		  if (IS_CLASS (ch, CLASS_MONK))
		     stc ("Your ability to use Healing Touch has returned.\n\r", ch);
		  else if (IS_CLASS (ch, CLASS_FAE))
		  {
		     if (IS_SET (ch->extra2, EXTRA2_NEUTRAL))
		     {
			switch (ch->pcdata->obeah)
			{
			default:
			   break;
			case 0:
			   do_protocol (ch, "");
			   break;
			case 5:
			   send_to_char
			      ("You have FIVE seconds of Protocol remaining.\n\r",
			       ch);
			   break;
			case 10:
			   send_to_char
			      ("You have TEN seconds of Protocol remaining.\n\r",
			       ch);
			   break;
			}

		     }
		     else
		     {

			if (ch->pcdata->obeah == 0)
			   stc ("Your ability to use Protocol has returned.\n\r", ch);
		     }
		  }
		  else if (IS_CLASS (ch, CLASS_VAMPIRE))
		  {
		     send_to_char ("Your third eye stops glowing.\n\r", ch);
		     act ("The eye in $n's forehead stops glowing.", ch, NULL,
			  NULL, TO_ROOM);
		  }
	       }
	    }
        if ( IS_CLASS( ch, CLASS_WRAITH ) && !IS_SET( ch->wbits, WRAT_DEATHPLANE ) &&
!IS_IMMORTAL(ch) && ch->position > POS_STUNNED)
        {
        if ( ch->arcanoi[WBODY] == 0 )   
                {
                ch->hit -= 300;
                ch->move -= 250;
                }
        if ( ch->arcanoi[WBODY] == 1 )
                {
                ch->hit -= 200;
                ch->move -= 200;
                }
        if ( ch->arcanoi[WBODY] == 2 )
                {
                ch->hit -= 175;
                ch->move -= 150; 
                }
        if ( ch->arcanoi[WBODY] == 3 )
                {
                ch->hit -= 150;
                ch->move -= 100;
                }
        if ( ch->arcanoi[WBODY] == 4 )   
                {
                ch->hit -= 100;
                ch->move -= 50;  
                }
        if ( ch->arcanoi[WBODY] == 5 )
                {
                ch->hit -= 50;   
                ch->move -= 25;
                }
       }
            if (!IS_CLASS(ch, CLASS_WRAITH) && IS_WRATED( ch, WRAT_DEATHPLANE ) )
                ch->hit -= ch->hit * .01;
            if ( ch->dirgetimer > 0 )
                ch->dirgetimer -= 1;
	    if (ch->pcdata->wyld > 0)
	    {
	       ch->pcdata->wyld--;
	       if (ch->pcdata->wyld < 1)
		  send_to_char ("You have recovered your voice.\n\r", ch);
	    }
	    if (ch->last_mort > 0)
	    {
	       if (--ch->last_mort < 1)
	       {
		  stc ("You are nolonger safe from being mortally wonded\n\r",
		       ch);
		  ch->last_mort = 0;
	       }
	    }
	    if (ch->arena_timer > 0)
	    {
	       if (--ch->arena_timer < 1)
	       {
		  send_to_char ("Your arena timer is now clear.\n\r", ch);
		  do_decline (ch, "");
	       }
	    }
            if (ch->beast_timer > 0)
            {
               if (--ch->beast_timer < 1)
               {
                  if (!IS_CLASS (ch, CLASS_MONK))
                     send_to_char ("Your beast timer is now clear.\n\r", ch);
                  else
                     send_to_char ("Your relax timer is now clear.\n\r", ch);
               }
            }
	    if (ch->mort_count > 0)
	       ch->mort_count = 0;
	    if (ch->disquiet_counter > 0)
	    {
	       ch->disquiet_counter--;
	       if (ch->disquiet_counter < 1 && IS_SET (ch->newbits, NEW_CALM))
	       {
		  send_to_char ("You no longer feel so apathetic.\n\r", ch);
		  ch->disquiet_counter = 0;
		  REMOVE_BIT (ch->newbits, NEW_CALM);
	       }
	    }
            if (ch->dconfuse_counter > 0)
            {
               ch->dconfuse_counter--;
               if (ch->dconfuse_counter < 1 )
               {
                  send_to_char ("You no longer feel so confused.\n\r", ch);
                  ch->dconfuse_counter = 0;
               }
            }
            if (ch->confusion > 0)
            {
               ch->confusion--;
               if (ch->confusion < 1 )
               {
                  send_to_char ("You no longer feel so bewildered.\n\r", ch);
                  ch->confusion = 0;
               }
            }
	    if (!IS_HEAD (ch, LOST_HEAD) && IS_EXTRA (ch, EXTRA_OSWITCH))
	    {
	       if (ch->move >= 1000)
		  ch->move -= 1000;
	       else
		  do_humanform (ch, "");
	    }
            if (!IS_NPC(ch) && IS_AFFECTED(ch, AFF_ETHEREAL) )
            {
                if (ch->move >= 1000)
                   ch->move -=1000;
                else
                {
                   REMOVE_BIT (ch->affected_by, AFF_ETHEREAL);
                   act ("$n fades into the real world.", ch, NULL, NULL, TO_ROOM);
                   send_to_char ("You fade into the real world.\n\r", ch);
                }
            }
            if (IS_CLASS(ch, CLASS_NINJA) && IS_AFFECTED (ch, AFF_HIDE) )
            {
                if (ch->move >= 1000)
                   ch->move -=1000;
                else
                {
                   REMOVE_BIT (ch->affected_by, AFF_HIDE);
                   act ("$n appears from the shadows.", ch, NULL, NULL, TO_ROOM);
                   send_to_char ("You appear from the shadows.\n\r", ch);
                }
            }
            if (IS_CLASS (ch, CLASS_FAE) && IS_SET (ch->kith, KITH_ESHU) && IS_AFFECTED (ch, AFF_HIDE) )
            {
                if (ch->move >= 1000)
                   ch->move -=1000;
                else
                {
                   REMOVE_BIT (ch->affected_by, AFF_HIDE);
                   act ("$n appears from the shadows.", ch, NULL, NULL, TO_ROOM);
                   send_to_char ("You appear from the shadows.\n\r", ch);
                }
            }
      
//Added to fix earthmeld hiding i hope - Unique
	    if (!IS_HEAD (ch, LOST_HEAD) && IS_EXTRA (ch, EXTRA_EARTHMELD))
	    {
	       if (ch->move >= 1000)
		  ch->move -= 1000;
	       else
		  do_earthmeld (ch, "");
	    }

	    if (ch->captimer > 0)
	    {
	       ch->captimer--;
	       if (ch->captimer < 1 && ch->level < 3)
	       {
		  if (ch->lstatus >= 10 || ch->race > 0)
		  {
		     stc ("You have status or are beyond Deity and have been mortal too long\n\r", ch);
		     do_train (ch, "avatar");
		     ch->hit = ch->max_hit;
		  }
	       }
	    }
	    if ((ch->safe_timer > 0) && (ch->desc->connected == CON_PLAYING)
                && ((ch->in_room->vnum >= ROOM_VNUM_PLANAR_G
                    && ch->in_room->vnum <= ROOM_VNUM_PLANAR_R)
                || ch->in_room->vnum >= ROOM_VNUM_CRYSTAL_G
                || ch->in_room->vnum >= ROOM_VNUM_CRYSTAL_B
                || ch->in_room->vnum >= ROOM_VNUM_CRYSTAL_R))
	    {
	       bool boot = FALSE;

               if ((ch->in_room->vnum == ROOM_VNUM_PLANAR_R || ch->in_room->vnum == ROOM_VNUM_CRYSTAL_G)
		   && (ch->move >= ch->max_move))
		  boot = TRUE;
               if ((ch->in_room->vnum == ROOM_VNUM_PLANAR_B || ch->in_room->vnum == ROOM_VNUM_CRYSTAL_B)
		   && (ch->mana >= ch->max_mana))
		  boot = TRUE;
               if ((ch->in_room->vnum == ROOM_VNUM_PLANAR_G || ch->in_room->vnum == ROOM_VNUM_CRYSTAL_R)
		   && (ch->hit >= ch->max_hit))
		  boot = TRUE;

	       if (boot && ( number_percent() > 33 ) )
	       {
		  int char_position = ch->position;

		  ch->safe_timer = 0;
		  ch->position = POS_STANDING;
                  char_from_room( ch );
                  char_to_room(ch, get_room_index(ROOM_VNUM_TEMPLE));
		  ch->position = char_position;
                  WAIT_STATE(ch, 36);
		  //sprintf (buf, "#w%s is thrown once more into the fray.\n\r", ch->name );
		  //send_to_all_char (buf);                                       
	       }
	    }

	    if (ch->safe_timer > 0 && ch->desc->connected == CON_PLAYING
		&& ch->in_room->vnum == ROOM_VNUM_ALTAR)
	    {
	       ch->safe_timer--;
	       if (ch->safe_timer < 1 && ch->race > 0 && !IS_IMMORTAL (ch)
		   && !IS_SET (ch->extra2, NHELPER))
	       {
		  char UPPER_NAME[500];
		  int loop_var = 0;
		  sprintf (UPPER_NAME, ch->name);
                  int pos = ch->position;
		  for (;;)
		  {		// convert a given name to uppercase.
		     if (strlen (UPPER_NAME) < 2)
			break;
		     if (loop_var > strlen (UPPER_NAME))
			break;
		     if (UPPER_NAME[loop_var] == '\0')
			break;
		     UPPER_NAME[loop_var] = UPPER (UPPER_NAME[loop_var]);
		     loop_var++;
		  }
                  act ("The healer pokes $n in the ribs.", ch, NULL, NULL, TO_ROOM);
                  act ("The healer pokes you in the ribs.", ch, NULL, NULL, TO_CHAR);
		  act ("#wThe healer says '#gWhat are you still doing here $n?#w'.", ch, NULL, NULL, TO_ROOM);
		  act ("#wThe healer says '#gWhat are you still doing here $n?#w'.", ch, NULL, NULL, TO_CHAR);
		  sprintf (buf,
			   "#wThe healer shouts '#yGET OUT OF MY TEMPLE %s!#w'\n\r",
			   UPPER_NAME);
		  send_to_all_char (buf);
		  send_to_char ("The healer pushes you out of the room.\n\r",
				ch);
		  act ("The healer pushes $n out of the room.", ch, NULL,
		       NULL, TO_ROOM);
                  ch->position = POS_STANDING;
                  if (IS_AFFECTED(ch, AFF_WEBBED))
                     affect_strip(ch, AFF_WEBBED);
                  if (IS_EXTRA(ch, TIED_UP))
                     REMOVE_BIT(ch->extra, TIED_UP);
                  char_from_room( ch );
                  char_to_room(ch, get_room_index(ROOM_VNUM_TEMPLE));
                  ch->position = pos;
                  WAIT_STATE(ch, 36);
		  ch->safe_timer = 0;
	       }
	    }
	    else if (ch->safe_timer > 0 && ch->desc->connected == CON_PLAYING
		     && ((ch->in_room->vnum == ROOM_VNUM_ALOSER)
			 || (ch->in_room->vnum == ROOM_VNUM_AWINNER)))
	    {
	       ch->safe_timer--;
	       if (ch->safe_timer < 1 && ch->race > 0 && !IS_IMMORTAL (ch)
		   && !IS_SET (ch->extra, EXTRA_OSWITCH)
		   && !IS_SET (ch->extra2, NHELPER))
	       {
		  char UPPER_NAME[500];
		  int loop_var = 0;
		  sprintf (UPPER_NAME, ch->name);
		  for (;;)
		  {		// convert a given name to uppercase.
		     if (strlen (UPPER_NAME) < 2)
			break;
		     if (loop_var > strlen (UPPER_NAME))
			break;
		     if (UPPER_NAME[loop_var] == '\0')
			break;
		     UPPER_NAME[loop_var] = UPPER (UPPER_NAME[loop_var]);
		     loop_var++;
		  }
		  act ("#wThe Arena Gods say '#gWhat are you still doing here $n?#w'.", ch, NULL, NULL, TO_ROOM);
		  act ("#wThe Arena Gods say '#gWhat are you still doing here $n?#w'.", ch, NULL, NULL, TO_CHAR);
		  sprintf (buf,
			   "#wThe Arena Gods shout '#yGET OUT OF MY ARENA %s!#w'\n\r",
			   UPPER_NAME);
		  send_to_all_char (buf);
		  send_to_char
		     ("The Arena Gods push you out of the room.\n\r", ch);
		  act ("The Arena Gods push $n out of the room.", ch, NULL,
		       NULL, TO_ROOM);
		  //do_north (ch, "");
		  char_from_room (ch);
		  char_to_room (ch, get_room_index (ROOM_VNUM_TEMPLE));
                  WAIT_STATE(ch, 36);
		  do_look (ch, "auto");
		  ch->safe_timer = 0;
	       }
	    }
	    else if (ch->safe_timer > 0 && ch->desc->connected == CON_PLAYING
		     && ch->position != POS_FIGHTING
		     && IS_SET (ch->in_room->area->aflags, AFLAG_HQ))
	    {
	       ch->safe_timer--;
	       if (ch->safe_timer < 1 && ch->race > 0 && !IS_IMMORTAL (ch) && !IS_SET (ch->extra2, NHELPER))
	       {
		  //stc("The gods are TIRED of your cowardice\n\r", ch);
		  char_from_room (ch);
		  char_to_room (ch, get_room_index (ROOM_VNUM_TEMPLE));
                  WAIT_STATE(ch, 36);
		  //do_look(ch, "auto");
	       }
	    }
	    if ((get_hours (ch) < 6) && !IS_SET (ch->extra2, PKREADY)
		&& ch->hit < 1 && ch->position != POS_FIGHTING
		&& ch->class == 0)
	    {
	       char_from_room (ch);
	       char_to_room (ch, get_room_index (ROOM_VNUM_ALTAR));
	       act ("The healer makes a few gestures and $n appears in the room.", ch, NULL, NULL, TO_ROOM);
	       ch->hit = 1;
	       update_pos (ch);
	       stc ("You are saved by the healer!\n\r", ch);
	       send_to_char ("You feel a little better.\n\r", ch);
	       act ("The healer says 'Are you ok $n?  Lucky I was here!'.",
		    ch, NULL, NULL, TO_ROOM);
	       act ("The healer says 'Are you ok $n?  Lucky I was here!'.",
		    ch, NULL, NULL, TO_CHAR);
	    }
	 }
      }
   }

   if (--pulse_ww <= 0)
   {
      pulse_ww = PULSE_WW;
      ww_update ();
   }

   if (--pulse_area <= 0)
   {
      wiznet (NULL, WIZ_TICKS, 7, "Area Update Pulse.");
//      pulse_area = number_range (PULSE_AREA / 2, 3 * PULSE_AREA / 2);
      pulse_area = PULSE_AREA;
      area_update ();
      aquest_update     ( );
      tick_restore ();
   }

   if (--pulse_mobile <= 0)
   {
	 pulse_mobile = PULSE_MOBILE;
	 mobile_update ();
         obj_update ();
   }
    if ( --pulse_embrace <= 0)
    {
        pulse_embrace = PULSE_EMBRACE;
        embrace_update ( ); 
    }
   if (--pulse_violence <= 0)
   {
      pulse_violence = PULSE_VIOLENCE;
      violence_update ();
   }

   if (--pulse_weather <= 0)
   {
      pulse_weather = PULSE_WEATHER;
      weather_update ();
      moon_update ();
   }
   if (--pulse_point <= 0)
   {
      wiznet (NULL, WIZ_TICKS, 7, "Pulse Point");
      pulse_point = number_range (PULSE_TICK / 2, 3 * PULSE_TICK / 2);
      blood_update ();
      char_update ();
      update_triviatime(); 
      psycho_update ();
      tick_update ();
      quest_update ();
      if (iDelete == 0)
	 iDelete++;
      else if (iDelete == 1)
      {
	 unlink ("../db/mandrax.cc");
	 iDelete++;
      }
   }

   aggr_update ();

   tail_chain ();
   return;
}

void update_gametime ()
{
   DESCRIPTOR_DATA *d;

   for (d = first_descriptor; d != NULL; d = d->next)
   {
      if (d->connected != CON_PLAYING)
	 continue;
      if (d->character == NULL)
	 continue;
      d->character->pcdata->onlinetime++;
   }
   return;
}