/**************************************************************************** * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | \\._.// * * -----------------------------------------------------------| (0...0) * * SMAUG 1.0 (C) 1994, 1995, 1996, 1998 by Derek Snider | ).:.( * * -----------------------------------------------------------| {o o} * * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, | / ' ' \ * * Scryn, Rennard, Swordbearer, Gorog, Grishnakh, Nivek, |~'~.VxvxV.~'~* * Tricops and Fireblade | * * ------------------------------------------------------------------------ * * 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{rfeldt, Tom Madsen, and Katja Nyboe. * * ------------------------------------------------------------------------ * * Database management module * ****************************************************************************/ #include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <stdarg.h> #include <string.h> #include <time.h> #include <sys/stat.h> #ifndef WIN32 #include <dirent.h> #else #define strcasecmp strcmp #endif #include "mud.h" extern int _filbuf args( ( FILE * ) ); static OBJ_DATA *rgObjNest[MAX_NEST]; #if defined(KEY) #undef KEY #endif void init_supermob( ); #define KEY( literal, field, value ) \ if ( !str_cmp( word, literal ) ) \ { \ field = value; \ fMatch = TRUE; \ break; \ } /* * Globals. */ WIZENT *first_wiz; WIZENT *last_wiz; time_t last_restore_all_time = 0; HELP_DATA *first_help; HELP_DATA *last_help; SHOP_DATA *first_shop; SHOP_DATA *last_shop; REPAIR_DATA *first_repair; REPAIR_DATA *last_repair; TELEPORT_DATA *first_teleport; TELEPORT_DATA *last_teleport; PROJECT_DATA *first_project; PROJECT_DATA *last_project; OBJ_DATA *extracted_obj_queue; EXTRACT_CHAR_DATA *extracted_char_queue; char bug_buf[2 * MAX_INPUT_LENGTH]; CHAR_DATA *first_char; CHAR_DATA *last_char; char *help_greeting; char log_buf[2 * MAX_INPUT_LENGTH]; OBJ_DATA *first_object; OBJ_DATA *last_object; TIME_INFO_DATA time_info; WEATHER_DATA weather_info; int weath_unit; /* global weather param */ int rand_factor; int climate_factor; int neigh_factor; int max_vector; int cur_qobjs; int cur_qchars; int nummobsloaded; int numobjsloaded; int physicalobjects; int last_pkroom; MAP_INDEX_DATA *first_map; /* maps */ AUCTION_DATA *auction; /* auctions */ FILE *fpLOG; char *GfpName = NULL; bool StopFP = FALSE; //Added stuff. sh_int gsn_thunder_flash; sh_int gsn_super_dragonfist; sh_int gsn_genocide_attack; sh_int gsn_kakusandan; // Android Trans sh_int gsn_t4; sh_int gsn_t3; sh_int gsn_t2; sh_int gsn_t1; sh_int gsn_omega; sh_int gsn_vm1; sh_int gsn_vm2; sh_int gsn_sent_chip; /* Buu */ sh_int gsn_demonwave; sh_int gsn_candyblast; sh_int gsn_tentacle; sh_int gsn_skin_trap; sh_int gsn_thin_trans; sh_int gsn_super_trans; sh_int gsn_kid_trans; /* weaponry */ sh_int gsn_pugilism; sh_int gsn_long_blades; sh_int gsn_short_blades; sh_int gsn_flexible_arms; sh_int gsn_talonous_arms; sh_int gsn_bludgeons; sh_int gsn_missile_weapons; /* thief */ sh_int gsn_detrap; sh_int gsn_backstab; sh_int gsn_circle; sh_int gsn_dodge; sh_int gsn_block; sh_int gsn_dcd; sh_int gsn_hide; sh_int gsn_peek; sh_int gsn_pick_lock; sh_int gsn_sneak; sh_int gsn_steal; sh_int gsn_gouge; sh_int gsn_poison_weapon; /* thief & warrior */ sh_int gsn_disarm; sh_int gsn_enhanced_damage; sh_int gsn_kick; sh_int gsn_dkick; sh_int gsn_dpunch; sh_int gsn_parry; sh_int gsn_rescue; sh_int gsn_second_attack; sh_int gsn_third_attack; sh_int gsn_fourth_attack; sh_int gsn_fifth_attack; sh_int gsn_dual_wield; sh_int gsn_punch; sh_int gsn_bash; sh_int gsn_stun; sh_int gsn_bashdoor; sh_int gsn_grip; sh_int gsn_berserk; sh_int gsn_hitall; sh_int gsn_tumble; /* vampire */ sh_int gsn_feed; sh_int gsn_bloodlet; sh_int gsn_broach; sh_int gsn_mistwalk; /* other */ sh_int gsn_aid; sh_int gsn_track; sh_int gsn_search; sh_int gsn_dig; sh_int gsn_mount; sh_int gsn_bite; sh_int gsn_claw; sh_int gsn_sting; sh_int gsn_tail; sh_int gsn_scribe; sh_int gsn_brew; sh_int gsn_climb; sh_int gsn_cook; // sh_int gsn_scan; sh_int gsn_slice; sh_int gsn_sensu_bean; sh_int gsn_kaioken; sh_int gsn_essj; sh_int gsn_super_oozaru; sh_int gsn_hssj; sh_int gsn_ssj; sh_int gsn_ssj2; sh_int gsn_ssj3; sh_int gsn_ssj4; sh_int gsn_snamek; sh_int gsn_unamek; sh_int gsn_namekfuse; sh_int gsn_fusiondance; sh_int gsn_icer2; sh_int gsn_icer3; sh_int gsn_icer4; sh_int gsn_icer5; sh_int gsn_semiperfect; sh_int gsn_perfect; sh_int gsn_ultraperfect; sh_int gsn_fly; sh_int gsn_energy_ball; sh_int gsn_desperation; sh_int gsn_kamehameha; sh_int gsn_vanishing; sh_int gsn_daichiretsuzan; sh_int gsn_honoo; sh_int gsn_buuball; //new stuff -Karn sh_int gsn_tuffle_blow; sh_int gsn_shakkahou; sh_int gsn_raizou; sh_int gsn_raikyuu; sh_int gsn_riku; sh_int gsn_devil_flash; sh_int gsn_headbutt; sh_int gsn_roundhouse; sh_int gsn_acid_burn; sh_int gsn_acid_slash; sh_int gsn_fakemoon; sh_int gsn_clawstrike; sh_int gsn_saibaman1; sh_int gsn_saibaman2; sh_int gsn_saibaman3; sh_int gsn_jibaku; // end sh_int gsn_energy_ring; sh_int gsn_wff; sh_int gsn_finalshine; sh_int gsn_super_kamehameha; sh_int gsn_super_dragonfist; sh_int gsn_masenko; sh_int gsn_sbc; sh_int gsn_dd; sh_int gsn_ff; sh_int gsn_suppress; sh_int gsn_meditate; sh_int gsn_scatter_shot; sh_int gsn_sense; sh_int gsn_uppercut; sh_int gsn_tail_attack; sh_int gsn_eye_beam; sh_int gsn_finger_beam; sh_int gsn_ddd; sh_int gsn_death_ball; sh_int gsn_super_nova; sh_int gsn_preservation; sh_int gsn_regeneration; sh_int gsn_multi_eye; sh_int gsn_ssd_bomber; sh_int gsn_absorb; sh_int gsn_absorb2; sh_int gsn_battery; sh_int gsn_rocket_punch; sh_int gsn_drp; sh_int gsn_bz; sh_int gsn_enhance; sh_int gsn_railgun; sh_int gsn_cruise_punch; sh_int gsn_electric_shield; sh_int gsn_electric_shield2; sh_int gsn_electric_shield3; sh_int gsn_electric_shield4; sh_int gsn_self_destruct; sh_int gsn_duplicate; sh_int gsn_extreme; sh_int gsn_tribeam; sh_int gsn_solar_flare; sh_int gsn_multi_form; sh_int gsn_tri_form; sh_int gsn_split_form; sh_int gsn_hyper; sh_int gsn_instant_trans; sh_int gsn_mystic; sh_int gsn_lssj; sh_int gsn_majin; sh_int gsn_skga; sh_int gsn_charge2; sh_int gsn_charge3; sh_int gsn_charge4; sh_int gsn_charge5; sh_int gsn_multi_disk; sh_int gsn_ki_absorb; sh_int gsn_hells_flash; sh_int gsn_ki_burst; sh_int gsn_ki_heal; sh_int gsn_growth; sh_int gsn_giant; sh_int gsn_destructive_wave; sh_int gsn_dodon_ray; sh_int gsn_spirit_ball; sh_int gsn_big_bang; sh_int gsn_bbk; sh_int gsn_monkey_gun; sh_int gsn_gallic_gun; sh_int gsn_burning_attack; sh_int gsn_finishing_buster; sh_int gsn_heaven_splitter_cannon; sh_int gsn_hellzone_grenade; sh_int gsn_makosen; sh_int gsn_trap_ball; sh_int gsn_scattered_finger_beam; sh_int gsn_spirit_bomb; sh_int gsn_shockwave; sh_int gsn_psiblast; sh_int gsn_divine; sh_int gsn_kaiocreate; sh_int gsn_superandroid; sh_int gsn_ehb; sh_int gsn_evilboost; sh_int gsn_evilsurge; sh_int gsn_eviloverload; sh_int gsn_demonweapon; sh_int gsn_wss; sh_int gsn_darkness_flare; sh_int gsn_cleaver; sh_int gsn_maliceray; sh_int gsn_demonic_eclipse; sh_int gsn_clone; sh_int gsn_ussj; sh_int gsn_ussj2; /* spells */ sh_int gsn_aqua_breath; sh_int gsn_blindness; sh_int gsn_charm_person; sh_int gsn_curse; sh_int gsn_invis; sh_int gsn_mass_invis; sh_int gsn_poison; sh_int gsn_sleep; sh_int gsn_possess; sh_int gsn_fireball; sh_int gsn_chill_touch; sh_int gsn_lightning_bolt; /* languages */ sh_int gsn_common; sh_int gsn_saiyan; sh_int gsn_halfbreed; sh_int gsn_namek; sh_int gsn_android; sh_int gsn_icer; sh_int gsn_bio_android; // sh_int gsn_halfling; sh_int gsn_kaio; sh_int gsn_demon; sh_int gsn_wizard; /* for searching */ sh_int gsn_first_spell; sh_int gsn_first_skill; sh_int gsn_first_ability; sh_int gsn_first_weapon; sh_int gsn_first_tongue; sh_int gsn_top_sn; /* For styles? Trying to rebuild from some kind of accident here - Blod */ sh_int gsn_style_evasive; sh_int gsn_style_defensive; sh_int gsn_style_standard; sh_int gsn_style_aggressive; sh_int gsn_style_berserk; /* * Locals. */ MOB_INDEX_DATA *mob_index_hash[MAX_KEY_HASH]; OBJ_INDEX_DATA *obj_index_hash[MAX_KEY_HASH]; ROOM_INDEX_DATA *room_index_hash[MAX_KEY_HASH]; AREA_DATA *first_area; AREA_DATA *last_area; AREA_DATA *first_area_name; /*Used for alphanum. sort */ AREA_DATA *last_area_name; AREA_DATA *first_build; AREA_DATA *last_build; AREA_DATA *first_asort; AREA_DATA *last_asort; AREA_DATA *first_bsort; AREA_DATA *last_bsort; SYSTEM_DATA sysdata; int top_affect; int top_area; int top_ed; int top_exit; int top_help; int top_mob_index; int top_obj_index; int top_reset; int top_room; int top_shop; int top_repair; int top_vroom; /* * Semi-locals. */ bool fBootDb; FILE *fpArea; char strArea[MAX_INPUT_LENGTH]; void shop_inventory_update( void ); /* * Local booting procedures. */ void init_mm args( ( void ) ); void boot_log args( ( const char *str, ... ) ); void load_area args( ( FILE * fp ) ); void load_author args( ( AREA_DATA * tarea, FILE * fp ) ); void load_economy( void ); void load_resetmsg args( ( AREA_DATA * tarea, FILE * fp ) ); /* Rennard */ void load_flags args( ( AREA_DATA * tarea, FILE * fp ) ); void load_helps args( ( AREA_DATA * tarea, FILE * fp ) ); void load_mobiles args( ( AREA_DATA * tarea, FILE * fp ) ); void load_objects args( ( AREA_DATA * tarea, FILE * fp ) ); void load_projects args( ( void ) ); void load_resets args( ( AREA_DATA * tarea, FILE * fp ) ); void load_rooms args( ( AREA_DATA * tarea, FILE * fp ) ); void load_shops args( ( AREA_DATA * tarea, FILE * fp ) ); void load_repairs args( ( AREA_DATA * tarea, FILE * fp ) ); void load_specials args( ( AREA_DATA * tarea, FILE * fp ) ); void load_ranges args( ( AREA_DATA * tarea, FILE * fp ) ); void load_climate args( ( AREA_DATA * tarea, FILE * fp ) ); /* FB */ void load_neighbor args( ( AREA_DATA * tarea, FILE * fp ) ); void load_buildlist args( ( void ) ); bool load_systemdata args( ( SYSTEM_DATA * sys ) ); void load_banlist args( ( void ) ); void load_version args( ( AREA_DATA * tarea, FILE * fp ) ); void load_watchlist args( ( void ) ); void load_reserved args( ( void ) ); void initialize_economy args( ( void ) ); void fix_exits args( ( void ) ); void sort_reserved args( ( RESERVE_DATA * pRes ) ); void init_area_weather args( ( void ) ); void load_weatherdata args( ( void ) ); void load_auth_list args( ( void ) ); /* New Auth Code */ void save_auth_list args( ( void ) ); void load_storages args( ( void ) ); void load_storage args( ( char *filename ) ); PROJECT_DATA *read_project args( ( char *filename, FILE * fp ) ); NOTE_DATA *read_log args( ( FILE * fp ) ); void load_areaPlanet args( ( AREA_DATA * tarea, FILE * fp ) ); char *fread_string_wspace args( ( FILE * fp ) ); /* * External booting function */ void load_corpses args( ( void ) ); void renumber_put_resets args( ( AREA_DATA * pArea ) ); void load_colors args( ( void ) ); /* * MUDprogram locals */ int mprog_name_to_type args( ( char *name ) ); MPROG_DATA *mprog_file_read args( ( char *f, MPROG_DATA * mprg, MOB_INDEX_DATA * pMobIndex ) ); /* int oprog_name_to_type args ( ( char* name ) ); */ MPROG_DATA *oprog_file_read args( ( char *f, MPROG_DATA * mprg, OBJ_INDEX_DATA * pObjIndex ) ); /* int rprog_name_to_type args ( ( char* name ) ); */ MPROG_DATA *rprog_file_read args( ( char *f, MPROG_DATA * mprg, ROOM_INDEX_DATA * pRoomIndex ) ); void load_mudprogs args( ( AREA_DATA * tarea, FILE * fp ) ); void load_objprogs args( ( AREA_DATA * tarea, FILE * fp ) ); void load_roomprogs args( ( AREA_DATA * tarea, FILE * fp ) ); void mprog_read_programs args( ( FILE * fp, MOB_INDEX_DATA * pMobIndex ) ); void oprog_read_programs args( ( FILE * fp, OBJ_INDEX_DATA * pObjIndex ) ); void rprog_read_programs args( ( FILE * fp, ROOM_INDEX_DATA * pRoomIndex ) ); void shutdown_mud( char *reason ) { FILE *fp; if( ( fp = fopen( SHUTDOWN_FILE, "a" ) ) != NULL ) { fprintf( fp, "%s\n", reason ); fclose( fp ); } } /* * Big mama top level function. */ void boot_db( bool fCopyOver ) { sh_int wear, x; fpArea = NULL; show_hash( 32 ); unlink( BOOTLOG_FILE ); boot_log( "---------------------[ Boot Log ]--------------------" ); log_string( "Loading commands" ); load_commands( ); log_string( "Loading sysdata configuration..." ); /* * default values */ sysdata.read_all_mail = LEVEL_DEMI; sysdata.read_mail_free = LEVEL_IMMORTAL; sysdata.write_mail_free = LEVEL_IMMORTAL; sysdata.take_others_mail = LEVEL_DEMI; sysdata.imc_mail_vnum = 0; sysdata.muse_level = LEVEL_DEMI; sysdata.think_level = LEVEL_HIGOD; sysdata.build_level = LEVEL_DEMI; sysdata.log_level = LEVEL_LOG; sysdata.level_modify_proto = LEVEL_LESSER; sysdata.level_override_private = LEVEL_GREATER; sysdata.level_mset_player = LEVEL_LESSER; sysdata.stun_plr_vs_plr = 65; sysdata.stun_regular = 15; sysdata.gouge_nontank = 0; sysdata.gouge_plr_vs_plr = 0; sysdata.bash_nontank = 0; sysdata.bash_plr_vs_plr = 0; sysdata.dodge_mod = 2; sysdata.parry_mod = 2; sysdata.tumble_mod = 4; sysdata.dam_plr_vs_plr = 100; sysdata.dam_plr_vs_mob = 100; sysdata.dam_mob_vs_plr = 100; sysdata.dam_mob_vs_mob = 100; sysdata.level_getobjnotake = LEVEL_GREATER; sysdata.save_frequency = 20; /* minutes */ sysdata.bestow_dif = 5; sysdata.check_imm_host = 1; sysdata.morph_opt = 1; sysdata.save_pets = 0; sysdata.pk_loot = 1; sysdata.stall_hiscores = 0; sysdata.rpChannel = 0; sysdata.save_flags = SV_DEATH | SV_PASSCHG | SV_AUTO | SV_PUT | SV_DROP | SV_GIVE | SV_AUCTION | SV_ZAPDROP | SV_IDLE; sysdata.kaiRestoreTimer = 0; if( !load_systemdata( &sysdata ) ) { log_string( "Not found. Creating new configuration." ); sysdata.alltimemax = 0; sysdata.mud_name = str_dup( "(Name not set)" ); } log_string( "Loading socials" ); load_socials( ); log_string( "Loading skill table" ); load_skill_table( ); sort_skill_table( ); remap_slot_numbers( ); /* must be after the sort */ gsn_first_spell = 0; gsn_first_skill = 0; gsn_first_ability = 0; gsn_first_weapon = 0; gsn_first_tongue = 0; gsn_top_sn = top_sn; for( x = 0; x < top_sn; x++ ) if( !gsn_first_spell && skill_table[x]->type == SKILL_SPELL ) gsn_first_spell = x; else if( !gsn_first_skill && skill_table[x]->type == SKILL_SKILL ) gsn_first_skill = x; else if( !gsn_first_ability && skill_table[x]->type == SKILL_ABILITY ) gsn_first_ability = x; else if( !gsn_first_weapon && skill_table[x]->type == SKILL_WEAPON ) gsn_first_weapon = x; else if( !gsn_first_tongue && skill_table[x]->type == SKILL_TONGUE ) gsn_first_tongue = x; log_string( "Loading classes" ); load_classes( ); log_string( "Loading races" ); load_races( ); log_string( "Loading herb table" ); load_herb_table( ); log_string( "Loading tongues" ); load_tongues( ); log_string( "Making wizlist" ); make_wizlist( ); log_string( "Building wizinfo" ); build_wizinfo( TRUE ); log_string( "Initializing request pipe" ); init_request_pipe( ); fBootDb = TRUE; nummobsloaded = 0; numobjsloaded = 0; physicalobjects = 0; sysdata.maxplayers = 0; first_object = NULL; last_object = NULL; first_char = NULL; last_char = NULL; first_area = NULL; first_area_name = NULL; /*Used for alphanum. sort */ last_area_name = NULL; last_area = NULL; first_build = NULL; last_area = NULL; first_shop = NULL; last_shop = NULL; first_repair = NULL; last_repair = NULL; first_teleport = NULL; last_teleport = NULL; first_asort = NULL; last_asort = NULL; extracted_obj_queue = NULL; extracted_char_queue = NULL; cur_qobjs = 0; cur_qchars = 0; cur_char = NULL; cur_obj = 0; cur_obj_serial = 0; cur_char_died = FALSE; cur_obj_extracted = FALSE; cur_room = NULL; quitting_char = NULL; loading_char = NULL; saving_char = NULL; last_pkroom = 1; immortal_host_start = NULL; immortal_host_end = NULL; first_ban_class = NULL; last_ban_class = NULL; first_ban_race = NULL; last_ban_race = NULL; first_ban = NULL; last_ban = NULL; top_mob_serial = 0; CREATE( auction, AUCTION_DATA, 1 ); auction->item = NULL; auction->hist_timer = 0; for( x = 0; x < AUCTION_MEM; x++ ) auction->history[x] = NULL; auction->freeQueSlot = -1; auction->queued_obj[0] = NULL; auction->queued_char[0] = NULL; auction->queued_starting_bid[0] = 0; auction->queued_obj[1] = NULL; auction->queued_char[1] = NULL; auction->queued_starting_bid[1] = 0; auction->queued_obj[2] = NULL; auction->queued_char[2] = NULL; auction->queued_starting_bid[2] = 0; auction->queued_obj[3] = NULL; auction->queued_char[3] = NULL; auction->queued_starting_bid[3] = 0; auction->queued_obj[4] = NULL; auction->queued_char[4] = NULL; auction->queued_starting_bid[4] = 0; weath_unit = 10; rand_factor = 2; climate_factor = 1; neigh_factor = 3; max_vector = weath_unit * 3; for( wear = 0; wear < MAX_WEAR; wear++ ) for( x = 0; x < MAX_LAYERS; x++ ) save_equipment[wear][x] = NULL; /* * Init random number generator. */ log_string( "Initializing random number generator" ); init_mm( ); /* * Set time and weather. */ { long lhour, lday, lmonth; log_string( "Setting time and weather" ); if( !load_timedata( ) ) { lhour = ( current_time - 650336715 ) / ( PULSE_TICK / PULSE_PER_SECOND ); time_info.hour = lhour % 24; lday = lhour / 24; time_info.day = lday % 35; lmonth = lday / 35; time_info.month = lmonth % 17; time_info.year = lmonth / 17; } if( time_info.hour < 5 ) time_info.sunlight = SUN_DARK; else if( time_info.hour < 6 ) time_info.sunlight = SUN_RISE; else if( time_info.hour < 19 ) time_info.sunlight = SUN_LIGHT; else if( time_info.hour < 20 ) time_info.sunlight = SUN_SET; else time_info.sunlight = SUN_DARK; /* * weather_info.change = 0; * weather_info.mmhg = 960; * if ( time_info.month >= 7 && time_info.month <=12 ) * weather_info.mmhg += number_range( 1, 50 ); * else * weather_info.mmhg += number_range( 1, 80 ); * * if ( weather_info.mmhg <= 980 ) weather_info.sky = SKY_LIGHTNING; * else if ( weather_info.mmhg <= 1000 ) weather_info.sky = SKY_RAINING; * else if ( weather_info.mmhg <= 1020 ) weather_info.sky = SKY_CLOUDY; * else weather_info.sky = SKY_CLOUDLESS; */ } /* * Assign gsn's for skills which need them. */ { log_string( "Assigning gsn's" ); ASSIGN_GSN( gsn_style_evasive, "evasive style" ); ASSIGN_GSN( gsn_style_defensive, "defensive style" ); ASSIGN_GSN( gsn_style_standard, "standard style" ); ASSIGN_GSN( gsn_style_aggressive, "aggressive style" ); ASSIGN_GSN( gsn_style_berserk, "berserk style" ); ASSIGN_GSN( gsn_dodge, "dodge" ); ASSIGN_GSN( gsn_block, "block" ); ASSIGN_GSN( gsn_dcd, "dcd" ); ASSIGN_GSN( gsn_hide, "hide" ); ASSIGN_GSN( gsn_sneak, "sneak" ); ASSIGN_GSN( gsn_gouge, "gouge" ); ASSIGN_GSN( gsn_enhanced_damage, "enhanced damage" ); ASSIGN_GSN( gsn_kick, "kick" ); ASSIGN_GSN( gsn_thunder_flash, "thunder flash" ); ASSIGN_GSN( gsn_dkick, "double kick" ); ASSIGN_GSN( gsn_dpunch, "double punch" ); ASSIGN_GSN( gsn_rescue, "rescue" ); ASSIGN_GSN( gsn_second_attack, "second attack" ); ASSIGN_GSN( gsn_third_attack, "third attack" ); ASSIGN_GSN( gsn_fourth_attack, "fourth attack" ); ASSIGN_GSN( gsn_fifth_attack, "fifth attack" ); ASSIGN_GSN( gsn_bash, "bash" ); ASSIGN_GSN( gsn_stun, "stun" ); ASSIGN_GSN( gsn_hitall, "hitall" ); ASSIGN_GSN( gsn_aid, "aid" ); ASSIGN_GSN( gsn_track, "track" ); ASSIGN_GSN( gsn_search, "search" ); ASSIGN_GSN( gsn_claw, "claw" ); ASSIGN_GSN( gsn_tail, "tail" ); ASSIGN_GSN( gsn_mass_invis, "mass invis" ); ASSIGN_GSN( gsn_sensu_bean, "sensu bean" ); //added stuff ASSIGN_GSN( gsn_kakusandan, "kakusandan" ); ASSIGN_GSN( gsn_genocide_attack, "genocide" ); /* ASSIGN_GSN( gsn_charge2, "charge L2" ); * ASSIGN_GSN( gsn_charge3, "charge L3" ); * ASSIGN_GSN( gsn_charge4, "charge L4" ); * ASSIGN_GSN( gsn_charge5, "charge L1" ); */ ASSIGN_GSN( gsn_charge2, "charge L1" ); ASSIGN_GSN( gsn_charge3, "charge L2" ); ASSIGN_GSN( gsn_charge4, "charge L3" ); ASSIGN_GSN( gsn_charge5, "charge L4" ); ASSIGN_GSN( gsn_kaioken, "kaioken" ); ASSIGN_GSN( gsn_super_oozaru, "super oozaru" ); ASSIGN_GSN( gsn_essj, "essj" ); ASSIGN_GSN( gsn_hssj, "hssj" ); ASSIGN_GSN( gsn_ssj, "ssj1" ); ASSIGN_GSN( gsn_ssj2, "ssj2" ); ASSIGN_GSN( gsn_ssj3, "ssj3" ); ASSIGN_GSN( gsn_ssj4, "ssj4" ); ASSIGN_GSN( gsn_snamek, "super namek" ); ASSIGN_GSN( gsn_saibaman1, "enhanced form" ); ASSIGN_GSN( gsn_saibaman2, "superior form" ); ASSIGN_GSN( gsn_saibaman3, "giant form" ); ASSIGN_GSN( gsn_namekfuse, "namekfuse" ); ASSIGN_GSN( gsn_fusiondance, "fusion dance" ); ASSIGN_GSN( gsn_icer2, "2nd form" ); ASSIGN_GSN( gsn_icer3, "3rd form" ); ASSIGN_GSN( gsn_icer4, "4th form" ); ASSIGN_GSN( gsn_icer5, "5th form" ); ASSIGN_GSN( gsn_semiperfect, "semi-perfect form" ); ASSIGN_GSN( gsn_perfect, "perfect form" ); ASSIGN_GSN( gsn_ultraperfect, "ultra-perfect form" ); ASSIGN_GSN( gsn_punch, "punch" ); ASSIGN_GSN( gsn_fly, "fly" ); ASSIGN_GSN( gsn_energy_ball, "energy ball" ); ASSIGN_GSN( gsn_desperation, "desperation" ); ASSIGN_GSN( gsn_kamehameha, "kamehameha" ); ASSIGN_GSN( gsn_vanishing, "vanishing ball" ); ASSIGN_GSN( gsn_daichiretsuzan, "daichiretsuzan" ); ASSIGN_GSN( gsn_honoo, "honoo" ); ASSIGN_GSN( gsn_buuball, "buuball" ); ASSIGN_GSN( gsn_tuffle_blow, "tuffle blow" ); ASSIGN_GSN( gsn_shakkahou, "shakkahou" ); ASSIGN_GSN( gsn_raizou, "raizou" ); ASSIGN_GSN( gsn_raikyuu, "raikyuu" ); ASSIGN_GSN( gsn_riku, "riku" ); ASSIGN_GSN( gsn_devil_flash, "devil flash" ); ASSIGN_GSN( gsn_roundhouse, "roundhouse" ); ASSIGN_GSN( gsn_headbutt, "headbutt" ); ASSIGN_GSN( gsn_acid_burn, "acid burn" ); ASSIGN_GSN( gsn_acid_slash, "acid slash"); ASSIGN_GSN( gsn_fakemoon, "fakemoon" ); ASSIGN_GSN( gsn_clawstrike, "claw strike" ); ASSIGN_GSN( gsn_jibaku, "jibaku" ); ASSIGN_GSN( gsn_energy_ring, "energy ring" ); ASSIGN_GSN( gsn_wff, "wolf fang fist" ); ASSIGN_GSN( gsn_finalshine, "final shine" ); ASSIGN_GSN( gsn_super_kamehameha, "super kamehameha" ); ASSIGN_GSN( gsn_super_dragonfist, "super dragon fist" ); ASSIGN_GSN( gsn_masenko, "masenko" ); ASSIGN_GSN( gsn_sbc, "special beam cannon" ); ASSIGN_GSN( gsn_dd, "destructo disk" ); ASSIGN_GSN( gsn_ff, "final flash" ); ASSIGN_GSN( gsn_suppress, "suppress" ); ASSIGN_GSN( gsn_meditate, "meditate" ); ASSIGN_GSN( gsn_scatter_shot, "scatter shot" ); ASSIGN_GSN( gsn_sense, "sense" ); ASSIGN_GSN( gsn_uppercut, "uppercut" ); ASSIGN_GSN( gsn_tail_attack, "tail attack" ); ASSIGN_GSN( gsn_eye_beam, "eye beam" ); ASSIGN_GSN( gsn_finger_beam, "finger beam" ); ASSIGN_GSN( gsn_ddd, "dual destructo disk" ); ASSIGN_GSN( gsn_death_ball, "death ball" ); ASSIGN_GSN( gsn_super_nova, "super nova" ); ASSIGN_GSN( gsn_preservation, "preservation" ); ASSIGN_GSN( gsn_regeneration, "regeneration" ); ASSIGN_GSN( gsn_multi_eye, "multi eye beam" ); ASSIGN_GSN( gsn_ssd_bomber, "ssd bomber" ); ASSIGN_GSN( gsn_absorb, "absorb" ); ASSIGN_GSN( gsn_absorb2, "upgraded absorb L1" ); ASSIGN_GSN( gsn_battery, "battery" ); ASSIGN_GSN( gsn_rocket_punch, "rocket punch" ); ASSIGN_GSN( gsn_drp, "double rocket punch" ); ASSIGN_GSN( gsn_bz, "blast zone" ); ASSIGN_GSN( gsn_enhance, "enhance" ); ASSIGN_GSN( gsn_railgun, "railgun" ); ASSIGN_GSN( gsn_cruise_punch, "cruise punch" ); ASSIGN_GSN( gsn_electric_shield, "electric shield" ); ASSIGN_GSN( gsn_electric_shield2, "upgraded shield L1" ); ASSIGN_GSN( gsn_electric_shield3, "upgraded shield L2" ); ASSIGN_GSN( gsn_electric_shield4, "upgraded shield L3" ); ASSIGN_GSN( gsn_self_destruct, "self destruct" ); ASSIGN_GSN( gsn_duplicate, "duplicate" ); ASSIGN_GSN( gsn_extreme, "extreme" ); ASSIGN_GSN( gsn_tribeam, "tri-beam" ); ASSIGN_GSN( gsn_solar_flare, "solar flare" ); ASSIGN_GSN( gsn_multi_form, "multi-form" ); ASSIGN_GSN( gsn_tri_form, "tri-form" ); ASSIGN_GSN( gsn_hyper, "hyper" ); ASSIGN_GSN( gsn_instant_trans, "instant transmission" ); ASSIGN_GSN( gsn_mystic, "mystic" ); ASSIGN_GSN( gsn_lssj, "lssj" ); ASSIGN_GSN( gsn_majin, "majin" ); ASSIGN_GSN( gsn_skga, "skga" ); ASSIGN_GSN( gsn_common, "common" ); ASSIGN_GSN( gsn_saiyan, "saiyan" ); ASSIGN_GSN( gsn_halfbreed, "halfbreed" ); ASSIGN_GSN( gsn_namek, "namek" ); ASSIGN_GSN( gsn_android, "android" ); ASSIGN_GSN( gsn_icer, "icer" ); ASSIGN_GSN( gsn_bio_android, "bio-android" ); ASSIGN_GSN( gsn_kaio, "kaio" ); ASSIGN_GSN( gsn_demon, "demon" ); ASSIGN_GSN( gsn_wizard, "wizard" ); ASSIGN_GSN( gsn_multi_disk, "multi disk" ); ASSIGN_GSN( gsn_ki_absorb, "ki absorb" ); ASSIGN_GSN( gsn_hells_flash, "hells flash" ); ASSIGN_GSN( gsn_ki_burst, "ki burst" ); ASSIGN_GSN( gsn_ki_heal, "ki heal" ); ASSIGN_GSN( gsn_growth, "growth" ); ASSIGN_GSN( gsn_giant, "giant size" ); ASSIGN_GSN( gsn_split_form, "split-form" ); ASSIGN_GSN( gsn_destructive_wave, "destructive wave" ); ASSIGN_GSN( gsn_dodon_ray, "dodon ray" ); ASSIGN_GSN( gsn_spirit_ball, "spirit ball" ); ASSIGN_GSN( gsn_big_bang, "bigbang" ); ASSIGN_GSN( gsn_bbk, "big bang kamehameha" ); ASSIGN_GSN( gsn_monkey_gun, "oozaru mouth cannon" ); ASSIGN_GSN( gsn_gallic_gun, "gallic gun" ); ASSIGN_GSN( gsn_burning_attack, "burning attack" ); ASSIGN_GSN( gsn_finishing_buster, "finishing buster" ); ASSIGN_GSN( gsn_heaven_splitter_cannon, "heaven-splitter cannon" ); ASSIGN_GSN( gsn_hellzone_grenade, "hellzone grenade" ); ASSIGN_GSN( gsn_makosen, "makosen" ); ASSIGN_GSN( gsn_trap_ball, "trap ball" ); ASSIGN_GSN( gsn_scattered_finger_beam, "scattered finger beam" ); ASSIGN_GSN( gsn_spirit_bomb, "spirit bomb" ); ASSIGN_GSN( gsn_shockwave, "shockwave" ); ASSIGN_GSN( gsn_psiblast, "psionic blast" ); ASSIGN_GSN( gsn_divine, "divine wrath" ); ASSIGN_GSN( gsn_kaiocreate, "kaio create" ); ASSIGN_GSN( gsn_superandroid, "super android" ); ASSIGN_GSN( gsn_ehb, "electric hell ball" ); ASSIGN_GSN( gsn_evilboost, "evil boost" ); ASSIGN_GSN( gsn_evilsurge, "evil surge" ); ASSIGN_GSN( gsn_eviloverload, "evil overload" ); ASSIGN_GSN( gsn_demonweapon, "demon weapon" ); ASSIGN_GSN( gsn_wss, "weapon soul seppuku" ); ASSIGN_GSN( gsn_darkness_flare, "darkness flare" ); ASSIGN_GSN( gsn_cleaver, "cleaver" ); ASSIGN_GSN( gsn_maliceray, "malice ray" ); ASSIGN_GSN( gsn_demonic_eclipse, "demonic eclipse" ); ASSIGN_GSN( gsn_clone, "clone" ); ASSIGN_GSN( gsn_ussj, "ussj1" ); ASSIGN_GSN( gsn_ussj2, "ussj2" ); ASSIGN_GSN( gsn_thin_trans, "thin transformation" ); ASSIGN_GSN( gsn_super_trans, "super transformation" ); ASSIGN_GSN( gsn_kid_trans, "kid transformation" ); ASSIGN_GSN( gsn_demonwave, "demon wave" ); ASSIGN_GSN( gsn_candyblast, "candy blast" ); ASSIGN_GSN( gsn_tentacle, "tentacle attack" ); ASSIGN_GSN( gsn_skin_trap, "skin trap" ); ASSIGN_GSN( gsn_t4, "t4" ); ASSIGN_GSN( gsn_t3, "t3" ); ASSIGN_GSN( gsn_t2, "t2" ); ASSIGN_GSN( gsn_t1, "t1" ); ASSIGN_GSN( gsn_omega, "omega" ); ASSIGN_GSN( gsn_vm1, "vm1" ); ASSIGN_GSN( gsn_vm2, "vm2" ); ASSIGN_GSN( gsn_sent_chip, "sentient chip" ); ASSIGN_GSN( gsn_unamek, "ultra namek" ); } log_string( "Loading DNS cache..." ); /* Samson 1-30-02 */ load_dns( ); #ifdef PLANES log_string( "Reading in plane file..." ); load_planes( ); #endif /* * Read in all the area files. */ { FILE *fpList; log_string( "Reading in area files..." ); if( ( fpList = fopen( AREA_LIST, "r" ) ) == NULL ) { perror( AREA_LIST ); shutdown_mud( "Unable to open area list" ); exit( 1 ); } for( ;; ) { strcpy( strArea, fread_word( fpList ) ); if( strArea[0] == '$' ) break; load_area_file( last_area, strArea ); } fclose( fpList ); } #ifdef PLANES log_string( "Making sure rooms are planed..." ); check_planes( NULL ); #endif /* * initialize supermob. * must be done before reset_area! * */ init_supermob( ); /* * Has some bad memory bugs in it */ #ifdef PROFANITY_CHECK init_profanity_checker( ); /* as good a place as any */ #endif /* * Fix up exits. * Declare db booting over. * Reset all areas once. * Load up the notes file. */ { log_string( "Fixing exits" ); fix_exits( ); fBootDb = FALSE; log_string( "Loading economy" ); load_economy( ); log_string( "Initializing economy" ); initialize_economy( ); log_string( "Resetting areas" ); area_update( ); log_string( "Loading buildlist" ); load_buildlist( ); log_string( "Loading boards" ); load_boards( ); log_string( "Loading Global Boards" ); load_global_boards( ); log_string( "Loading clans" ); load_clans( ); log_string( "Loading deities" ); load_deity( ); log_string( "Loading councils" ); load_councils( ); log_string( "Loading watches" ); load_watchlist( ); log_string( "Loading bans" ); load_banlist( ); log_string( "Loading reserved names" ); load_reserved( ); log_string( "Loading auth namelist" ); load_auth_list( ); save_auth_list( ); log_string( "Loading censored words" ); load_censor( ); scan_equipment( ); log_string( "Loading corpses" ); load_corpses( ); log_string( "Loading space" ); load_space( ); log_string( "Loading ships" ); load_ships( ); log_string( "Loading governments" ); load_planets( ); log_string( "Loading Immortal Hosts" ); load_imm_host( ); log_string( "Loading Projects" ); load_projects( ); /* Morphs MUST be loaded after class and race tables are set up --Shaddai */ log_string( "Loading Morphs" ); load_morphs( ); log_string( "Loading storerooms" ); load_storages( ); log_string( "Loading Colors" ); load_colors( ); log_string( "Loading Housing System, Home Accessories Data," " and Home Auctioning System" ); load_homedata( ); load_accessories( ); load_homebuy( ); if( fCopyOver ) { log_string( "Initiating hotboot recovery." ); hotboot_recover( ); } MOBtrigger = TRUE; /* * cronel hiscore */ log_string( "Loading hiscore tables" ); load_hiscores( ); } /* * Initialize area weather data */ load_weatherdata( ); init_area_weather( ); /* * init_maps ( ); */ return; } /* * Load an 'area' header line. */ void load_area( FILE * fp ) { AREA_DATA *pArea; CREATE( pArea, AREA_DATA, 1 ); pArea->first_reset = NULL; pArea->last_reset = NULL; pArea->name = fread_string_nohash( fp ); pArea->author = STRALLOC( "unknown" ); pArea->filename = str_dup( strArea ); pArea->age = 15; pArea->nplayer = 0; pArea->low_r_vnum = 0; pArea->low_o_vnum = 0; pArea->low_m_vnum = 0; pArea->hi_r_vnum = 0; pArea->hi_o_vnum = 0; pArea->hi_m_vnum = 0; pArea->low_soft_range = 0; pArea->hi_soft_range = MAX_LEVEL; pArea->low_hard_range = 0; pArea->hi_hard_range = MAX_LEVEL; pArea->spelllimit = 0; /* * initialize weather data - FB */ CREATE( pArea->weather, WEATHER_DATA, 1 ); pArea->weather->temp = 0; pArea->weather->precip = 0; pArea->weather->wind = 0; pArea->weather->temp_vector = 0; pArea->weather->precip_vector = 0; pArea->weather->wind_vector = 0; pArea->weather->climate_temp = 2; pArea->weather->climate_precip = 2; pArea->weather->climate_wind = 2; pArea->weather->first_neighbor = NULL; pArea->weather->last_neighbor = NULL; pArea->weather->echo = NULL; pArea->weather->echo_color = AT_GREY; area_version = 0; LINK( pArea, first_area, last_area, next, prev ); top_area++; return; } /* Load the version number of the area file if none exists, then it * is set to version 0 when #AREA is read in which is why we check for * the #AREA here. --Shaddai */ void load_version( AREA_DATA * tarea, FILE * fp ) { if( !tarea ) { bug( "Load_author: no #AREA seen yet." ); if( fBootDb ) { shutdown_mud( "No #AREA" ); exit( 1 ); } else return; } area_version = fread_number( fp ); return; } /* * Load an author section. Scryn 2/1/96 */ void load_author( AREA_DATA * tarea, FILE * fp ) { if( !tarea ) { bug( "Load_author: no #AREA seen yet." ); if( fBootDb ) { shutdown_mud( "No #AREA" ); exit( 1 ); } else return; } if( tarea->author ) STRFREE( tarea->author ); tarea->author = fread_string( fp ); return; } /* * Load an economy section. Thoric */ void load_economy( void ) { AREA_DATA *tarea; char buf[MAX_STRING_LENGTH]; FILE *fpout; for( tarea = first_area; tarea; tarea = tarea->next ) { sprintf( buf, "%s.econ", tarea->filename ); if( ( fpout = fopen( buf, "r" ) ) == NULL ) { bug( "load_economy: fopen", 0 ); perror( buf ); return; } tarea->economy = fread_number_skill( fpout ); fclose( fpout ); } return; } /* * Load what planet the area is on */ void load_areaPlanet( AREA_DATA * tarea, FILE * fp ) { if( !tarea ) { bug( "Load_areaPlanet: no #AREA seen yet." ); if( fBootDb ) { shutdown_mud( "No #AREA" ); exit( 1 ); } else return; } tarea->areaPlanet = fread_number( fp ); return; } /* Reset Message Load, Rennard */ void load_resetmsg( AREA_DATA * tarea, FILE * fp ) { if( !tarea ) { bug( "Load_resetmsg: no #AREA seen yet." ); if( fBootDb ) { shutdown_mud( "No #AREA" ); exit( 1 ); } else return; } if( tarea->resetmsg ) DISPOSE( tarea->resetmsg ); tarea->resetmsg = fread_string_nohash( fp ); return; } /* * Load area flags. Narn, Mar/96 */ void load_flags( AREA_DATA * tarea, FILE * fp ) { char *ln; int x1, x2; if( !tarea ) { bug( "Load_flags: no #AREA seen yet." ); if( fBootDb ) { shutdown_mud( "No #AREA" ); exit( 1 ); } else return; } ln = fread_line( fp ); x1 = x2 = 0; sscanf( ln, "%d %d", &x1, &x2 ); tarea->flags = x1; tarea->reset_frequency = x2; if( x2 ) tarea->age = x2; return; } /* * Adds a help page to the list if it is not a duplicate of an existing page. * Page is insert-sorted by keyword. -Thoric * (The reason for sorting is to keep do_hlist looking nice) */ void add_help( HELP_DATA * pHelp ) { HELP_DATA *tHelp; int match; for( tHelp = first_help; tHelp; tHelp = tHelp->next ) if( pHelp->level == tHelp->level && strcmp( pHelp->keyword, tHelp->keyword ) == 0 ) { bug( "add_help: duplicate: %s. Deleting.", pHelp->keyword ); STRFREE( pHelp->text ); STRFREE( pHelp->keyword ); DISPOSE( pHelp ); return; } else if( ( match = strcmp( pHelp->keyword[0] == '\'' ? pHelp->keyword + 1 : pHelp->keyword, tHelp->keyword[0] == '\'' ? tHelp->keyword + 1 : tHelp->keyword ) ) < 0 || ( match == 0 && pHelp->level > tHelp->level ) ) { if( !tHelp->prev ) first_help = pHelp; else tHelp->prev->next = pHelp; pHelp->prev = tHelp->prev; pHelp->next = tHelp; tHelp->prev = pHelp; break; } if( !tHelp ) LINK( pHelp, first_help, last_help, next, prev ); top_help++; } /* * Load a help section. */ void load_helps( AREA_DATA * tarea, FILE * fp ) { HELP_DATA *pHelp; for( ;; ) { CREATE( pHelp, HELP_DATA, 1 ); pHelp->level = fread_number( fp ); pHelp->keyword = fread_string( fp ); if( pHelp->keyword[0] == '$' ) { STRFREE( pHelp->keyword ); DISPOSE( pHelp ); break; } pHelp->text = fread_string( fp ); if( pHelp->keyword[0] == '\0' ) { STRFREE( pHelp->text ); STRFREE( pHelp->keyword ); DISPOSE( pHelp ); continue; } if( !str_cmp( pHelp->keyword, "greeting" ) ) help_greeting = pHelp->text; add_help( pHelp ); } return; } /* * Add a character to the list of all characters -Thoric */ void add_char( CHAR_DATA * ch ) { LINK( ch, first_char, last_char, next, prev ); } /* * Load a mob section. */ void load_mobiles( AREA_DATA * tarea, FILE * fp ) { MOB_INDEX_DATA *pMobIndex; char *ln; int x1, x2, x3, x4, x5, x6, x7, x8; char *rem_break = NULL; if( !tarea ) { bug( "Load_mobiles: no #AREA seen yet." ); if( fBootDb ) { shutdown_mud( "No #AREA" ); exit( 1 ); } else return; } for( ;; ) { char buf[MAX_STRING_LENGTH]; int vnum; char letter; int iHash; bool oldmob; bool tmpBootDb; letter = fread_letter( fp ); if( letter != '#' ) { bug( "Load_mobiles: # not found." ); if( fBootDb ) { shutdown_mud( "# not found" ); exit( 1 ); } else return; } vnum = fread_number( fp ); if( vnum == 0 ) break; tmpBootDb = fBootDb; fBootDb = FALSE; if( get_mob_index( vnum ) ) { if( tmpBootDb ) { bug( "Load_mobiles: vnum %d duplicated.", vnum ); shutdown_mud( "duplicate vnum" ); exit( 1 ); } else { pMobIndex = get_mob_index( vnum ); sprintf( buf, "Cleaning mobile: %d", vnum ); log_string_plus( buf, LOG_BUILD, sysdata.log_level ); clean_mob( pMobIndex ); oldmob = TRUE; } } else { oldmob = FALSE; CREATE( pMobIndex, MOB_INDEX_DATA, 1 ); } fBootDb = tmpBootDb; pMobIndex->vnum = vnum; if( fBootDb ) { if( !tarea->low_m_vnum ) tarea->low_m_vnum = vnum; if( vnum > tarea->hi_m_vnum ) tarea->hi_m_vnum = vnum; } pMobIndex->player_name = fread_string( fp ); pMobIndex->short_descr = fread_string( fp ); pMobIndex->long_descr = fread_string( fp ); pMobIndex->description = fread_string( fp ); pMobIndex->long_descr[0] = UPPER( pMobIndex->long_descr[0] ); pMobIndex->description[0] = UPPER( pMobIndex->description[0] ); // For whatever stupid ass reason, all the long descs have \n\r at the end. // So I'm going to KILL THEM ALL!!!!!!!!! --Saiyr 12.29.05 if( ( rem_break = strstr( pMobIndex->long_descr + strlen(pMobIndex->long_descr) - 2, "\n\r" ) ) ) { *rem_break = '\0'; rem_break++; *rem_break = '\0'; } pMobIndex->act = fread_bitvector( fp ); xSET_BIT( pMobIndex->act, ACT_IS_NPC ); pMobIndex->affected_by = fread_bitvector( fp ); pMobIndex->pShop = NULL; pMobIndex->rShop = NULL; pMobIndex->alignment = fread_number( fp ); letter = fread_letter( fp ); pMobIndex->level = fread_number( fp ); pMobIndex->mobthac0 = fread_number( fp ); pMobIndex->ac = fread_number( fp ); pMobIndex->hitnodice = fread_number( fp ); /* * 'd' */ fread_letter( fp ); pMobIndex->hitsizedice = fread_number( fp ); /* * '+' */ fread_letter( fp ); pMobIndex->hitplus = fread_number( fp ); pMobIndex->damnodice = fread_number( fp ); /* * 'd' */ fread_letter( fp ); pMobIndex->damsizedice = fread_number( fp ); /* * '+' */ fread_letter( fp ); pMobIndex->damplus = fread_number( fp ); /* * pMobIndex->gold = */ fread_number( fp ); /* * All mobs should use the rtg -Goku 09.28.04 */ pMobIndex->gold = -1; pMobIndex->exp = fread_number_ld( fp ); /* * pMobIndex->position = fread_number( fp ); */ pMobIndex->position = fread_number( fp ); if( pMobIndex->position < 100 ) { switch ( pMobIndex->position ) { default: case 0: case 1: case 2: case 3: case 4: break; case 5: pMobIndex->position = 6; break; case 6: pMobIndex->position = 8; break; case 7: pMobIndex->position = 9; break; case 8: pMobIndex->position = 12; break; case 9: pMobIndex->position = 13; break; case 10: pMobIndex->position = 14; break; case 11: pMobIndex->position = 15; break; } } else { pMobIndex->position -= 100; } /* * pMobIndex->defposition = fread_number( fp ); */ pMobIndex->defposition = fread_number( fp ); if( pMobIndex->defposition < 100 ) { switch ( pMobIndex->defposition ) { default: case 0: case 1: case 2: case 3: case 4: break; case 5: pMobIndex->defposition = 6; break; case 6: pMobIndex->defposition = 8; break; case 7: pMobIndex->defposition = 9; break; case 8: pMobIndex->defposition = 12; break; case 9: pMobIndex->defposition = 13; break; case 10: pMobIndex->defposition = 14; break; case 11: pMobIndex->defposition = 15; break; } } else { pMobIndex->defposition -= 100; } /* * Back to meaningful values. */ pMobIndex->sex = fread_number( fp ); if( letter != 'S' && letter != 'C' ) { bug( "Load_mobiles: vnum %d: letter '%c' not S or C.", vnum, letter ); shutdown_mud( "bad mob data" ); exit( 1 ); } if( letter == 'C' ) /* Realms complex mob -Thoric */ { if( area_version < 250 ) { pMobIndex->perm_str = fread_number( fp ); pMobIndex->perm_int = fread_number( fp ); pMobIndex->perm_dex = fread_number( fp ); pMobIndex->perm_dex = fread_number( fp ); pMobIndex->perm_con = fread_number( fp ); pMobIndex->perm_lck = fread_number( fp ); pMobIndex->perm_lck = fread_number( fp ); } else { pMobIndex->perm_str = fread_number( fp ); pMobIndex->perm_int = fread_number( fp ); pMobIndex->perm_dex = fread_number( fp ); pMobIndex->perm_con = fread_number( fp ); pMobIndex->perm_lck = fread_number( fp ); } pMobIndex->saving_poison_death = fread_number( fp ); pMobIndex->saving_wand = fread_number( fp ); pMobIndex->saving_para_petri = fread_number( fp ); pMobIndex->saving_breath = fread_number( fp ); pMobIndex->saving_spell_staff = fread_number( fp ); ln = fread_line( fp ); x1 = x2 = x3 = x4 = x5 = x6 = x7 = x8 = 0; sscanf( ln, "%d %d %d %d %d %d %d", &x1, &x2, &x3, &x4, &x5, &x6, &x7 ); pMobIndex->race = x1; pMobIndex->class = x2; pMobIndex->height = x3; pMobIndex->weight = x4; pMobIndex->speaks = x5; pMobIndex->speaking = x6; pMobIndex->numattacks = x7; /* * Thanks to Nick Gammon for noticing this. * if ( !pMobIndex->speaks ) * pMobIndex->speaks = race_table[pMobIndex->race]->language | LANG_COMMON; * if ( !pMobIndex->speaking ) * pMobIndex->speaking = race_table[pMobIndex->race]->language; */ if( !pMobIndex->speaks ) pMobIndex->speaks = LANG_COMMON; if( !pMobIndex->speaking ) pMobIndex->speaking = LANG_COMMON; #ifndef XBI ln = fread_line( fp ); x1 = x2 = x3 = x4 = x5 = x6 = x7 = x8 = 0; sscanf( ln, "%d %d %d %d %d %d %d %d", &x1, &x2, &x3, &x4, &x5, &x6, &x7, &x8 ); pMobIndex->hitroll = x1; pMobIndex->damroll = x2; pMobIndex->xflags = x3; pMobIndex->resistant = x4; pMobIndex->immune = x5; pMobIndex->susceptible = x6; pMobIndex->attacks = x7; pMobIndex->defenses = x8; #else pMobIndex->hitroll = fread_number( fp ); pMobIndex->damroll = fread_number( fp ); pMobIndex->xflags = fread_number( fp ); pMobIndex->resistant = fread_number( fp ); pMobIndex->immune = fread_number( fp ); pMobIndex->susceptible = fread_number( fp ); pMobIndex->attacks = fread_bitvector( fp ); pMobIndex->defenses = fread_bitvector( fp ); #endif } else { pMobIndex->perm_str = 10; pMobIndex->perm_dex = 10; pMobIndex->perm_int = 10; pMobIndex->perm_con = 10; pMobIndex->perm_lck = 10; pMobIndex->race = 0; pMobIndex->class = 0; pMobIndex->xflags = 0; pMobIndex->resistant = 0; pMobIndex->immune = 0; pMobIndex->susceptible = 0; pMobIndex->numattacks = 0; #ifdef XBI xCLEAR_BITS( pMobIndex->attacks ); xCLEAR_BITS( pMobIndex->defenses ); #else pMobIndex->attacks = 0; pMobIndex->defenses = 0; #endif } letter = fread_letter( fp ); if( letter == '>' ) { ungetc( letter, fp ); mprog_read_programs( fp, pMobIndex ); } else ungetc( letter, fp ); if( !oldmob ) { iHash = vnum % MAX_KEY_HASH; pMobIndex->next = mob_index_hash[iHash]; mob_index_hash[iHash] = pMobIndex; top_mob_index++; } } return; } /* * Load an obj section. */ void load_objects( AREA_DATA * tarea, FILE * fp ) { OBJ_INDEX_DATA *pObjIndex; char letter; char *ln; int x1, x2, x3, x4, x5, x6; if( !tarea ) { bug( "Load_objects: no #AREA seen yet." ); if( fBootDb ) { shutdown_mud( "No #AREA" ); exit( 1 ); } else return; } for( ;; ) { char buf[MAX_STRING_LENGTH]; int vnum; int iHash; bool tmpBootDb; bool oldobj; letter = fread_letter( fp ); if( letter != '#' ) { bug( "Load_objects: # not found." ); if( fBootDb ) { shutdown_mud( "# not found" ); exit( 1 ); } else return; } vnum = fread_number( fp ); if( vnum == 0 ) break; tmpBootDb = fBootDb; fBootDb = FALSE; if( get_obj_index( vnum ) ) { if( tmpBootDb ) { bug( "Load_objects: vnum %d duplicated.", vnum ); shutdown_mud( "duplicate vnum" ); exit( 1 ); } else { pObjIndex = get_obj_index( vnum ); sprintf( buf, "Cleaning object: %d", vnum ); log_string_plus( buf, LOG_BUILD, sysdata.log_level ); clean_obj( pObjIndex ); oldobj = TRUE; } } else { oldobj = FALSE; CREATE( pObjIndex, OBJ_INDEX_DATA, 1 ); } fBootDb = tmpBootDb; pObjIndex->vnum = vnum; if( fBootDb ) { if( !tarea->low_o_vnum ) tarea->low_o_vnum = vnum; if( vnum > tarea->hi_o_vnum ) tarea->hi_o_vnum = vnum; } pObjIndex->name = fread_string( fp ); pObjIndex->short_descr = fread_string( fp ); pObjIndex->description = fread_string( fp ); pObjIndex->action_desc = fread_string( fp ); /* * Commented out by Narn, Apr/96 to allow item short descs like * Bonecrusher and Oblivion */ /* * pObjIndex->short_descr[0] = LOWER(pObjIndex->short_descr[0]); */ pObjIndex->description[0] = UPPER( pObjIndex->description[0] ); pObjIndex->item_type = fread_number( fp ); pObjIndex->extra_flags = fread_bitvector( fp ); ln = fread_line( fp ); x1 = x2 = 0; sscanf( ln, "%d %d", &x1, &x2 ); pObjIndex->wear_flags = x1; pObjIndex->layers = x2; ln = fread_line( fp ); x1 = x2 = x3 = x4 = x5 = x6 = 0; sscanf( ln, "%d %d %d %d %d %d", &x1, &x2, &x3, &x4, &x5, &x6 ); pObjIndex->value[0] = x1; pObjIndex->value[1] = x2; pObjIndex->value[2] = x3; pObjIndex->value[3] = x4; pObjIndex->value[4] = x5; pObjIndex->value[5] = x6; if( area_version < 251 ) { ln = fread_line( fp ); x1 = x2 = x3 = x4 = 0; sscanf( ln, "%d %d %d %d", &x1, &x2, &x3, &x4 ); pObjIndex->weight = x1; pObjIndex->weight = UMAX( 1, pObjIndex->weight ); pObjIndex->cost = x2; pObjIndex->rent = x3; /* unused */ pObjIndex->level = x4; } else { ln = fread_line( fp ); x1 = x2 = x3 = 0; sscanf( ln, "%d %d %d", &x1, &x2, &x3 ); pObjIndex->weight = x1; pObjIndex->weight = UMAX( 1, pObjIndex->weight ); pObjIndex->cost = x2; pObjIndex->rent = x3; /* unused */ pObjIndex->level = fread_number_ld( fp ); } if( area_version >= 1 ) { switch ( pObjIndex->item_type ) { case ITEM_PILL: case ITEM_POTION: case ITEM_SCROLL: pObjIndex->value[1] = skill_lookup( fread_word( fp ) ); pObjIndex->value[2] = skill_lookup( fread_word( fp ) ); pObjIndex->value[3] = skill_lookup( fread_word( fp ) ); break; case ITEM_STAFF: case ITEM_WAND: pObjIndex->value[3] = skill_lookup( fread_word( fp ) ); break; case ITEM_SALVE: pObjIndex->value[4] = skill_lookup( fread_word( fp ) ); pObjIndex->value[5] = skill_lookup( fread_word( fp ) ); break; } } for( ;; ) { letter = fread_letter( fp ); if( letter == 'A' ) { AFFECT_DATA *paf; CREATE( paf, AFFECT_DATA, 1 ); paf->type = -1; paf->duration = -1; paf->location = fread_number( fp ); if( paf->location == APPLY_WEAPONSPELL || paf->location == APPLY_WEARSPELL || paf->location == APPLY_REMOVESPELL || paf->location == APPLY_STRIPSN || paf->location == APPLY_RECURRINGSPELL ) paf->modifier = slot_lookup( fread_number( fp ) ); else paf->modifier = fread_number( fp ); xCLEAR_BITS( paf->bitvector ); LINK( paf, pObjIndex->first_affect, pObjIndex->last_affect, next, prev ); top_affect++; } else if( letter == 'E' ) { EXTRA_DESCR_DATA *ed; CREATE( ed, EXTRA_DESCR_DATA, 1 ); ed->keyword = fread_string( fp ); ed->description = fread_string( fp ); LINK( ed, pObjIndex->first_extradesc, pObjIndex->last_extradesc, next, prev ); top_ed++; } else if( letter == '>' ) { ungetc( letter, fp ); oprog_read_programs( fp, pObjIndex ); } else { ungetc( letter, fp ); break; } } /* * Translate spell "slot numbers" to internal "skill numbers." */ if( area_version == 0 ) switch ( pObjIndex->item_type ) { case ITEM_PILL: case ITEM_POTION: case ITEM_SCROLL: pObjIndex->value[1] = slot_lookup( pObjIndex->value[1] ); pObjIndex->value[2] = slot_lookup( pObjIndex->value[2] ); pObjIndex->value[3] = slot_lookup( pObjIndex->value[3] ); break; case ITEM_STAFF: case ITEM_WAND: pObjIndex->value[3] = slot_lookup( pObjIndex->value[3] ); break; case ITEM_SALVE: pObjIndex->value[4] = slot_lookup( pObjIndex->value[4] ); pObjIndex->value[5] = slot_lookup( pObjIndex->value[5] ); break; } if( !oldobj ) { iHash = vnum % MAX_KEY_HASH; pObjIndex->next = obj_index_hash[iHash]; obj_index_hash[iHash] = pObjIndex; top_obj_index++; } } return; } /* * Load a reset section. */ void load_resets( AREA_DATA * tarea, FILE * fp ) { char buf[MAX_STRING_LENGTH]; bool not01 = FALSE; int count = 0; if( !tarea ) { bug( "Load_resets: no #AREA seen yet." ); if( fBootDb ) { shutdown_mud( "No #AREA" ); exit( 1 ); } else return; } if( tarea->first_reset ) { if( fBootDb ) { RESET_DATA *rtmp; bug( "load_resets: WARNING: resets already exist for this area." ); for( rtmp = tarea->first_reset; rtmp; rtmp = rtmp->next ) ++count; } else { /* * Clean out the old resets */ sprintf( buf, "Cleaning resets: %s", tarea->name ); log_string_plus( buf, LOG_BUILD, sysdata.log_level ); clean_resets( tarea ); } } for( ;; ) { ROOM_INDEX_DATA *pRoomIndex; EXIT_DATA *pexit; char letter; int extra, arg1, arg2, arg3; if( ( letter = fread_letter( fp ) ) == 'S' ) break; if( letter == '*' ) { fread_to_eol( fp ); continue; } extra = fread_number( fp ); arg1 = fread_number( fp ); arg2 = fread_number( fp ); if( letter == 'E' ) arg2 = 1; arg3 = ( letter == 'G' || letter == 'R' ) ? 0 : fread_number( fp ); fread_to_eol( fp ); ++count; /* * Validate parameters. * We're calling the index functions for the side effect. */ switch ( letter ) { default: bug( "Load_resets: bad command '%c'.", letter ); if( fBootDb ) boot_log( "Load_resets: %s (%d) bad command '%c'.", tarea->filename, count, letter ); return; case 'M': if( get_mob_index( arg1 ) == NULL && fBootDb ) boot_log( "Load_resets: %s (%d) 'M': mobile %d doesn't exist.", tarea->filename, count, arg1 ); if( get_room_index( arg3 ) == NULL && fBootDb ) boot_log( "Load_resets: %s (%d) 'M': room %d doesn't exist.", tarea->filename, count, arg3 ); break; case 'O': if( get_obj_index( arg1 ) == NULL && fBootDb ) boot_log( "Load_resets: %s (%d) '%c': object %d doesn't exist.", tarea->filename, count, letter, arg1 ); if( get_room_index( arg3 ) == NULL && fBootDb ) boot_log( "Load_resets: %s (%d) '%c': room %d doesn't exist.", tarea->filename, count, letter, arg3 ); break; case 'P': if( get_obj_index( arg1 ) == NULL && fBootDb ) boot_log( "Load_resets: %s (%d) '%c': object %d doesn't exist.", tarea->filename, count, letter, arg1 ); if( arg3 > 0 ) { if( get_obj_index( arg3 ) == NULL && fBootDb ) boot_log( "Load_resets: %s (%d) 'P': destination object %d doesn't exist.", tarea->filename, count, arg3 ); } else { if( extra > 1 ) not01 = TRUE; } break; case 'G': case 'E': if( get_obj_index( arg1 ) == NULL && fBootDb ) boot_log( "Load_resets: %s (%d) '%c': object %d doesn't exist.", tarea->filename, count, letter, arg1 ); break; case 'T': break; case 'H': if( arg1 > 0 ) if( get_obj_index( arg1 ) == NULL && fBootDb ) boot_log( "Load_resets: %s (%d) 'H': object %d doesn't exist.", tarea->filename, count, arg1 ); break; case 'B': switch ( arg2 & BIT_RESET_TYPE_MASK ) { case BIT_RESET_DOOR: { int door; pRoomIndex = get_room_index( arg1 ); if( !pRoomIndex ) { bug( "Load_resets: 'B': room %d doesn't exist.", arg1 ); bug( "Reset: %c %d %d %d %d", letter, extra, arg1, arg2, arg3 ); if( fBootDb ) boot_log( "Load_resets: %s (%d) 'B': room %d doesn't exist.", tarea->filename, count, arg1 ); } door = ( arg2 & BIT_RESET_DOOR_MASK ) >> BIT_RESET_DOOR_THRESHOLD; if( !( pexit = get_exit( pRoomIndex, door ) ) ) { bug( "Load_resets: 'B': exit %d not door.", door ); bug( "Reset: %c %d %d %d %d", letter, extra, arg1, arg2, arg3 ); if( fBootDb ) boot_log( "Load_resets: %s (%d) 'B': exit %d not door.", tarea->filename, count, door ); } } break; case BIT_RESET_ROOM: if( get_room_index( arg1 ) == NULL ) { bug( "Load_resets: 'B': room %d doesn't exist.", arg1 ); bug( "Reset: %c %d %d %d %d", letter, extra, arg1, arg2, arg3 ); if( fBootDb ) boot_log( "Load_resets: %s (%d) 'B': room %d doesn't exist.", tarea->filename, count, arg1 ); } break; case BIT_RESET_OBJECT: if( arg1 > 0 ) if( get_obj_index( arg1 ) == NULL && fBootDb ) boot_log( "Load_resets: %s (%d) 'B': object %d doesn't exist.", tarea->filename, count, arg1 ); break; case BIT_RESET_MOBILE: if( arg1 > 0 ) if( get_mob_index( arg1 ) == NULL && fBootDb ) boot_log( "Load_resets: %s (%d) 'B': mobile %d doesn't exist.", tarea->filename, count, arg1 ); break; default: boot_log( "Load_resets: %s (%d) 'B': bad type flag (%d).", tarea->filename, count, arg2 & BIT_RESET_TYPE_MASK ); break; } break; case 'D': pRoomIndex = get_room_index( arg1 ); if( !pRoomIndex ) { bug( "Load_resets: 'D': room %d doesn't exist.", arg1 ); bug( "Reset: %c %d %d %d %d", letter, extra, arg1, arg2, arg3 ); if( fBootDb ) boot_log( "Load_resets: %s (%d) 'D': room %d doesn't exist.", tarea->filename, count, arg1 ); break; } if( arg2 < 0 || arg2 > MAX_DIR + 1 || ( pexit = get_exit( pRoomIndex, arg2 ) ) == NULL || !IS_SET( pexit->exit_info, EX_ISDOOR ) ) { bug( "Load_resets: 'D': exit %d not door.", arg2 ); bug( "Reset: %c %d %d %d %d", letter, extra, arg1, arg2, arg3 ); if( fBootDb ) boot_log( "Load_resets: %s (%d) 'D': exit %d not door.", tarea->filename, count, arg2 ); } if( arg3 < 0 || arg3 > 2 ) { bug( "Load_resets: 'D': bad 'locks': %d.", arg3 ); if( fBootDb ) boot_log( "Load_resets: %s (%d) 'D': bad 'locks': %d.", tarea->filename, count, arg3 ); } break; case 'R': pRoomIndex = get_room_index( arg1 ); if( !pRoomIndex && fBootDb ) boot_log( "Load_resets: %s (%d) 'R': room %d doesn't exist.", tarea->filename, count, arg1 ); if( arg2 < 0 || arg2 > 10 ) { bug( "Load_resets: 'R': bad exit %d.", arg2 ); if( fBootDb ) boot_log( "Load_resets: %s (%d) 'R': bad exit %d.", tarea->filename, count, arg2 ); break; } break; } /* * finally, add the reset */ add_reset( tarea, letter, extra, arg1, arg2, arg3 ); } if( !not01 ) renumber_put_resets( tarea ); return; } /* * Load a room section. */ void load_rooms( AREA_DATA * tarea, FILE * fp ) { ROOM_INDEX_DATA *pRoomIndex; char buf[MAX_STRING_LENGTH]; char *ln; if( !tarea ) { bug( "Load_rooms: no #AREA seen yet." ); shutdown_mud( "No #AREA" ); exit( 1 ); } for( ;; ) { int vnum; char letter; int door; int iHash; bool tmpBootDb; bool oldroom; int x1, x2, x3, x4, x5, x6; letter = fread_letter( fp ); if( letter != '#' ) { bug( "Load_rooms: # not found." ); if( fBootDb ) { shutdown_mud( "# not found" ); exit( 1 ); } else return; } vnum = fread_number( fp ); if( vnum == 0 ) break; tmpBootDb = fBootDb; fBootDb = FALSE; if( get_room_index( vnum ) != NULL ) { if( tmpBootDb ) { bug( "Load_rooms: vnum %d duplicated.", vnum ); shutdown_mud( "duplicate vnum" ); exit( 1 ); } else { pRoomIndex = get_room_index( vnum ); sprintf( buf, "Cleaning room: %d", vnum ); log_string_plus( buf, LOG_BUILD, sysdata.log_level ); clean_room( pRoomIndex ); oldroom = TRUE; } } else { oldroom = FALSE; CREATE( pRoomIndex, ROOM_INDEX_DATA, 1 ); pRoomIndex->first_person = NULL; pRoomIndex->last_person = NULL; pRoomIndex->first_content = NULL; pRoomIndex->last_content = NULL; } fBootDb = tmpBootDb; pRoomIndex->area = tarea; pRoomIndex->vnum = vnum; pRoomIndex->first_extradesc = NULL; pRoomIndex->last_extradesc = NULL; if( fBootDb ) { if( !tarea->low_r_vnum ) tarea->low_r_vnum = vnum; if( vnum > tarea->hi_r_vnum ) tarea->hi_r_vnum = vnum; } pRoomIndex->name = fread_string( fp ); pRoomIndex->description = fread_string_wspace( fp ); /* * Area number fread_number( fp ); */ x1 = x2 = x3 = x4 = x5 = x6 = 0; fread_number( fp ); pRoomIndex->room_flags = fread_bitvector( fp ); ln = fread_line( fp ); sscanf( ln, "%d %d %d %d", &x3, &x4, &x5, &x6 ); pRoomIndex->sector_type = x3; pRoomIndex->tele_delay = x4; pRoomIndex->tele_vnum = x5; pRoomIndex->tunnel = x6; if( pRoomIndex->sector_type < 0 || pRoomIndex->sector_type == SECT_MAX ) { bug( "Fread_rooms: vnum %d has bad sector_type %d.", vnum, pRoomIndex->sector_type ); pRoomIndex->sector_type = 1; } pRoomIndex->light = 0; pRoomIndex->first_exit = NULL; pRoomIndex->last_exit = NULL; for( ;; ) { letter = fread_letter( fp ); if( letter == 'S' ) break; if( letter == 'D' ) { EXIT_DATA *pexit; int locks; door = fread_number( fp ); if( door < 0 || door > 10 ) { bug( "Fread_rooms: vnum %d has bad door number %d.", vnum, door ); if( fBootDb ) exit( 1 ); } else { pexit = make_exit( pRoomIndex, NULL, door ); pexit->description = fread_string( fp ); pexit->keyword = fread_string( fp ); pexit->exit_info = 0; ln = fread_line( fp ); x1 = x2 = x3 = x4 = x5 = x6 = 0; sscanf( ln, "%d %d %d %d %d %d", &x1, &x2, &x3, &x4, &x5, &x6 ); locks = x1; pexit->key = x2; pexit->vnum = x3; pexit->vdir = door; pexit->distance = x4; pexit->pulltype = x5; pexit->pull = x6; switch ( locks ) { case 1: pexit->exit_info = EX_ISDOOR; break; case 2: pexit->exit_info = EX_ISDOOR | EX_PICKPROOF; break; default: pexit->exit_info = locks; } } } else if( letter == 'E' ) { EXTRA_DESCR_DATA *ed; CREATE( ed, EXTRA_DESCR_DATA, 1 ); ed->keyword = fread_string( fp ); ed->description = fread_string( fp ); LINK( ed, pRoomIndex->first_extradesc, pRoomIndex->last_extradesc, next, prev ); top_ed++; } else if( letter == 'M' ) /* maps */ { MAP_DATA *map; MAP_INDEX_DATA *map_index; int i, j; CREATE( map, MAP_DATA, 1 ); map->vnum = fread_number( fp ); map->x = fread_number( fp ); map->y = fread_number( fp ); map->entry = fread_letter( fp ); pRoomIndex->map = map; if( ( map_index = get_map_index( map->vnum ) ) == NULL ) { CREATE( map_index, MAP_INDEX_DATA, 1 ); map_index->vnum = map->vnum; map_index->next = first_map; first_map = map_index; for( i = 0; i < 49; i++ ) { for( j = 0; j < 79; j++ ) { map_index->map_of_vnums[i][j] = -1; /* * map_index->map_of_ptrs[i][j] = NULL; */ } } } if( ( map->y < 0 ) || ( map->y > 48 ) ) { bug( "Map y coord out of range. Room %d\n\r", map->y ); } if( ( map->x < 0 ) || ( map->x > 78 ) ) { bug( "Map x coord out of range. Room %d\n\r", map->x ); } if( ( map->x > 0 ) && ( map->x < 80 ) && ( map->y > 0 ) && ( map->y < 48 ) ) map_index->map_of_vnums[map->y][map->x] = pRoomIndex->vnum; } else if( letter == '>' ) { ungetc( letter, fp ); rprog_read_programs( fp, pRoomIndex ); } else { bug( "Load_rooms: vnum %d has flag '%c' not 'DES'.", vnum, letter ); shutdown_mud( "Room flag not DES" ); exit( 1 ); } } if( !oldroom ) { iHash = vnum % MAX_KEY_HASH; pRoomIndex->next = room_index_hash[iHash]; room_index_hash[iHash] = pRoomIndex; top_room++; } } return; } /* * Load a shop section. */ void load_shops( AREA_DATA * tarea, FILE * fp ) { SHOP_DATA *pShop; for( ;; ) { MOB_INDEX_DATA *pMobIndex; int iTrade; CREATE( pShop, SHOP_DATA, 1 ); pShop->keeper = fread_number( fp ); if( pShop->keeper == 0 ) { DISPOSE( pShop ); break; } for( iTrade = 0; iTrade < MAX_TRADE; iTrade++ ) pShop->buy_type[iTrade] = fread_number( fp ); pShop->profit_buy = fread_number( fp ); pShop->profit_sell = fread_number( fp ); pShop->profit_buy = URANGE( pShop->profit_sell + 5, pShop->profit_buy, 1000 ); pShop->profit_sell = URANGE( 0, pShop->profit_sell, pShop->profit_buy - 5 ); pShop->open_hour = fread_number( fp ); pShop->close_hour = fread_number( fp ); fread_to_eol( fp ); pMobIndex = get_mob_index( pShop->keeper ); pMobIndex->pShop = pShop; if( !first_shop ) first_shop = pShop; else last_shop->next = pShop; pShop->next = NULL; pShop->prev = last_shop; last_shop = pShop; top_shop++; } return; } /* * Load a repair shop section. -Thoric */ void load_repairs( AREA_DATA * tarea, FILE * fp ) { REPAIR_DATA *rShop; for( ;; ) { MOB_INDEX_DATA *pMobIndex; int iFix; CREATE( rShop, REPAIR_DATA, 1 ); rShop->keeper = fread_number( fp ); if( rShop->keeper == 0 ) { DISPOSE( rShop ); break; } for( iFix = 0; iFix < MAX_FIX; iFix++ ) rShop->fix_type[iFix] = fread_number( fp ); rShop->profit_fix = fread_number( fp ); rShop->shop_type = fread_number( fp ); rShop->open_hour = fread_number( fp ); rShop->close_hour = fread_number( fp ); fread_to_eol( fp ); pMobIndex = get_mob_index( rShop->keeper ); pMobIndex->rShop = rShop; if( !first_repair ) first_repair = rShop; else last_repair->next = rShop; rShop->next = NULL; rShop->prev = last_repair; last_repair = rShop; top_repair++; } return; } /* * Load spec proc declarations. */ void load_specials( AREA_DATA * tarea, FILE * fp ) { for( ;; ) { MOB_INDEX_DATA *pMobIndex; char letter; switch ( letter = fread_letter( fp ) ) { default: bug( "Load_specials: letter '%c' not *MS.", letter ); exit( 1 ); case 'S': return; case '*': break; case 'M': pMobIndex = get_mob_index( fread_number( fp ) ); pMobIndex->spec_fun = spec_lookup( fread_word( fp ) ); if( pMobIndex->spec_fun == 0 ) { bug( "Load_specials: 'M': vnum %d.", pMobIndex->vnum ); exit( 1 ); } break; } fread_to_eol( fp ); } } /* * Load soft / hard area ranges. */ void load_ranges( AREA_DATA * tarea, FILE * fp ) { int x1, x2, x3, x4; char *ln; if( !tarea ) { bug( "Load_ranges: no #AREA seen yet." ); shutdown_mud( "No #AREA" ); exit( 1 ); } for( ;; ) { ln = fread_line( fp ); if( ln[0] == '$' ) break; x1 = x2 = x3 = x4 = 0; sscanf( ln, "%d %d %d %d", &x1, &x2, &x3, &x4 ); tarea->low_soft_range = x1; tarea->hi_soft_range = x2; tarea->low_hard_range = x3; tarea->hi_hard_range = x4; } return; } /* * Load climate information for the area * Last modified: July 13, 1997 * Fireblade */ void load_climate( AREA_DATA * tarea, FILE * fp ) { if( !tarea ) { bug( "load_climate: no #AREA seen yet" ); if( fBootDb ) { shutdown_mud( "No #AREA" ); exit( 1 ); } else return; } tarea->weather->climate_temp = fread_number( fp ); tarea->weather->climate_precip = fread_number( fp ); tarea->weather->climate_wind = fread_number( fp ); return; } /* * Load data for a neghboring weather system * Last modified: July 13, 1997 * Fireblade */ void load_neighbor( AREA_DATA * tarea, FILE * fp ) { NEIGHBOR_DATA *new; if( !tarea ) { bug( "load_neighbor: no #AREA seen yet." ); if( fBootDb ) { shutdown_mud( "No #AREA" ); exit( 1 ); } else return; } CREATE( new, NEIGHBOR_DATA, 1 ); new->next = NULL; new->prev = NULL; new->address = NULL; new->name = fread_string( fp ); LINK( new, tarea->weather->first_neighbor, tarea->weather->last_neighbor, next, prev ); return; } /* * Go through all areas, and set up initial economy based on mob * levels and gold */ void initialize_economy( void ) { AREA_DATA *tarea; int low_random = 10000; // 10k int high_random = 10000000; // 10m for( tarea = first_area; tarea; tarea = tarea->next ) { /* * skip area if they already got some gold */ if( tarea->economy > low_random ) continue; boost_economy( tarea, number_range( low_random, high_random ) ); } } /* * Translate all room exits from virtual to real. * Has to be done after all rooms are read in. * Check for bad reverse exits. */ void fix_exits( void ) { ROOM_INDEX_DATA *pRoomIndex; EXIT_DATA *pexit, *pexit_next, *rev_exit; int iHash; for( iHash = 0; iHash < MAX_KEY_HASH; iHash++ ) { for( pRoomIndex = room_index_hash[iHash]; pRoomIndex; pRoomIndex = pRoomIndex->next ) { bool fexit; fexit = FALSE; for( pexit = pRoomIndex->first_exit; pexit; pexit = pexit_next ) { pexit_next = pexit->next; pexit->rvnum = pRoomIndex->vnum; if( pexit->vnum <= 0 || ( pexit->to_room = get_room_index( pexit->vnum ) ) == NULL ) { if( fBootDb ) boot_log( "Fix_exits: room %d, exit %s leads to bad vnum (%d)", pRoomIndex->vnum, dir_name[pexit->vdir], pexit->vnum ); bug( "Deleting %s exit in room %d", dir_name[pexit->vdir], pRoomIndex->vnum ); extract_exit( pRoomIndex, pexit ); } else fexit = TRUE; } if( !fexit ) xSET_BIT( pRoomIndex->room_flags, ROOM_NO_MOB ); } } /* * Set all the rexit pointers -Thoric */ for( iHash = 0; iHash < MAX_KEY_HASH; iHash++ ) { for( pRoomIndex = room_index_hash[iHash]; pRoomIndex; pRoomIndex = pRoomIndex->next ) { for( pexit = pRoomIndex->first_exit; pexit; pexit = pexit->next ) { if( pexit->to_room && !pexit->rexit ) { rev_exit = get_exit_to( pexit->to_room, rev_dir[pexit->vdir], pRoomIndex->vnum ); if( rev_exit ) { pexit->rexit = rev_exit; rev_exit->rexit = pexit; } } } } } return; } /* * Get diku-compatable exit by number -Thoric */ EXIT_DATA *get_exit_number( ROOM_INDEX_DATA * room, int xit ) { EXIT_DATA *pexit; int count; count = 0; for( pexit = room->first_exit; pexit; pexit = pexit->next ) if( ++count == xit ) return pexit; return NULL; } /* * (prelude...) This is going to be fun... NOT! * (conclusion) QSort is f*cked! */ int exit_comp( EXIT_DATA ** xit1, EXIT_DATA ** xit2 ) { int d1, d2; d1 = ( *xit1 )->vdir; d2 = ( *xit2 )->vdir; if( d1 < d2 ) return -1; if( d1 > d2 ) return 1; return 0; } void sort_exits( ROOM_INDEX_DATA * room ) { EXIT_DATA *pexit; /* *texit *//* Unused */ EXIT_DATA *exits[MAX_REXITS]; int x, nexits; nexits = 0; for( pexit = room->first_exit; pexit; pexit = pexit->next ) { exits[nexits++] = pexit; if( nexits > MAX_REXITS ) { bug( "sort_exits: more than %d exits in room... fatal", nexits ); return; } } qsort( &exits[0], nexits, sizeof( EXIT_DATA * ), ( int ( * )( const void *, const void * ) )exit_comp ); for( x = 0; x < nexits; x++ ) { if( x > 0 ) exits[x]->prev = exits[x - 1]; else { exits[x]->prev = NULL; room->first_exit = exits[x]; } if( x >= ( nexits - 1 ) ) { exits[x]->next = NULL; room->last_exit = exits[x]; } else exits[x]->next = exits[x + 1]; } } void randomize_exits( ROOM_INDEX_DATA * room, sh_int maxdir ) { EXIT_DATA *pexit; int nexits, /* maxd, */ d0, d1, count, door; /* Maxd unused */ int vdirs[MAX_REXITS]; nexits = 0; for( pexit = room->first_exit; pexit; pexit = pexit->next ) vdirs[nexits++] = pexit->vdir; for( d0 = 0; d0 < nexits; d0++ ) { if( vdirs[d0] > maxdir ) continue; count = 0; while( vdirs[( d1 = number_range( d0, nexits - 1 ) )] > maxdir || ++count > 5 ); if( vdirs[d1] > maxdir ) continue; door = vdirs[d0]; vdirs[d0] = vdirs[d1]; vdirs[d1] = door; } count = 0; for( pexit = room->first_exit; pexit; pexit = pexit->next ) pexit->vdir = vdirs[count++]; sort_exits( room ); } /* * Repopulate areas periodically. */ void area_update( void ) { AREA_DATA *pArea; for( pArea = first_area; pArea; pArea = pArea->next ) { CHAR_DATA *pch; int reset_age = pArea->reset_frequency ? pArea->reset_frequency : 15; if( ( reset_age == -1 && pArea->age == -1 ) || ++pArea->age < ( reset_age - 1 ) ) continue; /* * Check for PC's. */ if( pArea->nplayer > 0 && pArea->age == ( reset_age - 1 ) ) { char buf[MAX_STRING_LENGTH]; /* * Rennard */ if( pArea->resetmsg ) sprintf( buf, "%s\n\r", pArea->resetmsg ); else strcpy( buf, "You hear some squeaking sounds...\n\r" ); for( pch = first_char; pch; pch = pch->next ) { if( !IS_NPC( pch ) && IS_AWAKE( pch ) && pch->in_room && pch->in_room->area == pArea ) { set_char_color( AT_RESET, pch ); send_to_char( buf, pch ); } } } /* * Check age and reset. * Note: Mud Academy resets every 3 minutes (not 15). */ if( pArea->nplayer == 0 || pArea->age >= reset_age ) { ROOM_INDEX_DATA *pRoomIndex; fprintf( stderr, "Resetting: %s\n", pArea->filename ); reset_area( pArea ); if( reset_age == -1 ) pArea->age = -1; else pArea->age = number_range( 0, reset_age / 5 ); pRoomIndex = get_room_index( ROOM_VNUM_SCHOOL ); if( pRoomIndex != NULL && pArea == pRoomIndex->area && pArea->reset_frequency == 0 ) pArea->age = 15 - 3; } } return; } /* * Create an instance of a mobile. */ CHAR_DATA *create_mobile( MOB_INDEX_DATA * pMobIndex ) { CHAR_DATA *mob; if( !pMobIndex ) { bug( "Create_mobile: NULL pMobIndex." ); exit( 1 ); } CREATE( mob, CHAR_DATA, 1 ); clear_char( mob ); mob->pIndexData = pMobIndex; mob->mob_serial = -1; mob->editor = NULL; mob->name = QUICKLINK( pMobIndex->player_name ); mob->short_descr = QUICKLINK( pMobIndex->short_descr ); mob->long_descr = QUICKLINK( pMobIndex->long_descr ); mob->description = QUICKLINK( pMobIndex->description ); mob->spec_fun = pMobIndex->spec_fun; mob->mpscriptpos = 0; mob->level = number_fuzzy( pMobIndex->level ); mob->act = pMobIndex->act; if( xIS_SET( mob->act, ACT_MOBINVIS ) ) mob->mobinvis = mob->level; mob->affected_by = pMobIndex->affected_by; mob->alignment = pMobIndex->alignment; mob->sex = pMobIndex->sex; /* * Bug fix from mailing list by stu (sprice@ihug.co.nz) * was: if ( !pMobIndex->ac ) */ if( pMobIndex->ac ) mob->armor = pMobIndex->ac; else mob->armor = 100; if( !pMobIndex->hitnodice ) /* mob->max_hit = mob->level * 8 + number_range( mob->level * mob->level / 4, mob->level * mob->level ); else mob->max_hit = pMobIndex->hitnodice * number_range(1, pMobIndex->hitsizedice ) + pMobIndex->hitplus; */ mob->max_hit = 100; mob->hit = mob->max_hit; /* * lets put things back the way they used to be! -Thoric */ mob->gold = pMobIndex->gold; if( mob->gold > -1 ) bug( "mob(%d)zeni not -1", pMobIndex->vnum ); mob->exp = pMobIndex->exp; /* * Add's some varity to mobs power level -Goku 09.25.04 */ if( xIS_SET( mob->act, ACT_RANDOMIZE_PL ) ) { switch ( number_range( 1, 10 ) ) { case 1: mob->exp = ( double )number_range( 7500, 9000 ) / 10000 * mob->exp; break; default: mob->exp = ( double )number_range( 9000, 11000 ) / 10000 * mob->exp; break; case 6: case 7: mob->exp = ( double )number_range( 11000, 12000 ) / 10000 * mob->exp; break; case 8: mob->exp = ( double )number_range( 12000, 13000 ) / 10000 * mob->exp; break; case 9: mob->exp = ( double )number_range( 13000, 14000 ) / 10000 * mob->exp; break; case 10: mob->exp = ( double )number_range( 14000, 15000 ) / 10000 * mob->exp; break; } } mob->pl = mob->exp; // New method of setting the mob's mana/energy values if( mob->exp < 1000000 ) { mob->mana = 5000; mob->max_mana = 5000; } else if( mob->exp < 10000000 ) { mob->mana = 10000; mob->max_mana = 10000; } else if( mob->exp < 100000000 ) { mob->mana = 15000; mob->max_mana = 15000; } else if( mob->exp < 1000000000 ) { mob->mana = 25000; mob->max_mana = 25000; } else if( mob->exp < 10000000000ULL ) { mob->mana = 50000; mob->max_mana = 50000; } else { mob->mana = 99999; mob->max_mana = 99999; } mob->position = pMobIndex->position; mob->defposition = pMobIndex->defposition; mob->barenumdie = pMobIndex->damnodice; mob->baresizedie = pMobIndex->damsizedice; mob->mobthac0 = pMobIndex->mobthac0; mob->hitplus = pMobIndex->hitplus; mob->damplus = pMobIndex->damplus; mob->perm_str = pMobIndex->perm_str; mob->perm_dex = pMobIndex->perm_dex; mob->perm_int = pMobIndex->perm_int; mob->perm_con = pMobIndex->perm_con; mob->perm_lck = pMobIndex->perm_lck; mob->hitroll = pMobIndex->hitroll; mob->damroll = pMobIndex->damroll; mob->race = pMobIndex->race; mob->class = pMobIndex->class; mob->xflags = pMobIndex->xflags; mob->saving_poison_death = pMobIndex->saving_poison_death; mob->saving_wand = pMobIndex->saving_wand; mob->saving_para_petri = pMobIndex->saving_para_petri; mob->saving_breath = pMobIndex->saving_breath; mob->saving_spell_staff = pMobIndex->saving_spell_staff; mob->height = pMobIndex->height; mob->weight = pMobIndex->weight; mob->resistant = pMobIndex->resistant; mob->immune = pMobIndex->immune; mob->susceptible = pMobIndex->susceptible; mob->attacks = pMobIndex->attacks; mob->defenses = pMobIndex->defenses; mob->numattacks = pMobIndex->numattacks; mob->speaks = pMobIndex->speaks; mob->speaking = pMobIndex->speaking; /* * Perhaps add this to the index later --Shaddai */ xCLEAR_BITS( mob->no_affected_by ); mob->no_resistant = 0; mob->no_immune = 0; mob->no_susceptible = 0; /* * Insert in list. */ add_char( mob ); pMobIndex->count++; nummobsloaded++; return mob; } OBJ_DATA *create_object( OBJ_INDEX_DATA * pObjIndex, int level ) { OBJ_DATA *obj; char originText[MAX_STRING_LENGTH]; if( !pObjIndex ) { bug( "Create_object: NULL pObjIndex." ); exit( 1 ); } CREATE( obj, OBJ_DATA, 1 ); obj->pIndexData = pObjIndex; obj->in_room = NULL; obj->level = pObjIndex->level; obj->wear_loc = -1; obj->count = 1; cur_obj_serial = UMAX( ( cur_obj_serial + 1 ) & ( BV30 - 1 ), 1 ); obj->serial = obj->pIndexData->serial = cur_obj_serial; obj->name = QUICKLINK( pObjIndex->name ); obj->short_descr = QUICKLINK( pObjIndex->short_descr ); obj->description = QUICKLINK( pObjIndex->description ); obj->action_desc = QUICKLINK( pObjIndex->action_desc ); obj->item_type = pObjIndex->item_type; obj->extra_flags = pObjIndex->extra_flags; obj->wear_flags = pObjIndex->wear_flags; obj->value[0] = pObjIndex->value[0]; obj->value[1] = pObjIndex->value[1]; obj->value[2] = pObjIndex->value[2]; obj->value[3] = pObjIndex->value[3]; obj->value[4] = pObjIndex->value[4]; obj->value[5] = pObjIndex->value[5]; obj->weight = pObjIndex->weight; obj->cost = pObjIndex->cost; sprintf( originText, "%d, UNKNOWN", ORIGIN_DBSCODE ); obj->origin = STRALLOC( originText ); /* * obj->cost = number_fuzzy( 10 ) * * number_fuzzy( level ) * number_fuzzy( level ); */ /* * Mess with object properties. */ switch ( obj->item_type ) { default: bug( "Read_object: vnum %d bad type.", pObjIndex->vnum ); bug( "------------------------> %d ", obj->item_type ); break; case ITEM_LIGHT: case ITEM_SCOUTER: case ITEM_DRAGONBALL: case ITEM_DRAGONRADAR: case ITEM_ARMOR: case ITEM_TREASURE: case ITEM_FURNITURE: case ITEM_TRASH: case ITEM_CONTAINER: case ITEM_DRINK_CON: case ITEM_KEY: case ITEM_KEYRING: case ITEM_ODOR: case ITEM_CHANCE: break; case ITEM_COOK: case ITEM_FOOD: /* * optional food condition (rotting food) -Thoric * value1 is the max condition of the food * value4 is the optional initial condition */ if( obj->value[4] ) obj->timer = obj->value[4]; else obj->timer = obj->value[1]; break; case ITEM_BOAT: case ITEM_CORPSE_NPC: case ITEM_CORPSE_PC: case ITEM_FOUNTAIN: case ITEM_BLOOD: case ITEM_BLOODSTAIN: case ITEM_SCRAPS: case ITEM_PIPE: case ITEM_HERB_CON: case ITEM_HERB: case ITEM_INCENSE: case ITEM_FIRE: case ITEM_BOOK: case ITEM_SWITCH: case ITEM_LEVER: case ITEM_PULLCHAIN: case ITEM_BUTTON: case ITEM_DIAL: case ITEM_RUNE: case ITEM_RUNEPOUCH: case ITEM_MATCH: case ITEM_TRAP: case ITEM_MAP: case ITEM_PORTAL: case ITEM_PAPER: case ITEM_PEN: case ITEM_TINDER: case ITEM_LOCKPICK: case ITEM_SPIKE: case ITEM_DISEASE: case ITEM_OIL: case ITEM_FUEL: case ITEM_QUIVER: case ITEM_SHOVEL: break; case ITEM_SALVE: obj->value[3] = number_fuzzy( obj->value[3] ); break; case ITEM_SCROLL: obj->value[0] = number_fuzzy( obj->value[0] ); break; case ITEM_WAND: case ITEM_STAFF: obj->value[0] = number_fuzzy( obj->value[0] ); obj->value[1] = number_fuzzy( obj->value[1] ); obj->value[2] = obj->value[1]; break; case ITEM_WEAPON: case ITEM_MISSILE_WEAPON: case ITEM_PROJECTILE: if( obj->value[1] && obj->value[2] ) obj->value[2] *= obj->value[1]; else { obj->value[1] = number_fuzzy( number_fuzzy( 1 * level / 4 + 2 ) ); obj->value[2] = number_fuzzy( number_fuzzy( 3 * level / 4 + 6 ) ); } if( obj->value[0] == 0 ) obj->value[0] = INIT_WEAPON_CONDITION; break; case ITEM_POTION: case ITEM_PILL: obj->value[0] = number_fuzzy( number_fuzzy( obj->value[0] ) ); break; case ITEM_MONEY: obj->value[0] = obj->cost; if( obj->value[0] == 0 ) obj->value[0] = 1; break; } LINK( obj, first_object, last_object, next, prev ); ++pObjIndex->count; ++numobjsloaded; ++physicalobjects; return obj; } /* * Create an instance of an object. */ OBJ_DATA *create_object_new( OBJ_INDEX_DATA * pObjIndex, int level, int originCode, char *originNote ) { OBJ_DATA *obj; char originText[MAX_STRING_LENGTH]; if( !pObjIndex ) { bug( "Create_object: NULL pObjIndex." ); exit( 1 ); } CREATE( obj, OBJ_DATA, 1 ); obj->pIndexData = pObjIndex; obj->in_room = NULL; obj->level = pObjIndex->level; obj->wear_loc = -1; obj->count = 1; cur_obj_serial = UMAX( ( cur_obj_serial + 1 ) & ( BV30 - 1 ), 1 ); obj->serial = obj->pIndexData->serial = cur_obj_serial; obj->name = QUICKLINK( pObjIndex->name ); obj->short_descr = QUICKLINK( pObjIndex->short_descr ); obj->description = QUICKLINK( pObjIndex->description ); obj->action_desc = QUICKLINK( pObjIndex->action_desc ); obj->item_type = pObjIndex->item_type; obj->extra_flags = pObjIndex->extra_flags; obj->wear_flags = pObjIndex->wear_flags; obj->value[0] = pObjIndex->value[0]; obj->value[1] = pObjIndex->value[1]; obj->value[2] = pObjIndex->value[2]; obj->value[3] = pObjIndex->value[3]; obj->value[4] = pObjIndex->value[4]; obj->value[5] = pObjIndex->value[5]; obj->weight = pObjIndex->weight; obj->cost = pObjIndex->cost; sprintf( originText, "%d, %s", originCode, originNote ); obj->origin = STRALLOC( originText ); /* * obj->cost = number_fuzzy( 10 ) * * number_fuzzy( level ) * number_fuzzy( level ); */ /* * Mess with object properties. */ switch ( obj->item_type ) { default: bug( "Read_object: vnum %d bad type.", pObjIndex->vnum ); bug( "------------------------> %d ", obj->item_type ); break; case ITEM_LIGHT: case ITEM_SCOUTER: case ITEM_DRAGONBALL: case ITEM_DRAGONRADAR: case ITEM_ARMOR: case ITEM_TREASURE: case ITEM_FURNITURE: case ITEM_TRASH: case ITEM_CONTAINER: case ITEM_DRINK_CON: case ITEM_KEY: case ITEM_KEYRING: case ITEM_ODOR: case ITEM_CHANCE: break; case ITEM_COOK: case ITEM_FOOD: /* * optional food condition (rotting food) -Thoric * value1 is the max condition of the food * value4 is the optional initial condition */ if( obj->value[4] ) obj->timer = obj->value[4]; else obj->timer = obj->value[1]; break; case ITEM_BOAT: case ITEM_CORPSE_NPC: case ITEM_CORPSE_PC: case ITEM_FOUNTAIN: case ITEM_BLOOD: case ITEM_BLOODSTAIN: case ITEM_SCRAPS: case ITEM_PIPE: case ITEM_HERB_CON: case ITEM_HERB: case ITEM_INCENSE: case ITEM_FIRE: case ITEM_BOOK: case ITEM_SWITCH: case ITEM_LEVER: case ITEM_PULLCHAIN: case ITEM_BUTTON: case ITEM_DIAL: case ITEM_RUNE: case ITEM_RUNEPOUCH: case ITEM_MATCH: case ITEM_TRAP: case ITEM_MAP: case ITEM_PORTAL: case ITEM_PAPER: case ITEM_PEN: case ITEM_TINDER: case ITEM_LOCKPICK: case ITEM_SPIKE: case ITEM_DISEASE: case ITEM_OIL: case ITEM_FUEL: case ITEM_QUIVER: case ITEM_SHOVEL: break; case ITEM_SALVE: obj->value[3] = number_fuzzy( obj->value[3] ); break; case ITEM_SCROLL: obj->value[0] = number_fuzzy( obj->value[0] ); break; case ITEM_WAND: case ITEM_STAFF: obj->value[0] = number_fuzzy( obj->value[0] ); obj->value[1] = number_fuzzy( obj->value[1] ); obj->value[2] = obj->value[1]; break; case ITEM_WEAPON: case ITEM_MISSILE_WEAPON: case ITEM_PROJECTILE: if( obj->value[1] && obj->value[2] ) obj->value[2] *= obj->value[1]; else { obj->value[1] = number_fuzzy( number_fuzzy( 1 * level / 4 + 2 ) ); obj->value[2] = number_fuzzy( number_fuzzy( 3 * level / 4 + 6 ) ); } if( obj->value[0] == 0 ) obj->value[0] = INIT_WEAPON_CONDITION; break; case ITEM_POTION: case ITEM_PILL: obj->value[0] = number_fuzzy( number_fuzzy( obj->value[0] ) ); break; case ITEM_MONEY: obj->value[0] = obj->cost; if( obj->value[0] == 0 ) obj->value[0] = 1; break; } LINK( obj, first_object, last_object, next, prev ); ++pObjIndex->count; ++numobjsloaded; ++physicalobjects; return obj; } /* * Clear a new character. */ void clear_char( CHAR_DATA * ch ) { ch->editor = NULL; ch->hunting = NULL; ch->fearing = NULL; ch->hating = NULL; ch->mob_serial = -1; ch->name = NULL; ch->short_descr = NULL; ch->long_descr = NULL; ch->next = NULL; ch->prev = NULL; ch->reply = NULL; ch->retell = NULL; ch->first_carrying = NULL; ch->last_carrying = NULL; ch->next_in_room = NULL; ch->prev_in_room = NULL; ch->fighting = NULL; ch->switched = NULL; ch->first_affect = NULL; ch->last_affect = NULL; ch->prev_cmd = NULL; /* maps */ ch->last_cmd = NULL; ch->dest_buf = NULL; ch->alloc_ptr = NULL; ch->spare_ptr = NULL; ch->mount = NULL; ch->morph = NULL; xCLEAR_BITS( ch->affected_by ); ch->logon = current_time; ch->armor = 100; ch->position = POS_STANDING; ch->practice = 2; ch->max_prac = 2; ch->train = 4; ch->max_train = 4; ch->hit = 100; ch->max_hit = 100; ch->mana = 100; ch->max_mana = 100; ch->max_energy = 1; ch->move = 100; ch->max_move = 100; ch->powerup = 0; ch->height = 72; ch->weight = 180; ch->xflags = 0; ch->race = 0; ch->class = 0; ch->speaking = LANG_COMMON; ch->speaks = LANG_COMMON; ch->barenumdie = 2; ch->baresizedie = 4; ch->substate = 0; ch->tempnum = 0; ch->perm_str = 10; ch->perm_dex = 10; ch->perm_int = 10; ch->perm_con = 10; ch->perm_lck = 0; ch->mod_str = 0; ch->mod_dex = 0; ch->mod_int = 0; ch->mod_con = 0; ch->mod_lck = 0; ch->teaching = NULL; ch->tmystic = 0; ch->canmajin = 0; ch->pagelen = 24; /* BUILD INTERFACE */ ch->inter_page = NO_PAGE; /* BUILD INTERFACE */ ch->inter_type = NO_TYPE; /* BUILD INTERFACE */ ch->inter_editing = NULL; /* BUILD INTERFACE */ ch->inter_editing_vnum = -1; /* BUILD INTERFACE */ ch->inter_substate = SUB_NORTH; /* BUILD INTERFACE */ return; } /* * Free a character. */ void free_char( CHAR_DATA * ch ) { OBJ_DATA *obj; AFFECT_DATA *paf; TIMER *timer; MPROG_ACT_LIST *mpact, *mpact_next; NOTE_DATA *comments, *comments_next; if( !ch ) { bug( "Free_char: null ch!" ); return; } if( ch->desc ) bug( "Free_char: char still has descriptor." ); if( ch->morph ) free_char_morph( ch->morph ); while( ( obj = ch->last_carrying ) != NULL ) extract_obj( obj ); while( ( paf = ch->last_affect ) != NULL ) affect_remove( ch, paf ); while( ( timer = ch->first_timer ) != NULL ) extract_timer( ch, timer ); if( ch->editor ) stop_editing( ch ); STRFREE( ch->name ); STRFREE( ch->short_descr ); STRFREE( ch->long_descr ); STRFREE( ch->description ); if( ch->inter_editing ) DISPOSE( ch->inter_editing ); stop_hunting( ch ); stop_hating( ch ); stop_fearing( ch ); free_fight( ch ); if( ch->pnote ) free_note( ch->pnote ); if( ch->pcdata ) { IGNORE_DATA *temp, *next; /* * free up memory allocated to stored ignored names */ for( temp = ch->pcdata->first_ignored; temp; temp = next ) { next = temp->next; UNLINK( temp, ch->pcdata->first_ignored, ch->pcdata->last_ignored, next, prev ); STRFREE( temp->name ); DISPOSE( temp ); } STRFREE( ch->pcdata->filename ); STRFREE( ch->pcdata->deity_name ); STRFREE( ch->pcdata->clan_name ); STRFREE( ch->pcdata->council_name ); DISPOSE( ch->pcdata->pwd ); /* no hash */ DISPOSE( ch->pcdata->bamfin ); /* no hash */ DISPOSE( ch->pcdata->bamfout ); /* no hash */ if( ch->level >= LEVEL_IMMORTAL && ch->pcdata->pretitle && ch->pcdata->pretitle[0] != '\0' ) STRFREE( ch->pcdata->pretitle ); STRFREE( ch->pcdata->title ); STRFREE( ch->pcdata->description1 ); STRFREE( ch->pcdata->description2 ); STRFREE( ch->pcdata->description3 ); STRFREE( ch->pcdata->description4 ); STRFREE( ch->pcdata->description5 ); STRFREE( ch->pcdata->bio ); if( ch->pcdata->rreply ) DISPOSE( ch->pcdata->rreply ); /* no hash */ if( ch->pcdata->rreply_name ) DISPOSE( ch->pcdata->rreply_name ); /* no hash */ DISPOSE( ch->pcdata->bestowments ); /* no hash */ DISPOSE( ch->pcdata->homepage ); /* no hash */ STRFREE( ch->pcdata->authed_by ); DISPOSE( ch->pcdata->email ); /* no hash */ STRFREE( ch->pcdata->prompt ); STRFREE( ch->pcdata->fprompt ); if( ch->pcdata->bounty_by ) DISPOSE( ch->pcdata->bounty_by ); if( ch->pcdata->hunting ) DISPOSE( ch->pcdata->hunting ); if( ch->pcdata->spouse ) DISPOSE( ch->pcdata->spouse ); if( ch->pcdata->helled_by ) STRFREE( ch->pcdata->helled_by ); if( ch->pcdata->subprompt ) STRFREE( ch->pcdata->subprompt ); if( ch->pcdata->tell_history ) { int i; for( i = 0; i < 26; i++ ) { if( ch->pcdata->tell_history[i] ) STRFREE( ch->pcdata->tell_history[i] ); } DISPOSE( ch->pcdata->tell_history ); } DISPOSE( ch->pcdata->ice_listen ); STRFREE( ch->pcdata->silencedby ); if( ch->pcdata->last_name ) DISPOSE( ch->pcdata->last_name ); /* no hash */ STRFREE( ch->pcdata->lasthost ); /* * ch->pcdata->HBTCPartner ? */ DISPOSE( ch->pcdata ); } for( mpact = ch->mpact; mpact; mpact = mpact_next ) { mpact_next = mpact->next; DISPOSE( mpact->buf ); DISPOSE( mpact ); } for( comments = ch->comments; comments; comments = comments_next ) { comments_next = comments->next; STRFREE( comments->text ); STRFREE( comments->to_list ); STRFREE( comments->subject ); STRFREE( comments->sender ); STRFREE( comments->date ); DISPOSE( comments ); } DISPOSE( ch ); return; } /* * Get an extra description from a list. */ char *get_extra_descr( const char *name, EXTRA_DESCR_DATA * ed ) { for( ; ed; ed = ed->next ) if( is_name( name, ed->keyword ) ) return ed->description; return NULL; } /* * Translates mob virtual number to its mob index struct. * Hash table lookup. */ MOB_INDEX_DATA *get_mob_index( int vnum ) { MOB_INDEX_DATA *pMobIndex; if( vnum < 0 ) vnum = 0; for( pMobIndex = mob_index_hash[vnum % MAX_KEY_HASH]; pMobIndex; pMobIndex = pMobIndex->next ) if( pMobIndex->vnum == vnum ) return pMobIndex; if( fBootDb ) bug( "Get_mob_index: bad vnum %d.", vnum ); return NULL; } /* * Translates obj virtual number to its obj index struct. * Hash table lookup. */ OBJ_INDEX_DATA *get_obj_index( int vnum ) { OBJ_INDEX_DATA *pObjIndex; if( vnum < 0 ) vnum = 0; for( pObjIndex = obj_index_hash[vnum % MAX_KEY_HASH]; pObjIndex; pObjIndex = pObjIndex->next ) if( pObjIndex->vnum == vnum ) return pObjIndex; if( fBootDb ) bug( "Get_obj_index: bad vnum %d.", vnum ); return NULL; } /* * Translates room virtual number to its room index struct. * Hash table lookup. */ ROOM_INDEX_DATA *get_room_index( int vnum ) { ROOM_INDEX_DATA *pRoomIndex; if( vnum < 0 ) vnum = 0; for( pRoomIndex = room_index_hash[vnum % MAX_KEY_HASH]; pRoomIndex; pRoomIndex = pRoomIndex->next ) if( pRoomIndex->vnum == vnum ) return pRoomIndex; if( fBootDb ) bug( "Get_room_index: bad vnum %d.", vnum ); return NULL; } /* * Added lots of EOF checks, as most of the file crashes are based on them. * If an area file encounters EOF, the fread_* functions will shutdown the * MUD, as all area files should be read in in full or bad things will * happen during the game. Any files loaded in without fBootDb which * encounter EOF will return what they have read so far. These files * should include player files, and in-progress areas that are not loaded * upon bootup. * -- Altrag */ /* * Read a letter from a file. */ char fread_letter( FILE * fp ) { char c; char buf[MAX_STRING_LENGTH]; do { if( feof( fp ) ) { bug( "fread_letter: EOF encountered on read.\n\r", 0 ); if( GfpName ) { sprintf( buf, "[*****] FILE: %s", GfpName ); log_string( buf ); } if( fBootDb ) exit( 1 ); else StopFP = TRUE; return '\0'; } c = getc( fp ); } while( isspace( c ) ); if( StopFP ) StopFP = FALSE; return c; } /* * Read a number from a file. */ int fread_number( FILE * fp ) { int number; bool sign; char c; do { if( feof( fp ) ) { bug( "fread_number: EOF encountered on read.\n\r", 0 ); if( fBootDb ) exit( 1 ); return 0; } c = getc( fp ); } while( isspace( c ) ); number = 0; sign = FALSE; if( c == '+' ) { c = getc( fp ); } else if( c == '-' ) { sign = TRUE; c = getc( fp ); } if( !isdigit( c ) ) { bug( "Fread_number: bad format. (%c)", c, 0 ); if( fBootDb ) exit( 1 ); return 0; } while( isdigit( c ) ) { if( feof( fp ) ) { bug( "fread_number: EOF encountered on read.\n\r", 0 ); if( fBootDb ) exit( 1 ); return number; } number = number * 10 + c - '0'; c = getc( fp ); } if( sign ) number = 0 - number; if( c == '|' ) number += fread_number( fp ); else if( c != ' ' ) ungetc( c, fp ); return number; } /* * Read a number from a file. */ long double fread_number_ld( FILE * fp ) { long double number; char c; bool sign; do { if( feof( fp ) ) { bug( "fread_number: EOF encountered on read.\n\r", 0 ); if( fBootDb ) exit( 1 ); return 0; } c = getc( fp ); } while( isspace( c ) ); number = 0; sign = FALSE; if( c == '+' ) { c = getc( fp ); } else if( c == '-' ) { sign = TRUE; c = getc( fp ); } if( !isdigit( c ) ) { bug( "Fread_number: bad format. (%c)", c, 0 ); if( fBootDb ) exit( 1 ); return 0; } while( isdigit( c ) ) { if( feof( fp ) ) { bug( "fread_number: EOF encountered on read.\n\r", 0 ); if( fBootDb ) exit( 1 ); return number; } number = number * 10 + c - '0'; c = getc( fp ); } if( sign ) number = 0 - number; if( c == '|' ) number += fread_number( fp ); else if( c != ' ' ) ungetc( c, fp ); return number; } double fread_number_skill( FILE * fp ) { long double number; char c; char toLd[MAX_INPUT_LENGTH]; int i = 0; do { if( feof( fp ) ) { bug( "fread_number: EOF encountered on read.\n\r", 0 ); if( fBootDb ) exit( 1 ); return 0; } c = getc( fp ); } while( isspace( c ) ); number = 0; if( !isdigit( c ) ) { bug( "Fread_number: bad format. (%c)", c, 0 ); if( fBootDb ) exit( 1 ); return 0; } while( isdigit( c ) || c == '.' ) { if( feof( fp ) ) { bug( "fread_number: EOF encountered on read.\n\r", 0 ); if( fBootDb ) exit( 1 ); return number; } toLd[i] = c; i++; c = getc( fp ); } number = atof( toLd ); if( c == '|' ) number += fread_number( fp ); else if( c != ' ' ) ungetc( c, fp ); return number; } /* * custom str_dup using create -Thoric */ char *str_dup( char const *str ) { static char *ret; int len; if( !str ) return NULL; len = strlen( str ) + 1; CREATE( ret, char, len ); strcpy( ret, str ); return ret; } /* * Read a string from file fp (goku hacked verson) */ char *fread_string_wspace( FILE * fp ) { char buf[MAX_STRING_LENGTH]; char *plast; char c; int ln; plast = buf; buf[0] = '\0'; ln = 0; /* * Don't skip blanks. * Read first char. */ do { if( feof( fp ) ) { bug( "fread_string: EOF encountered on read.\n\r", 0 ); if( fBootDb ) exit( 1 ); return STRALLOC( "" ); } c = getc( fp ); } while( iscntrl( c ) ); if( ( *plast++ = c ) == '~' ) return STRALLOC( "" ); for( ;; ) { if( ln >= ( MAX_STRING_LENGTH - 1 ) ) { bug( "fread_string: string too long", 0 ); *plast = '\0'; return STRALLOC( buf ); } switch ( *plast = getc( fp ) ) { default: plast++; ln++; break; case EOF: bug( "Fread_string: EOF", 0 ); if( fBootDb ) exit( 1 ); *plast = '\0'; return STRALLOC( buf ); break; case '\n': plast++; ln++; *plast++ = '\r'; ln++; break; case '\r': break; case '~': *plast = '\0'; return STRALLOC( buf ); } } } /* * Read a string from file fp */ char *fread_string( FILE * fp ) { char buf[MAX_STRING_LENGTH]; char *plast; char c; int ln; plast = buf; buf[0] = '\0'; ln = 0; /* * Skip blanks. * Read first char. */ do { if( feof( fp ) ) { bug( "fread_string: EOF encountered on read.\n\r", 0 ); if( fBootDb ) exit( 1 ); return STRALLOC( "" ); } c = getc( fp ); } while( isspace( c ) ); if( ( *plast++ = c ) == '~' ) return STRALLOC( "" ); for( ;; ) { if( ln >= ( MAX_STRING_LENGTH - 1 ) ) { bug( "fread_string: string too long", 0 ); *plast = '\0'; return STRALLOC( buf ); } switch ( *plast = getc( fp ) ) { default: plast++; ln++; break; case EOF: bug( "Fread_string: EOF", 0 ); if( fBootDb ) exit( 1 ); *plast = '\0'; return STRALLOC( buf ); break; case '\n': plast++; ln++; *plast++ = '\r'; ln++; break; case '\r': break; case '~': *plast = '\0'; return STRALLOC( buf ); } } } /* * Read a string from file fp using str_dup (ie: no string hashing) */ char *fread_string_nohash( FILE * fp ) { char buf[MAX_STRING_LENGTH]; char *plast; char c; int ln; plast = buf; buf[0] = '\0'; ln = 0; /* * Skip blanks. * Read first char. */ do { if( feof( fp ) ) { bug( "fread_string_no_hash: EOF encountered on read.\n\r", 0 ); if( fBootDb ) exit( 1 ); return str_dup( "" ); } c = getc( fp ); } while( isspace( c ) ); if( ( *plast++ = c ) == '~' ) return str_dup( "" ); for( ;; ) { if( ln >= ( MAX_STRING_LENGTH - 1 ) ) { bug( "fread_string_no_hash: string too long", 0 ); *plast = '\0'; return str_dup( buf ); } switch ( *plast = getc( fp ) ) { default: plast++; ln++; break; case EOF: bug( "Fread_string_no_hash: EOF", 0 ); if( fBootDb ) exit( 1 ); *plast = '\0'; return str_dup( buf ); break; case '\n': plast++; ln++; *plast++ = '\r'; ln++; break; case '\r': break; case '~': *plast = '\0'; return str_dup( buf ); } } } /* * Read to end of line (for comments). */ void fread_to_eol( FILE * fp ) { char c; do { if( feof( fp ) ) { bug( "fread_to_eol: EOF encountered on read.\n\r", 0 ); if( fBootDb ) exit( 1 ); return; } c = getc( fp ); } while( c != '\n' && c != '\r' ); do { c = getc( fp ); } while( c == '\n' || c == '\r' ); ungetc( c, fp ); return; } /* * Read to end of line into static buffer -Thoric */ char *fread_line( FILE * fp ) { static char line[MAX_STRING_LENGTH]; char *pline; char c; int ln; pline = line; line[0] = '\0'; ln = 0; /* * Skip blanks. * Read first char. */ do { if( feof( fp ) ) { bug( "fread_line: EOF encountered on read.\n\r", 0 ); if( fBootDb ) exit( 1 ); strcpy( line, "" ); return line; } c = getc( fp ); } while( isspace( c ) ); ungetc( c, fp ); do { if( feof( fp ) ) { bug( "fread_line: EOF encountered on read.\n\r", 0 ); if( fBootDb ) exit( 1 ); *pline = '\0'; return line; } c = getc( fp ); *pline++ = c; ln++; if( ln >= ( MAX_STRING_LENGTH - 1 ) ) { bug( "fread_line: line too long", 0 ); break; } } while( c != '\n' && c != '\r' ); do { c = getc( fp ); } while( c == '\n' || c == '\r' ); ungetc( c, fp ); *pline = '\0'; return line; } /* * Read one word (into static buffer). */ char *fread_word( FILE * fp ) { static char word[MAX_INPUT_LENGTH]; char *pword; char cEnd; do { if( feof( fp ) ) { bug( "fread_word: EOF encountered on read.\n\r", 0 ); if( fBootDb ) exit( 1 ); word[0] = '\0'; return word; } cEnd = getc( fp ); } while( isspace( cEnd ) ); if( cEnd == '\'' || cEnd == '\"' ) { pword = word; } else { word[0] = cEnd; pword = word + 1; cEnd = ' '; } for( ; pword < word + MAX_INPUT_LENGTH; pword++ ) { if( feof( fp ) ) { bug( "fread_word: EOF encountered on read.\n\r", 0 ); if( fBootDb ) exit( 1 ); *pword = '\0'; return word; } *pword = getc( fp ); if( cEnd == ' ' ? isspace( *pword ) : *pword == cEnd ) { if( cEnd == ' ' ) ungetc( *pword, fp ); *pword = '\0'; return word; } } bug( "Fread_word: word too long.\n\r", 0 ); bug( "%s", word, 0 ); exit( 1 ); return NULL; } void do_memory( CHAR_DATA * ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; int hash; set_char_color( AT_PLAIN, ch ); argument = one_argument( argument, arg ); send_to_char_color( "\n\r&wSystem Memory [arguments - hash, check, showhigh]\n\r", ch ); ch_printf_color( ch, "&wAffects: &W%5d\t\t\t&wAreas: &W%5d\n\r", top_affect, top_area ); ch_printf_color( ch, "&wExtDes: &W%5d\t\t\t&wExits: &W%5d\n\r", top_ed, top_exit ); ch_printf_color( ch, "&wHelps: &W%5d\t\t\t&wResets: &W%5d\n\r", top_help, top_reset ); ch_printf_color( ch, "&wIdxMobs: &W%5d\t\t\t&wMobiles: &W%5d\n\r", top_mob_index, nummobsloaded ); ch_printf_color( ch, "&wIdxObjs: &W%5d\t\t\t&wObjs: &W%5d(%d)\n\r", top_obj_index, numobjsloaded, physicalobjects ); ch_printf_color( ch, "&wRooms: &W%5d\t\t\t&wVRooms: &W%5d\n\r", top_room, top_vroom ); ch_printf_color( ch, "&wShops: &W%5d\t\t\t&wRepShps: &W%5d\n\r", top_shop, top_repair ); ch_printf_color( ch, "&wCurOq's: &W%5d\t\t\t&wCurCq's: &W%5d\n\r", cur_qobjs, cur_qchars ); ch_printf_color( ch, "&wPlayers: &W%5d\t\t\t&wMaxplrs: &W%5d\n\r", num_descriptors, sysdata.maxplayers ); ch_printf_color( ch, "&wMaxEver: &W%5d\t\t\t&wTopsn: &W%5d(%d)\n\r", sysdata.alltimemax, top_sn, MAX_SKILL ); ch_printf_color( ch, "&wMaxEver was recorded on: &W%s\n\r\n\r", sysdata.time_of_max ); ch_printf_color( ch, "&wPotion Val: &W%-16d &wScribe/Brew: &W%d/%d\n\r", sysdata.upotion_val, sysdata.scribed_used, sysdata.brewed_used ); ch_printf_color( ch, "&wPill Val: &W%-16d &wGlobal loot: &W%d\n\r", sysdata.upill_val, sysdata.global_looted ); if( !str_cmp( arg, "check" ) ) { #ifdef HASHSTR send_to_char( check_hash( argument ), ch ); #else send_to_char( "Hash strings not enabled.\n\r", ch ); #endif return; } if( !str_cmp( arg, "showhigh" ) ) { #ifdef HASHSTR show_high_hash( atoi( argument ) ); #else send_to_char( "Hash strings not enabled.\n\r", ch ); #endif return; } if( argument[0] != '\0' ) hash = atoi( argument ); else hash = -1; if( !str_cmp( arg, "hash" ) ) { #ifdef HASHSTR ch_printf( ch, "Hash statistics:\n\r%s", hash_stats( ) ); if( hash != -1 ) hash_dump( hash ); #else send_to_char( "Hash strings not enabled.\n\r", ch ); #endif } return; } /* * Stick a little fuzz on a number. */ int number_fuzzy( int number ) { switch ( number_bits( 2 ) ) { case 0: number -= 1; break; case 3: number += 1; break; } return UMAX( 1, number ); } /* * Generate a random number. * Ooops was (number_mm() % to) + from which doesn't work -Shaddai */ int number_range( int from, int to ) { if( ( to - from ) < 1 ) return from; return ( ( number_mm( ) % ( to - from + 1 ) ) + from ); } /*long double number_range_ld( long double from, long double to ) { if( ( to-from) < 1 ) return from; return ((number_mm() % (to-from+1)) + from); }*/ /* * Generate a percentile roll. * number_mm() % 100 only does 0-99, changed to do 1-100 -Shaddai */ int number_percent( void ) { return ( number_mm( ) % 100 ) + 1; } /* * Generate a random door. */ int number_door( void ) { int door; while( ( door = number_mm( ) & ( 16 - 1 ) ) > 9 ) ; return door; /* return number_mm() & 10; */ } int number_bits( int width ) { return number_mm( ) & ( ( 1 << width ) - 1 ); } /* * I've gotten too many bad reports on OS-supplied random number generators. * This is the Mitchell-Moore algorithm from Knuth Volume II. * Best to leave the constants alone unless you've read Knuth. * -- Furey */ static int rgiState[2 + 55]; void init_mm( ) { int *piState; int iState; piState = &rgiState[2]; piState[-2] = 55 - 55; piState[-1] = 55 - 24; piState[0] = ( ( int )current_time ) & ( ( 1 << 30 ) - 1 ); piState[1] = 1; for( iState = 2; iState < 55; iState++ ) { piState[iState] = ( piState[iState - 1] + piState[iState - 2] ) & ( ( 1 << 30 ) - 1 ); } return; } int number_mm( void ) { int *piState; int iState1; int iState2; int iRand; piState = &rgiState[2]; iState1 = piState[-2]; iState2 = piState[-1]; iRand = ( piState[iState1] + piState[iState2] ) & ( ( 1 << 30 ) - 1 ); piState[iState1] = iRand; if( ++iState1 == 55 ) iState1 = 0; if( ++iState2 == 55 ) iState2 = 0; piState[-2] = iState1; piState[-1] = iState2; return iRand >> 6; } /* * Roll some dice. -Thoric */ int dice( int number, int size ) { int idice; int sum; switch ( size ) { case 0: return 0; case 1: return number; } for( idice = 0, sum = 0; idice < number; idice++ ) sum += number_range( 1, size ); return sum; } /* * Simple linear interpolation. */ int interpolate( int level, int value_00, int value_32 ) { return value_00 + level * ( value_32 - value_00 ) / 32; } /* * Removes the tildes from a string. * Used for player-entered strings that go into disk files. */ void smash_tilde( char *str ) { for( ; *str != '\0'; str++ ) if( *str == '~' ) *str = '-'; return; } /* * Encodes the tildes in a string. -Thoric * Used for player-entered strings that go into disk files. */ void hide_tilde( char *str ) { for( ; *str != '\0'; str++ ) if( *str == '~' ) *str = HIDDEN_TILDE; return; } char *show_tilde( char *str ) { static char buf[MAX_STRING_LENGTH]; char *bufptr; bufptr = buf; for( ; *str != '\0'; str++, bufptr++ ) { if( *str == HIDDEN_TILDE ) *bufptr = '~'; else *bufptr = *str; } *bufptr = '\0'; return buf; } /* * Compare strings, case insensitive. * Return TRUE if different * (compatibility with historical functions). */ bool str__cmp( const char *astr, const char *bstr ) { if( !astr ) { bug( "Str_cmp: null astr." ); if( bstr ) fprintf( stderr, "str_cmp: astr: (null) bstr: %s\n", bstr ); return TRUE; } if( !bstr ) { bug( "Str_cmp: null bstr." ); if( astr ) fprintf( stderr, "str_cmp: astr: %s bstr: (null)\n", astr ); return TRUE; } for( ; *astr || *bstr; astr++, bstr++ ) { if( LOWER( *astr ) != LOWER( *bstr ) ) return TRUE; } return FALSE; } /* * Compare strings, case insensitive, for prefix matching. * Return TRUE if astr not a prefix of bstr * (compatibility with historical functions). */ bool str_prefix( const char *astr, const char *bstr ) { if( !astr ) { bug( "Strn_cmp: null astr." ); return TRUE; } if( !bstr ) { bug( "Strn_cmp: null bstr." ); return TRUE; } for( ; *astr; astr++, bstr++ ) { if( LOWER( *astr ) != LOWER( *bstr ) ) return TRUE; } return FALSE; } /* * Compare strings, case insensitive, for match anywhere. * Returns TRUE is astr not part of bstr. * (compatibility with historical functions). */ bool str_infix( const char *astr, const char *bstr ) { int sstr1; int sstr2; int ichar; char c0; if( ( c0 = LOWER( astr[0] ) ) == '\0' ) return FALSE; sstr1 = strlen( astr ); sstr2 = strlen( bstr ); for( ichar = 0; ichar <= sstr2 - sstr1; ichar++ ) if( c0 == LOWER( bstr[ichar] ) && !str_prefix( astr, bstr + ichar ) ) return FALSE; return TRUE; } /* * Compare strings, case insensitive, for suffix matching. * Return TRUE if astr not a suffix of bstr * (compatibility with historical functions). */ bool str_suffix( const char *astr, const char *bstr ) { int sstr1; int sstr2; sstr1 = strlen( astr ); sstr2 = strlen( bstr ); if( sstr1 <= sstr2 && !str_cmp( astr, bstr + sstr2 - sstr1 ) ) return FALSE; else return TRUE; } /* * Returns an initial-capped string. */ char *capitalize( const char *str ) { static char strcap[MAX_STRING_LENGTH]; int i; for( i = 0; str[i] != '\0'; i++ ) strcap[i] = LOWER( str[i] ); strcap[i] = '\0'; strcap[0] = UPPER( strcap[0] ); return strcap; } /* * Returns a lowercase string. */ char *strlower( const char *str ) { static char strlow[MAX_STRING_LENGTH]; int i; for( i = 0; str[i] != '\0'; i++ ) strlow[i] = LOWER( str[i] ); strlow[i] = '\0'; return strlow; } /* * Returns an uppercase string. */ char *strupper( const char *str ) { static char strup[MAX_STRING_LENGTH]; int i; for( i = 0; str[i] != '\0'; i++ ) strup[i] = UPPER( str[i] ); strup[i] = '\0'; return strup; } /* * Returns TRUE or FALSE if a letter is a vowel -Thoric */ bool isavowel( char letter ) { char c; c = LOWER( letter ); if( c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' ) return TRUE; else return FALSE; } /* * Shove either "a " or "an " onto the beginning of a string -Thoric */ char *aoran( const char *str ) { static char temp[MAX_STRING_LENGTH]; if( !str ) { bug( "Aoran(): NULL str" ); return ""; } if( isavowel( str[0] ) || ( strlen( str ) > 1 && LOWER( str[0] ) == 'y' && !isavowel( str[1] ) ) ) strcpy( temp, "an " ); else strcpy( temp, "a " ); strcat( temp, str ); return temp; } /* * Append a string to a file. */ void append_file( CHAR_DATA * ch, char *file, char *str ) { FILE *fp; if( IS_NPC( ch ) || str[0] == '\0' ) return; fclose( fpLOG ); if( ( fp = fopen( file, "a" ) ) == NULL ) { perror( file ); send_to_char( "Could not open the file!\n\r", ch ); } else { fprintf( fp, "[%5d] %s: %s\n", ch->in_room ? ch->in_room->vnum : 0, ch->name, str ); fclose( fp ); } fpLOG = fopen( NULL_FILE, "r" ); return; } /* * Append a string to a file. */ void append_to_file( char *file, char *str ) { FILE *fp; if( ( fp = fopen( file, "a" ) ) == NULL ) perror( file ); else { fprintf( fp, "%s\n", str ); fclose( fp ); } return; } /* * Reports a bug. */ void bug( const char *str, ... ) { char buf[MAX_STRING_LENGTH]; FILE *fp; struct stat fst; if( fpArea != NULL ) { int iLine; int iChar; if( fpArea == stdin ) { iLine = 0; } else { iChar = ftell( fpArea ); fseek( fpArea, 0, 0 ); for( iLine = 0; ftell( fpArea ) < iChar; iLine++ ) { while( getc( fpArea ) != '\n' ) ; } fseek( fpArea, iChar, 0 ); } sprintf( buf, "[*****] FILE: %s LINE: %d", strArea, iLine ); log_string( buf ); if( stat( SHUTDOWN_FILE, &fst ) != -1 ) /* file exists */ { if( ( fp = fopen( SHUTDOWN_FILE, "a" ) ) != NULL ) { fprintf( fp, "[*****] %s\n", buf ); fclose( fp ); } } } strcpy( buf, "[*****] BUG: " ); { va_list param; va_start( param, str ); vsprintf( buf + strlen( buf ), str, param ); va_end( param ); } log_string( buf ); fclose( fpLOG ); /* * if( ( fp = fopen( BUG_FILE, "a" ) ) != NULL ) * { * fprintf( fp, "%s\n", buf ); * fclose( fp ); * } */ fpLOG = fopen( NULL_FILE, "r" ); return; } /* * Add a string to the boot-up log -Thoric */ void boot_log( const char *str, ... ) { char buf[MAX_STRING_LENGTH]; FILE *fp; va_list param; strcpy( buf, "[*****] BOOT: " ); va_start( param, str ); vsprintf( buf + strlen( buf ), str, param ); va_end( param ); log_string( buf ); fclose( fpLOG ); if( ( fp = fopen( BOOTLOG_FILE, "a" ) ) != NULL ) { fprintf( fp, "%s\n", buf ); fclose( fp ); } fpLOG = fopen( NULL_FILE, "r" ); return; } /* * Dump a text file to a player, a line at a time -Thoric */ void show_file( CHAR_DATA * ch, char *filename ) { FILE *fp; char buf[MAX_STRING_LENGTH]; int c; int num = 0; fclose( fpReserve ); if( ( fp = fopen( filename, "r" ) ) != NULL ) { while( !feof( fp ) ) { while( ( buf[num] = fgetc( fp ) ) != EOF && buf[num] != '\n' && buf[num] != '\r' && num < ( MAX_STRING_LENGTH - 2 ) ) num++; c = fgetc( fp ); if( ( c != '\n' && c != '\r' ) || c == buf[num] ) ungetc( c, fp ); buf[num++] = '\n'; buf[num++] = '\r'; buf[num] = '\0'; send_to_pager_color( buf, ch ); num = 0; } /* * Thanks to stu <sprice@ihug.co.nz> from the mailing list in pointing * * This out. */ fclose( fp ); } fpReserve = fopen( NULL_FILE, "r" ); } /* * Show the boot log file -Thoric */ void do_dmesg( CHAR_DATA * ch, char *argument ) { set_pager_color( AT_LOG, ch ); show_file( ch, BOOTLOG_FILE ); } /* * Writes a string to the log, extended version -Thoric */ void log_string_plus( const char *str, sh_int log_type, sh_int level ) { char *strtime; int offset; strtime = ctime( ¤t_time ); strtime[strlen( strtime ) - 1] = '\0'; fprintf( stderr, "%s :: %s\n", strtime, str ); if( strncmp( str, "Log ", 4 ) == 0 ) offset = 4; else offset = 0; switch ( log_type ) { default: to_channel( str + offset, CHANNEL_LOG, "Log", level ); break; case LOG_BUILD: to_channel( str + offset, CHANNEL_BUILD, "Build", level ); break; case LOG_COMM: to_channel( str + offset, CHANNEL_COMM, "Comm", level ); break; case LOG_WARN: to_channel( str + offset, CHANNEL_WARN, "Warn", level ); break; case LOG_ALL: break; } return; } /* * wizlist builder! -Thoric */ void towizfile( const char *line ) { int filler, xx; char outline[MAX_STRING_LENGTH]; FILE *wfp; outline[0] = '\0'; if( line && line[0] != '\0' ) { filler = ( 78 - strlen( line ) ); if( filler < 1 ) filler = 1; filler /= 2; for( xx = 0; xx < filler; xx++ ) strcat( outline, " " ); strcat( outline, line ); } strcat( outline, "\n\r" ); wfp = fopen( WIZLIST_FILE, "a" ); if( wfp ) { fputs( outline, wfp ); fclose( wfp ); } } void add_to_wizlist( char *name, int level ) { WIZENT *wiz, *tmp; #ifdef DEBUG log_string( "Adding to wizlist..." ); #endif CREATE( wiz, WIZENT, 1 ); wiz->name = str_dup( name ); wiz->level = level; if( !first_wiz ) { wiz->last = NULL; wiz->next = NULL; first_wiz = wiz; last_wiz = wiz; return; } /* * insert sort, of sorts */ for( tmp = first_wiz; tmp; tmp = tmp->next ) if( level > tmp->level ) { if( !tmp->last ) first_wiz = wiz; else tmp->last->next = wiz; wiz->last = tmp->last; wiz->next = tmp; tmp->last = wiz; return; } wiz->last = last_wiz; wiz->next = NULL; last_wiz->next = wiz; last_wiz = wiz; return; } /* * Wizlist builder -Thoric */ void make_wizlist( ) { DIR *dp; struct dirent *dentry; FILE *gfp; char *word; int ilevel, iflags; WIZENT *wiz, *wiznext; char buf[MAX_STRING_LENGTH]; first_wiz = NULL; last_wiz = NULL; dp = opendir( GOD_DIR ); ilevel = 0; dentry = readdir( dp ); while( dentry ) { if( dentry->d_name[0] != '.' ) { sprintf( buf, "%s%s", GOD_DIR, dentry->d_name ); gfp = fopen( buf, "r" ); if( gfp ) { word = feof( gfp ) ? "End" : fread_word( gfp ); ilevel = fread_number( gfp ); fread_to_eol( gfp ); word = feof( gfp ) ? "End" : fread_word( gfp ); if( !str_cmp( word, "Pcflags" ) ) iflags = fread_number( gfp ); else iflags = 0; fclose( gfp ); if( IS_SET( iflags, PCFLAG_RETIRED ) ) ilevel = MAX_LEVEL - 15; if( IS_SET( iflags, PCFLAG_GUEST ) ) ilevel = MAX_LEVEL - 16; add_to_wizlist( dentry->d_name, ilevel ); } } dentry = readdir( dp ); } closedir( dp ); unlink( WIZLIST_FILE ); sprintf( buf, "&c The Immortal Wizlist&Y" ); towizfile( buf ); buf[0] = '\0'; ilevel = 65535; for( wiz = first_wiz; wiz; wiz = wiz->next ) { if( wiz->level < ilevel ) { if( buf[0] ) { towizfile( buf ); buf[0] = '\0'; } towizfile( "" ); ilevel = wiz->level; switch ( ilevel ) { case MAX_LEVEL - 0: towizfile( " Owners" ); break; case MAX_LEVEL - 1: towizfile( " Head Administrators" ); break; case MAX_LEVEL - 2: towizfile( " Coders" ); break; case MAX_LEVEL - 3: towizfile( " Quest Master" ); break; case MAX_LEVEL - 4: towizfile( " Head Builders" ); break; case MAX_LEVEL - 5: towizfile( " Some Guy" ); break; case MAX_LEVEL - 6: towizfile( " Head Enforcers" ); break; case MAX_LEVEL - 7: towizfile( " Advanced Builders" ); break; case MAX_LEVEL - 8: towizfile( " Advanced Enforcers" ); break; case MAX_LEVEL - 9: towizfile( " Enforcers" ); break; case MAX_LEVEL - 10: towizfile( " Enforcers" ); break; case MAX_LEVEL - 11: towizfile( " Builders" ); break; case MAX_LEVEL - 12: towizfile( " Head of Roleplay" ); break; case MAX_LEVEL - 13: towizfile( " RP Admin" ); break; case MAX_LEVEL - 14: towizfile( " Trustees" ); break; case MAX_LEVEL - 15: towizfile( " Retired" ); break; case MAX_LEVEL - 16: towizfile( " Guests" ); break; default: towizfile( " Servants" ); break; } } if( strlen( buf ) + strlen( wiz->name ) > 76 ) { towizfile( buf ); buf[0] = '\0'; } strcat( buf, " " ); if( str_cmp( wiz->name, "normed" ) ) strcat( buf, wiz->name ); if( strlen( buf ) > 70 ) { towizfile( buf ); buf[0] = '\0'; } } if( buf[0] ) towizfile( buf ); for( wiz = first_wiz; wiz; wiz = wiznext ) { wiznext = wiz->next; DISPOSE( wiz->name ); DISPOSE( wiz ); } first_wiz = NULL; last_wiz = NULL; } void do_makewizlist( CHAR_DATA * ch, char *argument ) { make_wizlist( ); } /* mud prog functions */ /* This routine reads in scripts of MUDprograms from a file */ int mprog_name_to_type( char *name ) { if( !str_cmp( name, "in_file_prog" ) ) return IN_FILE_PROG; if( !str_cmp( name, "act_prog" ) ) return ACT_PROG; if( !str_cmp( name, "speech_prog" ) ) return SPEECH_PROG; if( !str_cmp( name, "rand_prog" ) ) return RAND_PROG; if( !str_cmp( name, "fight_prog" ) ) return FIGHT_PROG; if( !str_cmp( name, "hitprcnt_prog" ) ) return HITPRCNT_PROG; if( !str_cmp( name, "death_prog" ) ) return DEATH_PROG; if( !str_cmp( name, "entry_prog" ) ) return ENTRY_PROG; if( !str_cmp( name, "greet_prog" ) ) return GREET_PROG; if( !str_cmp( name, "all_greet_prog" ) ) return ALL_GREET_PROG; if( !str_cmp( name, "give_prog" ) ) return GIVE_PROG; if( !str_cmp( name, "bribe_prog" ) ) return BRIBE_PROG; if( !str_cmp( name, "time_prog" ) ) return TIME_PROG; if( !str_cmp( name, "hour_prog" ) ) return HOUR_PROG; if( !str_cmp( name, "wear_prog" ) ) return WEAR_PROG; if( !str_cmp( name, "remove_prog" ) ) return REMOVE_PROG; if( !str_cmp( name, "sac_prog" ) ) return SAC_PROG; if( !str_cmp( name, "look_prog" ) ) return LOOK_PROG; if( !str_cmp( name, "exa_prog" ) ) return EXA_PROG; if( !str_cmp( name, "zap_prog" ) ) return ZAP_PROG; if( !str_cmp( name, "get_prog" ) ) return GET_PROG; if( !str_cmp( name, "drop_prog" ) ) return DROP_PROG; if( !str_cmp( name, "damage_prog" ) ) return DAMAGE_PROG; if( !str_cmp( name, "repair_prog" ) ) return REPAIR_PROG; if( !str_cmp( name, "greet_prog" ) ) return GREET_PROG; if( !str_cmp( name, "randiw_prog" ) ) return RANDIW_PROG; if( !str_cmp( name, "speechiw_prog" ) ) return SPEECHIW_PROG; if( !str_cmp( name, "pull_prog" ) ) return PULL_PROG; if( !str_cmp( name, "push_prog" ) ) return PUSH_PROG; if( !str_cmp( name, "sleep_prog" ) ) return SLEEP_PROG; if( !str_cmp( name, "rest_prog" ) ) return REST_PROG; if( !str_cmp( name, "rfight_prog" ) ) return FIGHT_PROG; if( !str_cmp( name, "enter_prog" ) ) return ENTRY_PROG; if( !str_cmp( name, "leave_prog" ) ) return LEAVE_PROG; if( !str_cmp( name, "rdeath_prog" ) ) return DEATH_PROG; if( !str_cmp( name, "script_prog" ) ) return SCRIPT_PROG; if( !str_cmp( name, "use_prog" ) ) return USE_PROG; return ( ERROR_PROG ); } MPROG_DATA *mprog_file_read( char *f, MPROG_DATA * mprg, MOB_INDEX_DATA * pMobIndex ) { char MUDProgfile[MAX_INPUT_LENGTH]; FILE *progfile; char letter; MPROG_DATA *mprg_next, *mprg2; bool done = FALSE; sprintf( MUDProgfile, "%s%s", PROG_DIR, f ); progfile = fopen( MUDProgfile, "r" ); if( !progfile ) { bug( "Mob: %d couldn't open mudprog file", pMobIndex->vnum ); exit( 1 ); } mprg2 = mprg; switch ( letter = fread_letter( progfile ) ) { case '>': break; case '|': bug( "empty mudprog file." ); exit( 1 ); break; default: bug( "in mudprog file syntax error." ); exit( 1 ); break; } while( !done ) { mprg2->type = mprog_name_to_type( fread_word( progfile ) ); switch ( mprg2->type ) { case ERROR_PROG: bug( "mudprog file type error" ); exit( 1 ); break; case IN_FILE_PROG: bug( "mprog file contains a call to file." ); exit( 1 ); break; default: xSET_BIT( pMobIndex->progtypes, mprg2->type ); mprg2->arglist = fread_string( progfile ); mprg2->comlist = fread_string( progfile ); switch ( letter = fread_letter( progfile ) ) { case '>': CREATE( mprg_next, MPROG_DATA, 1 ); mprg_next->next = mprg2; mprg2 = mprg_next; break; case '|': done = TRUE; break; default: bug( "in mudprog file syntax error." ); exit( 1 ); break; } break; } } fclose( progfile ); return mprg2; } /* Load a MUDprogram section from the area file. */ void load_mudprogs( AREA_DATA * tarea, FILE * fp ) { MOB_INDEX_DATA *iMob; MPROG_DATA *original; MPROG_DATA *working; char letter; int value; for( ;; ) switch ( letter = fread_letter( fp ) ) { default: bug( "Load_mudprogs: bad command '%c'.", letter ); exit( 1 ); break; case 'S': case 's': fread_to_eol( fp ); return; case '*': fread_to_eol( fp ); break; case 'M': case 'm': value = fread_number( fp ); if( ( iMob = get_mob_index( value ) ) == NULL ) { bug( "Load_mudprogs: vnum %d doesnt exist", value ); exit( 1 ); } /* * Go to the end of the prog command list if other commands * exist */ if( ( original = iMob->mudprogs ) != NULL ) for( ; original->next; original = original->next ); CREATE( working, MPROG_DATA, 1 ); if( original ) original->next = working; else iMob->mudprogs = working; working = mprog_file_read( fread_word( fp ), working, iMob ); working->next = NULL; fread_to_eol( fp ); break; } return; } /* This procedure is responsible for reading any in_file MUDprograms. */ void mprog_read_programs( FILE * fp, MOB_INDEX_DATA * pMobIndex ) { MPROG_DATA *mprg; char letter; bool done = FALSE; if( ( letter = fread_letter( fp ) ) != '>' ) { bug( "Load_mobiles: vnum %d MUDPROG char", pMobIndex->vnum ); exit( 1 ); } CREATE( mprg, MPROG_DATA, 1 ); pMobIndex->mudprogs = mprg; while( !done ) { mprg->type = mprog_name_to_type( fread_word( fp ) ); switch ( mprg->type ) { case ERROR_PROG: bug( "Load_mobiles: vnum %d MUDPROG type.", pMobIndex->vnum ); exit( 1 ); break; case IN_FILE_PROG: mprg = mprog_file_read( fread_string( fp ), mprg, pMobIndex ); fread_to_eol( fp ); switch ( letter = fread_letter( fp ) ) { case '>': CREATE( mprg->next, MPROG_DATA, 1 ); mprg = mprg->next; break; case '|': mprg->next = NULL; fread_to_eol( fp ); done = TRUE; break; default: bug( "Load_mobiles: vnum %d bad MUDPROG.", pMobIndex->vnum ); exit( 1 ); break; } break; default: xSET_BIT( pMobIndex->progtypes, mprg->type ); mprg->arglist = fread_string( fp ); fread_to_eol( fp ); mprg->comlist = fread_string( fp ); fread_to_eol( fp ); switch ( letter = fread_letter( fp ) ) { case '>': CREATE( mprg->next, MPROG_DATA, 1 ); mprg = mprg->next; break; case '|': mprg->next = NULL; fread_to_eol( fp ); done = TRUE; break; default: bug( "Load_mobiles: vnum %d bad MUDPROG.", pMobIndex->vnum ); exit( 1 ); break; } break; } } return; } /*************************************************************/ /* obj prog functions */ /* This routine transfers between alpha and numeric forms of the * mob_prog bitvector types. This allows the use of the words in the * mob/script files. */ /* This routine reads in scripts of OBJprograms from a file */ MPROG_DATA *oprog_file_read( char *f, MPROG_DATA * mprg, OBJ_INDEX_DATA * pObjIndex ) { char MUDProgfile[MAX_INPUT_LENGTH]; FILE *progfile; char letter; MPROG_DATA *mprg_next, *mprg2; bool done = FALSE; sprintf( MUDProgfile, "%s%s", PROG_DIR, f ); progfile = fopen( MUDProgfile, "r" ); if( !progfile ) { bug( "Obj: %d couldnt open mudprog file", pObjIndex->vnum ); exit( 1 ); } mprg2 = mprg; switch ( letter = fread_letter( progfile ) ) { case '>': break; case '|': bug( "empty objprog file." ); exit( 1 ); break; default: bug( "in objprog file syntax error." ); exit( 1 ); break; } while( !done ) { mprg2->type = mprog_name_to_type( fread_word( progfile ) ); switch ( mprg2->type ) { case ERROR_PROG: bug( "objprog file type error" ); exit( 1 ); break; case IN_FILE_PROG: bug( "objprog file contains a call to file." ); exit( 1 ); break; default: xSET_BIT( pObjIndex->progtypes, mprg2->type ); mprg2->arglist = fread_string( progfile ); mprg2->comlist = fread_string( progfile ); switch ( letter = fread_letter( progfile ) ) { case '>': CREATE( mprg_next, MPROG_DATA, 1 ); mprg_next->next = mprg2; mprg2 = mprg_next; break; case '|': done = TRUE; break; default: bug( "in objprog file syntax error." ); exit( 1 ); break; } break; } } fclose( progfile ); return mprg2; } /* Load a MUDprogram section from the area file. */ void load_objprogs( AREA_DATA * tarea, FILE * fp ) { OBJ_INDEX_DATA *iObj; MPROG_DATA *original; MPROG_DATA *working; char letter; int value; for( ;; ) switch ( letter = fread_letter( fp ) ) { default: bug( "Load_objprogs: bad command '%c'.", letter ); exit( 1 ); break; case 'S': case 's': fread_to_eol( fp ); return; case '*': fread_to_eol( fp ); break; case 'M': case 'm': value = fread_number( fp ); if( ( iObj = get_obj_index( value ) ) == NULL ) { bug( "Load_objprogs: vnum %d doesnt exist", value ); exit( 1 ); } /* * Go to the end of the prog command list if other commands * exist */ if( ( original = iObj->mudprogs ) != NULL ) for( ; original->next; original = original->next ); CREATE( working, MPROG_DATA, 1 ); if( original ) original->next = working; else iObj->mudprogs = working; working = oprog_file_read( fread_word( fp ), working, iObj ); working->next = NULL; fread_to_eol( fp ); break; } return; } /* This procedure is responsible for reading any in_file OBJprograms. */ void oprog_read_programs( FILE * fp, OBJ_INDEX_DATA * pObjIndex ) { MPROG_DATA *mprg; char letter; bool done = FALSE; if( ( letter = fread_letter( fp ) ) != '>' ) { bug( "Load_objects: vnum %d OBJPROG char", pObjIndex->vnum ); exit( 1 ); } CREATE( mprg, MPROG_DATA, 1 ); pObjIndex->mudprogs = mprg; while( !done ) { mprg->type = mprog_name_to_type( fread_word( fp ) ); switch ( mprg->type ) { case ERROR_PROG: bug( "Load_objects: vnum %d OBJPROG type.", pObjIndex->vnum ); exit( 1 ); break; case IN_FILE_PROG: mprg = oprog_file_read( fread_string( fp ), mprg, pObjIndex ); fread_to_eol( fp ); switch ( letter = fread_letter( fp ) ) { case '>': CREATE( mprg->next, MPROG_DATA, 1 ); mprg = mprg->next; break; case '|': mprg->next = NULL; fread_to_eol( fp ); done = TRUE; break; default: bug( "Load_objects: vnum %d bad OBJPROG.", pObjIndex->vnum ); exit( 1 ); break; } break; default: xSET_BIT( pObjIndex->progtypes, mprg->type ); mprg->arglist = fread_string( fp ); fread_to_eol( fp ); mprg->comlist = fread_string( fp ); fread_to_eol( fp ); switch ( letter = fread_letter( fp ) ) { case '>': CREATE( mprg->next, MPROG_DATA, 1 ); mprg = mprg->next; break; case '|': mprg->next = NULL; fread_to_eol( fp ); done = TRUE; break; default: bug( "Load_objects: vnum %d bad OBJPROG.", pObjIndex->vnum ); exit( 1 ); break; } break; } } return; } /*************************************************************/ /* room prog functions */ /* This routine transfers between alpha and numeric forms of the * mob_prog bitvector types. This allows the use of the words in the * mob/script files. */ /* This routine reads in scripts of OBJprograms from a file */ MPROG_DATA *rprog_file_read( char *f, MPROG_DATA * mprg, ROOM_INDEX_DATA * RoomIndex ) { char MUDProgfile[MAX_INPUT_LENGTH]; FILE *progfile; char letter; MPROG_DATA *mprg_next, *mprg2; bool done = FALSE; sprintf( MUDProgfile, "%s%s", PROG_DIR, f ); progfile = fopen( MUDProgfile, "r" ); if( !progfile ) { bug( "Room: %d couldnt open roomprog file", RoomIndex->vnum ); exit( 1 ); } mprg2 = mprg; switch ( letter = fread_letter( progfile ) ) { case '>': break; case '|': bug( "empty roomprog file." ); exit( 1 ); break; default: bug( "in roomprog file syntax error." ); exit( 1 ); break; } while( !done ) { mprg2->type = mprog_name_to_type( fread_word( progfile ) ); switch ( mprg2->type ) { case ERROR_PROG: bug( "roomprog file type error" ); exit( 1 ); break; case IN_FILE_PROG: bug( "roomprog file contains a call to file." ); exit( 1 ); break; default: xSET_BIT( RoomIndex->progtypes, mprg2->type ); mprg2->arglist = fread_string( progfile ); mprg2->comlist = fread_string( progfile ); switch ( letter = fread_letter( progfile ) ) { case '>': CREATE( mprg_next, MPROG_DATA, 1 ); mprg_next->next = mprg2; mprg2 = mprg_next; break; case '|': done = TRUE; break; default: bug( "in roomprog file syntax error." ); exit( 1 ); break; } break; } } fclose( progfile ); return mprg2; } /* Load a ROOMprogram section from the area file. */ void load_roomprogs( AREA_DATA * tarea, FILE * fp ) { ROOM_INDEX_DATA *iRoom; MPROG_DATA *original; MPROG_DATA *working; char letter; int value; for( ;; ) switch ( letter = fread_letter( fp ) ) { default: bug( "Load_objprogs: bad command '%c'.", letter ); exit( 1 ); break; case 'S': case 's': fread_to_eol( fp ); return; case '*': fread_to_eol( fp ); break; case 'M': case 'm': value = fread_number( fp ); if( ( iRoom = get_room_index( value ) ) == NULL ) { bug( "Load_roomprogs: vnum %d doesnt exist", value ); exit( 1 ); } /* * Go to the end of the prog command list if other commands * exist */ if( ( original = iRoom->mudprogs ) != NULL ) for( ; original->next; original = original->next ); CREATE( working, MPROG_DATA, 1 ); if( original ) original->next = working; else iRoom->mudprogs = working; working = rprog_file_read( fread_word( fp ), working, iRoom ); working->next = NULL; fread_to_eol( fp ); break; } return; } /* This procedure is responsible for reading any in_file ROOMprograms. */ void rprog_read_programs( FILE * fp, ROOM_INDEX_DATA * pRoomIndex ) { MPROG_DATA *mprg; char letter; bool done = FALSE; if( ( letter = fread_letter( fp ) ) != '>' ) { bug( "Load_rooms: vnum %d ROOMPROG char", pRoomIndex->vnum ); exit( 1 ); } CREATE( mprg, MPROG_DATA, 1 ); pRoomIndex->mudprogs = mprg; while( !done ) { mprg->type = mprog_name_to_type( fread_word( fp ) ); switch ( mprg->type ) { case ERROR_PROG: bug( "Load_rooms: vnum %d ROOMPROG type.", pRoomIndex->vnum ); exit( 1 ); break; case IN_FILE_PROG: mprg = rprog_file_read( fread_string( fp ), mprg, pRoomIndex ); fread_to_eol( fp ); switch ( letter = fread_letter( fp ) ) { case '>': CREATE( mprg->next, MPROG_DATA, 1 ); mprg = mprg->next; break; case '|': mprg->next = NULL; fread_to_eol( fp ); done = TRUE; break; default: bug( "Load_rooms: vnum %d bad ROOMPROG.", pRoomIndex->vnum ); exit( 1 ); break; } break; default: xSET_BIT( pRoomIndex->progtypes, mprg->type ); mprg->arglist = fread_string( fp ); fread_to_eol( fp ); mprg->comlist = fread_string( fp ); fread_to_eol( fp ); switch ( letter = fread_letter( fp ) ) { case '>': CREATE( mprg->next, MPROG_DATA, 1 ); mprg = mprg->next; break; case '|': mprg->next = NULL; fread_to_eol( fp ); done = TRUE; break; default: bug( "Load_rooms: vnum %d bad ROOMPROG.", pRoomIndex->vnum ); exit( 1 ); break; } break; } } return; } /*************************************************************/ /* Function to delete a room index. Called from do_rdelete in build.c Narn, May/96 Don't ask me why they return bool.. :).. oh well.. -- Alty */ bool delete_room( ROOM_INDEX_DATA * room ) { int hash; ROOM_INDEX_DATA *prev, *limbo = get_room_index( ROOM_VNUM_LIMBO ); OBJ_DATA *o; CHAR_DATA *ch; EXTRA_DESCR_DATA *ed; EXIT_DATA *ex; MPROG_ACT_LIST *mpact; MPROG_DATA *mp; while( ( ch = room->first_person ) != NULL ) { if( !IS_NPC( ch ) ) { char_from_room( ch ); char_to_room( ch, limbo ); } else extract_char( ch, TRUE ); } while( ( o = room->first_content ) != NULL ) extract_obj( o ); while( ( ed = room->first_extradesc ) != NULL ) { room->first_extradesc = ed->next; STRFREE( ed->keyword ); STRFREE( ed->description ); DISPOSE( ed ); --top_ed; } while( ( ex = room->first_exit ) != NULL ) extract_exit( room, ex ); while( ( mpact = room->mpact ) != NULL ) { room->mpact = mpact->next; DISPOSE( mpact->buf ); DISPOSE( mpact ); } while( ( mp = room->mudprogs ) != NULL ) { room->mudprogs = mp->next; STRFREE( mp->arglist ); STRFREE( mp->comlist ); DISPOSE( mp ); } if( room->map ) { MAP_INDEX_DATA *mapi; if( ( mapi = get_map_index( room->map->vnum ) ) != NULL ) if( room->map->x > 0 && room->map->x < 80 && room->map->y > 0 && room->map->y < 48 ) mapi->map_of_vnums[room->map->y][room->map->x] = -1; DISPOSE( room->map ); } STRFREE( room->name ); STRFREE( room->description ); hash = room->vnum % MAX_KEY_HASH; if( room == room_index_hash[hash] ) room_index_hash[hash] = room->next; else { for( prev = room_index_hash[hash]; prev; prev = prev->next ) if( prev->next == room ) break; if( prev ) prev->next = room->next; else bug( "delete_room: room %d not in hash bucket %d.", room->vnum, hash ); } DISPOSE( room ); --top_room; return TRUE; } /* See comment on delete_room. */ bool delete_obj( OBJ_INDEX_DATA * obj ) { int hash; OBJ_INDEX_DATA *prev; OBJ_DATA *o, *o_next; EXTRA_DESCR_DATA *ed; AFFECT_DATA *af; MPROG_DATA *mp; int auc; /* * Remove references to object index */ for( o = first_object; o; o = o_next ) { o_next = o->next; if( o->pIndexData == obj ) extract_obj( o ); } while( ( ed = obj->first_extradesc ) != NULL ) { obj->first_extradesc = ed->next; STRFREE( ed->keyword ); STRFREE( ed->description ); DISPOSE( ed ); --top_ed; } while( ( af = obj->first_affect ) != NULL ) { obj->first_affect = af->next; DISPOSE( af ); --top_affect; } while( ( mp = obj->mudprogs ) != NULL ) { obj->mudprogs = mp->next; STRFREE( mp->arglist ); STRFREE( mp->comlist ); DISPOSE( mp ); } STRFREE( obj->name ); STRFREE( obj->short_descr ); STRFREE( obj->description ); STRFREE( obj->action_desc ); for( auc = 0; auc < AUCTION_MEM; ++auc ) if( auction->history[auc] == obj ) { if( auc < AUCTION_MEM - 1 ) memmove( &auction->history[auc], &auction->history[auc + 1], ( AUCTION_MEM - auc - 1 ) * sizeof( OBJ_INDEX_DATA * ) ); auction->history[AUCTION_MEM - 1] = NULL; --auc; } hash = obj->vnum % MAX_KEY_HASH; if( obj == obj_index_hash[hash] ) obj_index_hash[hash] = obj->next; else { for( prev = obj_index_hash[hash]; prev; prev = prev->next ) if( prev->next == obj ) break; if( prev ) prev->next = obj->next; else bug( "delete_obj: object %d not in hash bucket %d.", obj->vnum, hash ); } DISPOSE( obj ); --top_obj_index; return TRUE; } /* See comment on delete_room. */ bool delete_mob( MOB_INDEX_DATA * mob ) { int hash; MOB_INDEX_DATA *prev; CHAR_DATA *ch, *ch_next; MPROG_DATA *mp; for( ch = first_char; ch; ch = ch_next ) { ch_next = ch->next; if( ch->pIndexData == mob ) extract_char( ch, TRUE ); } while( ( mp = mob->mudprogs ) != NULL ) { mob->mudprogs = mp->next; STRFREE( mp->arglist ); STRFREE( mp->comlist ); DISPOSE( mp ); } if( mob->pShop ) { UNLINK( mob->pShop, first_shop, last_shop, next, prev ); DISPOSE( mob->pShop ); --top_shop; } if( mob->rShop ) { UNLINK( mob->rShop, first_repair, last_repair, next, prev ); DISPOSE( mob->rShop ); --top_repair; } STRFREE( mob->player_name ); STRFREE( mob->short_descr ); STRFREE( mob->long_descr ); STRFREE( mob->description ); hash = mob->vnum % MAX_KEY_HASH; if( mob == mob_index_hash[hash] ) mob_index_hash[hash] = mob->next; else { for( prev = mob_index_hash[hash]; prev; prev = prev->next ) if( prev->next == mob ) break; if( prev ) prev->next = mob->next; else bug( "delete_mob: mobile %d not in hash bucket %d.", mob->vnum, hash ); } DISPOSE( mob ); --top_mob_index; return TRUE; } /* * Creat a new room (for online building) -Thoric */ ROOM_INDEX_DATA *make_room( int vnum ) { ROOM_INDEX_DATA *pRoomIndex; int iHash; CREATE( pRoomIndex, ROOM_INDEX_DATA, 1 ); pRoomIndex->first_person = NULL; pRoomIndex->last_person = NULL; pRoomIndex->first_content = NULL; pRoomIndex->last_content = NULL; pRoomIndex->first_extradesc = NULL; pRoomIndex->last_extradesc = NULL; pRoomIndex->area = NULL; pRoomIndex->vnum = vnum; pRoomIndex->name = STRALLOC( "Floating in a void" ); pRoomIndex->description = STRALLOC( "" ); // pRoomIndex->room_flags = if( !xIS_SET( pRoomIndex->room_flags, ROOM_PROTOTYPE ) ) xSET_BIT( pRoomIndex->room_flags, ROOM_PROTOTYPE ); pRoomIndex->sector_type = 1; pRoomIndex->light = 0; pRoomIndex->first_exit = NULL; pRoomIndex->last_exit = NULL; iHash = vnum % MAX_KEY_HASH; pRoomIndex->next = room_index_hash[iHash]; room_index_hash[iHash] = pRoomIndex; top_room++; return pRoomIndex; } /* * Create a new INDEX object (for online building) -Thoric * Option to clone an existing index object. */ OBJ_INDEX_DATA *make_object( int vnum, int cvnum, char *name ) { OBJ_INDEX_DATA *pObjIndex, *cObjIndex; char buf[MAX_STRING_LENGTH]; int iHash; if( cvnum > 0 ) cObjIndex = get_obj_index( cvnum ); else cObjIndex = NULL; CREATE( pObjIndex, OBJ_INDEX_DATA, 1 ); pObjIndex->vnum = vnum; pObjIndex->name = STRALLOC( name ); pObjIndex->first_affect = NULL; pObjIndex->last_affect = NULL; pObjIndex->first_extradesc = NULL; pObjIndex->last_extradesc = NULL; if( !cObjIndex ) { sprintf( buf, "A newly created %s", name ); pObjIndex->short_descr = STRALLOC( buf ); sprintf( buf, "Some god dropped a newly created %s here.", name ); pObjIndex->description = STRALLOC( buf ); pObjIndex->action_desc = STRALLOC( "" ); pObjIndex->short_descr[0] = LOWER( pObjIndex->short_descr[0] ); pObjIndex->description[0] = UPPER( pObjIndex->description[0] ); pObjIndex->item_type = ITEM_TRASH; xCLEAR_BITS( pObjIndex->extra_flags ); xSET_BIT( pObjIndex->extra_flags, ITEM_PROTOTYPE ); pObjIndex->wear_flags = 0; pObjIndex->value[0] = 0; pObjIndex->value[1] = 0; pObjIndex->value[2] = 0; pObjIndex->value[3] = 0; pObjIndex->weight = 1; pObjIndex->cost = 0; } else { EXTRA_DESCR_DATA *ed, *ced; AFFECT_DATA *paf, *cpaf; pObjIndex->short_descr = QUICKLINK( cObjIndex->short_descr ); pObjIndex->description = QUICKLINK( cObjIndex->description ); pObjIndex->action_desc = QUICKLINK( cObjIndex->action_desc ); pObjIndex->item_type = cObjIndex->item_type; pObjIndex->extra_flags = cObjIndex->extra_flags; xSET_BIT( pObjIndex->extra_flags, ITEM_PROTOTYPE ); pObjIndex->wear_flags = cObjIndex->wear_flags; pObjIndex->value[0] = cObjIndex->value[0]; pObjIndex->value[1] = cObjIndex->value[1]; pObjIndex->value[2] = cObjIndex->value[2]; pObjIndex->value[3] = cObjIndex->value[3]; pObjIndex->weight = cObjIndex->weight; pObjIndex->cost = cObjIndex->cost; for( ced = cObjIndex->first_extradesc; ced; ced = ced->next ) { CREATE( ed, EXTRA_DESCR_DATA, 1 ); ed->keyword = QUICKLINK( ced->keyword ); ed->description = QUICKLINK( ced->description ); LINK( ed, pObjIndex->first_extradesc, pObjIndex->last_extradesc, next, prev ); top_ed++; } for( cpaf = cObjIndex->first_affect; cpaf; cpaf = cpaf->next ) { CREATE( paf, AFFECT_DATA, 1 ); paf->type = cpaf->type; paf->duration = cpaf->duration; paf->location = cpaf->location; paf->modifier = cpaf->modifier; paf->bitvector = cpaf->bitvector; LINK( paf, pObjIndex->first_affect, pObjIndex->last_affect, next, prev ); top_affect++; } } pObjIndex->count = 0; iHash = vnum % MAX_KEY_HASH; pObjIndex->next = obj_index_hash[iHash]; obj_index_hash[iHash] = pObjIndex; top_obj_index++; return pObjIndex; } /* * Create a new INDEX mobile (for online building) -Thoric * Option to clone an existing index mobile. */ MOB_INDEX_DATA *make_mobile( int vnum, int cvnum, char *name ) { MOB_INDEX_DATA *pMobIndex, *cMobIndex; char buf[MAX_STRING_LENGTH]; int iHash; if( cvnum > 0 ) cMobIndex = get_mob_index( cvnum ); else cMobIndex = NULL; CREATE( pMobIndex, MOB_INDEX_DATA, 1 ); pMobIndex->vnum = vnum; pMobIndex->count = 0; pMobIndex->killed = 0; pMobIndex->player_name = STRALLOC( name ); if( !cMobIndex ) { sprintf( buf, "A newly created %s", name ); pMobIndex->short_descr = STRALLOC( buf ); sprintf( buf, "Some god abandoned a newly created %s here.", name ); pMobIndex->long_descr = STRALLOC( buf ); pMobIndex->description = STRALLOC( "" ); pMobIndex->short_descr[0] = LOWER( pMobIndex->short_descr[0] ); pMobIndex->long_descr[0] = UPPER( pMobIndex->long_descr[0] ); pMobIndex->description[0] = UPPER( pMobIndex->description[0] ); xCLEAR_BITS( pMobIndex->act ); xSET_BIT( pMobIndex->act, ACT_IS_NPC ); xSET_BIT( pMobIndex->act, ACT_PROTOTYPE ); xCLEAR_BITS( pMobIndex->affected_by ); pMobIndex->pShop = NULL; pMobIndex->rShop = NULL; pMobIndex->spec_fun = NULL; pMobIndex->mudprogs = NULL; xCLEAR_BITS( pMobIndex->progtypes ); pMobIndex->alignment = 0; pMobIndex->level = 1; pMobIndex->mobthac0 = 0; pMobIndex->ac = 100; pMobIndex->hitnodice = 1; pMobIndex->hitsizedice = 20; pMobIndex->hitplus = 0; pMobIndex->damnodice = 2; pMobIndex->damsizedice = 5; pMobIndex->damplus = 0; pMobIndex->gold = -1; pMobIndex->exp = 1; /* * Bug noticed by Sevoreria Dragonlight * -- So we set it back to constants.. :P.. changed to POS_STANDING -- Alty */ pMobIndex->position = POS_STANDING; pMobIndex->defposition = POS_STANDING; pMobIndex->sex = 0; pMobIndex->perm_str = 10; pMobIndex->perm_dex = 10; pMobIndex->perm_int = 10; pMobIndex->perm_con = 10; pMobIndex->perm_lck = 0; pMobIndex->race = 0; pMobIndex->class = 0; pMobIndex->xflags = 0; pMobIndex->resistant = 0; pMobIndex->immune = 0; pMobIndex->susceptible = 0; pMobIndex->numattacks = 0; xCLEAR_BITS( pMobIndex->attacks ); xCLEAR_BITS( pMobIndex->defenses ); } else { pMobIndex->short_descr = QUICKLINK( cMobIndex->short_descr ); pMobIndex->long_descr = QUICKLINK( cMobIndex->long_descr ); pMobIndex->description = QUICKLINK( cMobIndex->description ); pMobIndex->act = cMobIndex->act; xSET_BIT( pMobIndex->act, ACT_PROTOTYPE ); pMobIndex->affected_by = cMobIndex->affected_by; pMobIndex->pShop = NULL; pMobIndex->rShop = NULL; pMobIndex->spec_fun = cMobIndex->spec_fun; pMobIndex->mudprogs = NULL; xCLEAR_BITS( pMobIndex->progtypes ); pMobIndex->alignment = cMobIndex->alignment; pMobIndex->level = cMobIndex->level; pMobIndex->mobthac0 = cMobIndex->mobthac0; pMobIndex->ac = cMobIndex->ac; pMobIndex->hitnodice = cMobIndex->hitnodice; pMobIndex->hitsizedice = cMobIndex->hitsizedice; pMobIndex->hitplus = cMobIndex->hitplus; pMobIndex->damnodice = cMobIndex->damnodice; pMobIndex->damsizedice = cMobIndex->damsizedice; pMobIndex->damplus = cMobIndex->damplus; pMobIndex->gold = cMobIndex->gold; pMobIndex->exp = cMobIndex->exp; pMobIndex->position = cMobIndex->position; pMobIndex->defposition = cMobIndex->defposition; pMobIndex->sex = cMobIndex->sex; pMobIndex->perm_str = cMobIndex->perm_str; pMobIndex->perm_dex = cMobIndex->perm_dex; pMobIndex->perm_int = cMobIndex->perm_int; pMobIndex->perm_con = cMobIndex->perm_con; pMobIndex->perm_lck = cMobIndex->perm_lck; pMobIndex->race = cMobIndex->race; pMobIndex->class = cMobIndex->class; pMobIndex->xflags = cMobIndex->xflags; pMobIndex->resistant = cMobIndex->resistant; pMobIndex->immune = cMobIndex->immune; pMobIndex->susceptible = cMobIndex->susceptible; pMobIndex->numattacks = cMobIndex->numattacks; pMobIndex->attacks = cMobIndex->attacks; pMobIndex->defenses = cMobIndex->defenses; } iHash = vnum % MAX_KEY_HASH; pMobIndex->next = mob_index_hash[iHash]; mob_index_hash[iHash] = pMobIndex; top_mob_index++; return pMobIndex; } /* * Creates a simple exit with no fields filled but rvnum and optionally * to_room and vnum. -Thoric * Exits are inserted into the linked list based on vdir. */ EXIT_DATA *make_exit( ROOM_INDEX_DATA * pRoomIndex, ROOM_INDEX_DATA * to_room, sh_int door ) { EXIT_DATA *pexit, *texit; bool broke; CREATE( pexit, EXIT_DATA, 1 ); pexit->vdir = door; pexit->rvnum = pRoomIndex->vnum; pexit->to_room = to_room; pexit->distance = 1; if( to_room ) { pexit->vnum = to_room->vnum; texit = get_exit_to( to_room, rev_dir[door], pRoomIndex->vnum ); if( texit ) /* assign reverse exit pointers */ { texit->rexit = pexit; pexit->rexit = texit; } } broke = FALSE; for( texit = pRoomIndex->first_exit; texit; texit = texit->next ) if( door < texit->vdir ) { broke = TRUE; break; } if( !pRoomIndex->first_exit ) pRoomIndex->first_exit = pexit; else { /* * keep exits in incremental order - insert exit into list */ if( broke && texit ) { if( !texit->prev ) pRoomIndex->first_exit = pexit; else texit->prev->next = pexit; pexit->prev = texit->prev; pexit->next = texit; texit->prev = pexit; top_exit++; return pexit; } pRoomIndex->last_exit->next = pexit; } pexit->next = NULL; pexit->prev = pRoomIndex->last_exit; pRoomIndex->last_exit = pexit; top_exit++; return pexit; } void fix_area_exits( AREA_DATA * tarea ) { ROOM_INDEX_DATA *pRoomIndex; EXIT_DATA *pexit, *rev_exit; int rnum; bool fexit; for( rnum = tarea->low_r_vnum; rnum <= tarea->hi_r_vnum; rnum++ ) { if( ( pRoomIndex = get_room_index( rnum ) ) == NULL ) continue; fexit = FALSE; for( pexit = pRoomIndex->first_exit; pexit; pexit = pexit->next ) { fexit = TRUE; pexit->rvnum = pRoomIndex->vnum; if( pexit->vnum <= 0 ) pexit->to_room = NULL; else pexit->to_room = get_room_index( pexit->vnum ); } if( !fexit ) xSET_BIT( pRoomIndex->room_flags, ROOM_NO_MOB ); } for( rnum = tarea->low_r_vnum; rnum <= tarea->hi_r_vnum; rnum++ ) { if( ( pRoomIndex = get_room_index( rnum ) ) == NULL ) continue; for( pexit = pRoomIndex->first_exit; pexit; pexit = pexit->next ) { if( pexit->to_room && !pexit->rexit ) { rev_exit = get_exit_to( pexit->to_room, rev_dir[pexit->vdir], pRoomIndex->vnum ); if( rev_exit ) { pexit->rexit = rev_exit; rev_exit->rexit = pexit; } } } } } void load_area_file( AREA_DATA * tarea, char *filename ) { if( fBootDb ) tarea = last_area; if( !fBootDb && !tarea ) { bug( "Load_area: null area!" ); return; } if( ( fpArea = fopen( filename, "r" ) ) == NULL ) { perror( filename ); bug( "load_area: error loading file (can't open)" ); bug( filename ); return; } area_version = 0; for( ;; ) { char *word; if( fread_letter( fpArea ) != '#' ) { bug( tarea->filename ); bug( "load_area: # not found." ); exit( 1 ); } word = fread_word( fpArea ); if( word[0] == '$' ) break; else if( !str_cmp( word, "AREA" ) ) { if( fBootDb ) { load_area( fpArea ); tarea = last_area; } else { DISPOSE( tarea->name ); tarea->name = fread_string_nohash( fpArea ); } } else if( !str_cmp( word, "AUTHOR" ) ) load_author( tarea, fpArea ); else if( !str_cmp( word, "FLAGS" ) ) load_flags( tarea, fpArea ); else if( !str_cmp( word, "RANGES" ) ) load_ranges( tarea, fpArea ); /* * if we're loading this value than it's an old area version so * * we just junk the values and let it auto set -Goku 09.29.04 */ else if( !str_cmp( word, "ECONOMY" ) ) { fread_number( fpArea ); fread_number( fpArea ); } else if( !str_cmp( word, "PLANET" ) ) load_areaPlanet( tarea, fpArea ); else if( !str_cmp( word, "RESETMSG" ) ) load_resetmsg( tarea, fpArea ); /* * Rennard */ else if( !str_cmp( word, "HELPS" ) ) load_helps( tarea, fpArea ); else if( !str_cmp( word, "MOBILES" ) ) load_mobiles( tarea, fpArea ); else if( !str_cmp( word, "MUDPROGS" ) ) load_mudprogs( tarea, fpArea ); else if( !str_cmp( word, "OBJECTS" ) ) load_objects( tarea, fpArea ); else if( !str_cmp( word, "OBJPROGS" ) ) load_objprogs( tarea, fpArea ); else if( !str_cmp( word, "RESETS" ) ) load_resets( tarea, fpArea ); else if( !str_cmp( word, "ROOMS" ) ) load_rooms( tarea, fpArea ); else if( !str_cmp( word, "SHOPS" ) ) load_shops( tarea, fpArea ); else if( !str_cmp( word, "REPAIRS" ) ) load_repairs( tarea, fpArea ); else if( !str_cmp( word, "SPECIALS" ) ) load_specials( tarea, fpArea ); else if( !str_cmp( word, "CLIMATE" ) ) load_climate( tarea, fpArea ); else if( !str_cmp( word, "NEIGHBOR" ) ) load_neighbor( tarea, fpArea ); else if( !str_cmp( word, "VERSION" ) ) load_version( tarea, fpArea ); else if( !str_cmp( word, "SPELLLIMIT" ) ) { tarea->spelllimit = fread_number( fpArea ); } else { bug( tarea->filename ); bug( "load_area: bad section name." ); if( fBootDb ) exit( 1 ); else { fclose( fpArea ); fpArea = NULL; return; } } } fclose( fpArea ); fpArea = NULL; if( tarea ) { if( fBootDb ) { sort_area_by_name( tarea ); /* 4/27/97 */ sort_area( tarea, FALSE ); } fprintf( stderr, "%-14s: Rooms: %5d - %-5d Objs: %5d - %-5d Mobs: %5d - %d\n", tarea->filename, tarea->low_r_vnum, tarea->hi_r_vnum, tarea->low_o_vnum, tarea->hi_o_vnum, tarea->low_m_vnum, tarea->hi_m_vnum ); if( !tarea->author ) tarea->author = STRALLOC( "" ); SET_BIT( tarea->status, AREA_LOADED ); } else fprintf( stderr, "(%s)\n", filename ); } void load_reserved( void ) { RESERVE_DATA *res; FILE *fp; if( !( fp = fopen( SYSTEM_DIR RESERVED_LIST, "r" ) ) ) return; for( ;; ) { if( feof( fp ) ) { bug( "Load_reserved: no $ found." ); fclose( fp ); return; } CREATE( res, RESERVE_DATA, 1 ); res->name = fread_string_nohash( fp ); if( *res->name == '$' ) break; sort_reserved( res ); } DISPOSE( res->name ); DISPOSE( res ); fclose( fp ); return; } /* Build list of in_progress areas. Do not load areas. * define AREA_READ if you want it to build area names rather than reading * them out of the area files. -- Altrag */ void load_buildlist( void ) { DIR *dp; struct dirent *dentry; FILE *fp; char buf[MAX_STRING_LENGTH]; AREA_DATA *pArea; char line[81]; char word[81]; int low, hi; int mlow, mhi, olow, ohi, rlow, rhi; bool badfile = FALSE; char temp; dp = opendir( GOD_DIR ); dentry = readdir( dp ); while( dentry ) { if( dentry->d_name[0] != '.' ) { sprintf( buf, "%s%s", GOD_DIR, dentry->d_name ); if( !( fp = fopen( buf, "r" ) ) ) { bug( "Load_buildlist: invalid file" ); perror( buf ); dentry = readdir( dp ); continue; } log_string( buf ); badfile = FALSE; rlow = rhi = olow = ohi = mlow = mhi = 0; while( !feof( fp ) && !ferror( fp ) ) { low = 0; hi = 0; word[0] = 0; line[0] = 0; if( ( temp = fgetc( fp ) ) != EOF ) ungetc( temp, fp ); else break; fgets( line, 80, fp ); sscanf( line, "%s %d %d", word, &low, &hi ); if( !strcmp( word, "Level" ) ) { if( low < LEVEL_IMMORTAL ) { sprintf( buf, "%s: God file with level %d < %d", dentry->d_name, low, LEVEL_IMMORTAL ); badfile = TRUE; } } if( !strcmp( word, "RoomRange" ) ) rlow = low, rhi = hi; else if( !strcmp( word, "MobRange" ) ) mlow = low, mhi = hi; else if( !strcmp( word, "ObjRange" ) ) olow = low, ohi = hi; } fclose( fp ); if( rlow && rhi && !badfile ) { sprintf( buf, "%s%s.are", BUILD_DIR, dentry->d_name ); if( !( fp = fopen( buf, "r" ) ) ) { bug( "Load_buildlist: cannot open area file for read" ); perror( buf ); dentry = readdir( dp ); continue; } #if !defined(READ_AREA) /* Dont always want to read stuff.. dunno.. shrug */ strcpy( word, fread_word( fp ) ); if( word[0] != '#' || strcmp( &word[1], "AREA" ) ) { sprintf( buf, "Make_buildlist: %s.are: no #AREA found.", dentry->d_name ); fclose( fp ); dentry = readdir( dp ); continue; } #endif CREATE( pArea, AREA_DATA, 1 ); sprintf( buf, "%s.are", dentry->d_name ); pArea->author = STRALLOC( dentry->d_name ); pArea->filename = str_dup( buf ); #if !defined(READ_AREA) pArea->name = fread_string_nohash( fp ); #else sprintf( buf, "{PROTO} %s's area in progress", dentry->d_name ); pArea->name = str_dup( buf ); #endif fclose( fp ); pArea->low_r_vnum = rlow; pArea->hi_r_vnum = rhi; pArea->low_m_vnum = mlow; pArea->hi_m_vnum = mhi; pArea->low_o_vnum = olow; pArea->hi_o_vnum = ohi; pArea->low_soft_range = -1; pArea->hi_soft_range = -1; pArea->low_hard_range = -1; pArea->hi_hard_range = -1; CREATE( pArea->weather, WEATHER_DATA, 1 ); /* FB */ pArea->weather->temp = 0; pArea->weather->precip = 0; pArea->weather->wind = 0; pArea->weather->temp_vector = 0; pArea->weather->precip_vector = 0; pArea->weather->wind_vector = 0; pArea->weather->climate_temp = 2; pArea->weather->climate_precip = 2; pArea->weather->climate_wind = 2; pArea->weather->first_neighbor = NULL; pArea->weather->last_neighbor = NULL; pArea->weather->echo = NULL; pArea->weather->echo_color = AT_GREY; pArea->first_reset = NULL; pArea->last_reset = NULL; LINK( pArea, first_build, last_build, next, prev ); fprintf( stderr, "%-14s: Rooms: %5d - %-5d Objs: %5d - %-5d " "Mobs: %5d - %-5d\n", pArea->filename, pArea->low_r_vnum, pArea->hi_r_vnum, pArea->low_o_vnum, pArea->hi_o_vnum, pArea->low_m_vnum, pArea->hi_m_vnum ); sort_area( pArea, TRUE ); } } dentry = readdir( dp ); } closedir( dp ); } /* Rebuilt from broken copy, but bugged - commented out for now - Blod */ void sort_reserved( RESERVE_DATA * pRes ) { RESERVE_DATA *res = NULL; if( !pRes ) { bug( "Sort_reserved: NULL pRes" ); return; } pRes->next = NULL; pRes->prev = NULL; for( res = first_reserved; res; res = res->next ) { if( strcasecmp( pRes->name, res->name ) > 0 ) { INSERT( pRes, res, first_reserved, next, prev ); break; } } if( !res ) { LINK( pRes, first_reserved, last_reserved, next, prev ); } return; } /* * Sort areas by name alphanumercially * - 4/27/97, Fireblade */ void sort_area_by_name( AREA_DATA * pArea ) { AREA_DATA *temp_area; if( !pArea ) { bug( "Sort_area_by_name: NULL pArea" ); return; } for( temp_area = first_area_name; temp_area; temp_area = temp_area->next_sort_name ) { if( strcmp( pArea->name, temp_area->name ) < 0 ) { INSERT( pArea, temp_area, first_area_name, next_sort_name, prev_sort_name ); break; } } if( !temp_area ) { LINK( pArea, first_area_name, last_area_name, next_sort_name, prev_sort_name ); } return; } /* * Sort by room vnums -Altrag & Thoric */ void sort_area( AREA_DATA * pArea, bool proto ) { AREA_DATA *area = NULL; AREA_DATA *first_sort, *last_sort; bool found; if( !pArea ) { bug( "Sort_area: NULL pArea" ); return; } if( proto ) { first_sort = first_bsort; last_sort = last_bsort; } else { first_sort = first_asort; last_sort = last_asort; } found = FALSE; pArea->next_sort = NULL; pArea->prev_sort = NULL; if( !first_sort ) { pArea->prev_sort = NULL; pArea->next_sort = NULL; first_sort = pArea; last_sort = pArea; found = TRUE; } else for( area = first_sort; area; area = area->next_sort ) if( pArea->low_r_vnum < area->low_r_vnum ) { if( !area->prev_sort ) first_sort = pArea; else area->prev_sort->next_sort = pArea; pArea->prev_sort = area->prev_sort; pArea->next_sort = area; area->prev_sort = pArea; found = TRUE; break; } if( !found ) { pArea->prev_sort = last_sort; pArea->next_sort = NULL; last_sort->next_sort = pArea; last_sort = pArea; } if( proto ) { first_bsort = first_sort; last_bsort = last_sort; } else { first_asort = first_sort; last_asort = last_sort; } } /* * Display vnums currently assigned to areas -Altrag & Thoric * Sorted, and flagged if loaded. */ void show_vnums( CHAR_DATA * ch, int low, int high, bool proto, bool shownl, char *loadst, char *notloadst ) { AREA_DATA *pArea, *first_sort; int count, loaded; count = 0; loaded = 0; set_pager_color( AT_PLAIN, ch ); if( proto ) first_sort = first_bsort; else first_sort = first_asort; for( pArea = first_sort; pArea; pArea = pArea->next_sort ) { if( IS_SET( pArea->status, AREA_DELETED ) ) continue; if( pArea->low_r_vnum < low ) continue; if( pArea->hi_r_vnum > high ) break; if( IS_SET( pArea->status, AREA_LOADED ) ) loaded++; else if( !shownl ) continue; pager_printf( ch, "%-15s| Rooms: %5d - %-5d" " Objs: %5d - %-5d Mobs: %5d - %-5d%s\n\r", ( pArea->filename ? pArea->filename : "(invalid)" ), pArea->low_r_vnum, pArea->hi_r_vnum, pArea->low_o_vnum, pArea->hi_o_vnum, pArea->low_m_vnum, pArea->hi_m_vnum, IS_SET( pArea->status, AREA_LOADED ) ? loadst : notloadst ); count++; } pager_printf( ch, "Areas listed: %d Loaded: %d\n\r", count, loaded ); return; } /* * Shows prototype vnums ranges, and if loaded */ void do_vnums( CHAR_DATA * ch, char *argument ) { char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; int low, high; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); low = 0; high = MAX_VNUMS; if( arg1[0] != '\0' ) { low = atoi( arg1 ); if( arg2[0] != '\0' ) high = atoi( arg2 ); } show_vnums( ch, low, high, TRUE, TRUE, " *", "" ); } /* * Shows installed areas, sorted. Mark unloaded areas with an X */ void do_zones( CHAR_DATA * ch, char *argument ) { char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; int low, high; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); low = 0; high = MAX_VNUMS; if( arg1[0] != '\0' ) { low = atoi( arg1 ); if( arg2[0] != '\0' ) high = atoi( arg2 ); } show_vnums( ch, low, high, FALSE, TRUE, "", " X" ); } /* * Show prototype areas, sorted. Only show loaded areas */ void do_newzones( CHAR_DATA * ch, char *argument ) { char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; int low, high; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); low = 0; high = MAX_VNUMS; if( arg1[0] != '\0' ) { low = atoi( arg1 ); if( arg2[0] != '\0' ) high = atoi( arg2 ); } show_vnums( ch, low, high, TRUE, FALSE, "", " X" ); } /* * Save system info to data file */ void save_sysdata( SYSTEM_DATA sys ) { FILE *fp; char filename[MAX_INPUT_LENGTH]; extern bool wizlock; extern int locklev; int a = 0; sprintf( filename, "%ssysdata.dat", SYSTEM_DIR ); fclose( fpReserve ); if( ( fp = fopen( filename, "w" ) ) == NULL ) { bug( "save_sysdata: fopen" ); perror( filename ); } else { fprintf( fp, "#SYSTEM\n" ); fprintf( fp, "MudName %s~\n", sys.mud_name ); fprintf( fp, "Highplayers %d\n", sys.alltimemax ); fprintf( fp, "Highplayertime %s~\n", sys.time_of_max ); fprintf( fp, "CheckImmHost %d\n", sys.check_imm_host ); fprintf( fp, "Nameresolving %d\n", sys.NO_NAME_RESOLVING ); fprintf( fp, "Waitforauth %d\n", sys.WAIT_FOR_AUTH ); fprintf( fp, "Readallmail %d\n", sys.read_all_mail ); fprintf( fp, "Readmailfree %d\n", sys.read_mail_free ); fprintf( fp, "Writemailfree %d\n", sys.write_mail_free ); fprintf( fp, "Takeothersmail %d\n", sys.take_others_mail ); fprintf( fp, "IMCMailVnum %d\n", sys.imc_mail_vnum ); fprintf( fp, "Muse %d\n", sys.muse_level ); fprintf( fp, "Think %d\n", sys.think_level ); fprintf( fp, "Build %d\n", sys.build_level ); fprintf( fp, "Log %d\n", sys.log_level ); fprintf( fp, "Protoflag %d\n", sys.level_modify_proto ); fprintf( fp, "Invokeall %d\n", sys.level_invoke_proto ); fprintf( fp, "Overridepriv %d\n", sys.level_override_private ); fprintf( fp, "Msetplayer %d\n", sys.level_mset_player ); fprintf( fp, "Stunplrvsplr %d\n", sys.stun_plr_vs_plr ); fprintf( fp, "Stunregular %d\n", sys.stun_regular ); fprintf( fp, "Gougepvp %d\n", sys.gouge_plr_vs_plr ); fprintf( fp, "Gougenontank %d\n", sys.gouge_nontank ); fprintf( fp, "Bashpvp %d\n", sys.bash_plr_vs_plr ); fprintf( fp, "Bashnontank %d\n", sys.bash_nontank ); fprintf( fp, "Dodgemod %d\n", sys.dodge_mod ); fprintf( fp, "Parrymod %d\n", sys.parry_mod ); fprintf( fp, "Tumblemod %d\n", sys.tumble_mod ); fprintf( fp, "Damplrvsplr %d\n", sys.dam_plr_vs_plr ); fprintf( fp, "Damplrvsmob %d\n", sys.dam_plr_vs_mob ); fprintf( fp, "Dammobvsplr %d\n", sys.dam_mob_vs_plr ); fprintf( fp, "Dammobvsmob %d\n", sys.dam_mob_vs_mob ); fprintf( fp, "Forcepc %d\n", sys.level_forcepc ); fprintf( fp, "Guildoverseer %s~\n", sys.guild_overseer ); fprintf( fp, "Guildadvisor %s~\n", sys.guild_advisor ); fprintf( fp, "Saveflags %d\n", sys.save_flags ); fprintf( fp, "Savefreq %d\n", sys.save_frequency ); fprintf( fp, "Bestowdif %d\n", sys.bestow_dif ); fprintf( fp, "BanSiteLevel %d\n", sys.ban_site_level ); fprintf( fp, "BanRaceLevel %d\n", sys.ban_race_level ); fprintf( fp, "BanClassLevel %d\n", sys.ban_class_level ); fprintf( fp, "MorphOpt %d\n", sys.morph_opt ); fprintf( fp, "PetSave %d\n", sys.save_pets ); fprintf( fp, "IdentTries %d\n", sys.ident_retries ); fprintf( fp, "Pkloot %d\n", sys.pk_loot ); fprintf( fp, "Newbie_purge %d\n", sys.newbie_purge ); fprintf( fp, "Regular_purge %d\n", sys.regular_purge ); fprintf( fp, "Autopurge %d\n", sys.CLEANPFILES ); fprintf( fp, "Player_Limit %d\n", sys.plimit ); fprintf( fp, "Level_NoPlimit %d\n", sys.level_noplimit ); fprintf( fp, "Check_Plimit %d\n", sys.check_plimit ); fprintf( fp, "AHelp %d\n", sys.ahelp ); fprintf( fp, "RpChannel %d\n", sys.rpChannel ); /* * Put here to handle saving and updating of race ranks * * -Karma. */ /* * Kaioshin ranks */ fprintf( fp, "Supremekai %s~\n", kaioshin[5] ); fprintf( fp, "Grandkai %s~\n", kaioshin[4] ); fprintf( fp, "Northkai %s~\n", kaioshin[3] ); fprintf( fp, "Westkai %s~\n", kaioshin[2] ); fprintf( fp, "Eastkai %s~\n", kaioshin[1] ); fprintf( fp, "Southkai %s~\n", kaioshin[0] ); for( a = 0; a < 6; a++ ) fprintf( fp, "Kaioshinlast %d %d\n", a, kaioshinlast[a] ); /* * Demon ranks */ fprintf( fp, "Demonking %s~\n", demonking ); fprintf( fp, "Demonkinglast %d\n", demonkinglast ); fprintf( fp, "Demonwarlord1 %s~\n", demonwarlord[0] ); fprintf( fp, "Demonwarlord2 %s~\n", demonwarlord[1] ); fprintf( fp, "Demonwarlord3 %s~\n", demonwarlord[2] ); for( a = 0; a < 3; a++ ) fprintf( fp, "Demonwarlordlast %d %d\n", a, demonwarlordlast[a] ); fprintf( fp, "Greaterdemon1 %s~\n", greaterdemon[0] ); fprintf( fp, "Greaterdemon2 %s~\n", greaterdemon[1] ); fprintf( fp, "Greaterdemon3 %s~\n", greaterdemon[2] ); fprintf( fp, "Greaterdemon4 %s~\n", greaterdemon[3] ); fprintf( fp, "Greaterdemon5 %s~\n", greaterdemon[4] ); fprintf( fp, "Greaterdemon6 %s~\n", greaterdemon[5] ); for( a = 0; a < 6; a++ ) fprintf( fp, "Greaterdemonlast %d %d\n", a, greaterdemonlast[a] ); /* * Saiyan ranks */ fprintf( fp, "Saiyanking %s~\n", saiyanking ); fprintf( fp, "Saiyankinglast %d\n", saiyankinglast ); fprintf( fp, "Saiyanprince1 %s~\n", saiyanprince[0] ); fprintf( fp, "Saiyanprince2 %s~\n", saiyanprince[1] ); // fprintf( fp, "Saiyanprince3 %s~\n", saiyanprince[2] ); for( a = 0; a < 2; a++ ) fprintf( fp, "Saiyanprincelast %d %d\n", a, saiyanprincelast[a] ); fprintf( fp, "Saiyanelite1 %s~\n", saiyanelite[0] ); fprintf( fp, "Saiyanelite2 %s~\n", saiyanelite[1] ); fprintf( fp, "Saiyanelite3 %s~\n", saiyanelite[2] ); fprintf( fp, "Saiyanelite4 %s~\n", saiyanelite[3] ); // fprintf( fp, "Saiyanelite5 %s~\n", saiyanelite[4] ); //fprintf( fp, "Saiyanelite6 %s~\n", saiyanelite[5] ); for( a = 0; a < 4; a++ ) fprintf( fp, "Saiyanelitelast %d %d\n", a, saiyanelitelast[a] ); fprintf( fp, "Wizlock %d\n", wizlock ); fprintf( fp, "Locklev %d\n", locklev ); fprintf( fp, "End\n\n" ); fprintf( fp, "#END\n" ); } fclose( fp ); fpReserve = fopen( NULL_FILE, "r" ); return; } void fread_sysdata( SYSTEM_DATA * sys, FILE * fp ) { char *word; bool fMatch; extern bool wizlock; extern int locklev; sys->time_of_max = NULL; sys->mud_name = NULL; for( ;; ) { word = feof( fp ) ? "End" : fread_word( fp ); fMatch = FALSE; switch ( UPPER( word[0] ) ) { case '*': fMatch = TRUE; fread_to_eol( fp ); break; case 'A': KEY( "Autopurge", sys->CLEANPFILES, fread_number( fp ) ); KEY( "AHelp", sys->ahelp, fread_number( fp ) ); break; case 'B': KEY( "Bashpvp", sys->bash_plr_vs_plr, fread_number( fp ) ); KEY( "Bashnontank", sys->bash_nontank, fread_number( fp ) ); KEY( "Bestowdif", sys->bestow_dif, fread_number( fp ) ); KEY( "Build", sys->build_level, fread_number( fp ) ); KEY( "BanSiteLevel", sys->ban_site_level, fread_number( fp ) ); KEY( "BanClassLevel", sys->ban_class_level, fread_number( fp ) ); KEY( "BanRaceLevel", sys->ban_race_level, fread_number( fp ) ); break; case 'C': KEY( "CheckImmHost", sys->check_imm_host, fread_number( fp ) ); KEY( "Check_Plimit", sys->check_plimit, fread_number( fp ) ); break; case 'D': KEY( "Damplrvsplr", sys->dam_plr_vs_plr, fread_number( fp ) ); KEY( "Damplrvsmob", sys->dam_plr_vs_mob, fread_number( fp ) ); KEY( "Dammobvsplr", sys->dam_mob_vs_plr, fread_number( fp ) ); KEY( "Dammobvsmob", sys->dam_mob_vs_mob, fread_number( fp ) ); KEY( "Dodgemod", sys->dodge_mod, fread_number( fp ) ); KEY( "Demonking", demonking, fread_string( fp ) ); KEY( "Demonkinglast", demonkinglast, fread_number( fp ) ); KEY( "Demonwarlord1", demonwarlord[0], fread_string( fp ) ); KEY( "Demonwarlord2", demonwarlord[1], fread_string( fp ) ); KEY( "Demonwarlord3", demonwarlord[2], fread_string( fp ) ); if( !str_cmp( word, "Demonwarlordlast" ) ) { int a = fread_number( fp ); demonwarlordlast[a] = fread_number( fp ); fMatch = TRUE; break; } break; case 'E': KEY( "Eastkai", kaioshin[1], fread_string( fp ) ); if( !str_cmp( word, "End" ) ) { if( !sys->time_of_max ) sys->time_of_max = str_dup( "(not recorded)" ); if( !sys->mud_name ) sys->mud_name = str_dup( "(Name Not Set)" ); return; } break; case 'F': KEY( "Forcepc", sys->level_forcepc, fread_number( fp ) ); break; case 'G': KEY( "Gougepvp", sys->gouge_plr_vs_plr, fread_number( fp ) ); KEY( "Gougenontank", sys->gouge_nontank, fread_number( fp ) ); KEY( "Guildoverseer", sys->guild_overseer, fread_string( fp ) ); KEY( "Guildadvisor", sys->guild_advisor, fread_string( fp ) ); KEY( "Grandkai", kaioshin[4], fread_string( fp ) ); KEY( "Greaterdemon1", greaterdemon[0], fread_string( fp ) ); KEY( "Greaterdemon2", greaterdemon[1], fread_string( fp ) ); KEY( "Greaterdemon3", greaterdemon[2], fread_string( fp ) ); KEY( "Greaterdemon4", greaterdemon[3], fread_string( fp ) ); KEY( "Greaterdemon5", greaterdemon[4], fread_string( fp ) ); KEY( "Greaterdemon6", greaterdemon[5], fread_string( fp ) ); if( !str_cmp( word, "Greaterdemonlast" ) ) { int a = fread_number( fp ); greaterdemonlast[a] = fread_number( fp ); fMatch = TRUE; break; } break; case 'H': KEY( "Highplayers", sys->alltimemax, fread_number( fp ) ); KEY( "Highplayertime", sys->time_of_max, fread_string_nohash( fp ) ); break; case 'I': KEY( "IdentTries", sys->ident_retries, fread_number( fp ) ); KEY( "IMCMailVnum", sys->imc_mail_vnum, fread_number( fp ) ); KEY( "Invokeall", sys->level_invoke_proto, fread_number( fp ) ); break; case 'K': if( !str_cmp( word, "Kaioshinlast" ) ) { int a = fread_number( fp ); kaioshinlast[a] = fread_number( fp ); fMatch = TRUE; break; } case 'L': KEY( "Level_NoPlimit", sys->level_noplimit, fread_number( fp ) ); KEY( "Log", sys->log_level, fread_number( fp ) ); KEY( "Locklev", locklev, fread_number( fp ) ); break; case 'M': KEY( "MorphOpt", sys->morph_opt, fread_number( fp ) ); KEY( "Msetplayer", sys->level_mset_player, fread_number( fp ) ); KEY( "MudName", sys->mud_name, fread_string_nohash( fp ) ); KEY( "Muse", sys->muse_level, fread_number( fp ) ); break; case 'N': KEY( "Nameresolving", sys->NO_NAME_RESOLVING, fread_number( fp ) ); KEY( "Newbie_purge", sys->newbie_purge, fread_number( fp ) ); KEY( "Northkai", kaioshin[3], fread_string( fp ) ); break; case 'O': KEY( "Overridepriv", sys->level_override_private, fread_number( fp ) ); break; case 'P': KEY( "Parrymod", sys->parry_mod, fread_number( fp ) ); KEY( "PetSave", sys->save_pets, fread_number( fp ) ); KEY( "Pkloot", sys->pk_loot, fread_number( fp ) ); KEY( "Player_Limit", sys->plimit, fread_number( fp ) ); KEY( "Protoflag", sys->level_modify_proto, fread_number( fp ) ); break; case 'R': KEY( "RpChannel", sys->rpChannel, fread_number( fp ) ); KEY( "Readallmail", sys->read_all_mail, fread_number( fp ) ); KEY( "Readmailfree", sys->read_mail_free, fread_number( fp ) ); KEY( "Regular_purge", sys->regular_purge, fread_number( fp ) ); break; case 'S': KEY( "Stunplrvsplr", sys->stun_plr_vs_plr, fread_number( fp ) ); KEY( "Stunregular", sys->stun_regular, fread_number( fp ) ); KEY( "Saveflags", sys->save_flags, fread_number( fp ) ); KEY( "Savefreq", sys->save_frequency, fread_number( fp ) ); KEY( "Southkai", kaioshin[0], fread_string( fp ) ); KEY( "Supremekai", kaioshin[5], fread_string( fp ) ); KEY( "Saiyanking", saiyanking, fread_string( fp ) ); KEY( "Saiyankinglast", saiyankinglast, fread_number( fp ) ); KEY( "Saiyanprince1", saiyanprince[0], fread_string( fp ) ); KEY( "Saiyanprince2", saiyanprince[1], fread_string( fp ) ); // KEY( "Demonwarlord3", demonwarlord[2], fread_string( fp ) ); if( !str_cmp( word, "Saiyanprincelast" ) ) { int a = fread_number( fp ); saiyanprincelast[a] = fread_number( fp ); fMatch = TRUE; break; } KEY( "Saiyanelite1", saiyanelite[0], fread_string( fp ) ); KEY( "Saiyanelite2", saiyanelite[1], fread_string( fp ) ); KEY( "Saiyanelite3", saiyanelite[2], fread_string( fp ) ); KEY( "Saiyanelite4", saiyanelite[3], fread_string( fp ) ); // KEY( "Demonwarlord3", demonwarlord[2], fread_string( fp ) ); if( !str_cmp( word, "Saiyanelitelast" ) ) { int a = fread_number( fp ); saiyanelitelast[a] = fread_number( fp ); fMatch = TRUE; break; } // break; break; case 'T': KEY( "Takeothersmail", sys->take_others_mail, fread_number( fp ) ); KEY( "Think", sys->think_level, fread_number( fp ) ); KEY( "Tumblemod", sys->tumble_mod, fread_number( fp ) ); break; case 'W': KEY( "Waitforauth", sys->WAIT_FOR_AUTH, fread_number( fp ) ); KEY( "Writemailfree", sys->write_mail_free, fread_number( fp ) ); KEY( "Westkai", kaioshin[2], fread_string( fp ) ); KEY( "Wizlock", wizlock, fread_number( fp ) ); break; } if( !fMatch ) { bug( "Fread_sysdata: no match: %s", word ); } } } /* * Load the sysdata file */ bool load_systemdata( SYSTEM_DATA * sys ) { char filename[MAX_INPUT_LENGTH]; FILE *fp; bool found; found = FALSE; sprintf( filename, "%ssysdata.dat", SYSTEM_DIR ); if( ( fp = fopen( filename, "r" ) ) != NULL ) { found = TRUE; for( ;; ) { char letter; char *word; letter = fread_letter( fp ); if( letter == '*' ) { fread_to_eol( fp ); continue; } if( letter != '#' ) { bug( "Load_sysdata_file: # not found." ); break; } word = fread_word( fp ); if( !str_cmp( word, "SYSTEM" ) ) { fread_sysdata( sys, fp ); break; } else if( !str_cmp( word, "END" ) ) break; else { bug( "Load_sysdata_file: bad section." ); break; } } fclose( fp ); } if( !sysdata.guild_overseer ) sysdata.guild_overseer = STRALLOC( "" ); if( !sysdata.guild_advisor ) sysdata.guild_advisor = STRALLOC( "" ); return found; } void load_watchlist( void ) { WATCH_DATA *pwatch; FILE *fp; int number; CMDTYPE *cmd; if( !( fp = fopen( SYSTEM_DIR WATCH_LIST, "r" ) ) ) return; for( ;; ) { if( feof( fp ) ) { bug( "Load_watchlist: no -1 found." ); fclose( fp ); return; } number = fread_number( fp ); if( number == -1 ) { fclose( fp ); return; } CREATE( pwatch, WATCH_DATA, 1 ); pwatch->imm_level = number; pwatch->imm_name = fread_string_nohash( fp ); pwatch->target_name = fread_string_nohash( fp ); if( strlen( pwatch->target_name ) < 2 ) DISPOSE( pwatch->target_name ); pwatch->player_site = fread_string_nohash( fp ); if( strlen( pwatch->player_site ) < 2 ) DISPOSE( pwatch->player_site ); /* * Check for command watches */ if( pwatch->target_name ) for( cmd = command_hash[( int )pwatch->target_name[0]]; cmd; cmd = cmd->next ) { if( !str_cmp( pwatch->target_name, cmd->name ) ) { SET_BIT( cmd->flags, CMD_WATCH ); break; } } LINK( pwatch, first_watch, last_watch, next, prev ); } } /* Check to make sure range of vnums is free - Scryn 2/27/96 */ void do_check_vnums( CHAR_DATA * ch, char *argument ) { char buf[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; AREA_DATA *pArea; char arg1[MAX_STRING_LENGTH]; char arg2[MAX_STRING_LENGTH]; bool room, mob, obj, all, area_conflict; int low_range, high_range; room = FALSE; mob = FALSE; obj = FALSE; all = FALSE; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if( arg1[0] == '\0' ) { send_to_char( "Please specify room, mob, object, or all as your first argument.\n\r", ch ); return; } if( !str_cmp( arg1, "room" ) ) room = TRUE; else if( !str_cmp( arg1, "mob" ) ) mob = TRUE; else if( !str_cmp( arg1, "object" ) ) obj = TRUE; else if( !str_cmp( arg1, "all" ) ) all = TRUE; else { send_to_char( "Please specify room, mob, or object as your first argument.\n\r", ch ); return; } if( arg2[0] == '\0' ) { send_to_char( "Please specify the low end of the range to be searched.\n\r", ch ); return; } if( argument[0] == '\0' ) { send_to_char( "Please specify the high end of the range to be searched.\n\r", ch ); return; } low_range = atoi( arg2 ); high_range = atoi( argument ); if( low_range < 1 || low_range > MAX_VNUMS ) { send_to_char( "Invalid argument for bottom of range.\n\r", ch ); return; } if( high_range < 1 || high_range > MAX_VNUMS ) { send_to_char( "Invalid argument for top of range.\n\r", ch ); return; } if( high_range < low_range ) { send_to_char( "Bottom of range must be below top of range.\n\r", ch ); return; } if( all ) { sprintf( buf, "room %d %d", low_range, high_range ); do_check_vnums( ch, buf ); sprintf( buf, "mob %d %d", low_range, high_range ); do_check_vnums( ch, buf ); sprintf( buf, "object %d %d", low_range, high_range ); do_check_vnums( ch, buf ); return; } set_char_color( AT_PLAIN, ch ); for( pArea = first_asort; pArea; pArea = pArea->next_sort ) { area_conflict = FALSE; if( IS_SET( pArea->status, AREA_DELETED ) ) continue; else if( room ) { if( low_range < pArea->low_r_vnum && pArea->low_r_vnum < high_range ) area_conflict = TRUE; if( low_range < pArea->hi_r_vnum && pArea->hi_r_vnum < high_range ) area_conflict = TRUE; if( ( low_range >= pArea->low_r_vnum ) && ( low_range <= pArea->hi_r_vnum ) ) area_conflict = TRUE; if( ( high_range <= pArea->hi_r_vnum ) && ( high_range >= pArea->low_r_vnum ) ) area_conflict = TRUE; } if( mob ) { if( low_range < pArea->low_m_vnum && pArea->low_m_vnum < high_range ) area_conflict = TRUE; if( low_range < pArea->hi_m_vnum && pArea->hi_m_vnum < high_range ) area_conflict = TRUE; if( ( low_range >= pArea->low_m_vnum ) && ( low_range <= pArea->hi_m_vnum ) ) area_conflict = TRUE; if( ( high_range <= pArea->hi_m_vnum ) && ( high_range >= pArea->low_m_vnum ) ) area_conflict = TRUE; } if( obj ) { if( low_range < pArea->low_o_vnum && pArea->low_o_vnum < high_range ) area_conflict = TRUE; if( low_range < pArea->hi_o_vnum && pArea->hi_o_vnum < high_range ) area_conflict = TRUE; if( ( low_range >= pArea->low_o_vnum ) && ( low_range <= pArea->hi_o_vnum ) ) area_conflict = TRUE; if( ( high_range <= pArea->hi_o_vnum ) && ( high_range >= pArea->low_o_vnum ) ) area_conflict = TRUE; } if( area_conflict ) { sprintf( buf, "Conflict:%-15s| ", ( pArea->filename ? pArea->filename : "(invalid)" ) ); if( room ) sprintf( buf2, "Rooms: %5d - %-5d\n\r", pArea->low_r_vnum, pArea->hi_r_vnum ); if( mob ) sprintf( buf2, "Mobs: %5d - %-5d\n\r", pArea->low_m_vnum, pArea->hi_m_vnum ); if( obj ) sprintf( buf2, "Objects: %5d - %-5d\n\r", pArea->low_o_vnum, pArea->hi_o_vnum ); strcat( buf, buf2 ); send_to_char( buf, ch ); } } for( pArea = first_bsort; pArea; pArea = pArea->next_sort ) { area_conflict = FALSE; if( IS_SET( pArea->status, AREA_DELETED ) ) continue; else if( room ) { if( low_range < pArea->low_r_vnum && pArea->low_r_vnum < high_range ) area_conflict = TRUE; if( low_range < pArea->hi_r_vnum && pArea->hi_r_vnum < high_range ) area_conflict = TRUE; if( ( low_range >= pArea->low_r_vnum ) && ( low_range <= pArea->hi_r_vnum ) ) area_conflict = TRUE; if( ( high_range <= pArea->hi_r_vnum ) && ( high_range >= pArea->low_r_vnum ) ) area_conflict = TRUE; } if( mob ) { if( low_range < pArea->low_m_vnum && pArea->low_m_vnum < high_range ) area_conflict = TRUE; if( low_range < pArea->hi_m_vnum && pArea->hi_m_vnum < high_range ) area_conflict = TRUE; if( ( low_range >= pArea->low_m_vnum ) && ( low_range <= pArea->hi_m_vnum ) ) area_conflict = TRUE; if( ( high_range <= pArea->hi_m_vnum ) && ( high_range >= pArea->low_m_vnum ) ) area_conflict = TRUE; } if( obj ) { if( low_range < pArea->low_o_vnum && pArea->low_o_vnum < high_range ) area_conflict = TRUE; if( low_range < pArea->hi_o_vnum && pArea->hi_o_vnum < high_range ) area_conflict = TRUE; if( ( low_range >= pArea->low_o_vnum ) && ( low_range <= pArea->hi_o_vnum ) ) area_conflict = TRUE; if( ( high_range <= pArea->hi_o_vnum ) && ( high_range >= pArea->low_o_vnum ) ) area_conflict = TRUE; } if( area_conflict ) { sprintf( buf, "Conflict:%-15s| ", ( pArea->filename ? pArea->filename : "(invalid)" ) ); if( room ) sprintf( buf2, "Rooms: %5d - %-5d\n\r", pArea->low_r_vnum, pArea->hi_r_vnum ); if( mob ) sprintf( buf2, "Mobs: %5d - %-5d\n\r", pArea->low_m_vnum, pArea->hi_m_vnum ); if( obj ) sprintf( buf2, "Objects: %5d - %-5d\n\r", pArea->low_o_vnum, pArea->hi_o_vnum ); strcat( buf, buf2 ); send_to_char( buf, ch ); } } /* for ( pArea = first_asort; pArea; pArea = pArea->next_sort ) { area_conflict = FALSE; if ( IS_SET( pArea->status, AREA_DELETED ) ) continue; else if (room) if((pArea->low_r_vnum >= low_range) && (pArea->hi_r_vnum <= high_range)) area_conflict = TRUE; if (mob) if((pArea->low_m_vnum >= low_range) && (pArea->hi_m_vnum <= high_range)) area_conflict = TRUE; if (obj) if((pArea->low_o_vnum >= low_range) && (pArea->hi_o_vnum <= high_range)) area_conflict = TRUE; if (area_conflict) ch_printf(ch, "Conflict:%-15s| Rooms: %5d - %-5d" " Objs: %5d - %-5d Mobs: %5d - %-5d\n\r", (pArea->filename ? pArea->filename : "(invalid)"), pArea->low_r_vnum, pArea->hi_r_vnum, pArea->low_o_vnum, pArea->hi_o_vnum, pArea->low_m_vnum, pArea->hi_m_vnum ); } for ( pArea = first_bsort; pArea; pArea = pArea->next_sort ) { area_conflict = FALSE; if ( IS_SET( pArea->status, AREA_DELETED ) ) continue; else if (room) if((pArea->low_r_vnum >= low_range) && (pArea->hi_r_vnum <= high_range)) area_conflict = TRUE; if (mob) if((pArea->low_m_vnum >= low_range) && (pArea->hi_m_vnum <= high_range)) area_conflict = TRUE; if (obj) if((pArea->low_o_vnum >= low_range) && (pArea->hi_o_vnum <= high_range)) area_conflict = TRUE; if (area_conflict) sprintf(ch, "Conflict:%-15s| Rooms: %5d - %-5d" " Objs: %5d - %-5d Mobs: %5d - %-5d\n\r", (pArea->filename ? pArea->filename : "(invalid)"), pArea->low_r_vnum, pArea->hi_r_vnum, pArea->low_o_vnum, pArea->hi_o_vnum, pArea->low_m_vnum, pArea->hi_m_vnum ); } */ return; } /* * This function is here to aid in debugging. * If the last expression in a function is another function call, * gcc likes to generate a JMP instead of a CALL. * This is called "tail chaining." * It hoses the debugger call stack for that call. * So I make this the last call in certain critical functions, * where I really need the call stack to be right for debugging! * * If you don't understand this, then LEAVE IT ALONE. * Don't remove any calls to tail_chain anywhere. * * -- Furey */ void tail_chain( void ) { return; } /* * Initialize the weather for all the areas * Last Modified: July 21, 1997 * Fireblade */ void init_area_weather( ) { AREA_DATA *pArea; NEIGHBOR_DATA *neigh; NEIGHBOR_DATA *next_neigh; for( pArea = first_area; pArea; pArea = pArea->next ) { int cf; /* * init temp and temp vector */ cf = pArea->weather->climate_temp - 2; pArea->weather->temp = number_range( -weath_unit, weath_unit ) + cf * number_range( 0, weath_unit ); pArea->weather->temp_vector = cf + number_range( -rand_factor, rand_factor ); /* * init precip and precip vector */ cf = pArea->weather->climate_precip - 2; pArea->weather->precip = number_range( -weath_unit, weath_unit ) + cf * number_range( 0, weath_unit ); pArea->weather->precip_vector = cf + number_range( -rand_factor, rand_factor ); /* * init wind and wind vector */ cf = pArea->weather->climate_wind - 2; pArea->weather->wind = number_range( -weath_unit, weath_unit ) + cf * number_range( 0, weath_unit ); pArea->weather->wind_vector = cf + number_range( -rand_factor, rand_factor ); /* * check connections between neighbors */ for( neigh = pArea->weather->first_neighbor; neigh; neigh = next_neigh ) { AREA_DATA *tarea; NEIGHBOR_DATA *tneigh; /* * get the address if needed */ if( !neigh->address ) neigh->address = get_area( neigh->name ); /* * area does not exist */ if( !neigh->address ) { tneigh = neigh; next_neigh = tneigh->next; UNLINK( tneigh, pArea->weather->first_neighbor, pArea->weather->last_neighbor, next, prev ); STRFREE( tneigh->name ); DISPOSE( tneigh ); fold_area( pArea, pArea->filename, FALSE ); continue; } /* * make sure neighbors both point to each other */ tarea = neigh->address; for( tneigh = tarea->weather->first_neighbor; tneigh; tneigh = tneigh->next ) { if( !strcmp( pArea->name, tneigh->name ) ) break; } if( !tneigh ) { CREATE( tneigh, NEIGHBOR_DATA, 1 ); tneigh->name = STRALLOC( pArea->name ); LINK( tneigh, tarea->weather->first_neighbor, tarea->weather->last_neighbor, next, prev ); fold_area( tarea, tarea->filename, FALSE ); } tneigh->address = pArea; next_neigh = neigh->next; } } return; } /* * Load weather data from appropriate file in system dir * Last Modified: July 24, 1997 * Fireblade */ void load_weatherdata( ) { char filename[MAX_INPUT_LENGTH]; FILE *fp; sprintf( filename, "%sweather.dat", SYSTEM_DIR ); if( ( fp = fopen( filename, "r" ) ) != NULL ) { for( ;; ) { char letter; char *word; letter = fread_letter( fp ); if( letter != '#' ) { bug( "load_weatherdata: # not found" ); return; } word = fread_word( fp ); if( !str_cmp( word, "RANDOM" ) ) rand_factor = fread_number( fp ); else if( !str_cmp( word, "CLIMATE" ) ) climate_factor = fread_number( fp ); else if( !str_cmp( word, "NEIGHBOR" ) ) neigh_factor = fread_number( fp ); else if( !str_cmp( word, "UNIT" ) ) weath_unit = fread_number( fp ); else if( !str_cmp( word, "MAXVECTOR" ) ) max_vector = fread_number( fp ); else if( !str_cmp( word, "END" ) ) { fclose( fp ); break; } else { bug( "load_weatherdata: unknown field" ); fclose( fp ); break; } } } return; } /* * Write data for global weather parameters * Last Modified: July 24, 1997 * Fireblade */ void save_weatherdata( ) { char filename[MAX_INPUT_LENGTH]; FILE *fp; sprintf( filename, "%sweather.dat", SYSTEM_DIR ); if( ( fp = fopen( filename, "w" ) ) != NULL ) { fprintf( fp, "#RANDOM %d\n", rand_factor ); fprintf( fp, "#CLIMATE %d\n", climate_factor ); fprintf( fp, "#NEIGHBOR %d\n", neigh_factor ); fprintf( fp, "#UNIT %d\n", weath_unit ); fprintf( fp, "#MAXVECTOR %d\n", max_vector ); fprintf( fp, "#END\n" ); fclose( fp ); } else { bug( "save_weatherdata: could not open file" ); } return; } void load_projects( void ) /* Copied load_boards structure for simplicity */ { char filename[MAX_INPUT_LENGTH]; FILE *fp; PROJECT_DATA *project; first_project = NULL; last_project = NULL; sprintf( filename, "%s", PROJECTS_FILE ); if( ( fp = fopen( filename, "r" ) ) == NULL ) return; while( ( project = read_project( filename, fp ) ) != NULL ) LINK( project, first_project, last_project, next, prev ); return; } PROJECT_DATA *read_project( char *filename, FILE * fp ) { PROJECT_DATA *project; NOTE_DATA *log, *tlog; char *word; char buf[MAX_STRING_LENGTH]; bool fMatch; char letter; do { letter = getc( fp ); if( feof( fp ) ) { fclose( fp ); return NULL; } } while( isspace( letter ) ); ungetc( letter, fp ); CREATE( project, PROJECT_DATA, 1 ); #ifdef KEY #undef KEY #endif #define KEY( literal, field, value ) \ if ( !str_cmp( word, literal ) ) \ { \ field = value; \ fMatch = TRUE; \ break; \ } project->first_log = NULL; project->last_log = NULL; project->next = NULL; project->prev = NULL; project->coder = NULL; project->description = STRALLOC( "" ); project->name = STRALLOC( "" ); project->owner = STRALLOC( "" ); project->date = STRALLOC( "Not Set?!" ); project->status = STRALLOC( "No update." ); for( ;; ) { word = feof( fp ) ? "End" : fread_word( fp ); fMatch = FALSE; switch ( UPPER( word[0] ) ) { case '*': fMatch = TRUE; fread_to_eol( fp ); break; case 'C': KEY( "Coder", project->coder, fread_string_nohash( fp ) ); break; case 'D': if( !str_cmp( word, "Date" ) ) STRFREE( project->date ); else if( !str_cmp( word, "Description" ) ) STRFREE( project->description ); KEY( "Date", project->date, fread_string( fp ) ); KEY( "Description", project->description, fread_string( fp ) ); break; case 'E': if( !str_cmp( word, "End" ) ) { if( !project->description ) project->description = STRALLOC( "" ); if( !project->name ) project->name = STRALLOC( "" ); if( !project->owner ) project->owner = STRALLOC( "" ); if( !project->date ) project->date = STRALLOC( "Not Set?!" ); if( !project->status ) project->status = STRALLOC( "No update." ); if( str_cmp( project->owner, "None" ) ) project->taken = TRUE; return project; } break; case 'L': if( !str_cmp( word, "Log" ) ) { fread_to_eol( fp ); log = read_log( fp ); if( !log ) { sprintf( buf, "read_project: couldn't read log, aborting" ); bug( buf, 0 ); exit( 1 ); } if( !log->sender ) log->sender = STRALLOC( "" ); if( !log->date ) log->date = STRALLOC( "" ); if( !log->subject ) log->subject = STRALLOC( "None" ); log->to_list = STRALLOC( "" ); LINK( log, project->first_log, project->last_log, next, prev ); fMatch = TRUE; break; } break; case 'N': if( !str_cmp( word, "Name" ) ) STRFREE( project->name ); KEY( "Name", project->name, fread_string_nohash( fp ) ); break; case 'O': if( !str_cmp( word, "Owner" ) ) STRFREE( project->owner ); KEY( "Owner", project->owner, fread_string( fp ) ); break; case 'S': if( !str_cmp( word, "Status" ) ) STRFREE( project->status ); KEY( "Status", project->status, fread_string( fp ) ); break; } if( !fMatch ) { sprintf( buf, "read_project: no match: %s", word ); bug( buf, 0 ); } } log = project->last_log; while( log ) { UNLINK( log, project->first_log, project->last_log, next, prev ); tlog = log->prev; free_note( log ); log = tlog; } if( project->coder ) DISPOSE( project->coder ); if( project->description ) STRFREE( project->description ); if( project->name ) STRFREE( project->name ); if( project->owner ) STRFREE( project->owner ); if( project->date ) STRFREE( project->date ); if( project->status ) STRFREE( project->status ); DISPOSE( project ); return project; } NOTE_DATA *read_log( FILE * fp ) { NOTE_DATA *log; char *word; CREATE( log, NOTE_DATA, 1 ); for( ;; ) { word = fread_word( fp ); if( !str_cmp( word, "Sender" ) ) log->sender = fread_string( fp ); else if( !str_cmp( word, "Date" ) ) log->date = fread_string( fp ); else if( !str_cmp( word, "Subject" ) ) log->subject = fread_string( fp ); else if( !str_cmp( word, "Text" ) ) log->text = fread_string( fp ); else if( !str_cmp( word, "Endlog" ) ) { fread_to_eol( fp ); log->next = NULL; log->prev = NULL; return log; } else { DISPOSE( log ); bug( "read_log: bad key word.", 0 ); return NULL; } } } void write_projects( ) { PROJECT_DATA *project; NOTE_DATA *log; FILE *fpout; char filename[MAX_INPUT_LENGTH]; sprintf( filename, "%s", PROJECTS_FILE ); fpout = fopen( filename, "w" ); if( !fpout ) { bug( "FATAL: cannot open projects.txt for writing!\n\r", 0 ); return; } for( project = first_project; project; project = project->next ) { fprintf( fpout, "Name %s~\n", project->name ); fprintf( fpout, "Owner %s~\n", ( project->owner ) ? project->owner : "None" ); if( project->coder ) fprintf( fpout, "Coder %s~\n", project->coder ); fprintf( fpout, "Status %s~\n", ( project->status ) ? project->status : "No update." ); fprintf( fpout, "Date %s~\n", ( project->date ) ? project->date : "Not Set?!?" ); if( project->description ) fprintf( fpout, "Description %s~\n", project->description ); for( log = project->first_log; log; log = log->next ) fprintf( fpout, "Log\nSender %s~\nDate %s~\nSubject %s~\nText %s~\nEndlog\n", log->sender, log->date, log->subject, log->text ); fprintf( fpout, "End\n" ); } fclose( fpout ); } void load_storages( void ) { DIR *dp; struct dirent *dentry; dp = opendir( STORAGE_DIR ); dentry = readdir( dp ); while( dentry ) { if( dentry->d_name[0] != '.' ) load_storage( dentry->d_name ); dentry = readdir( dp ); } closedir( dp ); } void load_storage( char *filename ) { char buf[MAX_STRING_LENGTH]; FILE *fp; sprintf( buf, "%s%s", STORAGE_DIR, filename ); if( ( fp = fopen( buf, "r" ) ) != NULL ) { int iNest; bool found; OBJ_DATA *tobj, *tobj_next; int vnum; ROOM_INDEX_DATA *room = NULL; log_string( "Loading storage room" ); for( iNest = 0; iNest < MAX_NEST; iNest++ ) rgObjNest[iNest] = NULL; found = TRUE; for( ;; ) { char letter; char *word; letter = fread_letter( fp ); if( letter == '*' ) { fread_to_eol( fp ); continue; } if( letter != '#' ) { bug( "Load_storeroom: # not found.", 0 ); break; } word = fread_word( fp ); if( !str_cmp( word, "OBJECT" ) ) fread_obj( supermob, fp, OS_CARRY ); else if( !str_cmp( word, "VNUM" ) ) { vnum = fread_number( fp ); if( ( room = get_room_index( vnum ) ) == NULL ) { bug( "load_storeroom: bad vnum.", 0 ); return; } else { rset_supermob( room ); } } else if( !str_cmp( word, "END" ) ) break; else { bug( "Load_storeroom: bad section.", 0 ); break; } } fclose( fp ); for( tobj = supermob->first_carrying; tobj; tobj = tobj_next ) { tobj_next = tobj->next_content; obj_from_char( tobj ); obj_to_room( tobj, room ); } release_supermob( ); } else log_string( "Cannot load vault" ); }