/*************************************************************************** * 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. * * * * Ground ZERO improvements copyright pending 1994, 1995 by James Hilke * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * Much time and thought has gone into this software and you are * * benefitting. We hope that you share your changes too. What goes * * around, comes around. * ***************************************************************************/ #if defined(macintosh) #include <types.h> #else #include <sys/types.h> #endif #include <stdio.h> #include <string.h> #include <time.h> #include "ground0.h" /* command procedures needed */ DECLARE_DO_FUN(do_quit ); /* * 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 weather_update args( ( void ) ); void char_update args( ( void ) ); void obj_update args( ( void ) ); void aggr_update args( ( void ) ); /* used for saving */ int save_number = 0; int tick_counter = 0; /* * Regeneration stuff. */ int hit_gain( CHAR_DATA *ch ) { int gain; int number; gain = number_range (125, 325); switch ( ch->position ) { case POS_SLEEPING: gain *= 2; break; } return UMIN(gain, ch->max_hit - ch->hit); } /* * Update all chars, including mobs. */ void char_update( void ) { CHAR_DATA *ch; CHAR_DATA *ch_next; /* update save counter */ save_number++; if (save_number > 29) save_number = 0; for ( ch = char_list; ch != NULL; ch = ch_next ) { ch_next = ch->next; if (ch->ld_timer == 1) { ch->last_hit_by = NULL; char_death (ch); } if (ch->ld_timer) ch->ld_timer--; if (!number_range (0, 5) && IS_SET (ch->affected_by, AFF_BLIND)) { REMOVE_BIT (ch->affected_by, AFF_BLIND); send_to_char ("You can see again!\n\r", ch); } if (!number_range (0, 2) && IS_SET (ch->affected_by, AFF_DAZE)) { REMOVE_BIT (ch->affected_by, AFF_DAZE); send_to_char ("You are no longer dazed!\n\r", ch); } if ( ch->position >= POS_STUNNED ) { if ( ch->hit < ch->max_hit ) ch->hit += hit_gain(ch); else ch->hit = ch->max_hit; } if ( ch->position == POS_STUNNED ) update_pos( ch ); if ( !IS_NPC(ch) && !ch->trust) if (IS_IMMORTAL(ch)) ch->timer = 0; ch->donate_num = UMAX (0, ch->donate_num - 2); ch->chan_delay = UMAX(0, ch->chan_delay - 4*PULSE_PER_SECOND); } /* * Autosave. * Check that these chars still exist. */ for ( ch = char_list; ch != NULL; ch = ch_next ) { ch_next = ch->next; if (ch->desc != NULL && ch->desc->descriptor % 30 == save_number) save_char_obj(ch); } return; } /* * Update all objs. * This function is performance sensitive. */ void obj_update( void ) { OBJ_DATA *obj; OBJ_DATA *obj_next; AFFECT_DATA *paf, *paf_next; CHAR_DATA *all_chars; for ( obj = object_list; obj != NULL; obj = obj_next ) { CHAR_DATA *rch; char *message; char buf[MAX_STRING_LENGTH]; DESCRIPTOR_DATA *d; obj_next = obj->next; if (obj->arrival_time >= 0) { obj->arrival_time--; if (obj->arrival_time == -1) { ROOM_DATA *temp_room; if (!obj->in_room) sbug ("obj_update: object not in room"); obj_from_room (obj); temp_room = obj->destination; obj->destination = NULL; obj_to_room (obj, temp_room); if (obj->in_room->people) { act ("$p lands at your feet.", obj->in_room->people, obj, NULL, TO_ROOM); act ("$p lands at your feet.", obj->in_room->people, obj, NULL, TO_CHAR); } if (IS_SET (obj->general_flags, GEN_EXTRACT_ON_IMPACT)) bang_obj (obj, 0); } } /* for clarity, this means that we either have a timer of -1 or 0 (a stopped timer) from the first half of the clause, or we have a timer that is positive int after subtracting 1 from it, the else clause means the timer must have just expired */ if ( obj->timer <= 0 || --obj->timer > 0 ) { if (obj->carried_by && obj->timer > 0) if (IS_SET (obj->extract_flags, EXTRACT_BURN_ON_EXTRACT)) act ("$p burns quietly in your hand.", obj->carried_by, obj, NULL, TO_CHAR); else act ("$p ticks very quietly.", obj->carried_by, obj, NULL, TO_CHAR); if (IS_SET (obj->general_flags, GEN_BURNS_ROOM)) if (obj->in_room && obj->in_room->people) burn_obj (obj); continue; } else { if (obj->arrival_time >= 0) extract_obj (obj, 0); else { if (obj->extract_flags) bang_obj (obj, 0); else if (IS_SET (obj->general_flags, GEN_BURNS_ROOM)) { if (obj->in_room->people) { act ("$p burns down and dies leaving nothing but " "ashes.", obj->in_room->people, obj, NULL, TO_CHAR); act ("$p burns down and dies leaving nothing but " "ashes.", obj->in_room->people, obj, NULL, TO_ROOM); } extract_obj (obj, 1); } else if (IS_SET (obj->general_flags, GEN_DARKS_ROOM)) { if (obj->in_room->people) { act ("This room is no longer dark.", obj->in_room->people, obj, NULL, TO_CHAR); act ("This room is no longer dark.", obj->in_room->people, obj, NULL, TO_ROOM); } extract_obj (obj, 1); } } } } } void tick_stuff (int imm_generated) { static int pulse_point = PULSE_TICK; char buf[100]; CHAR_DATA *all_chars; int count; if ((--pulse_point > 0) && !imm_generated) return; sprintf(buf,"TICK %d\n\r", tick_counter); log_string(buf); tick_counter++; if (!teleport_time) { if (!number_range (0, 99)) { for (all_chars = char_list; all_chars; all_chars = all_chars->next) send_to_char ("A scratchy voice comes in over your comm " "badge '`tRedeployment systems are\n\r" "operational for the moment, but may go " "offline at any second. Should you\n\rneed " "redeployment in the near future, please do " "so now.``'\n\r", all_chars); teleport_time = 1; } } else { if (!number_range (0, 11)) { for (all_chars = char_list; all_chars; all_chars = all_chars->next) send_to_char ("A scratchy voice comes in over your comm " "badge '`tTransportation systems have\n\rjust " "gone off line. Redeployment services are " "temporarily unavailable.``'\n\r", all_chars); teleport_time =0; } } pulse_point = PULSE_TICK; char_update ( ); } /* * Handle all kinds of updates. * Called once per pulse from game loop. * Random times to defeat tick-timing clients and players. */ void update_handler() { static int pulse_violence = PULSE_VIOLENCE; static int pulse_objects = PULSE_OBJECTS; static int pulse_save = PULSE_SAVE; tick_stuff (0); if ( --pulse_violence <= 0 ) { pulse_violence = PULSE_VIOLENCE; violence_update ( ); } if ( --pulse_objects <= 0 ) { pulse_objects = PULSE_OBJECTS; obj_update ( ); } if ( --pulse_save <= 0 ) { pulse_save = PULSE_SAVE; do_save_all (NULL, ""); } /* get rid of dead folk */ while (extract_list) { CHAR_DATA *ch; ch = extract_list; extract_list = extract_list->next_extract; extract_char (ch, TRUE); } tail_chain( ); }