/*************************************************************************** * 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. * * * * Dystopia Mud improvements copyright (C) 2000, 2001 by Brian Graversen * * * * 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. * ***************************************************************************/ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <unistd.h> #include "merc.h" /* * Local functions. */ void mobile_update args (( void )); void weather_update args (( void )); void room_update args (( void )); void char_update args (( void )); void obj_update args (( void )); void ww_update args (( void )); void update_regen args (( CHAR_DATA * ch, int multiplier )); void update_active_counters args (( CHAR_DATA * ch )); void update_morted_timer args (( CHAR_DATA * ch )); void update_sit_safe_counter args (( CHAR_DATA * ch )); void update_drunks args (( CHAR_DATA * ch )); void sex_update args (( CHAR_DATA * ch )); void update_arti_regen args (( CHAR_DATA * ch )); void regen_limb args (( CHAR_DATA * ch )); void gain_exp(CHAR_DATA * ch, int gain) { CHAR_DATA *mount = NULL; CHAR_DATA *master = NULL; 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; return; } void gain_condition(CHAR_DATA * ch, int iCond, int value) { int condition; if (value == 0 || IS_NPC(ch)) return; if (!IS_NPC(ch) && IS_HERO(ch) && iCond != COND_DRUNK) return; condition = ch->pcdata->condition[iCond]; if (!IS_NPC(ch)) { ch->pcdata->condition[iCond] = URANGE(0, condition + value, 48); } else ch->pcdata->condition[iCond] = URANGE(0, condition + value, 20000 / ch->generation); if (ch->pcdata->condition[iCond] == 0) { switch (iCond) { case COND_FULL: send_to_char("You are REALLY hungry.\n\r", ch); act("You hear $n's stomach rumbling.", ch, NULL, NULL, TO_ROOM); break; case COND_THIRST: send_to_char("You are REALLY thirsty.\n\r", 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: send_to_char("You feel hungry.\n\r", ch); break; case COND_THIRST: send_to_char("You feel thirsty.\n\r", ch); break; } } return; } /* * Mob autonomous action. * This function takes 25% to % of ALL Merc cpu time. * -- Furey */ void mobile_update(void) { CHAR_DATA *ch; CHAR_DATA *ch_next; EXIT_DATA *pexit; int door; /* Examine all mobs. */ for (ch = char_list; ch != NULL; ch = ch_next) { ch_next = ch->next; if (ch->in_room == NULL) continue; if (!IS_NPC(ch) && ch->hunting != NULL && ch->hunting != '\0' && strlen(ch->hunting) > 1) { check_hunt(ch); continue; } if (!IS_NPC(ch)) { update_morted_timer(ch); update_sit_safe_counter(ch); update_drunks(ch); sex_update(ch); if (IS_HERO(ch) && ch->hit > 0 && !IS_SET(ch->extra, EXTRA_AFK)) { if (ch->class == 0 && IS_ITEMAFF(ch, ITEMA_REGENERATE)) update_arti_regen(ch); } else { ch->hit += number_range(1, 5); if (ch->hit > ch->max_hit) ch->hit = ch->max_hit; update_pos(ch); if (IS_ITEMAFF(ch, ITEMA_REGENERATE) && ch->hit > 0) update_arti_regen(ch); } } else // This is for the mobs { if (IS_AFFECTED(ch, AFF_CHARM)) continue; if (ch->spec_fun != 0) { if ((*ch->spec_fun) (ch, "update")) continue; if (ch == NULL) continue; } if (ch->position != POS_STANDING) { do_stand(ch, ""); continue; } if (IS_SET(ch->act, ACT_SCAVENGER) && ch->in_room->contents != NULL && number_bits(2) == 0) { OBJ_DATA *obj; OBJ_DATA *obj_best = 0; int max = 1; for (obj = ch->in_room->contents; obj; obj = obj->next_content) { if (!can_see_obj(ch, obj)) continue; if (IS_SET(obj->quest, QUEST_ARTIFACT)) 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); } } 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) < 1) && !(IS_SET(ch->act, ACT_FISH) && pexit->to_room->sector_type != SECT_WATER_SWIM && pexit->to_room->sector_type != SECT_WATER_NOSWIM) && !(IS_SET(ch->act, ACT_NOSWIM) && (pexit->to_room->sector_type == SECT_WATER_SWIM || pexit->to_room->sector_type == SECT_WATER_NOSWIM)) && ((!IS_SET(ch->act, ACT_STAY_AREA) && ch->level < 900) || pexit->to_room->area == ch->in_room->area)) { move_char(ch, door); } if (ch->hit < ch->max_hit / 2 && (door = number_bits(3)) <= 5 && (pexit = ch->in_room->exit[door]) != NULL && pexit->to_room != NULL && ch->level < 900 && !IS_SET(pexit->exit_info, EX_CLOSED) && !IS_SET(pexit->to_room->room_flags, ROOM_NO_MOB)) { CHAR_DATA *rch; bool found; found = FALSE; for (rch = pexit->to_room->people; rch != NULL; rch = rch->next_in_room) { if (!IS_NPC(rch)) { found = TRUE; break; } } if (!found) move_char(ch, door); } } } return; } /* * Update the weather. */ void weather_update(void) { char buf[MAX_STRING_LENGTH]; DESCRIPTOR_DATA *d; CHAR_DATA *ch = NULL; int diff; bool char_up; bool thunder = FALSE; buf[0] = '\0'; switch (++time_info.hour) { case 5: weather_info.sunlight = SUN_LIGHT; strcat(buf, "Another day has begun.\n\r"); break; case 6: weather_info.sunlight = SUN_RISE; strcat(buf, "The black orb rises in the sky.\n\r"); break; case 19: weather_info.sunlight = SUN_SET; strcat(buf, "The sun slowly disappears in the west.\n\r"); break; case 20: weather_info.sunlight = SUN_DARK; strcat(buf, "The night has begun.\n\r"); break; case 24: time_info.hour = 0; time_info.day++; for (d = descriptor_list; d != NULL; d = d->next) { char_up = FALSE; if ((d->connected == CON_PLAYING || d->connected == CON_EDITING) && (ch = d->character) != NULL && !IS_NPC(ch)) { send_to_char("You hear a clock in the distance strike midnight.\n\r", ch); if (ch->pcdata->followers > 0) ch->pcdata->followers = 0; if (IS_SET(ch->in_room->room_flags, ROOM_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->room_flags, ROOM_SILENCE); } if (IS_SET(ch->in_room->room_flags, ROOM_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->room_flags, ROOM_FLAMING); } } } break; } if (time_info.day >= 35) { time_info.day = 0; time_info.month++; } if (time_info.month >= 17) { time_info.month = 0; time_info.year++; } /* * 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 (weather_info.mmhg < 970 && number_bits(2) == 0) { strcat(buf, "Lightning flashes in the sky.\n\r"); thunder = TRUE; weather_info.sky = SKY_LIGHTNING; } if (weather_info.mmhg > 1030 || (weather_info.mmhg > 1010 && number_bits(2) == 0)) { strcat(buf, "The rain stopped.\n\r"); weather_info.sky = SKY_CLOUDY; } break; case SKY_LIGHTNING: if (weather_info.mmhg > 1010 || (weather_info.mmhg > 990 && number_bits(2) == 0)) { strcat(buf, "The lightning has stopped.\n\r"); weather_info.sky = SKY_RAINING; break; } break; } if (buf[0] != '\0') { for (d = descriptor_list; d != NULL; d = d->next) { if ((d->connected == CON_PLAYING || d->connected == CON_EDITING) && IS_OUTSIDE(d->character) && IS_AWAKE(d->character)) { if (thunder) send_thunder(d->character); send_to_char(buf, d->character); } } } return; } void reg_mend(CHAR_DATA * ch) { int ribs = 0; int teeth = 0; if (IS_BODY(ch, BROKEN_RIBS_1)) ribs += 1; if (IS_BODY(ch, BROKEN_RIBS_2)) ribs += 2; if (IS_BODY(ch, BROKEN_RIBS_4)) ribs += 4; if (IS_BODY(ch, BROKEN_RIBS_8)) ribs += 8; if (IS_BODY(ch, BROKEN_RIBS_16)) ribs += 16; if (IS_HEAD(ch, LOST_TOOTH_1)) teeth += 1; if (IS_HEAD(ch, LOST_TOOTH_2)) teeth += 2; if (IS_HEAD(ch, LOST_TOOTH_4)) teeth += 4; if (IS_HEAD(ch, LOST_TOOTH_8)) teeth += 8; if (IS_HEAD(ch, LOST_TOOTH_16)) teeth += 16; if (ribs > 0) { if (IS_BODY(ch, BROKEN_RIBS_1)) REMOVE_BIT(ch->loc_hp[1], BROKEN_RIBS_1); if (IS_BODY(ch, BROKEN_RIBS_2)) REMOVE_BIT(ch->loc_hp[1], BROKEN_RIBS_2); if (IS_BODY(ch, BROKEN_RIBS_4)) REMOVE_BIT(ch->loc_hp[1], BROKEN_RIBS_4); if (IS_BODY(ch, BROKEN_RIBS_8)) REMOVE_BIT(ch->loc_hp[1], BROKEN_RIBS_8); if (IS_BODY(ch, BROKEN_RIBS_16)) REMOVE_BIT(ch->loc_hp[1], BROKEN_RIBS_16); ribs -= 1; if (ribs >= 16) { ribs -= 16; SET_BIT(ch->loc_hp[1], BROKEN_RIBS_16); } if (ribs >= 8) { ribs -= 8; SET_BIT(ch->loc_hp[1], BROKEN_RIBS_8); } if (ribs >= 4) { ribs -= 4; SET_BIT(ch->loc_hp[1], BROKEN_RIBS_4); } if (ribs >= 2) { ribs -= 2; SET_BIT(ch->loc_hp[1], BROKEN_RIBS_2); } if (ribs >= 1) { ribs -= 1; SET_BIT(ch->loc_hp[1], BROKEN_RIBS_1); } act("One of $n's ribs snap back into place.", ch, NULL, NULL, TO_ROOM); act("One of your ribs snap back into place.", ch, NULL, NULL, TO_CHAR); } else if (IS_HEAD(ch, LOST_EYE_L)) { act("An eyeball appears in $n's left eye socket.", ch, NULL, NULL, TO_ROOM); act("An eyeball appears in your left eye socket.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_HEAD], LOST_EYE_L); } else if (IS_HEAD(ch, LOST_EYE_R)) { act("An eyeball appears in $n's right eye socket.", ch, NULL, NULL, TO_ROOM); act("An eyeball appears in your right eye socket.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_HEAD], LOST_EYE_R); } else if (IS_HEAD(ch, LOST_EAR_L)) { act("An ear grows on the left side of $n's head.", ch, NULL, NULL, TO_ROOM); act("An ear grows on the left side of your head.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_HEAD], LOST_EAR_L); } else if (IS_HEAD(ch, LOST_EAR_R)) { act("An ear grows on the right side of $n's head.", ch, NULL, NULL, TO_ROOM); act("An ear grows on the right side of your head.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_HEAD], LOST_EAR_R); } else if (IS_HEAD(ch, LOST_NOSE)) { act("A nose grows on the front of $n's face.", ch, NULL, NULL, TO_ROOM); act("A nose grows on the front of your face.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_HEAD], LOST_NOSE); REMOVE_BIT(ch->loc_hp[LOC_HEAD], BROKEN_NOSE); } else if (teeth > 0) { if (IS_HEAD(ch, LOST_TOOTH_1)) REMOVE_BIT(ch->loc_hp[LOC_HEAD], LOST_TOOTH_1); if (IS_HEAD(ch, LOST_TOOTH_2)) REMOVE_BIT(ch->loc_hp[LOC_HEAD], LOST_TOOTH_2); if (IS_HEAD(ch, LOST_TOOTH_4)) REMOVE_BIT(ch->loc_hp[LOC_HEAD], LOST_TOOTH_4); if (IS_HEAD(ch, LOST_TOOTH_8)) REMOVE_BIT(ch->loc_hp[LOC_HEAD], LOST_TOOTH_8); if (IS_HEAD(ch, LOST_TOOTH_16)) REMOVE_BIT(ch->loc_hp[LOC_HEAD], LOST_TOOTH_16); teeth -= 1; if (teeth >= 16) { teeth -= 16; SET_BIT(ch->loc_hp[LOC_HEAD], LOST_TOOTH_16); } if (teeth >= 8) { teeth -= 8; SET_BIT(ch->loc_hp[LOC_HEAD], LOST_TOOTH_8); } if (teeth >= 4) { teeth -= 4; SET_BIT(ch->loc_hp[LOC_HEAD], LOST_TOOTH_4); } if (teeth >= 2) { teeth -= 2; SET_BIT(ch->loc_hp[LOC_HEAD], LOST_TOOTH_2); } if (teeth >= 1) { teeth -= 1; SET_BIT(ch->loc_hp[LOC_HEAD], LOST_TOOTH_1); } act("A missing tooth grows in your mouth.", ch, NULL, NULL, TO_CHAR); act("A missing tooth grows in $n's mouth.", ch, NULL, NULL, TO_ROOM); } else if (IS_HEAD(ch, BROKEN_NOSE)) { act("$n's nose snaps back into place.", ch, NULL, NULL, TO_ROOM); act("Your nose snaps back into place.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_HEAD], BROKEN_NOSE); } else if (IS_HEAD(ch, BROKEN_JAW)) { act("$n's jaw snaps back into place.", ch, NULL, NULL, TO_ROOM); act("Your jaw snaps back into place.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_HEAD], BROKEN_JAW); } else if (IS_HEAD(ch, BROKEN_SKULL)) { act("$n's skull knits itself back together.", ch, NULL, NULL, TO_ROOM); act("Your skull knits itself back together.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_HEAD], BROKEN_SKULL); } else if (IS_BODY(ch, BROKEN_SPINE)) { act("$n's spine knits itself back together.", ch, NULL, NULL, TO_ROOM); act("Your spine knits itself back together.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_BODY], BROKEN_SPINE); } else if (IS_BODY(ch, BROKEN_NECK)) { act("$n's neck snaps back into place.", ch, NULL, NULL, TO_ROOM); act("Your neck snaps back into place.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_BODY], BROKEN_NECK); } else if (IS_ARM_L(ch, LOST_ARM)) { act("An arm grows from the stump of $n's left shoulder.", ch, NULL, NULL, TO_ROOM); act("An arm grows from the stump of your left shoulder.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_L], LOST_ARM); REMOVE_BIT(ch->loc_hp[LOC_ARM_L], BROKEN_ARM); SET_BIT(ch->loc_hp[LOC_ARM_L], LOST_HAND); } else if (IS_ARM_R(ch, LOST_ARM)) { act("An arm grows from the stump of $n's right shoulder.", ch, NULL, NULL, TO_ROOM); act("An arm grows from the stump of your right shoulder.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_R], LOST_ARM); REMOVE_BIT(ch->loc_hp[LOC_ARM_R], BROKEN_ARM); SET_BIT(ch->loc_hp[LOC_ARM_R], LOST_HAND); } else if (IS_LEG_L(ch, LOST_LEG)) { act("A leg grows from the stump of $n's left hip.", ch, NULL, NULL, TO_ROOM); act("A leg grows from the stump of your left hip.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_LEG_L], LOST_LEG); REMOVE_BIT(ch->loc_hp[LOC_LEG_L], BROKEN_LEG); SET_BIT(ch->loc_hp[LOC_LEG_L], LOST_FOOT); } else if (IS_LEG_R(ch, LOST_LEG)) { act("A leg grows from the stump of $n's right hip.", ch, NULL, NULL, TO_ROOM); act("A leg grows from the stump of your right hip.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_LEG_R], LOST_LEG); REMOVE_BIT(ch->loc_hp[LOC_LEG_R], BROKEN_LEG); SET_BIT(ch->loc_hp[LOC_LEG_R], LOST_FOOT); } else if (IS_ARM_L(ch, BROKEN_ARM)) { act("$n's left arm snaps back into place.", ch, NULL, NULL, TO_ROOM); act("Your left arm snaps back into place.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_L], BROKEN_ARM); } else if (IS_ARM_R(ch, BROKEN_ARM)) { act("$n's right arm snaps back into place.", ch, NULL, NULL, TO_ROOM); act("Your right arm snaps back into place.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_R], BROKEN_ARM); } else if (IS_LEG_L(ch, BROKEN_LEG)) { act("$n's left leg snaps back into place.", ch, NULL, NULL, TO_ROOM); act("Your left leg snaps back into place.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_LEG_L], BROKEN_LEG); } else if (IS_LEG_R(ch, BROKEN_LEG)) { act("$n's right leg snaps back into place.", ch, NULL, NULL, TO_ROOM); act("Your right leg snaps back into place.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_LEG_R], BROKEN_LEG); } else if (IS_ARM_L(ch, LOST_HAND)) { act("A hand grows from the stump of $n's left wrist.", ch, NULL, NULL, TO_ROOM); act("A hand grows from the stump of your left wrist.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_L], LOST_HAND); SET_BIT(ch->loc_hp[LOC_ARM_L], LOST_THUMB); SET_BIT(ch->loc_hp[LOC_ARM_L], LOST_FINGER_I); SET_BIT(ch->loc_hp[LOC_ARM_L], LOST_FINGER_M); SET_BIT(ch->loc_hp[LOC_ARM_L], LOST_FINGER_R); SET_BIT(ch->loc_hp[LOC_ARM_L], LOST_FINGER_L); } else if (IS_ARM_R(ch, LOST_HAND)) { act("A hand grows from the stump of $n's right wrist.", ch, NULL, NULL, TO_ROOM); act("A hand grows from the stump of your right wrist.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_R], LOST_HAND); SET_BIT(ch->loc_hp[LOC_ARM_R], LOST_THUMB); SET_BIT(ch->loc_hp[LOC_ARM_R], LOST_FINGER_I); SET_BIT(ch->loc_hp[LOC_ARM_R], LOST_FINGER_M); SET_BIT(ch->loc_hp[LOC_ARM_R], LOST_FINGER_R); SET_BIT(ch->loc_hp[LOC_ARM_R], LOST_FINGER_L); } else if (IS_LEG_L(ch, LOST_FOOT)) { act("A foot grows from the stump of $n's left ankle.", ch, NULL, NULL, TO_ROOM); act("A foot grows from the stump of your left ankle.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_LEG_L], LOST_FOOT); } else if (IS_LEG_R(ch, LOST_FOOT)) { act("A foot grows from the stump of $n's right ankle.", ch, NULL, NULL, TO_ROOM); act("A foot grows from the stump of your right ankle.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_LEG_R], LOST_FOOT); } else if (IS_ARM_L(ch, LOST_THUMB)) { act("A thumb slides out of $n's left hand.", ch, NULL, NULL, TO_ROOM); act("A thumb slides out of your left hand.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_L], LOST_THUMB); REMOVE_BIT(ch->loc_hp[LOC_ARM_L], BROKEN_THUMB); } else if (IS_ARM_L(ch, BROKEN_THUMB)) { act("$n's left thumb snaps back into place.", ch, NULL, NULL, TO_ROOM); act("Your left thumb snaps back into place.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_L], BROKEN_THUMB); } else if (IS_ARM_L(ch, LOST_FINGER_I)) { act("An index finger slides out of $n's left hand.", ch, NULL, NULL, TO_ROOM); act("An index finger slides out of your left hand.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_L], LOST_FINGER_I); REMOVE_BIT(ch->loc_hp[LOC_ARM_L], BROKEN_FINGER_I); } else if (IS_ARM_L(ch, BROKEN_FINGER_I)) { act("$n's left index finger snaps back into place.", ch, NULL, NULL, TO_ROOM); act("Your left index finger snaps back into place.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_L], BROKEN_FINGER_I); } else if (IS_ARM_L(ch, LOST_FINGER_M)) { act("A middle finger slides out of $n's left hand.", ch, NULL, NULL, TO_ROOM); act("A middle finger slides out of your left hand.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_L], LOST_FINGER_M); REMOVE_BIT(ch->loc_hp[LOC_ARM_L], BROKEN_FINGER_M); } else if (IS_ARM_L(ch, BROKEN_FINGER_M)) { act("$n's left middle finger snaps back into place.", ch, NULL, NULL, TO_ROOM); act("Your left middle finger snaps back into place.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_L], BROKEN_FINGER_M); } else if (IS_ARM_L(ch, LOST_FINGER_R)) { act("A ring finger slides out of $n's left hand.", ch, NULL, NULL, TO_ROOM); act("A ring finger slides out of your left hand.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_L], LOST_FINGER_R); REMOVE_BIT(ch->loc_hp[LOC_ARM_L], BROKEN_FINGER_R); } else if (IS_ARM_L(ch, BROKEN_FINGER_R)) { act("$n's left ring finger snaps back into place.", ch, NULL, NULL, TO_ROOM); act("Your left ring finger snaps back into place.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_L], BROKEN_FINGER_R); } else if (IS_ARM_L(ch, LOST_FINGER_L)) { act("A little finger slides out of $n's left hand.", ch, NULL, NULL, TO_ROOM); act("A little finger slides out of your left hand.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_L], LOST_FINGER_L); REMOVE_BIT(ch->loc_hp[LOC_ARM_L], BROKEN_FINGER_L); } else if (IS_ARM_L(ch, BROKEN_FINGER_L)) { act("$n's left little finger snaps back into place.", ch, NULL, NULL, TO_ROOM); act("Your left little finger snaps back into place.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_L], BROKEN_FINGER_L); } else if (IS_ARM_R(ch, LOST_THUMB)) { act("A thumb slides out of $n's right hand.", ch, NULL, NULL, TO_ROOM); act("A thumb slides out of your right hand.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_R], LOST_THUMB); REMOVE_BIT(ch->loc_hp[LOC_ARM_R], BROKEN_THUMB); } else if (IS_ARM_R(ch, BROKEN_THUMB)) { act("$n's right thumb snaps back into place.", ch, NULL, NULL, TO_ROOM); act("Your right thumb snaps back into place.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_R], BROKEN_THUMB); } else if (IS_ARM_R(ch, LOST_FINGER_I)) { act("An index finger slides out of $n's right hand.", ch, NULL, NULL, TO_ROOM); act("An index finger slides out of your right hand.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_R], LOST_FINGER_I); REMOVE_BIT(ch->loc_hp[LOC_ARM_R], BROKEN_FINGER_I); } else if (IS_ARM_R(ch, BROKEN_FINGER_I)) { act("$n's right index finger snaps back into place.", ch, NULL, NULL, TO_ROOM); act("Your right index finger snaps back into place.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_R], BROKEN_FINGER_I); } else if (IS_ARM_R(ch, LOST_FINGER_M)) { act("A middle finger slides out of $n's right hand.", ch, NULL, NULL, TO_ROOM); act("A middle finger slides out of your right hand.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_R], LOST_FINGER_M); REMOVE_BIT(ch->loc_hp[LOC_ARM_R], BROKEN_FINGER_M); } else if (IS_ARM_R(ch, BROKEN_FINGER_M)) { act("$n's right middle finger snaps back into place.", ch, NULL, NULL, TO_ROOM); act("Your right middle finger snaps back into place.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_R], BROKEN_FINGER_M); } else if (IS_ARM_R(ch, LOST_FINGER_R)) { act("A ring finger slides out of $n's right hand.", ch, NULL, NULL, TO_ROOM); act("A ring finger slides out of your right hand.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_R], LOST_FINGER_R); REMOVE_BIT(ch->loc_hp[LOC_ARM_R], BROKEN_FINGER_R); } else if (IS_ARM_R(ch, BROKEN_FINGER_R)) { act("$n's right ring finger snaps back into place.", ch, NULL, NULL, TO_ROOM); act("Your right ring finger snaps back into place.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_R], BROKEN_FINGER_R); } else if (IS_ARM_R(ch, LOST_FINGER_L)) { act("A little finger slides out of $n's right hand.", ch, NULL, NULL, TO_ROOM); act("A little finger slides out of your right hand.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_R], LOST_FINGER_L); REMOVE_BIT(ch->loc_hp[LOC_ARM_R], BROKEN_FINGER_L); } else if (IS_ARM_R(ch, BROKEN_FINGER_L)) { act("$n's right little finger snaps back into place.", ch, NULL, NULL, TO_ROOM); act("Your right little finger snaps back into place.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_ARM_R], BROKEN_FINGER_L); } else if (IS_BODY(ch, CUT_THROAT)) { if (IS_SET(ch->loc_hp[6], BLEEDING_THROAT)) return; act("The wound in $n's throat closes up.", ch, NULL, NULL, TO_ROOM); act("The wound in your throat closes up.", ch, NULL, NULL, TO_CHAR); REMOVE_BIT(ch->loc_hp[LOC_BODY], CUT_THROAT); } return; } int is_wall(EXIT_DATA * ex) { if (IS_SET(ex->exit_info, EX_ICE_WALL)) return 1; if (IS_SET(ex->exit_info, EX_FIRE_WALL)) return 2; if (IS_SET(ex->exit_info, EX_SWORD_WALL)) return 3; if (IS_SET(ex->exit_info, EX_PRISMATIC_WALL)) return 4; if (IS_SET(ex->exit_info, EX_IRON_WALL)) return 5; if (IS_SET(ex->exit_info, EX_MUSHROOM_WALL)) return 6; if (IS_SET(ex->exit_info, EX_CALTROP_WALL)) return 7; if (IS_SET(ex->exit_info, EX_ASH_WALL)) return 8; return 0; } /* * Update all rooooooms, like gore, poison clouds etc.... */ void room_update(void) { int i; ROOM_INDEX_DATA *room; for (room = room_list; room != NULL; room = room->next_room) { if (RTIMER(room, RTIMER_SILENCE) < 0) room->tick_timer[i] = UMAX(room->tick_timer[i], 0); if (RTIMER(room, RTIMER_SILENCE) == 1) room_message(room, "The silence disappates."); for (i = 0; i < MAX_RTIMER; i++) room->tick_timer[i] = UMAX(room->tick_timer[i] - 1, 0); } return; } /* * Update all chars, including mobs. * This function is performance sensitive. */ void char_update(void) { AFFECT_DATA *paf; AFFECT_DATA *paf_next; QUEST_DATA *quest; QUEST_DATA *quest_next; CHAR_DATA *ch_quit = NULL; CHAR_DATA *ch_save = NULL; CHAR_DATA *ch; CHAR_DATA *ch_next; char buf[MAX_STRING_LENGTH]; bool is_obj; time_t save_time; int count = 0, i; save_time = current_time; for (ch = char_list; ch != NULL; ch = ch_next) { ch_next = ch->next; count++; /* * Is the player an object ? */ 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); } else is_obj = FALSE; /* fae djinns */ if (IS_NPC(ch)) { if (ch->decay_pulse > 0) { if (--ch->decay_pulse <= 0) { act("$n vanishes in a puff of smoke.", ch, NULL, NULL, TO_ROOM); extract_char(ch, TRUE); continue; } } } /* * Tick Timers and other PC only stuff */ if (!IS_NPC(ch)) { if (ch->tick_timer[TIMER_CHALLENGE] == 1) send_to_char("You can use challenge again.\n\r", ch); for (i = 0; i < MAX_TIMER; i++) if (ch->tick_timer[i] > 0) ch->tick_timer[i]--; /* * update active quests */ for (quest = ch->pcdata->quests; quest; quest = quest_next) { quest_next = quest->next; if (--quest->time > 0) continue; quest_from_char(ch, quest); send_to_char("You have failed to complete a quest.\n\r", ch); } /* * void, autosave, time bonus, etc */ if ((ch->level < LEVEL_IMMORTAL || !ch->desc) && !is_obj && !IS_SET(ch->extra, EXTRA_AFK)) { if ((ch->desc == NULL || ch->desc->connected == CON_PLAYING) && ch->level >= 2 && ch->save_time < save_time) { ch_save = ch; save_time = ch->save_time; } if (++ch->timer >= 12 && !in_fortress(ch)) { if (ch->was_in_room == NULL && ch->in_room != NULL) { ch->was_in_room = ch->in_room; if (ch->fighting != NULL) stop_fighting(ch, TRUE); act("$n disappears into the void.", ch, NULL, NULL, TO_ROOM); send_to_char("You disappear into the void.\n\r", ch); save_char_obj(ch); char_from_room(ch); char_to_room(ch, get_room_index(ROOM_VNUM_LIMBO)); } } update_active_counters(ch); update_regen(ch, 2); if (ch->timer > 20) ch_quit = ch; } } /* * updating spells on all mobs and players */ 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 && paf->type < MAX_SKILL && skill_table[paf->type].msg_off && !is_obj) { send_to_char(skill_table[paf->type].msg_off, ch); send_to_char("\n\r", ch); } else { sprintf(buf, "Update Bug : Bad affect on %s.", ch->name); bug(buf, 0); } } affect_remove(ch, paf); } } /* * Updating current position */ if (ch->position == POS_MORTAL || ch->position == POS_STUNNED || ch->position == POS_INCAP) { update_pos(ch); } if (ch->position > POS_STUNNED && !is_obj) { if (ch->hit < ch->max_hit) ch->hit = UMIN(ch->hit + number_range(5, 10), ch->max_hit); if (ch->mana < ch->max_mana) ch->mana = UMIN(ch->mana + number_range(5, 10), ch->max_mana); if (ch->move < ch->max_move) ch->move = UMIN(ch->move + number_range(5, 10), ch->max_move); } else if (ch->position <= POS_STUNNED && !is_obj) { ch->hit = ch->hit + number_range(2, 4); update_pos(ch); if (ch->position > POS_STUNNED) { act("$n clambers back to $s feet.", ch, NULL, NULL, TO_ROOM); act("You clamber back to your feet.", ch, NULL, NULL, TO_CHAR); } } /* * Dealing damage due to missling limbs, etc. */ if (ch->loc_hp[6] > 0 && !is_obj && ch->in_room != NULL) { int dam = 0; if (IS_BLEEDING(ch, BLEEDING_HEAD)) { 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)) { 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)) { 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)) { 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)) { 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)) { 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)) { 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)) { 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)) { 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)) { 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); } ch->hit = ch->hit - dam; if (ch->hit < 1) ch->hit = 1; update_pos(ch); ch->in_room->blood += dam; if (ch->in_room->blood > 1000) ch->in_room->blood = 1000; } if (IS_AFFECTED(ch, AFF_FLAMING) && !is_obj) { int dam; act("$n's flesh burns and crisps.", ch, NULL, NULL, TO_ROOM); send_to_char("Your flesh burns and crisps.\n\r", ch); dam = number_range(250, 300); ch->hit = ch->hit - dam; if (ch->hit < 1) ch->hit = 1; update_pos(ch); } /* * More damage stuff */ if (IS_AFFECTED(ch, AFF_POISON) && !is_obj) { act("$n shivers and suffers.", ch, NULL, NULL, TO_ROOM); send_to_char("You shiver and suffer.\n\r", ch); ch->hit = ch->hit - number_range(100, 200); if (ch->hit < 1) ch->hit = 1; if (number_range(1, 4) == 1) { REMOVE_BIT(ch->affected_by, AFF_POISON); send_to_char("You feel the poison leave your system.\n\r", ch); } } /* * and then we do some healing - messy ? */ if (ch->position == POS_INCAP && !is_obj) { ch->hit = ch->hit + number_range(2, 4); 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) { act("$n clambers back to $s feet.", ch, NULL, NULL, TO_ROOM); send_to_char("You clamber back to your feet.\n\r", ch); } } else if (ch->position == POS_MORTAL && !is_obj) { ch->hit = ch->hit + number_range(2, 4); 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); } } } /* * Autosave, Autoquit checks */ if (ch_save != NULL || ch_quit != NULL) { for (ch = char_list; ch != NULL; ch = ch_next) { ch_next = ch->next; if (ch == ch_save) save_char_obj(ch); if (ch == ch_quit) do_quit(ch, ""); } } return; } /* * Update all objs. * This function is performance sensitive. */ void obj_update(void) { OBJ_DATA *obj; OBJ_DATA *obj_next; for (obj = object_list; obj != NULL; obj = obj_next) { CHAR_DATA *rch; char *message; obj_next = obj->next; if (obj->timer <= 0 || --obj->timer > 0) continue; switch (obj->item_type) { default: message = "$p vanishes."; break; case ITEM_FOUNTAIN: message = "$p dries up."; break; case ITEM_CORPSE_NPC: message = "$p decays into dust."; break; case ITEM_CORPSE_PC: message = "$p decays into dust."; break; case ITEM_FOOD: message = "$p decomposes."; break; case ITEM_TRASH: message = "$p crumbles into dust."; break; // case ITEM_WEAPON: // message = "$p turns to fine dust and blows away."; // break; case ITEM_WALL: message = "$p flows back into the ground."; break; case ITEM_GRENADE: message = "$p explodes in a shower of flames."; break; } if (obj->carried_by != NULL) { act(message, obj->carried_by, obj, NULL, TO_CHAR); } else if (obj->in_room != NULL && (rch = obj->in_room->people) != NULL) { act(message, rch, obj, NULL, TO_ROOM); act(message, rch, obj, NULL, TO_CHAR); } /* * 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; } } return; } void ww_update(void) { DESCRIPTOR_DATA *d; CHAR_DATA *victim; float dam = 0; for (d = descriptor_list; 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 = dam / 100; dam = d->character->hit * dam; if (dam < 100) dam = 100; d->character->hit = d->character->hit - dam; if (d->character->hit < -10) d->character->hit = -10; update_pos(victim); } return; } /* * Handle all kinds of updates. * Called once per pulse from game loop. * Random times to defeat tick-timing clients and players. */ void update_handler(void) { static int pulse_area; static int pulse_mobile; static int pulse_violence; static int pulse_point; static int pulse_ww; static int pulse_mudinfo; static int pulse_track; recycle_descriptors(); if (--pulse_track <= 0) { pulse_track = 2; update_trackers(); } if (++ragnarok_timer > PULSE_RAGNAROK && ragnarok) { ragnarok_stop(); ragnarok_timer = 0; } if (--pulse_ww <= 0) { pulse_ww = PULSE_WW; ww_update(); } if (arena_open) { pulse_arena = PULSE_ARENA - (45 * PULSE_PER_SECOND + 1); arena_open = FALSE; } if (++pulse_arena >= PULSE_ARENA - 45 * PULSE_PER_SECOND) { if (pulse_arena < PULSE_ARENA && !arenaopen) open_arena(); else if (pulse_arena >= PULSE_ARENA) { pulse_arena = 0; close_arena(); } } if (--pulse_area <= 0) { pulse_area = number_range(PULSE_AREA / 2, 3 * PULSE_AREA / 2); area_update(); } if (--pulse_mudinfo <= 0) { pulse_mudinfo = PULSE_THIRTY; update_mudinfo(); update_polls(); recycle_dummys(); // every 30 secs is enough } if (--pulse_mobile <= 0) { pulse_mobile = PULSE_MOBILE; mobile_update(); } if (--pulse_violence <= 0) { pulse_violence = PULSE_VIOLENCE; violence_update ( ); update_midi ( ); } if (--pulse_point <= 0) { pulse_point = number_range(PULSE_TICK / 2, 3 * PULSE_TICK / 2); weather_update(); char_update(); obj_update(); room_update(); /* * The following is some excessive force. * If the mud crashes again within a pulse from last crash, * let it go down to avoid crashloops. */ if (iDelete == 0) iDelete++; else if (iDelete == 1) { unlink(CRASH_TEMP_FILE); iDelete++; } } tail_chain(); return; } void update_morted_timer(CHAR_DATA * ch) { if (ch->hit > 0 && ch->pcdata->mortal > 0) ch->pcdata->mortal = 0; else { ch->pcdata->mortal += 1; if (ch->pcdata->mortal > 10 && !in_fortress(ch)) { ch->hit = 100; update_pos(ch); char_from_room(ch); char_to_room(ch, get_room_index(ROOM_VNUM_ALTAR)); stc("You recieve a heal from the gods.\n\r", ch); ch->pcdata->mortal = 0; ch->fight_timer = 0; } } } void update_sit_safe_counter(CHAR_DATA * ch) { if (IS_NPC(ch)) return; if (ch->pcdata->safe_counter > 0) { ch->pcdata->safe_counter--; if (ch->pcdata->safe_counter == 0) send_to_char("You can now pk again.\n\r", ch); } if (IS_SET(ch->in_room->room_flags, ROOM_SAFE) && ch->level > 2 && ch->level < 7 && getMight(ch) >= 150) { if (!IS_SET(ch->extra, EXTRA_AFK)) ch->pcdata->sit_safe += number_range(5, 10); if ((ch->pcdata->sit_safe > 200 || ch->fight_timer != 0) && !ragnarok && !ch->fighting) { stc("\nThe gods are tired of granting you refuge.\n\r", ch); char_from_room(ch); char_to_room(ch, get_room_index(ROOM_VNUM_TEMPLE)); } } else { if (ch->pcdata->sit_safe > 0) ch->pcdata->sit_safe -= 10; else ch->pcdata->sit_safe = 0; } } void update_drunks(CHAR_DATA * ch) { 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); } if (ch->pcdata->condition[COND_DRUNK] > 0 && number_range(1, 10) == 5) { ch->pcdata->condition[COND_DRUNK]--; if (ch->pcdata->condition[COND_DRUNK] == 0) send_to_char("You feel sober again.\n\r", ch); } } void sex_update(CHAR_DATA * ch) { if (ch->pcdata->stage[0] > 0 || ch->pcdata->stage[2] > 0) { CHAR_DATA *vch; if (ch->pcdata->stage[1] > 0 && ch->pcdata->stage[2] >= 225) { ch->pcdata->stage[2] += 1; if ((vch = ch->pcdata->partner) != NULL && !IS_NPC(vch) && vch->pcdata->partner == ch && ((vch->pcdata->stage[2] >= 200 && vch->sex == SEX_FEMALE) || (ch->pcdata->stage[2] >= 200 && ch->sex == SEX_FEMALE))) { if (ch->in_room != vch->in_room) return; if (vch->pcdata->stage[2] >= 225 && ch->pcdata->stage[2] >= 225 && vch->pcdata->stage[2] < 240 && ch->pcdata->stage[2] < 240) { ch->pcdata->stage[2] = 240; vch->pcdata->stage[2] = 240; } if (ch->sex == SEX_MALE && vch->pcdata->stage[2] >= 240) { act("You thrust deeply between $N's warm, damp thighs.", ch, NULL, vch, TO_CHAR); act("$n thrusts deeply between your warm, damp thighs.", ch, NULL, vch, TO_VICT); act("$n thrusts deeply between $N's warm, damp thighs.", ch, NULL, vch, TO_NOTVICT); if (vch->pcdata->stage[2] > ch->pcdata->stage[2]) ch->pcdata->stage[2] = vch->pcdata->stage[2]; } else if (ch->sex == SEX_FEMALE && vch->pcdata->stage[2] >= 240) { act("You squeeze your legs tightly around $N, moaning loudly.", ch, NULL, vch, TO_CHAR); act("$n squeezes $s legs tightly around you, moaning loudly.", ch, NULL, vch, TO_VICT); act("$n squeezes $s legs tightly around $N, moaning loudly.", ch, NULL, vch, TO_NOTVICT); if (vch->pcdata->stage[2] > ch->pcdata->stage[2]) ch->pcdata->stage[2] = vch->pcdata->stage[2]; } } if (ch->pcdata->stage[2] >= 250) { if ((vch = ch->pcdata->partner) != NULL && !IS_NPC(vch) && vch->pcdata->partner == ch && ch->in_room == vch->in_room) { vch->pcdata->stage[2] = 250; if (ch->sex == SEX_MALE) { stage_update(ch, vch, 2, "xm-thrust"); stage_update(vch, ch, 2, "xf-squeeze"); } else { stage_update(vch, ch, 2, "xm-thrust"); stage_update(ch, vch, 2, "xf-squeeze"); } ch->pcdata->stage[0] = 0; vch->pcdata->stage[0] = 0; if (!IS_EXTRA(ch, EXTRA_EXP)) { send_to_char("Congratulations on achieving a simultanious orgasm! Recieve 100000 exp!\n\r", ch); SET_BIT(ch->extra, EXTRA_EXP); ch->exp += 100000; } if (!IS_EXTRA(vch, EXTRA_EXP)) { send_to_char("Congratulations on achieving a simultanious orgasm! Recieve 100000 exp!\n\r", vch); SET_BIT(vch->extra, EXTRA_EXP); vch->exp += 100000; } } } } else { if (ch->pcdata->stage[0] > 0 && ch->pcdata->stage[2] < 1 && ch->position != POS_RESTING) { if (ch->pcdata->stage[0] > 1) ch->pcdata->stage[0] -= 1; else ch->pcdata->stage[0] = 0; } else if (ch->pcdata->stage[2] > 0 && ch->pcdata->stage[0] < 1) { if (ch->pcdata->stage[2] > 10) ch->pcdata->stage[2] -= 10; else ch->pcdata->stage[2] = 0; if (ch->sex == SEX_MALE && ch->pcdata->stage[2] == 0) send_to_char("You feel fully recovered.\n\r", ch); } } } } void regen_limb(CHAR_DATA * ch) { if (ch->loc_hp[6] > 0) { int sn = skill_lookup("clot"); (*skill_table[sn].spell_fun) (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); return; } void update_arti_regen(CHAR_DATA * ch) { if (ch->hit < ch->max_hit || ch->mana < ch->max_mana || ch->move < ch->max_move) update_regen(ch, 2); regen_limb(ch); return; } void update_regen(CHAR_DATA * ch, int multiplier) { int min = 5; // 5 int max = 10; // 10 int hit_gain = 0; int mana_gain = 0; int move_gain = 0; if (IS_NPC(ch)) return; if (ch->position == POS_SLEEPING) { if (!IS_RACE(ch, RACE_TROLL)) { min += 800; max += 1000; } else { min += 1400; max += 2000; } hit_gain += number_range(min, max); mana_gain += number_range(min, max); move_gain += number_range(min, max); } else { if (!IS_RACE(ch, RACE_TROLL)) { min += 600; max += 700; } else { min += 1200; max += 1400; } hit_gain += number_range(min, max); mana_gain += number_range(min, max); move_gain += number_range(min, max); } ch->hit = UMIN(ch->hit + (hit_gain * multiplier), ch->max_hit); ch->mana = UMIN(ch->mana + (mana_gain * multiplier), ch->max_mana); ch->move = UMIN(ch->move + (move_gain * multiplier), ch->max_move); update_pos(ch); if (ch->hit >= ch->max_hit && ch->mana >= ch->max_mana && ch->move >= ch->max_move) send_to_char("Your body has completely regenerated itself.\n\r", ch); return; } void update_active_counters(CHAR_DATA *ch) { /* we do not update idle players */ if (ch->timer >= 6) return; if (ch->pcdata->time_tick < 250) ch->pcdata->time_tick++; }