/*************************************************************************** * Emud 2.2 by Igor van den Hoven, Michiel Lange, and Martin Bethlehem. * * * * MrMud 1.4 by David Bills and Dug Michael. * * * * Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * Original Diku Mud copyright (C) 1990 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeld, Tom Madsen, and Katje Nyboe. * ***************************************************************************/ #include "emud.h" /* Local functions. */ int hit_gain args ((CHAR_DATA * ch)); int mana_gain args ((CHAR_DATA * ch)); int move_gain args ((CHAR_DATA * ch)); void mobile_update args ((void)); void shop_update args ((void)); void weather_update args ((void)); void time_update args ((void)); void char_update args ((void)); void obj_update args ((void)); void aggr_update args ((void)); void bounty_update args ((void)); void auto_area_save args ((void)); void auto_char_save args ((void)); void mob_program_update args ((void)); void obj_program_update args ((void)); void purger_update args ((void)); /* Advancement stuff. */ void advance_level (CHAR_DATA * ch, bool fSave) { int add_hp; int add_mana; int add_move; int add_prac; push_call("advance_level(%p,%p)",ch,fSave); add_hp = con_app[get_curr_con (ch)].hitp + number_range ( class_table[ch->class].hp_min, class_table[ch->class].hp_max) + race_table[ch->race].hp_mod; add_mana = int_app[get_curr_int (ch)].manap + number_range ( class_table[ch->class].mana_min, class_table[ch->class].mana_max) + race_table[ch->race].mana_mod; add_move = number_range(get_curr_dex(ch)/3, 10+get_curr_dex(ch)/3) + race_table[ch->race].move_mod; add_prac = wis_app[get_curr_wis (ch)].practice; add_hp = UMAX (1, add_hp); add_mana = UMAX (1, add_mana); add_move = UMAX (3, add_move); add_hp += ch->pcdata->reincarnation * 8; add_mana += ch->pcdata->reincarnation * 6; add_move += ch->pcdata->reincarnation * 5; add_prac += ch->pcdata->reincarnation * 3; /* Knight stuff get double - Chaos 9/14/95 */ if (ch->level > 90 && ch->level < 96) { add_hp *= 2; add_mana *= 2; add_move *= 2; add_prac *= 2; } /* Followers get extra juice !! - Martin 22/7/98 */ if (ch->pcdata->god != GOD_NEUTRAL) { ch_printf(ch, "%s\n\r", god_table[ch->pcdata->god].level_msg); add_hp += god_table[ch->pcdata->god].bonus_hp; add_mana += god_table[ch->pcdata->god].bonus_mana; add_move += god_table[ch->pcdata->god].bonus_move; } ch->pcdata->actual_max_hit += add_hp; ch->pcdata->actual_max_mana += add_mana; ch->pcdata->actual_max_move += add_move; ch->max_hit += add_hp; ch->max_mana += add_mana; ch->max_move += add_move; ch->pcdata->practice += add_prac; if (fSave) { sub_player (ch); add_player (ch); save_char_obj (ch, NORMAL_SAVE); save_char_obj (ch, BACKUP_SAVE); } ch_printf(ch, "Your gain is: %d/%d hp, %d/%d m, %d/%d mv %d/%d prac.\n\r", add_hp, ch->max_hit, add_mana, ch->max_mana, add_move, ch->max_move, add_prac, ch->pcdata->practice ); vt100prompt(ch); pop_call(); return; } void gain_exp (CHAR_DATA * ch, int gain) { push_call("gain_exp(%p,%p)",ch,gain); if (IS_NPC (ch) || ch->level >= LEVEL_HERO - 1 || ch->in_room->area->low_r_vnum == ROOM_VNUM_ARENA) { pop_call(); return; } ch->pcdata->exp = UMAX(0, ch->pcdata->exp + gain); if (ch->pcdata->exp >= exp_level(ch->class, ch->level)) { send_to_char ("You raise a level!! ", ch); ch->pcdata->exp = exp_level(ch->class, ch->level) + 1; ch->level += 1; if (ch->level % 3 == 0) /*add a language every 3 levels Chaos 4/27/99*/ { add_language(ch); } ch->pcdata->mclass[ch->class] += 1; advance_level (ch, TRUE); } pop_call(); return; } /* Regeneration stuff. */ int hit_gain (CHAR_DATA * ch) { int gain; push_call("hit_gain(%p)",ch); if (IS_NPC (ch)) { gain = ch->level * 4 / 3; } else { gain = get_curr_con(ch) * 2; switch (ch->position) { case POS_SLEEPING: gain += gain; break; case POS_RESTING: gain += gain / 2; break; case POS_SITTING: gain += gain / 3; break; } if (ch->pcdata->condition[COND_FULL] == 0) { gain /= 2; } if (ch->pcdata->condition[COND_THIRST] == 0) { gain /= 2; } } if (ch->furniture && ch->furniture->item_type == ITEM_FURNITURE) { gain = gain * ch->furniture->value[3] / 100; } if (IS_AFFECTED(ch, AFF2_BERSERK)) { gain *= 2; } if (IS_AFFECTED(ch, AFF_POISON)) { gain /= 4; } if (IS_AFFECTED(ch, AFF2_TORRID_BALM)) { gain /= 4; } if (in_camp(ch)) { gain *= 2; } if (!IS_NPC(ch) && rspec_req(ch, RSPEC_FASTHEAL)) { gain = 3 * gain / 2; } if (IS_AFFECTED(ch, AFF2_ENHANCED_HEAL)) { if (!IS_NPC(ch) && rspec_req(ch,RSPEC_FASTHEAL)) { send_to_char ("You heal faster.\n\r", ch); } else { send_to_char ("You heal easier.\n\r", ch); } gain = 3 * gain / 2; } pop_call(); return UMIN(gain, ch->max_hit - ch->hit); } int mana_gain (CHAR_DATA * ch) { int gain; push_call("mana_gain(%p)",ch); if (IS_NPC (ch)) { gain = ch->level * 2; } else { gain = get_curr_wis(ch) * 3; switch (ch->position) { case POS_SLEEPING: gain += gain; break; case POS_RESTING: gain += gain / 2; break; case POS_SITTING: gain += gain / 3; break; } if (ch->pcdata->condition[COND_FULL] == 0) { gain /= 2; } if (ch->pcdata->condition[COND_THIRST] == 0) { gain /= 2; } } if (ch->furniture && ch->furniture->item_type == ITEM_FURNITURE) { gain = gain * ch->furniture->value[3] / 100; } if (IS_AFFECTED (ch, AFF2_BERSERK)) { gain /= 4; } if (IS_AFFECTED (ch, AFF_POISON)) { gain /= 4; } if (IS_AFFECTED (ch, AFF2_QUICKEN)) { gain /= 2; } if (in_camp (ch)) { gain *= 2; } if (!IS_NPC(ch) && rspec_req(ch, RSPEC_FASTREVIVE)) { gain = 3 * gain / 2; } if (!IS_NPC(ch) && learned(ch, gsn_warmth)) { gain += gain * multi_skill_level(ch, gsn_warmth) / 100; } if (IS_AFFECTED (ch, AFF2_ENHANCED_REVIVE)) { if (!IS_NPC(ch) && learned(ch, gsn_warmth)) { send_to_char("You feel warmth spreading through your body.\n\r", ch); check_improve(ch, gsn_warmth); } else if (!IS_NPC(ch) && rspec_req(ch, RSPEC_FASTREVIVE)) { send_to_char ("You revive quicker.\n\r", ch); } else { send_to_char ("You revive easier.\n\r", ch); } gain = 3 * gain / 2; } pop_call(); return UMIN (gain, ch->max_mana - ch->mana); } int move_gain (CHAR_DATA * ch) { int gain; push_call("move_gain(%p)",ch); if (IS_NPC (ch)) { gain = ch->level; } else { gain = get_curr_dex(ch) * 4; switch (ch->position) { case POS_SLEEPING: gain += gain; break; case POS_RESTING: gain += gain / 2; break; case POS_SITTING: gain += gain / 3; break; } if (ch->pcdata->condition[COND_FULL] == 0) { gain /= 2; } if (ch->pcdata->condition[COND_THIRST] == 0) { gain /= 2; } } if (ch->furniture && ch->furniture->item_type == ITEM_FURNITURE) { gain = gain * ch->furniture->value[3] / 100; } if (IS_AFFECTED (ch, AFF2_BERSERK)) { gain *= 2; } if (IS_AFFECTED (ch, AFF_POISON)) { gain /= 4; } if (in_camp (ch)) { gain *= 2; } if (IS_AFFECTED (ch, AFF2_ENHANCED_REST)) { send_to_char ("You rest easier.\n\r", ch); gain = 3 * gain / 2; } pop_call(); return UMIN (gain, ch->max_move - ch->move); } void gain_condition (CHAR_DATA * ch, int iCond, int value) { int condition; push_call("gain_condition(%p,%p,%p)",ch,iCond,value); if ( value == 0 || IS_NPC (ch)) { pop_call(); return; } condition = ch->pcdata->condition[iCond]; ch->pcdata->condition[iCond] = URANGE( 0, condition + value, 48 ); if (rspec_req(ch,RSPEC_VAMPIRIC)) { if (iCond == COND_THIRST && ch->pcdata->condition[COND_THIRST] <= 3) { send_to_char("Your body is craving for blood.\n\r", ch); act("$n looks pale and weak.", ch, NULL, NULL, TO_ROOM); damage(ch, ch, 1+ch->level/7, TYPE_NOFIGHT); } pop_call(); return; } if ( ch->pcdata->condition[iCond] == 0 ) { switch ( iCond ) { case COND_FULL: if (ch->level > 1) { send_to_char( "You are STARVING!\n\r", ch ); act( "$n is starved half to death!", ch, NULL, NULL, TO_ROOM); damage(ch, ch, 1+ch->level/7, TYPE_NOFIGHT); } else { send_to_char( "You are really hungry.\n\r", ch ); } pop_call(); return; break; case COND_THIRST: if( ch->level > 1 ) { send_to_char( "You are DYING of THIRST!\n\r", ch ); act( "$n is dying of thirst!", ch, NULL, NULL, TO_ROOM); damage(ch, ch, 1+ch->level/5, TYPE_NOFIGHT); } else { send_to_char( "You are really thirsty.\n\r", ch ); } pop_call(); return; break; case COND_DRUNK: if ( condition != 0 ) { send_to_char( "You are sober.\n\r", ch ); pop_call(); return; } break; default: bug( "Gain_condition: invalid condition type %d", iCond ); break; } } if ( ch->pcdata->condition[iCond] == 1 ) { switch ( iCond ) { case COND_FULL: send_to_char( "You are really hungry.\n\r", ch ); act( "You can hear $n's stomach growling.", ch, NULL, NULL, TO_ROOM); break; case COND_THIRST: send_to_char( "You are really thirsty.\n\r", ch ); act( "$n looks a little parched.", ch, NULL, NULL, TO_ROOM); break; case COND_DRUNK: if ( condition != 0 ) { send_to_char( "You are feeling a little less light headed.\n\r", ch ); } break; } } if ( ch->pcdata->condition[iCond] == 2 ) { switch ( iCond ) { case COND_FULL: send_to_char( "You are hungry.\n\r", ch ); break; case COND_THIRST: send_to_char( "You are thirsty.\n\r", ch ); break; } } if ( ch->pcdata->condition[iCond] == 3 ) { switch ( iCond ) { case COND_FULL: send_to_char( "You are a mite peckish.\n\r", ch ); break; case COND_THIRST: send_to_char( "You could use a sip of something refreshing.\n\r", ch ); break; } } pop_call(); return; } void obj_program_update (void) { PLAYER_GAME *pch, *pch_next; OBJ_DATA *obj, *obj_next; OBJ_PROG *prg; push_call("obj_program_update()"); for (pch = mud->f_player ; pch ; pch = pch_next) { pch_next = pch->next; if (pch->ch->desc) { for (obj = pch->ch->first_carrying ; obj ; obj = obj_next) { obj_next = obj->next_content; if (obj->carried_by && IS_SET(obj->pIndexData->progtypes, TRIG_TICK)) { for (prg = obj->pIndexData->first_prog ; prg ; prg = prg->next) { if (prg->trigger == TRIG_TICK) { if (number_range(1, 200) <= prg->percentage) { start_object_program( pch->ch, obj, prg, ""); } } } } } } } pop_call(); return; } void mob_program_update (void) { CHAR_DATA *ich; AREA_DATA *area; int vnum; push_call("mob_program_update()"); for (area = mud->f_area ; area ; area = area->next) { for (vnum = area->low_m_vnum ; vnum <= area->hi_m_vnum ; vnum++) { if (mob_index[vnum] == NULL || mob_index[vnum]->first_instance == NULL) { continue; } if (IS_SET(mob_index[vnum]->progtypes, RAND_PROG)) { for (ich = mob_index[vnum]->first_instance ; ich ; ich = mud->update_ich) { mud->update_ich = ich->next_instance; if (!MP_VALID_MOB(ich)) { continue; } if (ich->position <= POS_SLEEPING || ich->position == POS_FIGHTING) { continue; } mprog_percent_check(ich, NULL, NULL, NULL, RAND_PROG); } continue; } if (mob_index[vnum]->spec_fun && area->nplayer) { for (ich = mob_index[vnum]->first_instance ; ich ; ich = mud->update_ich) { mud->update_ich = ich->next_instance; if (!MP_VALID_MOB(ich)) { continue; } (*ich->pIndexData->spec_fun) (ich); } } } } /* Let's see if some trivia can be played - Scandum 01-11-2002 */ if (mud->f_trivia) { update_trivia(); } pop_call(); return; } void auto_char_save (void) { PLAYER_GAME *npl; CHAR_DATA *oldest; CLAN_DATA *oldest_clan, *clan; int oldest_time, oldest_clan_time, total_clans; static int save_delay; static int clan_delay; push_call("auto_char_save()"); if (save_delay >= 0) { save_delay--; } else { save_delay = 600 / PULSE_CHARSAVE / UMAX(1, mud->total_plr); oldest = NULL; oldest_time = mud->current_time; for (npl = mud->f_player ; npl ; npl = npl->next) { if (npl->ch->pcdata->last_saved < oldest_time) { oldest_time = npl->ch->pcdata->last_saved; oldest = npl->ch; } } if (oldest) { save_char_obj(oldest, NORMAL_SAVE); check_most(oldest); } for (npl = mud->f_player ; npl ; npl = npl->next) { if (npl->ch->timer > 30 && (!npl->ch->pcdata->switched || npl->ch->timer > 60) && (!IS_IMMORTAL(npl->ch) || !is_desc_valid(npl->ch))) { char_from_room(npl->ch); char_to_room(npl->ch, npl->ch->pcdata->was_in_room); do_quit(npl->ch, NULL); break; } } } if (clan_delay >= 0) { clan_delay--; } else { for (total_clans = 0, clan = mud->f_clan ; clan ; clan = clan->next) { total_clans++; } clan_delay = 3600 / PULSE_CHARSAVE / UMAX(1, total_clans); oldest_clan_time = mud->current_time; oldest_clan = NULL; for (clan = mud->f_clan ; clan ; clan = clan->next) { if (clan->last_saved < oldest_clan_time) { oldest_clan_time = clan->last_saved; oldest_clan = clan; } } if (oldest_clan) { save_clan(oldest_clan); oldest_clan->last_saved = mud->current_time; } } pop_call(); return; } void auto_area_save (void) { push_call("auto_area_save(void)"); do_savearea(NULL, "forreal"); pop_call(); return; } void shop_update (void) { OBJ_DATA *obj; CHAR_DATA *ich; AREA_DATA *area; int vnum; push_call("shop_update()"); for (area = mud->f_area ; area ; area = area->next) { for (vnum = area->low_m_vnum ; vnum <= area->hi_m_vnum ; vnum++) { if (mob_index[vnum] == NULL || mob_index[vnum]->pShop == NULL) { continue; } for (ich = mob_index[vnum]->first_instance ; ich ; ich = ich->next_instance) { for (obj = ich->last_carrying ; obj ; obj = obj->prev_content) { if (obj->reset == NULL) { if (number_bits(3) == 0) { act ("$n discards $p.", ich, obj, NULL, TO_ROOM); junk_obj(obj); } } else { break; } } } } } pop_call(); return; } void mobile_update (void) { CHAR_DATA *ich; CHAR_DATA *rch; AREA_DATA *area; PLAYER_GAME *gch; EXIT_DATA *pexit; OBJ_DATA *obj, *obj_best; int vnum, door, max; push_call("mobile_update()"); for (area = mud->f_area ; area ; area = area->next) { for (vnum = area->low_m_vnum ; vnum <= area->hi_m_vnum ; vnum++) { if (mob_index[vnum] == NULL || mob_index[vnum]->first_instance == NULL) { continue; } if (mob_index[vnum]->area->nplayer == 0 && number_bits(6)) { continue; } if (!IS_SET(mob_index[vnum]->act, ACT_SENTINEL)) { for (ich = mob_index[vnum]->first_instance ; ich ; ich = mud->update_ich) { mud->update_ich = ich->next_instance; if (!MP_VALID_MOB(ich)) { continue; } if (ich->position != POS_STANDING) { continue; } if (*ich->npcdata->hate_fear == '\0' && number_bits(4) != 0) { continue; } door = number_door(); if ((pexit = ich->in_room->exit[door]) == NULL) { continue; } if (room_index[pexit->to_room] == NULL) { continue; } if (IS_SET(room_index[pexit->to_room]->room_flags, ROOM_NO_MOB)) { continue; } if (IS_SET(ich->act, ACT_STAY_SECTOR) && ich->reset && room_index[pexit->to_room]->sector_type != room_index[ich->reset->arg3]->sector_type) { continue; } if (room_index[pexit->to_room]->area == ich->in_room->area) { move_char(ich, door, TRUE); } } } if (IS_SET(mob_index[vnum]->act, ACT_SCAVENGER)) { for (ich = mob_index[vnum]->first_instance ; ich ; ich = mud->update_ich) { mud->update_ich = ich->next_instance; if (!MP_VALID_MOB(ich)) { continue; } if (ich->position != POS_STANDING) { continue; } if (ich->in_room->first_content == NULL) { continue; } if (ich->carry_number >= 10) { continue; } if (number_bits(4)) { continue; } max = 1; obj_best = NULL; for (obj = ich->in_room->first_content ; obj ; obj = obj->next_content) { if (IS_SET(obj->wear_flags, ITEM_TAKE) && obj->cost > max) { obj_best = obj; max = obj->cost; } } if (obj_best) { char objName[MAX_INPUT_LENGTH]; sprintf (objName, "i%u", obj_best->pIndexData->vnum); do_get (ich, objName); do_wear(ich, objName); } } } if (mob_index[vnum]->area->nplayer == 0) { continue; } for (ich = mob_index[vnum]->first_instance ; ich ; ich = mud->update_ich) { mud->update_ich = ich->next_instance; if (*ich->npcdata->hate_fear == '\0') { continue; } if (!MP_VALID_MOB(ich)) { continue; } if (ich->position < POS_STANDING) { continue; } if (!IS_SET(ich->act, ACT_WIMPY)) { if (ich->fighting == NULL) { for (rch = ich->in_room->first_person ; rch ; rch = rch->next_in_room) { if (ich->npcdata->hate_fear == rch->name) { found_hating(ich, rch); break; } } } continue; } else { if (ich->hit > ich->max_hit / 2) { continue; } if (ich->fighting) { do_flee(ich, ""); continue; } door = number_door(); if ((pexit = get_exit(ich->in_room->vnum, door)) == NULL) { continue; } if (IS_SET(pexit->exit_info, EX_CLOSED)) { continue; } if (IS_SET(room_index[pexit->to_room]->room_flags, ROOM_NO_MOB)) { continue; } if (IS_SET(ich->act, ACT_STAY_SECTOR) && ich->reset && room_index[pexit->to_room]->sector_type != room_index[ich->reset->arg3]->sector_type) { continue; } for (rch = ich->in_room->first_person ; rch ; rch = rch->next_in_room) { if (ich->npcdata->hate_fear == rch->name && IS_SET(ich->act, ACT_SMART)) { char buf[MAX_INPUT_LENGTH]; if (IS_SET(ich->act, ACT_SMART)) { switch (number_bits (2)) { case 0: sprintf (buf, "Argh! %s is trying to kill me!", capitalize(get_name(rch))); break; case 1: sprintf (buf, "Help! I'm being attacked by %s!", get_name(rch)); break; case 2: sprintf (buf, "Stay away from me %s! Help!", short_to_name(get_name(rch), 1)); break; case 3: sprintf (buf, "Someone help me! %s is attacking me!", get_name(rch)); break; } do_shout (ich, buf); } else { switch (number_bits(2)) { case 0: act("$n looks around frantically as it searches for an escape!", ich, NULL, NULL, TO_ROOM); break; case 1: act("$n darts around mindlessly in an attempt to get away!", ich, NULL, NULL, TO_ROOM); break; case 2: act("$n lets out a whimper and tries to flee!", ich, NULL, NULL, TO_ROOM); break; case 3: act("$n howls in fear as it attempts to flee!", ich, NULL, NULL, TO_ROOM); break; } } break; } } if (rch) { move_char(ich, door, TRUE); } } } } } for (gch = mud->f_player ; gch ; gch = gch->next) { switch (gch->ch->in_room->sector_type) { case SECT_ASTRAL: if (!CAN_ASTRAL_WALK(gch->ch)) { if (gch->ch->position == POS_FIGHTING) { stop_fighting (gch->ch, FALSE); } char_from_room (gch->ch); if (room_index[gch->ch->pcdata->last_real_room]->sector_type == SECT_ASTRAL) { char_to_room (gch->ch, ROOM_VNUM_TEMPLE); } else { char_to_room (gch->ch, gch->ch->pcdata->last_real_room); } } break; case SECT_UNDER_WATER: if (!CAN_BREATH_WATER(gch->ch)) { if (!vnum_in_group (gch->ch, MOB_VNUM_WATER_ELEMENTAL)) { if (gch->ch->pcdata->condition[COND_AIR] <= 0) { send_to_char ("You cannot breath!\n\r", gch->ch); damage (gch->ch, gch->ch, 50, TYPE_NOFIGHT); } else { gch->ch->pcdata->condition[COND_AIR]--; if (gch->ch->pcdata->condition[COND_AIR] == 5) { send_to_char("You cannot hold in your breath much longer.\n\r", gch->ch); } } } } break; case SECT_LAVA: if (!CAN_FIREWALK(gch->ch)) { if (!vnum_in_group (gch->ch, MOB_VNUM_FIRE_ELEMENTAL)) { send_to_char ("That lava is REALLY hot!\n\r", gch->ch); if (CAN_FLY(gch->ch)) { damage(gch->ch, gch->ch, 15, TYPE_NOFIGHT); } else { damage(gch->ch, gch->ch, 20, TYPE_NOFIGHT); } } } break; case SECT_OCEAN: if (!CAN_FLY(gch->ch)) { if (!CAN_BREATH_WATER(gch->ch)) { if (!CAN_SWIM(gch->ch)) { OBJ_DATA *obj; for (obj = gch->ch->first_carrying ; obj ; obj = obj->next_content) { if (obj->item_type == ITEM_BOAT) { break; } } if (obj == NULL) { send_to_char ("You are sinking FAST!\n\r", gch->ch); damage (gch->ch, gch->ch, 10, TYPE_NOFIGHT); continue; } } } } break; default: if (gch->ch->pcdata->condition[COND_AIR] < 10) { send_to_char("You take a deep breath of fresh air.\n\r", gch->ch); gch->ch->pcdata->condition[COND_AIR] = 10; } break; } } pop_call(); return; } /* Update the weather - Scandum 22-06-2003 */ void weather_area_update( AREA_DATA *area ) { char buf[MAX_STRING_LENGTH]; PLAYER_GAME *gch; int temp, season, daily; buf[0] = '\0'; /* Calculate temperature in degrees Celcius */ season = area->weather_info->temp_summer - area->weather_info->temp_winter; daily = area->weather_info->temp_daily; temp = area->weather_info->temp_winter; temp += season * ( 8 - abs(mud->time_info->month - 8)) / 8; temp += daily * (12 - abs(mud->time_info->hour - 12)) / 12; /* Calculate the wind speed based on current wind speed 0 - 10 */ if (area->weather_info->wind_speed > area->weather_info->wind_scale + 1) { area->weather_info->wind_speed += number_range(0, 3) - 2; } else if (area->weather_info->wind_speed < area->weather_info->wind_scale - 1) { area->weather_info->wind_speed += number_range(0, 3) - 1; } else { area->weather_info->wind_speed += number_range(0, 2) - 1; } area->weather_info->wind_speed = URANGE(-10, area->weather_info->wind_speed, 20); /* Calculate the wind direction, based on current wind direction */ area->weather_info->wind_dir = abs(area->weather_info->wind_dir + number_range(0, 2) - 1) % 8; /* Calculate the weather, based on current weather */ if (area->weather_info->change < area->weather_info->wet_scale - 1) { area->weather_info->change += number_range(0, 3) - 1; } else if (area->weather_info->change > area->weather_info->wet_scale + 1) { area->weather_info->change += number_range(0, 3) - 2; } else { area->weather_info->change += number_range(0, 4) - 2; } area->weather_info->change = URANGE(-100, area->weather_info->change, 110); /* Modify temperature based on weather */ temp += 5 - URANGE(0, area->weather_info->change, 10); area->weather_info->temperature = temp; switch (area->weather_info->sky) { default: bug ("Weather_update: bad sky %d.", area->weather_info->sky); area->weather_info->sky = SKY_CLOUDLESS; break; case SKY_CLOUDLESS: if (area->weather_info->change > 3) { switch (number_bits(2)) { case 0: cat_sprintf(buf, "Threatening clouds gather on the %s horizon, blocking the sky from view.\n\r", wind_dir_name[area->weather_info->wind_dir]); break; case 1: cat_sprintf(buf, "Low clouds form on the %s horizon and slowly drift towards you.\n\r", wind_dir_name[area->weather_info->wind_dir]); break; case 2: cat_sprintf(buf, "Clouds sweep quickly across the %s horizon, darkening the skies above.\n\r", wind_dir_name[area->weather_info->wind_dir]); break; case 3: cat_sprintf(buf, "Bright white clouds drift lazily towards you from the %s horizon.\n\r", wind_dir_name[area->weather_info->wind_dir]); break; } area->weather_info->sky = SKY_CLOUDY; } break; case SKY_CLOUDY: if (area->weather_info->change > 6) { if (area->weather_info->temperature < 0) { switch (number_bits(2)) { case 0: strcat(buf, "Snowflakes flutter down from the leaden skies above.\n\r"); break; case 1: strcat(buf, "Lacy flakes of snow silently fall to the ground from the clouds above.\n\r"); break; case 2: strcat(buf, "The clouds above give way to softly falling snow.\n\r"); break; case 3: strcat(buf, "Snowflakes whisper down from the skies in a soft white dance.\n\r"); break; } } else if (area->weather_info->temperature < 4) { switch (number_bits(2)) { case 0: strcat(buf, "Snow begins to meld with icy rain as sleet falls to the ground.\n\r"); break; case 1: strcat(buf, "Sharp sleet stings as it falls from the clouds above.\n\r"); break; case 2: strcat(buf, "Icy sleet rains down from the heavens.\n\r"); break; case 3: strcat(buf, "Sheets of stinging sleet fall from the dark clouds.\n\r"); break; } } else { switch (number_bits(2)) { case 0: strcat(buf, "Dark clouds break open, pouring rain down upon the lands.\n\r"); break; case 1: strcat(buf, "Silvery drops of rain fall from angry looking clouds above.\n\r"); break; case 2: strcat(buf, "Soft ribbons of rain slip unheeded from the dark skies overhead.\n\r"); break; case 3: strcat(buf, "Fat raindrops merrily pepper the lands from the clouds looming above.\n\r"); break; } } area->weather_info->change += 2; area->weather_info->sky = SKY_RAINING; } else if (area->weather_info->change < 4) { switch (number_bits(2)) { case 0: strcat(buf, "The clouds recede, revealing a crystal clear sky.\n\r"); break; case 1: strcat(buf, "Dark clouds dip below the horizon as the skies clear.\n\r"); break; case 2: strcat(buf, "The clouds swiftly move across the skies as it grows clear.\n\r"); break; case 3: strcat(buf, "Clouds sigh softly as they disperse, leaving the skies clear.\n\r"); break; } area->weather_info->change -= 2; area->weather_info->sky = SKY_CLOUDLESS; } break; case SKY_RAINING: if (area->weather_info->change < 7) { if (area->weather_info->temperature < 0) { switch (number_bits(2)) { case 0: strcat(buf, "A few last snowflakes swirl over the ground as the snow stops.\n\r"); break; case 1: strcat(buf, "The world is left in silence as the snows stop falling.\n\r"); break; case 2: strcat(buf, "The lands are blanketed in white as the last snowflakes fall.\n\r"); break; case 3: strcat(buf, "With a final whisper, the snow stops falling.\n\r"); break; } } else if (area->weather_info->temperature < 4) { switch (number_bits(2)) { case 0: strcat(buf, "The final slivers of sleet fall from the dark clouds as it stops.\n\r"); break; case 1: strcat(buf, "The miserable sleet falling from the clouds above stops.\n\r"); break; case 2: strcat(buf, "The slippery razor-sharp sleet ends its assault on the lands.\n\r"); break; case 3: strcat(buf, "The stinging sleet suddenly ceases as quickly as it began.\n\r"); break; } } else { switch (number_bits(2)) { case 0: strcat(buf, "The air smells fresh as the rain stops falling.\n\r"); break; case 1: strcat(buf, "The clouds above dry their tears as the rain ceases.\n\r"); break; case 2: strcat(buf, "The greyness above seems to ease as the rains halt.\n\r"); break; case 3: strcat(buf, "A sweet scent fills the air as the rain suddenly stops.\n\r"); break; } } area->weather_info->change -= 1; area->weather_info->sky = SKY_CLOUDY; } else if (area->weather_info->wind_speed > 6) { if (area->weather_info->temperature < 0) { switch (number_bits(2)) { case 0: strcat(buf, "A ferocious blizzard sweeps through the lands, burying them in white.\n\r"); break; case 1: strcat(buf, "Heavy snows swirl in the air as the blizzard rages.\n\r"); break; case 2: strcat(buf, "The snows fall heavily upon the ground as a blizzard takes hold.\n\r"); break; case 3: strcat(buf, "Snowdrifts form quickly as the blizzard increases its fierceness.\n\r"); break; } } else if (area->weather_info->temperature < 4) { switch (number_bits(2)) { case 0: strcat(buf, "The clouds darken and thicken as they fill with hail.\n\r"); break; case 1: strcat(buf, "Huge chunks of hail fall to the grounds with a sizzle.\n\r"); break; case 2: strcat(buf, "Hail bombards the ground as creatures run for cover.\n\r"); break; case 3: strcat(buf, "A shower of hail falls from the sky to pelts the lands below.\n\r"); break; } } else { switch (number_bits(2)) { case 0: strcat(buf, "The lands glow blue-white as lightning cracks across the sky.\n\r"); break; case 1: strcat(buf, "Electricity fills the air as forks of lightning dance over the sky.\n\r"); break; case 2: strcat(buf, "The horizon shines brightly as sheet lightning flashes in a quick stutter.\n\r"); break; case 3: strcat(buf, "The winds gather speed as lightning paints the skies with broad strokes.\n\r"); break; } } area->weather_info->wind_speed += 2; area->weather_info->sky = SKY_LIGHTNING; } break; case SKY_LIGHTNING: if (area->weather_info->change < 7 || area->weather_info->wind_speed < 7) { if (area->weather_info->temperature < 0) { switch (number_bits(2)) { case 0: strcat(buf, "The thick, swirling snow peters out as the blizzard ends.\n\r"); break; case 1: strcat(buf, "The ferocity of the blizzard gives way as the snows diminish.\n\r"); break; case 2: strcat(buf, "With a last gasp, the blizzard dwindles away to nothing.\n\r"); break; case 3: strcat(buf, "With a final stroke of white, the blizzard dies out.\n\r"); break; } } else if (area->weather_info->temperature < 4) { switch (number_bits(2)) { case 0: strcat(buf, "The cannonade of hail comes to a sudden halt.\n\r"); break; case 1: strcat(buf, "The burning hail ends its furious salvo of the lands.\n\r"); break; case 2: strcat(buf, "The icy hot hail diminishes, retreating to the clouds above.\n\r"); break; case 3: strcat(buf, "As swiftly as it started, the hailstorm recedes.\n\r"); break; } } else { switch (number_bits(2)) { case 0: strcat(buf, "With a few last flashes, the lightning moves down the horizon.\n\r"); break; case 1: strcat(buf, "The skies turn ice blue and brilliant white with a final flash of lightning.\n\r"); break; case 2: strcat(buf, "The heavens calm as the lightning storm ends.\n\r"); break; case 3: strcat(buf, "The air is alive with electricity as the last fork of lightning appears.\n\r"); break; } } area->weather_info->wind_speed -= 2; area->weather_info->sky = SKY_RAINING; } break; } if (area->nplayer <= 0 || buf[0] == '\0') { return; } for (gch = mud->f_player ; gch ; gch = gch->next) { if (gch->ch->in_room->area != area) { continue; } if (!IS_OUTSIDE(gch->ch) || NO_WEATHER_SECT(gch->ch->in_room->sector_type)) { continue; } if (!IS_AWAKE(gch->ch)) { continue; } send_to_char(justify(buf, get_page_width(gch->ch)), gch->ch); } } void weather_update (void) { AREA_DATA *area; push_call("weather_update()"); for (area = mud->f_area ; area ; area = area->next) { weather_area_update(area); } pop_call(); return; } void strip_greater (char *str) { char *pt; push_call("strip_greater(%p)",str); for (pt = str; *pt != '\0'; pt++) { if (*pt == '<') { *pt = '('; } else if (*pt == '>') { *pt = ')'; } } pop_call(); return; } /* Make a html web page - Chaos 3/28/96 */ void save_html_who (void) { FILE *fp; char buf[MAX_STRING_LENGTH], buf_race[20]; char buf2[MAX_STRING_LENGTH]; int leng; CHAR_DATA *fch; DESCRIPTOR_DATA *d; int nMatch; int nTotal; CHAR_DATA *wch; char const *class; char god; char killer_thief; PLAYER_GAME *fpl; char *pt; push_call("save_html_who()"); /* Disabled since we're not using this atm - Scandum */ pop_call(); return; close_reserve(); fp = my_fopen ("../public_html/who.html", "w",TRUE); if (fp == NULL) { open_reserve(); pop_call(); return; } fprintf (fp, "<!DOCTYPE html PUBLIC \"-//IETF//DTD// HTML 2.0//EN\">\n"); fprintf (fp, "<BODY BACKGROUND=\"bumps1.jpg\" text=#ffff30 alink=#80FF30 vlink=#90FF30 link=#FFFF30 >\n"); fprintf (fp, "<HTML><HEAD><TITLE>E-Mud Who List</TITLE></HEAD>\n"); fprintf (fp, "<BODY><FONT SIZE=+2><CENTER>\n"); fprintf (fp, "E-Mud WHO Page<p>\n"); /* Set default arguments. */ fch = NULL; /* Now show matching chars. */ nMatch = 0; nTotal = 0; buf[0] = '\0'; leng = 0; for (fpl = mud->f_player ; fpl ; fpl = fpl->next) { wch = fpl->ch; d = NULL; if (is_desc_valid (wch)) d = wch->desc; /* Check for match against restrictions. * Don't use trust as that exposes trusted mortals. * Chaos set to see all chars, invis or not. */ if (IS_SET (wch->act, PLR_WIZINVIS)|| IS_SET(wch->act,PLR_WIZCLOAK)) { continue; } nTotal++; nMatch++; /* * Figure out what to print for class. */ class = class_table[wch->class].who_name; switch (wch->level) { default: break; case MAX_LEVEL - 0: class = "GOD"; break; case MAX_LEVEL - 1: class = "ARC"; break; case MAX_LEVEL - 2: class = "ANG"; break; break; } strcpy (buf_race, race_table[wch->race].race_name); buf_race[3] = '\0'; if (wch->level > MAX_LEVEL - 4) strcpy (buf_race, "---"); god = god_table[wch->pcdata->god].who_letter[0]; if (IS_SET (wch->act, PLR_KILLER)) { killer_thief = 'K'; } else if (IS_SET (wch->act, PLR_THIEF)) { killer_thief = 'T'; } else { killer_thief = ' '; } /* * Format it up. */ sprintf (buf2, "[%2d %s %s]%c%c%s%s", wch->level, class, buf_race, god, killer_thief, wch->name, IS_NPC (wch) ? "the monster" : wch->pcdata->title); buf2[71] = '\0'; strip_greater (buf2); while (strlen (buf2) < 71) { str_cat_max (buf2, " ", MAX_STRING_LENGTH);\ } leng = str_apd_max (buf, buf2, leng, MAX_STRING_LENGTH); if ((wch->pcdata->switched || wch->desc != NULL) && !IS_AFFECTED (wch, AFF_STEALTH)) { strcpy (buf2, wch->in_room->area->name); buf2[8] = '\0'; while (strlen (buf2) < 8) { str_cat_max (buf2, " ", MAX_STRING_LENGTH); } } else if (wch->desc == NULL) { strcpy (buf2, "LinkLost"); } else { strcpy (buf2, "Unknown "); /* Stealth Mode */ } leng = str_apd_max (buf, " {", leng, MAX_STRING_LENGTH); leng = str_apd_max (buf, buf2, leng, MAX_STRING_LENGTH); leng = str_apd_max (buf, "} ", leng, MAX_STRING_LENGTH); /* They don't need to see this either - Chaos 4/30/99 if (wch->desc != NULL && wch->desc->host != NULL) { leng = str_apd_max (buf, " (", leng, MAX_STRING_LENGTH); leng = str_apd_max (buf, wch->desc->host, leng, MAX_STRING_LENGTH); leng = str_apd_max (buf, ")", leng, MAX_STRING_LENGTH); } */ /* Let's be a bit discreet here. - Chaos 4/25/99 if (wch->pcdata->mail_address != NULL && *wch->pcdata->mail_address != '\0') { leng = str_apd_max (buf, " Email: <a href=\"mailto:", leng, MAX_STRING_LENGTH); leng = str_apd_max (buf, wch->pcdata->mail_address, leng, MAX_STRING_LENGTH); leng = str_apd_max (buf, "\">", leng, MAX_STRING_LENGTH); leng = str_apd_max (buf, wch->pcdata->mail_address, leng, MAX_STRING_LENGTH); leng = str_apd_max (buf, "</a>", leng, MAX_STRING_LENGTH); } */ if (wch->pcdata->html_address != NULL && *wch->pcdata->html_address != '\0') { strcpy (buf2, wch->pcdata->html_address); for (pt = buf2; *pt != '\0'; pt++) { if (*pt == '*') { *pt = '~'; } } leng = str_apd_max (buf, " Home Page: <a href=\"http://", leng, MAX_STRING_LENGTH); leng = str_apd_max (buf, buf2, leng, MAX_STRING_LENGTH); leng = str_apd_max (buf, "\">", leng, MAX_STRING_LENGTH); leng = str_apd_max (buf, buf2, leng, MAX_STRING_LENGTH); leng = str_apd_max (buf, "</a>", leng, MAX_STRING_LENGTH); } leng = str_apd_max (buf, "<p>\n", leng, MAX_STRING_LENGTH); } sprintf (buf2, "Players: %d</CENTER></font><p><font size=-1>\n", nTotal); fprintf (fp, "%s", buf2); fprintf (fp, "%s", buf); fprintf (fp, "</font></BODY></HTML>\n"); if(fp) /* this prevents the possibility to my_fclose(NULL) - Manwe, 15-10-2000 */ { my_fclose (fp); } open_reserve(); pop_call(); return; } void time_update (void) { char buf[MAX_INPUT_LENGTH]; AREA_DATA *area; PLAYER_GAME *gpl; push_call("time_update()"); mud->time_info->hour++; if (mud->time_info->hour >= 24) { mud->time_info->hour = 0; mud->time_info->day++; } if (mud->time_info->day >= 35) { mud->time_info->day = 0; mud->time_info->month++; } if (mud->time_info->month >= 16) { mud->time_info->month = 0; mud->time_info->year++; } switch (mud->time_info->hour) { case 5: mud->sunlight = SUN_RISE; break; case 6: mud->sunlight = SUN_LIGHT; break; case 19: mud->sunlight = SUN_SET; break; case 20: mud->sunlight = SUN_DARK; break; } for (area = mud->f_area ; area ; area = area->next) { if (area->nplayer == 0) { continue; } buf[0] = '\0'; switch (mud->time_info->hour) { case 5: sprintf(buf, "The day has begun.\n\r"); break; case 6: sprintf(buf, "The sun rises in the east.\n\r"); break; case 19: sprintf(buf, "The sun slowly disappears in the west.\n\r"); break; case 20: sprintf(buf, "The night has begun.\n\r"); break; } if (buf[0] == '\0') { continue; } for (gpl = mud->f_player ; gpl ; gpl = gpl->next) { if (gpl->ch->in_room->area == area && IS_OUTSIDE(gpl->ch) && !NO_WEATHER_SECT(gpl->ch->in_room->sector_type) && IS_AWAKE(gpl->ch)) { send_to_char(buf, gpl->ch); } } } pop_call(); return; } void char_update (void) { CHAR_DATA *ch; ROOM_TIMER_DATA *rtd, *rtd_next; AFFECT_DATA *paf, *paf_next; push_call("char_update()"); for (rtd = mud->f_room_timer ; rtd ; rtd = rtd_next) { rtd_next = rtd->next; if (--rtd->timer <= 0) { switch (rtd->type) { case ROOM_TIMER_SANCTIFY: REMOVE_BIT(room_index[rtd->vnum]->room_flags, ROOM_SAFE); room_index[rtd->vnum]->sanctify_char = NULL; send_to_room("The area does not look safe now..\n\r", room_index[rtd->vnum]); break; case ROOM_TIMER_SMOKE: REMOVE_BIT(room_index[rtd->vnum]->room_flags, ROOM_SMOKE); send_to_room("The smoke dissipates.\n\r", room_index[rtd->vnum]); break; case ROOM_TIMER_GLOBE: REMOVE_BIT(room_index[rtd->vnum]->room_flags, ROOM_GLOBE); send_to_room("The shroud of darkness dissipates.\n\r", room_index[rtd->vnum]); break; case ROOM_TIMER_BLOCK: REMOVE_BIT(room_index[rtd->vnum]->room_flags, ROOM_BLOCK); send_to_room("The magical plant life withers and dies.\n\r", room_index[rtd->vnum]); break; case ROOM_TIMER_ICE: REMOVE_BIT(room_index[rtd->vnum]->room_flags, ROOM_ICE); send_to_room("The air becomes warmer as the ice sheets melt away.\n\r", room_index[rtd->vnum]); break; case ROOM_TIMER_UNBLOCK: SET_BIT(room_index[rtd->vnum]->room_flags, ROOM_BLOCK); send_to_room("All sorts of plant growth sprout up everywhere!\n\r", room_index[rtd->vnum]); break; } del_room_timer(rtd->vnum, rtd->type); } } for (ch = mud->f_char ; ch ; ch = mud->update_wch) { mud->update_wch = ch->next; if (!IS_NPC(ch)) { if (ch->gold > 1000000 * ch->level) { ch->gold = 1000000 * ch->level; } if (ch->gold < 0) { ch->gold = 0; } if (ch->level < LEVEL_IMMORTAL) { if (ch->level < ch->in_room->area->low_hard_range || ch->level > ch->in_room->area->hi_hard_range) { char_to_room(ch, ROOM_VNUM_TEMPLE); ch->pcdata->death_room = ch->pcdata->recall = ROOM_VNUM_TEMPLE; } } if (IS_SET(ch->act, PLR_KILLER) && (ch->pcdata->played - ch->pcdata->killer_played) > 60 * 60 * 24) { REMOVE_BIT (ch->act, PLR_KILLER); } if (IS_SET(ch->act, PLR_OUTCAST) && (ch->pcdata->played - ch->pcdata->outcast_played) > 60 * 60 * 24) { REMOVE_BIT (ch->act, PLR_OUTCAST); } if (ch->pcdata->just_died_ctr > 0) { if (--ch->pcdata->just_died_ctr == 0) { send_to_char ("The Gods are no longer protecting you.\n\r", ch); break; } } if (++ch->timer > 20) { if (ch->in_room && ch->in_room->vnum != ROOM_VNUM_LIMBO) { if (!ch->pcdata->switched && !IS_IMMORTAL(ch)) { ch->pcdata->was_in_room = ch->in_room->vnum; if (ch->fighting) { stop_fighting(ch, FALSE); } act("$n disappears into the void.", ch, NULL, NULL, TO_ROOM); act("You disappear into the void.", ch, NULL, NULL, TO_CHAR); save_char_obj(ch, NORMAL_SAVE); char_from_room(ch); char_to_room(ch, ROOM_VNUM_LIMBO); } } } ch->pcdata->idle++; gain_condition (ch, COND_DRUNK, -1); if (ch->level > 5 && ch->level < 95 && (!IS_UNDEAD(ch) || rspec_req(ch, RSPEC_VAMPIRIC))) { gain_condition (ch, COND_FULL, -1); gain_condition (ch, COND_THIRST, -1); } } if (ch->position >= POS_STUNNED) { if (ch->hit < ch->max_hit) { ch->hit += hit_gain(ch); } if (ch->mana < ch->max_mana) { ch->mana += mana_gain(ch); } if (ch->move < ch->max_move) { ch->move += move_gain(ch); } } if (IS_NPC(ch)) { if (ch->npcdata->pvnum_last_hit != 0) { if (ch->hit == ch->max_hit) { ch->npcdata->pvnum_last_hit = 0; RESTRING(ch->npcdata->hate_fear, ""); } } if (ch->fighting == NULL && ch->position != POS_FIGHTING) { if (IS_SET(ch->pIndexData->affected_by, AFF_INVISIBLE) && !IS_SET(ch->affected_by, AFF_INVISIBLE)) { SET_BIT(ch->affected_by, AFF_INVISIBLE ); } if (IS_SET(ch->pIndexData->affected_by, AFF_HIDE) && !IS_SET(ch->affected_by, AFF_HIDE)) { SET_BIT(ch->affected_by, AFF_HIDE); } if (IS_SET(ch->pIndexData->affected_by, AFF_STEALTH) && !IS_SET(ch->affected_by, AFF_STEALTH)) { SET_BIT(ch->affected_by, AFF_STEALTH); } } } update_pos(ch); if (ch->position == POS_DEAD) { raw_kill(ch); continue; } for (paf = ch->first_affect ; paf ; paf = paf_next) { paf_next = paf->next; if (paf->duration >= 0 && --paf->duration <= 0) { if (paf->type > 0 && skill_table[paf->type].msg_off) { if (paf->next == NULL || paf->type != paf->next->type) { ch_printf(ch, "%s\n\r", skill_table[paf->type].msg_off); } } switch (paf->bitvector) { case AFF_CHARM: raw_kill(ch); continue; case AFF2_POSSESS: raw_kill(ch); continue; case AFF_SLEEP: if (IS_NPC(ch)) { ch->position = ch->pIndexData->position; } break; } if (paf->type == gsn_polymorph) { do_polymorph(ch, NULL); continue; } affect_from_char(ch, paf); } } if (IS_AFFECTED(ch, AFF_POISON)) { act ("$n shivers and suffers.", ch, NULL, NULL, TO_ROOM); send_to_char ("You shiver and suffer.\n\r", ch); damage (ch, ch, 2 + ch->level / 3, TYPE_NOFIGHT); } if (ch->position < POS_STUNNED) { damage(ch, ch, ch->position, TYPE_UNDEFINED); } if (!MP_VALID_MOB(ch)) { if (ch->desc && CH(ch->desc)->pcdata->vt100 == 1) { vt100prompt (ch); } continue; } if (ch->timer > 0) { ch->timer--; if (ch->timer == 0) { mprog_delay_trigger(ch, ch->npcdata->delay_index); } } if (IS_SET(ch->pIndexData->progtypes, TIME_PROG)) { if (!MP_VALID_MOB(ch) || ch->position < POS_RESTING || ch->position == POS_FIGHTING) { continue; } mprog_time_check(ch, NULL, NULL, NULL, TIME_PROG); } } { static int lastHour; mud->usage->players[mud->time.tm_hour][mud->time.tm_wday] = mud->total_plr; if (lastHour != mud->time.tm_hour) { save_usage(); save_hiscores(); bounty_update(); save_timeinfo(); /* Check for Clan Rent, Purger, Backup - Scandum 03-09-2002 */ if (mud->time.tm_hour == 0) { log_printf("Backing up player files."); system("cd ..;./backup&"); } if (mud->time.tm_wday == 0 && mud->time.tm_hour == 0) { if (IS_SET(mud->flags, MUD_CLANRENT)) { if (mud->f_clan == NULL) { log_printf("There are no clans."); } else { do_forcerent(NULL, NULL); } REMOVE_BIT(mud->flags, MUD_CLANRENT); start_purger(); } } else if (mud->time.tm_hour != 0) { SET_BIT(mud->flags, MUD_CLANRENT); } } lastHour = mud->time.tm_hour; } /* Minutely update on the WHO HTML Page - Chaos 3/26/96 We're not using this atm - Scandum if (IS_SET(mud->flags, MUD_EMUD_REALGAME)) { save_html_who(); } */ pop_call(); return; } /* Update all objs. */ void obj_update (void) { OBJ_DATA *obj; CHAR_DATA *owner; AFFECT_DATA *paf, *paf_next; char *message; push_call("obj_update()"); for (obj = mud->f_obj ; obj ; obj = mud->update_obj) { mud->update_obj = obj->next; /* Look for enhanced objects */ if (obj->item_type != obj->pIndexData->item_type) { obj->item_type = obj->pIndexData->item_type; obj->value[0] = obj->pIndexData->value[0]; obj->value[1] = obj->pIndexData->value[1]; obj->value[2] = obj->pIndexData->value[2]; obj->value[3] = obj->pIndexData->value[3]; log_printf("obj_update: bad item type: %d", obj->pIndexData->vnum); } switch (obj->item_type) { case ITEM_ARMOR: case ITEM_WEAPON: if (IS_SET(obj->extra_flags, ITEM_MODIFIED)) { if (obj->value[0] != obj->pIndexData->value[0] || obj->value[1] != obj->pIndexData->value[1] || obj->value[2] != obj->pIndexData->value[2] || obj->value[3] != obj->pIndexData->value[3]) { obj->value[0] = obj->pIndexData->value[0]; obj->value[1] = obj->pIndexData->value[1]; obj->value[2] = obj->pIndexData->value[2]; obj->value[3] = obj->pIndexData->value[3]; } } break; case ITEM_CONTAINER: if (obj->carried_by == NULL && IS_SET(obj->value[1], CONT_CLOSEABLE) && !IS_SET(obj->value[1], CONT_CLOSED)) { SET_BIT(obj->value[1], CONT_CLOSED); if (obj->value[2] > 0) { SET_BIT(obj->value[1], CONT_LOCKED); } } break; case ITEM_LIGHT: if (obj->value[0] != obj->pIndexData->value[0]) { obj->value[0] = obj->pIndexData->value[0]; } if (obj->wear_loc == WEAR_LIGHT && obj->carried_by && obj->carried_by->desc && obj->carried_by->desc->connected >= CON_PLAYING) { if (obj->value[2] > 1 && obj->value[2] < 5) { act ("$p flickers.", obj->carried_by, obj, NULL, TO_CHAR); } if (obj->value[2] > 0) { SET_BIT(obj->extra_flags, ITEM_MODIFIED); if (--obj->value[2] == 0) { act ("$p goes out.", obj->carried_by, obj, NULL, TO_ROOM); act ("$p goes out.", obj->carried_by, obj, NULL, TO_CHAR); junk_obj(obj); continue; } } } break; case ITEM_ARTIFACT: if (obj->value[0] && obj->value[0] < mud->current_time) { if (obj->carried_by) { act("$p has started to decay.", obj->carried_by, obj, NULL, TO_CHAR); } obj->value[0] = 0; obj->timer = OBJ_SAC_TIME; } break; case ITEM_TOTEM: totem_cast_spell(obj); break; } for (paf = obj->first_affect ; paf ; paf = paf_next) { paf_next = paf->next; if (paf->duration >= 0 && --paf->duration <= 0) { if (obj->carried_by) { act(skill_table[paf->type].msg_obj_off, obj->carried_by, obj, NULL, TO_CHAR); } if (obj->in_room && obj->in_room->first_person) { act(skill_table[paf->type].msg_obj_off, obj->in_room->first_person, obj, NULL, TO_CHAR); act(skill_table[paf->type].msg_obj_off, obj->in_room->first_person, obj, NULL, TO_ROOM); } affect_from_obj(obj, paf); } } if (!IS_SET(obj->extra_flags, ITEM_NOT_VALID) && !IS_SET(obj->pIndexData->extra_flags, ITEM_NOT_VALID)) { if (obj->timer == 0 && obj->sac_timer == 0) { continue; } if (obj->in_room == NULL) { if (obj->timer == 0 || (obj->timer > 0 && --obj->timer > 0)) { continue; } } if (obj->in_room != NULL) { if (IS_SET(obj->in_room->room_flags, ROOM_CLAN_DONATION)) { if (obj->timer == 0 || (obj->timer > 0 && --obj->timer > 0)) { continue; } } else { if ((obj->timer == 0 || (obj->timer > 0 && --obj->timer > 0)) && (obj->sac_timer == 0 || (obj->sac_timer > 0 && --obj->sac_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_ARTIFACT: message = "$p cackles in delight as the last vestiges of its power dies away."; break; } if (obj->carried_by != NULL) { act (message, obj->carried_by, obj, NULL, TO_CHAR); } else if (obj->in_room != NULL && obj->in_room->first_person != NULL) { act (message, obj->in_room->first_person, obj, NULL, TO_ROOM); act (message, obj->in_room->first_person, obj, NULL, TO_CHAR); } while (obj->first_content) { if (obj->carried_by) { obj_to_char(obj->first_content, obj->carried_by); } else if (obj->in_room) { obj->first_content->sac_timer = OBJ_SAC_TIME; obj_to_room(obj->first_content, obj->in_room->vnum); } else { junk_obj(obj->first_content); } } if (obj->owned_by && (owner = get_char_pvnum(obj->owned_by)) != NULL && owner->pcdata->corpse == obj) { send_to_char("Your corpse decays.\n\r", owner); owner->pcdata->corpse = find_char_corpse (owner, TRUE); save_char_obj(owner, NORMAL_SAVE); } junk_obj(obj); } pop_call(); return; } void aggr_update (void) { CHAR_DATA *ich; CHAR_DATA *ch; AREA_DATA *area; PLAYER_GAME *npl, *next_npl; int vnum; push_call("aggr_update()"); for (area = mud->f_area ; area ; area = area->next) { for (vnum = area->low_m_vnum ; vnum <= area->hi_m_vnum ; vnum++) { if (mob_index[vnum] == NULL) { continue; } if (!IS_SET(mob_index[vnum]->progtypes, DELAY_PROG)) { continue; } for (ich = mob_index[vnum]->first_instance ; ich ; ich = mud->update_ich) { mud->update_ich = ich->next_instance; if (ich->wait > 0 && !ich->desc) { ich->wait--; if (ich->wait == 0 && MP_VALID_MOB(ich)) { mprog_delay_trigger(ich, ich->npcdata->delay_index); } } } } } for (npl = mud->f_player ; npl ; npl = next_npl) { next_npl = npl->next; if (npl->ch->level >= LEVEL_IMMORTAL) { continue; } if (npl->ch->desc == NULL && npl->ch->wait > 0) { npl->ch->wait = UMAX(0, npl->ch->wait - PULSE_AGGRESSIVE); } for (ch = npl->ch->in_room->first_person ; ch ; ch = mud->update_rch) { mud->update_rch = ch->next_in_room; if (!IS_NPC(ch) || !IS_SET(ch->act, ACT_AGGRESSIVE)) { continue; } if (!MP_VALID_MOB(ch)) { continue; } if (!IS_AWAKE(ch) || ch->fighting || ch->hit < ch->max_hit/2) { continue; } if (IS_SET(ch->act, ACT_WIMPY) && IS_AWAKE(npl->ch)) { continue; } if (!can_see(ch, npl->ch) || number_bits(1) == 0) { continue; } if (abs(npl->ch->alignment - ch->alignment) <= 500) { if (npl->ch->class == CLASS_SHAMAN || number_bits(1) == 0) { continue; } } multi_hit(ch, npl->ch, TYPE_UNDEFINED); } } pop_call(); return; } void purger_update (void) { JUNK_DATA *junk; push_call("purger_update(void)"); while (mud->f_junk) { junk = mud->f_junk; if (junk->mob) { extract_char(junk->mob); } else { extract_obj(junk->obj); } UNLINK(junk, mud->f_junk, mud->l_junk, next, prev); FREEMEM(junk); } pop_call(); return; } /* Called once per pulse from game loop. Random times to defeat tick-timing clients and players. Update routines spread out over 10 pulses Scandum - 14-05-2003 */ void update_handler (void) { static sh_int pulse_areasave = 9 + PULSE_AREASAVE; static sh_int pulse_shops = 9 + PULSE_SHOPS; static sh_int pulse_area = 9 + PULSE_TICK; static sh_int pulse_weather = 9 + PULSE_TICK; static sh_int pulse_obj = 8 + PULSE_TICK; static sh_int pulse_tick = 7 + PULSE_TICK; static sh_int pulse_charsave = 6 + PULSE_CHARSAVE; static sh_int pulse_mobprog = 4 + PULSE_PROGRAM; static sh_int pulse_objprog = 3 + PULSE_PROGRAM; static sh_int pulse_violence = 2 + PULSE_VIOLENCE; static sh_int pulse_mobile = 1 + PULSE_MOBILE; static sh_int pulse_aggressive = 0 + PULSE_AGGRESSIVE; push_call("update_handler()"); if (--pulse_areasave <= 0) { pulse_areasave = PULSE_AREASAVE; start_timer(TIMER_AREA_SAVE); auto_area_save(); close_timer(TIMER_AREA_SAVE); } if (--pulse_shops <= 0) { pulse_shops = PULSE_SHOPS; start_timer (TIMER_SHOP_UPD); shop_update (); close_timer (TIMER_SHOP_UPD); } if (--pulse_tick <= 0) { pulse_tick = PULSE_TICK / 2 + 10 * number_range(0, PULSE_TICK / 10); start_timer (TIMER_CHAR_UPD); time_update(); char_update(); close_timer(TIMER_CHAR_UPD); } if (--pulse_area <= 0) { pulse_area = PULSE_AREA / 2 + 10 * number_range(0, PULSE_AREA / 10); start_timer (TIMER_AREA_UPD); area_update (); close_timer (TIMER_AREA_UPD); } if (--pulse_weather <= 0) { pulse_weather = PULSE_TICK / 2 + 10 * number_range(0, PULSE_TICK / 10); start_timer (TIMER_WEATHER_UPD); weather_update (); close_timer (TIMER_WEATHER_UPD); } if (--pulse_obj <= 0) { pulse_obj = PULSE_TICK / 2 + 10 * number_range(0, PULSE_TICK / 10); start_timer (TIMER_OBJ_UPD); obj_update (); close_timer (TIMER_OBJ_UPD); } if (--pulse_charsave <= 0) { pulse_charsave = PULSE_CHARSAVE; start_timer( TIMER_CHAR_SAVE ); auto_char_save(); close_timer( TIMER_CHAR_SAVE ); } if (--pulse_violence <= 0) { pulse_violence = PULSE_VIOLENCE; start_timer (TIMER_VIOL_UPD); violence_update (); close_timer (TIMER_VIOL_UPD); } if (--pulse_mobprog <= 0) { pulse_mobprog = PULSE_PROGRAM; start_timer(TIMER_MOB_PROG); mob_program_update(); close_timer(TIMER_MOB_PROG); } if (--pulse_objprog <= 0) { pulse_objprog = PULSE_PROGRAM; start_timer(TIMER_OBJ_PROG); obj_program_update(); close_timer(TIMER_OBJ_PROG); } if (--pulse_mobile <= 0) { pulse_mobile = PULSE_MOBILE; start_timer (TIMER_MOB_UPD); mobile_update(); close_timer (TIMER_MOB_UPD); } if (--pulse_aggressive <= 0) { pulse_aggressive = PULSE_AGGRESSIVE; start_timer (TIMER_AGGR_UPD); aggr_update(); close_timer (TIMER_AGGR_UPD); } { start_timer (TIMER_PURGE); purger_update(); if (IS_SET(mud->flags, MUD_PURGER)) { update_purger(); } close_timer (TIMER_PURGE); } pop_call(); return; } int exp_level (int class, int level) { float a, b, c, d, num, cap, inc, onum; int cnt, lv; push_call("exp_level(%p,%p)",class,level); if (level == 0) { pop_call(); return (0); } switch (class) { case CLASS_WARRIOR: a = 1600.0; b = 1.56; c = 1666.0; d = 0 - 250.0; cap = 4000000; inc = 1650000; break; case CLASS_GLADIATOR: a = 1600.0; b = 1.58; c = 1500.0; d = 0 - 250.0; cap = 4500000; inc = 1800000; break; case CLASS_MARAUDER: a = 1500.0; b = 1.50; c = 1500.0; d = 0 - 300; cap = 3000000; inc = 1500000; break; case CLASS_NINJA: a = 1550.0; b = 1.54; c = 1500.0; d = 0 - 300.0; cap = 4000000; inc = 1600000; break; case CLASS_DRUID: a = 1525.0; b = 1.51; c = 1500.0; d = 0 - 300.0; cap = 4000000; inc = 1550000; break; case CLASS_SORCERER: a = 1550.0; b = 1.55; c = 1500.0; d = 0 - 300.0; cap = 4000000; inc = 1700000; break; case CLASS_SHAMAN: a = 1525.0; b = 1.53; c = 1500.0; d = 0 - 300.0; cap = 3500000; inc = 1550000; break; case CLASS_WARLOCK: a = 1575.0; b = 1.57; c = 1500.0; d = 0 - 250.0; cap = 4500000; inc = 1750000; break; case CLASS_MONSTER: a = 45.0; b = 1.35; c = 120.0; d = 0; cap = 50000; inc = 7000; break; default: pop_call(); return (0); } num = b; for (cnt = 1 ; cnt < level ; cnt++) { num *= b; } num = a * num + c * (level - 1) + d; if (num < cap) { pop_call(); return ((int) num); } lv = 12; num = 0; while (num < cap) { onum = b; for (cnt = 1 ; cnt < lv ; cnt++) { onum *= b; } onum = a * onum + c * (lv - 1) + d; if (num < cap) { num = onum; lv++; } } for (; lv <= level; lv++) { num += inc; if (class != CLASS_MONSTER) { inc = (int) ((float) inc * 1.03); } else { inc = (int) ((float) inc * 1.01); } } pop_call(); return ((int) num); } void bounty_update( void ) { BOUNTY_DATA *bounty, *bounty_next; push_call("bounty_update()"); for (bounty = mud->f_bounty ; bounty ; bounty = bounty_next) { bounty_next = bounty->next; if (bounty->expires < mud->current_time) { remove_bounty( bounty ); save_bounties(); } } pop_call(); return; } void set_room_timer(int vnum, int type, int timer) { ROOM_TIMER_DATA *rtd; push_call("set_room_timer(%d,%d,%d)",vnum,type,timer); ALLOCMEM(rtd, ROOM_TIMER_DATA, 1); rtd->vnum = vnum; rtd->type = type; rtd->timer = timer; LINK(rtd, mud->f_room_timer, mud->l_room_timer, next, prev); pop_call(); return; } bool del_room_timer(int vnum, int type) { ROOM_TIMER_DATA *rtd; push_call("del_room_timer(%d,%d)",vnum,type); for (rtd = mud->f_room_timer ; rtd ; rtd = rtd->next) { if (rtd->vnum == vnum && type == -1) { rtd->vnum = ROOM_VNUM_JUNK; continue; } if (rtd->vnum == vnum && rtd->type == type) { break; } } if (rtd) { UNLINK(rtd, mud->f_room_timer, mud->l_room_timer, next, prev); FREEMEM(rtd); pop_call(); return TRUE; } pop_call(); return FALSE; }