#include "define.h" #include "struct.h" /* * LOCAL VARIABLES */ spell_data spell_table [ MAX_SPELL ]; social_type social_table [ MAX_PLYR_RACE+1 ][ MAX_SOCIAL ]; spell_act_type spell_act_table [ MAX_SPELL_ACT ]; liquid_type liquid_table [ MAX_LIQUID ]; town_type town_table [ MAX_TOWN ]; skill_type skill_table [ MAX_SKILL ]; metal_type material_table [ MAX_METAL ]; nation_data nation_table [ MAX_NATION ]; group_data group_table [ MAX_GROUP ]; race_data race_table [ MAX_RACE ]; plyr_race_data plyr_race_table [ MAX_PLYR_RACE ]; aff_char_type aff_char_table [ MAX_AFF_CHAR ]; aff_obj_type aff_obj_table [ MAX_AFF_OBJ ]; command_type command_table [ MAX_COMMAND ]; category_data cmd_cat_table [ MAX_CMD_CAT ]; clss_type clss_table [ MAX_CLSS ]; starting_data starting_table [ MAX_CLSS+MAX_PLYR_RACE+1 ]; tedit_data tedit_table [ MAX_TABLE ]; recipe_data build_table [ MAX_BUILD ]; category_data help_cat_table [ MAX_HELP_CAT ]; town_type astral_table [ MAX_ASTRAL ]; religion_data religion_table [ MAX_RELIGION ]; alignment_data alignment_table [ MAX_ALIGNMENT ]; int table_max [ MAX_TABLE ]; /* * LOCAL CONSTANTS */ const int table_abs_max [ MAX_TABLE ] = { MAX_SOCIAL, MAX_SOCIAL, MAX_SOCIAL, MAX_SOCIAL, MAX_SOCIAL, MAX_SOCIAL, MAX_SOCIAL, MAX_SOCIAL, MAX_SOCIAL, MAX_SOCIAL, MAX_SOCIAL, MAX_SOCIAL, MAX_SOCIAL, MAX_SOCIAL, MAX_SPELL_ACT, MAX_LIQUID, MAX_SPELL, MAX_TOWN, MAX_SKILL, MAX_METAL, MAX_NATION, MAX_GROUP, MAX_RACE, MAX_PLYR_RACE, MAX_AFF_CHAR, MAX_AFF_OBJ, MAX_COMMAND, MAX_CMD_CAT, MAX_CLSS, MAX_CLSS+MAX_PLYR_RACE+1, MAX_TABLE, MAX_BUILD, MAX_HELP_CAT, MAX_ASTRAL, MAX_RELIGION, MAX_ALIGNMENT }; const int table_size [ MAX_TABLE ] = { sizeof( social_type ), sizeof( social_type ), sizeof( social_type ), sizeof( social_type ), sizeof( social_type ), sizeof( social_type ), sizeof( social_type ), sizeof( social_type ), sizeof( social_type ), sizeof( social_type ), sizeof( social_type ), sizeof( social_type ), sizeof( social_type ), sizeof( social_type ), sizeof( spell_act_type ), sizeof( liquid_type ), sizeof( spell_data ), sizeof( town_type ), sizeof( skill_type ), sizeof( metal_type ), sizeof( nation_data ), sizeof( group_data ), sizeof( race_data ), sizeof( plyr_race_data ), sizeof( aff_char_type ), sizeof( aff_obj_type ), sizeof( command_type ), sizeof( category_data ), sizeof( clss_type ), sizeof( starting_data ), sizeof( tedit_data ), sizeof( recipe_data ), sizeof( category_data ), sizeof( town_type ), sizeof( religion_data ), sizeof( alignment_data ) }; entry_data table_entry [ MAX_TABLE-MAX_PLYR_RACE ][ MAX_FIELD ] = { { { &social_table[0][0].name, VAR_CHAR }, { &social_table[0][0].position, VAR_POS }, { &social_table[0][0].aggressive, VAR_BOOL }, { &social_table[0][0].reveal, VAR_BOOL }, { &social_table[0][0].disrupt, VAR_BOOL }, { &social_table[0][0].char_no_arg, VAR_CHAR }, { &social_table[0][0].others_no_arg, VAR_CHAR }, { &social_table[0][0].char_found, VAR_CHAR }, { &social_table[0][0].others_found, VAR_CHAR }, { &social_table[0][0].vict_found, VAR_CHAR }, { &social_table[0][0].vict_sleep, VAR_CHAR }, { &social_table[0][0].char_auto, VAR_CHAR }, { &social_table[0][0].others_auto, VAR_CHAR }, { &social_table[0][0].obj_self, VAR_CHAR }, { &social_table[0][0].obj_others, VAR_CHAR }, { &social_table[0][0].dir_self, VAR_CHAR }, { &social_table[0][0].dir_others, VAR_CHAR }, { &social_table[0][0].ch_obj_self, VAR_CHAR }, { &social_table[0][0].ch_obj_victim, VAR_CHAR }, { &social_table[0][0].ch_obj_others, VAR_CHAR }, { &social_table[0][0].ch_obj_sleep, VAR_CHAR }, { &social_table[0][0].self_obj_self, VAR_CHAR }, { &social_table[0][0].self_obj_others,VAR_CHAR } }, { { &spell_act_table[0].name, VAR_CHAR }, { &spell_act_table[0].self_other, VAR_CHAR }, { &spell_act_table[0].victim_other, VAR_CHAR }, { &spell_act_table[0].others_other, VAR_CHAR }, { &spell_act_table[0].self_self, VAR_CHAR }, { &spell_act_table[0].others_self, VAR_CHAR } }, { { &liquid_table[0].name, VAR_CHAR }, { &liquid_table[0].color, VAR_CHAR }, { &liquid_table[0].hunger, VAR_INT }, { &liquid_table[0].thirst, VAR_INT }, { &liquid_table[0].alcohol, VAR_INT }, { &liquid_table[0].cost, VAR_INT }, { &liquid_table[0].create, VAR_BOOL }, { &liquid_table[0].spell, VAR_SKILL } }, { { &spell_table[0].name, CNST_CHAR }, { &spell_table[0].prepare, VAR_INT }, { &spell_table[0].wait, VAR_INT }, { &spell_table[0].type, VAR_STYPE }, { &spell_table[0].damage, VAR_FORMULA }, { &spell_table[0].cast_mana, VAR_FORMULA }, { &spell_table[0].leech_mana, VAR_FORMULA }, { &spell_table[0].regen, VAR_FORMULA }, { &spell_table[0].duration, VAR_FORMULA }, { &spell_table[0].location, VAR_LOC }, { &spell_table[0].action[0], VAR_SA }, { &spell_table[0].action[1], VAR_SA }, { &spell_table[0].action[2], VAR_SA }, { &spell_table[0].action[3], VAR_SA }, { &spell_table[0].action[4], VAR_SA }, { &spell_table[0].reagent[0], VAR_INT }, { &spell_table[0].reagent[1], VAR_INT }, { &spell_table[0].reagent[2], VAR_INT }, { &spell_table[0].reagent[3], VAR_INT }, { &spell_table[0].reagent[4], VAR_INT } }, { { &town_table[0].name, VAR_CHAR }, { &town_table[0].recall, VAR_INT } }, { { &skill_table[0].name, VAR_CHAR }, { &skill_table[0].pre_skill[0], VAR_SKILL }, { &skill_table[0].pre_level[0], VAR_INT }, { &skill_table[0].pre_skill[1], VAR_SKILL }, { &skill_table[0].pre_level[1], VAR_INT }, { &skill_table[0].category, VAR_SCAT }, { &skill_table[0].prac_cost[ CLSS_MAGE ], VAR_INT }, { &skill_table[0].prac_cost[ CLSS_CLERIC ], VAR_INT }, { &skill_table[0].prac_cost[ CLSS_THIEF ], VAR_INT }, { &skill_table[0].prac_cost[ CLSS_WARRIOR ], VAR_INT }, { &skill_table[0].prac_cost[ CLSS_PALADIN ], VAR_INT }, { &skill_table[0].prac_cost[ CLSS_RANGER ], VAR_INT }, { &skill_table[0].prac_cost[ CLSS_MONK ], VAR_INT }, { &skill_table[0].prac_cost[ CLSS_PSIONIC ], VAR_INT }, { &skill_table[0].prac_cost[ CLSS_BARD ], VAR_INT }, { &skill_table[0].level[ CLSS_MAGE ], VAR_INT }, { &skill_table[0].level[ CLSS_CLERIC ], VAR_INT }, { &skill_table[0].level[ CLSS_THIEF ], VAR_INT }, { &skill_table[0].level[ CLSS_WARRIOR ], VAR_INT }, { &skill_table[0].level[ CLSS_PALADIN ], VAR_INT }, { &skill_table[0].level[ CLSS_RANGER ], VAR_INT }, { &skill_table[0].level[ CLSS_MONK ], VAR_INT }, { &skill_table[0].level[ CLSS_PSIONIC ], VAR_INT }, { &skill_table[0].level[ CLSS_BARD ], VAR_INT }, }, { { &material_table[0].name, CNST_CHAR }, { &material_table[0].cost, VAR_INT }, { &material_table[0].weight, VAR_INT }, { &material_table[0].mana, VAR_INT }, { &material_table[0].armor, VAR_INT }, { &material_table[0].enchant, VAR_INT }, { &material_table[0].save_fire, VAR_INT }, { &material_table[0].save_cold, VAR_INT }, { &material_table[0].save_acid, VAR_INT }, { &material_table[0].msg_fire, VAR_CHAR }, { &material_table[0].msg_cold, VAR_CHAR }, { &material_table[0].msg_acid, VAR_CHAR }, { &material_table[0].rust_name, VAR_CHAR }, { &material_table[0].rust[0], VAR_CHAR }, { &material_table[0].rust[1], VAR_CHAR }, { &material_table[0].rust[2], VAR_CHAR }, }, { { &nation_table[0].name, VAR_CHAR }, { &nation_table[0].abbrev, VAR_CHAR }, { &nation_table[0].temple, VAR_INT }, { &nation_table[0].room[0], VAR_INT }, { &nation_table[0].room[1], VAR_INT }, { &nation_table[0].race[0], VAR_INT }, { &nation_table[0].race[1], VAR_INT }, { &nation_table[0].race[2], VAR_INT }, { &nation_table[0].race[3], VAR_INT }, { &nation_table[0].race[4], VAR_INT }, { &nation_table[0].race[5], VAR_INT }, { &nation_table[0].race[6], VAR_INT }, { &nation_table[0].race[7], VAR_INT }, { &nation_table[0].race[8], VAR_INT }, { &nation_table[0].race[9], VAR_INT }, { &nation_table[0].race[10], VAR_INT }, { &nation_table[0].race[11], VAR_INT }, { &nation_table[0].race[12], VAR_INT }, { &nation_table[0].alignment[0], VAR_INT }, { &nation_table[0].alignment[1], VAR_INT }, { &nation_table[0].alignment[2], VAR_INT }, { &nation_table[0].alignment[3], VAR_INT }, { &nation_table[0].alignment[4], VAR_INT }, { &nation_table[0].alignment[5], VAR_INT }, { &nation_table[0].alignment[6], VAR_INT }, { &nation_table[0].alignment[7], VAR_INT }, { &nation_table[0].alignment[8], VAR_INT } }, { { &group_table[0].name, VAR_CHAR }, }, { { &race_table[0].name, VAR_CHAR }, { &race_table[0].abbrev, VAR_CHAR }, { &race_table[0].track, VAR_CHAR }, }, { { &plyr_race_table[0].name, VAR_CHAR }, { &plyr_race_table[0].plural, VAR_CHAR }, { &plyr_race_table[0].hp_bonus, VAR_INT }, { &plyr_race_table[0].mana_bonus, VAR_INT }, { &plyr_race_table[0].move_bonus, VAR_INT }, { &plyr_race_table[0].size, VAR_SIZE }, { &plyr_race_table[0].weight, VAR_CENT }, { &plyr_race_table[0].stat_bonus[0], VAR_INT }, { &plyr_race_table[0].stat_bonus[1], VAR_INT }, { &plyr_race_table[0].stat_bonus[2], VAR_INT }, { &plyr_race_table[0].stat_bonus[3], VAR_INT }, { &plyr_race_table[0].stat_bonus[4], VAR_INT }, { &plyr_race_table[0].resist[0], VAR_INT }, { &plyr_race_table[0].resist[1], VAR_INT }, { &plyr_race_table[0].resist[2], VAR_INT }, { &plyr_race_table[0].resist[3], VAR_INT }, { &plyr_race_table[0].resist[4], VAR_INT }, { &plyr_race_table[0].resist[5], VAR_INT }, { &plyr_race_table[0].resist[6], VAR_INT }, { &plyr_race_table[0].affect[0], VAR_AFF }, { &plyr_race_table[0].start_room[0], VAR_INT }, { &plyr_race_table[0].start_room[1], VAR_INT }, { &plyr_race_table[0].start_room[2], VAR_INT }, { &plyr_race_table[0].portal, VAR_INT }, { &plyr_race_table[0].start_age, VAR_INT }, { &plyr_race_table[0].life_span, VAR_INT }, { &plyr_race_table[0].alignments, VAR_ALIGN }, { &plyr_race_table[0].language, VAR_LANG }, { &plyr_race_table[0].open, VAR_BOOL }, }, { { &aff_char_table[0].name, VAR_CHAR }, { &aff_char_table[0].id_line, VAR_CHAR }, { &aff_char_table[0].score_name, VAR_CHAR }, { &aff_char_table[0].msg_on, VAR_CHAR }, { &aff_char_table[0].msg_on_room, VAR_CHAR }, { &aff_char_table[0].msg_off, VAR_CHAR }, { &aff_char_table[0].msg_off_room, VAR_CHAR }, { &aff_char_table[0].location, VAR_AFF_LOC }, { &aff_char_table[0].modifier, VAR_CHAR }, }, { { &aff_obj_table[0].name, VAR_CHAR }, { &aff_obj_table[0].msg_on, VAR_CHAR }, { &aff_obj_table[0].msg_off, VAR_CHAR }, { &aff_obj_table[0].location, VAR_INT }, }, { { &command_table[0].name, CNST_CHAR }, { &command_table[0].help, VAR_CHAR }, { &command_table[0].func_name, VAR_FUNC }, { &command_table[0].level[0], VAR_PERM }, { &command_table[0].reqlen, VAR_INT }, { &command_table[0].position, VAR_POS }, { &command_table[0].category, VAR_CC }, { &command_table[0].disrupt, VAR_BOOL }, { &command_table[0].reveal, VAR_BOOL }, { &command_table[0].queue, VAR_BOOL }, }, { { &cmd_cat_table[0].name, VAR_CHAR }, { &cmd_cat_table[0].level, VAR_INT }, }, { { &clss_table[0].name, VAR_CHAR }, { &clss_table[0].abbrev, VAR_CHAR }, { &clss_table[0].hit_min, VAR_INT }, { &clss_table[0].hit_max, VAR_INT }, { &clss_table[0].mana_min, VAR_INT }, { &clss_table[0].mana_max, VAR_INT }, { &clss_table[0].move_min, VAR_INT }, { &clss_table[0].move_max, VAR_INT }, { &clss_table[0].hit_bonus, VAR_INT }, { &clss_table[0].mana_bonus, VAR_INT }, { &clss_table[0].move_bonus, VAR_INT }, { &clss_table[0].resist[0], VAR_INT }, { &clss_table[0].resist[1], VAR_INT }, { &clss_table[0].resist[2], VAR_INT }, { &clss_table[0].resist[3], VAR_INT }, { &clss_table[0].resist[4], VAR_INT }, { &clss_table[0].resist[5], VAR_INT }, { &clss_table[0].resist[6], VAR_INT }, { &clss_table[0].alignments, VAR_ALIGN }, { &clss_table[0].open, VAR_BOOL }, }, { { &starting_table[0].name, VAR_CHAR }, { &starting_table[0].object[0], VAR_OBJ }, { &starting_table[0].object[2], VAR_OBJ }, { &starting_table[0].object[4], VAR_OBJ }, { &starting_table[0].object[6], VAR_OBJ }, { &starting_table[0].object[8], VAR_OBJ }, { &starting_table[0].skill[0], VAR_SKILL }, { &starting_table[0].skill[1], VAR_SKILL }, { &starting_table[0].skill[2], VAR_SKILL }, { &starting_table[0].skill[3], VAR_SKILL }, { &starting_table[0].skill[4], VAR_SKILL }, { &starting_table[0].level[0], VAR_INT }, { &starting_table[0].level[1], VAR_INT }, { &starting_table[0].level[2], VAR_INT }, { &starting_table[0].level[3], VAR_INT }, { &starting_table[0].level[4], VAR_INT }, }, { { &tedit_table[0].name, CNST_CHAR }, { &tedit_table[0].edit, VAR_INT }, { &tedit_table[0].new_delete, VAR_INT }, }, { { &build_table[0].name, VAR_CHAR }, { &build_table[0].result[0], VAR_OBJ }, { &build_table[0].ingredient[0], VAR_OBJ }, { &build_table[0].ingredient[2], VAR_OBJ }, { &build_table[0].ingredient[4], VAR_OBJ }, { &build_table[0].ingredient[6], VAR_OBJ }, { &build_table[0].ingredient[8], VAR_OBJ }, { &build_table[0].ingredient[10], VAR_OBJ }, { &build_table[0].ingredient[12], VAR_OBJ }, { &build_table[0].ingredient[14], VAR_OBJ }, { &build_table[0].ingredient[16], VAR_OBJ }, { &build_table[0].ingredient[18], VAR_OBJ }, { &build_table[0].skill[0], VAR_SKILL }, { &build_table[0].skill[1], VAR_SKILL }, { &build_table[0].skill[2], VAR_SKILL }, { &build_table[0].tool[0], VAR_OBJ }, { &build_table[0].tool[1], VAR_OBJ }, }, { { &help_cat_table[0].name, VAR_CHAR }, { &help_cat_table[0].level, VAR_INT }, }, { { &astral_table[0].name, VAR_CHAR }, { &astral_table[0].recall, VAR_INT } }, { { &religion_table[0].name, VAR_CHAR }, { &religion_table[0].sex, VAR_SEX }, { &religion_table[0].alignments, VAR_ALIGN }, { &religion_table[0].classes, VAR_INT } }, { { &alignment_table[0].name, VAR_CHAR }, { &alignment_table[0].abbrev, VAR_CHAR }, } }; const char* table_name [ MAX_TABLE ] = { "Soc.Default", "Soc.Human", "Soc.Elf", "Soc.Gnome", "Soc.Dwarf", "Soc.Halfling", "Soc.Ent", "Soc.Centaur", "Soc.Lizard", "Soc.Ogre", "Soc.Troll", "Soc.Orc", "Soc.Goblin", "Soc.Vyan", "Spell.Actions", "Liquids", "Spell.Data", "Towns", "Skills", "Materials", "Nations", "Groups", "Races", "Player.Races", "Aff.Char", "Aff.Obj", "Commands", "Cmd.Categories", "Classes", "Starting", "Tables", "Build", "Help.Categories", "Astral", "Religions", "Alignments" }; const char* social_fields [] = { "name", "position", "aggressive", "disrupt", "reveal", "no_arg.self", "no_arg.others", "ch.self", "ch.others", "ch.victim", "ch.sleep", "self.self", "self.others", "obj.self", "obj.others", "dir.self", "dir.others", "ch/obj.self", "ch/obj.victim", "ch/obj.others", "ch/obj.sleep", "self/obj.self", "self/obj.others", "" }; const char* spell_action_fields [] = { "name", "self_other", "victim_other", "others_other", "self_self", "others_self", "" }; const char* liquid_fields [] = { "name", "color", "hunger", "thirst", "alcohol", "cp/liter", "creatable", "spell", "" }; const char* spell_data_fields [] = { "name", "prepare", "wait", "type", "damage", "cast_mana", "leech_mana", "regen", "duration", "location", "action[1]", "action[2]", "action[3]", "action[4]", "action[5]", "reagent[1]", "reagent[2]", "reagent[3]", "reagent[4]", "reagent[5]", "" }; const char* town_fields [] = { "name", "recall_loc", "" }; const char* skill_fields [] = { "Name", "Prereq[1]", "Level[1]", "Prereq[2]", "Level[2]", "Category", "Cost[Mage]", "Cost[Cleric]", "Cost[Thief]", "Cost[Warrior]", "Cost[Paladin]", "Cost[Ranger]", "Cost[Monk]", "Cost[Psionic]", "Cost[Bard]", "Level[Mage]", "Level[Cleric]", "Level[Thief]", "Level[Warrior]", "Level[Paladin]", "Level[Ranger]", "Level[Monk]", "Level[Psionic]", "Level[Bard]", "" }; const char* material_fields [] = { "Name", "Cost", "Weight", "Mana", "Armor", "Enchant", "Save[Fire]", "Save[Cold]", "Save[Acid]", "Msg[Fire]", "Msg[Cold]", "Msg[Acid]", "Rust_Name", "Rust[1]", "Rust[2]", "Rust[3]", "" }; const char* nation_fields [] = { "Name", "Abbrev.", "Temple", "Room[1]", "Room[2]", "Rela[Human]", "Rela[Elf]", "Rela[Gnome]", "Rela[Dwarf]", "Rela[Halfling]", "Rela[Ent]", "Rela[Centaur]", "Rela[Lizardman]", "Rela[Ogre]", "Rela[Troll]", "Rela[Orc]", "Rela[Goblin]", "Rela[Vyan]", "Rela[LG]", "Rela[LN]", "Rela[LE]", "Rela[NG]", "Rela[PN]", "Rela[NE]", "Rela[CG]", "Rela[CN]", "Rela[CE]", "" }; const char* group_fields [] = { "Name", "" }; const char* race_fields [] = { "Name", "Abbrev.", "Tracks", "" }; const char* player_race_fields [] = { "Name", "Plural", "Hitpoints", "Energy", "Move", "Size", "Weight", "Strength", "Intelligence", "Wisdom", "Dexterity", "Constitution", "Magic", "Fire", "Cold", "Electricity", "Mind", "Acid", "Poison", "Affect", "Start[Good]", "Start[Neutral]", "Start[Evil]", "Portal", "Start.Age", "Life.Span", "Alignments", "Language", "Open", "" }; const char* aff_char_fields [] = { "Name", "Id.line", "Score.name", "Msg.on", "Msg.on_room", "Msg.off", "Msg.off_room", "Location", "Modifier", "" }; const char* aff_obj_fields [] = { "Name", "Msg.On", "Msg.Off", "Location", "" }; const char* command_fields [] = { "name", "help", "function", "level", "reqlen", "position", "category", "disrupt", "reveal", "queue", "" }; const char* cmd_cat_fields [] = { "name", "level", "" }; const char* class_fields [] = { "Name", "Abbrev.", "Hit_Min", "Hit_Max", "Energy_Min", "Energy_Max", "Move_Min", "Move_Max", "Hit_Regen", "Energy_Regen", "Move_Regen", "Magic", "Fire", "Cold", "Electricity", "Mind", "Acid", "Poison", "Alignments", "Open", "" }; const char* starting_fields [] = { "Class", "1_Object", "2_Object", "3_Object", "4_Object", "5_Object", "1_Skill", "2_Skill", "3_Skill", "4_Skill", "5_Skill", "1_Level", "2_Level", "3_Level", "4_Level", "5_Level", "" }; const char* table_fields [] = { "Name", "Edit", "New_Delete", "" }; const char* build_fields [] = { "name", "result", "ingred[1]", "ingred[2]", "ingred[3]", "ingred[4]", "ingred[5]", "ingred[6]", "ingred[7]", "ingred[8]", "ingred[9]", "ingred[10]", "skill[1]", "skill[2]", "skill[3]", "tool[1]", "tool[2]", "" }; const char* help_cat_fields [] = { "name", "level", "" }; const char* astral_fields [] = { "name", "location", "" }; const char* religion_fields [] = { "name", "sex", "alignments", "classes", "" }; const char* alignment_fields [] = { "name", "abbrev", "" }; const char** table_field [ MAX_TABLE ] = { social_fields, social_fields, social_fields, social_fields, social_fields, social_fields, social_fields, social_fields, social_fields, social_fields, social_fields, social_fields, social_fields, social_fields, spell_action_fields, liquid_fields, spell_data_fields, town_fields, skill_fields, material_fields, nation_fields, group_fields, race_fields, player_race_fields, aff_char_fields, aff_obj_fields, command_fields, cmd_cat_fields, class_fields, starting_fields, table_fields, build_fields, help_cat_fields, astral_fields, religion_fields, alignment_fields }; /* * LOCAL FUNCTIONS */ int find_table ( char_data*, char*&, const char*, const char* = empty_string ); int find_entry ( char_data*, char*&, int, const char* = empty_string ); void init_entry ( int, char* ); void init_commands ( void ); void remove_entry ( char_data*, int, int ); void sort_table ( char_data*, int ); void swap_entries ( int, int, int ); inline char* entry_name ( int, int ); /* * SUPPORT ROUTINES */ bool edit_table( char_data* ch, int table ) { int flag; switch( table ) { case TABLE_COMMAND : flag = PERM_COMMANDS; break; case TABLE_SPELL_DATA : case TABLE_SPELL_ACT : flag = PERM_SPELLS; break; default : flag = PERM_MISC_TABLES; break; } if( table <= MAX_PLYR_RACE && table == ch->shdata->race+1 ) flag = PERM_SOCIALS; if( !has_permission( ch, flag ) ) { send( ch, "You do not have permission to edit that table.\r\n" ); return FALSE; } return TRUE; } int find_table( char_data* ch, char*& argument, const char* msg1, const char* msg2 ) { int i; if( *argument == '\0' ) { if( msg2 != empty_string ) send( ch, msg2 ); return -2; } for( i = 0; i < MAX_TABLE; i++ ) if( matches( argument, table_name[i] ) ) return i; send( msg1, ch ); return -1; } int find_entry( char_data* ch, char*& argument, int table, const char* msg ) { int i; if( *argument == '\0' ) { if( msg != empty_string ) send( ch, msg ); return -2; } for( i = 0; i < table_max[table]; i++ ) if( exact_match( argument, entry_name( table, i ) ) ) return i; for( i = 0; i < table_max[table]; i++ ) if( fmatches( argument, entry_name( table, i )) ) return i; send( ch, "The %s table does not contain such an entry.\r\n", table_name[table] ); return -1; } /* * ENTRY INFO */ inline char* entry_name( int table, int col ) { void* pntr; if( table <= MAX_PLYR_RACE ) return social_table[table][col].name; pntr = (void *) (((int) table_entry[table - MAX_PLYR_RACE][0].offset) + col * table_size[table]); return (char*) *((void**) pntr); } int entry_type( int table, int entry ) { table = max( 0,table-MAX_PLYR_RACE ); return table_entry[table][entry].type; } void* table_pntr( int table, int entry, int col ) { if( table <= MAX_PLYR_RACE ) return (void *) ((int) &social_table[table][col] - (int) &social_table[0][0] + (int) table_entry[0][entry].offset); return (void *) ((int) table_entry[table - MAX_PLYR_RACE][entry].offset + col * table_size[table]); } /* * DISK ROUTINES */ void load_tables( ) { FILE* fp; int i, j, k; char** pntr; char* string; int table; echo( "Loading Tables ...\r\n" ); for( i = -1; i < MAX_TABLE; i++ ) { table = ( i == -1 ? TABLE_SKILL : i ); printf( " -%s\r\n", table_name[table] ); fp = open_file( TABLE_DIR, table_name[table], "r", TRUE ); if( strcmp( fread_word( fp ), "#TABLE" ) ) panic( "Load_tables: missing header" ); table_max[table] = fread_number( fp ); if( table_max[table] > table_abs_max[table] ) panic( "Load_Tables: Number of entries in table %s > table max.", table_name[table] ); for( j = 0; j < table_max[table]; j++ ) for( k = 0; *table_field[table][k] != '\0'; k++ ) { pntr = (char **) table_pntr( table, k, j ); switch( entry_type( table, k ) ) { case VAR_TEMP : *pntr = (char *) 0; break; case VAR_BLANK : *pntr = empty_string; break; case VAR_FORMULA : case VAR_CHAR : case CNST_CHAR : case VAR_FUNC : *pntr = fread_string( fp, MEM_TABLE ); break; case VAR_BOOL : case VAR_LEECH : case VAR_SIZE : case VAR_SA : case VAR_INT : case VAR_CC : case VAR_SCAT : case VAR_DICE : case VAR_STYPE : case VAR_ALIGN : case VAR_LANG : case VAR_AFF_LOC : case VAR_LOC : case VAR_CENT : case VAR_SEX : *pntr = (char *) fread_number( fp ); break; case VAR_POS : if( (*pntr = (char *) fread_number( fp ) ) < 0 || ((int) *pntr) >= MAX_POSITION ) panic( "Load_Tables: Impossible position." ); break; case VAR_DELETE : fread_number( fp ); break; case VAR_SKILL : string = fread_string( fp, MEM_UNKNOWN ); if( i != -1 ) *pntr = (char *) skill_index( string ); free_string( string, MEM_UNKNOWN ); break; case VAR_PERM : case VAR_OBJ : *pntr = (char *) fread_number( fp ); *(pntr+1) = (char *) fread_number( fp ); break; case VAR_AFF : *pntr = (char *) fread_number( fp ); *(pntr+1) = (char *) fread_number( fp ); *(pntr+2) = (char *) fread_number( fp ); break; } } fclose( fp ); } if( table_max[ TABLE_SKILL ] != MAX_SKILL ) { roach( "Load_Tables: Entries in skill table != max_skill." ); roach( "-- Max_Skill = %d", MAX_SKILL ); panic( "-- Entries = %d", table_max[ TABLE_SKILL ] ); } init_commands( ); init_spells( ); } void save_tables( ) { FILE* fp; char** pntr; int i, j, k; for( i = 0; i < MAX_TABLE; i++ ) { fp = open_file( TABLE_DIR, table_name[i], "w" ); fprintf( fp, "#TABLE\n\n" ); fprintf( fp, "%d\n\n", table_max[i] ); for( j = 0; j < table_max[i]; j++ ) { for( k = 0; *table_field[i][k] != '\0'; k++ ) { pntr = (char **) table_pntr( i,k,j ); switch( entry_type( i,k ) ) { case VAR_DELETE : break; case VAR_BLANK : case CNST_CHAR : case VAR_FUNC : case VAR_CHAR : case VAR_FORMULA : fprintf( fp, "%s~\n", (char*) *pntr ); break; case VAR_BOOL : case VAR_SIZE : case VAR_INT : case VAR_SA : case VAR_CC: case VAR_POS: case VAR_DICE : case VAR_SCAT : case VAR_STYPE : case VAR_LEECH : case VAR_TEMP : case VAR_ALIGN : case VAR_LANG : case VAR_AFF_LOC : case VAR_LOC : case VAR_CENT : case VAR_SEX : fprintf( fp, "%d\n", (int) *pntr ); break; case VAR_SKILL : if( (int) *pntr <= 0 ) fprintf( fp, "~\n" ); else fprintf( fp, "%s~\n", skill_table[ (int) *pntr ].name ); break; case VAR_PERM : case VAR_OBJ : fprintf( fp, "%d %d\n", (int) *pntr, (int) *(pntr+1) ); break; case VAR_AFF: fprintf( fp, "%d %d %d\n", (int) *pntr, (int) *(pntr+1), (int) *(pntr+2) ); break; } } fprintf( fp, "\n" ); } fprintf( fp, "\n" ); fclose( fp ); } } /* * TEDIT ROUTINE */ void do_tedit( char_data* ch, char* argument ) { wizard_data* imm = (wizard_data*) ch; int i = -1; int j = -1; if( *argument == '\0' ) { display_array( ch, "Tables", &table_name[0], &table_name[1], MAX_TABLE ); return; } if( exact_match( argument, "new" ) ) { if( ( i = find_table( ch, argument, "Table not found.", "Syntax: tedit new <table> <entry>" ) ) < 0 ) return; if( table_max[i] == table_abs_max[i] ) { send( ch, "That table has no open slots.\r\n" ); return; } if( !edit_table( ch, i ) ) return; init_entry( i, argument ); imm->table_edit[0] = i; imm->table_edit[1] = table_max[i]-1; send( ch, "Table entry added and you are now editing it.\r\n" ); return; } if( exact_match( argument, "delete" ) ) { if( ( i = find_table( ch, argument, "Table not found.\r\n" ) ) != -1 && ( j = find_entry( ch, argument, i, "Syntax: tedit delete <table> <name>\r\n" ) ) >= 0 ) remove_entry( ch, i, j ); return; } if( exact_match( argument, "sort" ) ) { if( ( i = find_table( ch, argument, "Table not found.\r\n", "Which table do you wish to sort?\r\n" ) ) < 0 ) return; sort_table( ch, i ); return; } if( ( i = find_table( ch, argument, "Table not found.\r\n" ) ) == -1 ) return; if( *argument == '\0' ) { display_array( ch, table_name[i], (const char**) table_pntr( i,0,0 ), (const char**) table_pntr( i,0,1 ), table_max[i] ); return; } if( ( j = find_entry( ch, argument, i ) ) == -1 ) return; imm->table_edit[0] = i; imm->table_edit[1] = j; send( ch, "Tstat and tset now work on the %s %s.\r\n", table_name[i], entry_name( i, j ) ); } void do_tset( char_data* ch, char* argument ) { char arg [ MAX_INPUT_LENGTH ]; char tmp [ MAX_INPUT_LENGTH ]; void** pntr; wizard_data* imm = (wizard_data*) ch; int length; int i = imm->table_edit[0]; int j = imm->table_edit[1]; int k, n; int* ipntr; bool error = FALSE; if( *argument == '\0' ) { do_tstat( ch, argument ); return; } if( !edit_table( ch, i ) ) return; argument = one_argument( argument, arg ); length = strlen( arg ); for( k = 0; *table_field[i][k] != '\0'; k++ ) if( !strncasecmp( arg, table_field[i][k], length ) ) break; if( *table_field[i][k] == '\0' ) { send( "Syntax: tset <field> <value>\r\n", ch ); return; } pntr = (void**) table_pntr( i,k,j ); switch( entry_type( i,k ) ) { case VAR_TEMP : send( "That is a unsorted variable and may not be set.\r\n", ch ); return; case VAR_SIZE : { class type_field size_field = { "size", MAX_SIZE, &size_name[0], &size_name[1], (int*) pntr }; pntr = (void **) table_pntr( i,0,j ); size_field.set( ch, (char*) *pntr, argument ); return; } case VAR_STYPE : { class type_field stype_field = { "type", MAX_STYPE, &stype_name[0], &stype_name[1], (int*) pntr }; pntr = (void **) table_pntr( i,0,j ); stype_field.set( ch, (char*) *pntr, argument ); return; } case VAR_AFF_LOC : { class type_field stype_field = { "type", MAX_AFF_LOCATION, &affect_location[0], &affect_location[1], (int*) pntr }; pntr = (void **) table_pntr( i,0,j ); stype_field.set( ch, (char*) *pntr, argument ); return; } case VAR_BOOL : ipntr = (int*) pntr; set_bool( ch, argument, table_field[i][k], *ipntr ); return; case VAR_ALIGN : align_flags.set( ch, argument, (int*) pntr ); return; case VAR_LANG : lang_flags.set( ch, argument, (int*) pntr ); return; case VAR_AFF : affect_flags.set( ch, argument, (int*) pntr ); return; case VAR_PERM : permission_flags.set( ch, argument, (int*) pntr ); return; case VAR_LOC : location_flags.set( ch, argument, (int*) pntr ); return; case VAR_POS : { class type_field pos_field = { "position", MAX_POSITION, &position_name[0], &position_name[1], (int*) pntr }; pntr = (void **) table_pntr( i,0,j ); pos_field.set( ch, (char*) *pntr, argument ); return; } case VAR_SEX : { class type_field sex_field = { "sex", MAX_SEX-1, &sex_name[0], &sex_name[1], (int*) pntr }; pntr = (void **) table_pntr( i,0,j ); sex_field.set( ch, (char*) *pntr, argument ); return; } case VAR_FORMULA : evaluate( argument, error ); if( error ) { send( ch, "Expression fails to evaluate.\r\n" ); return; } case VAR_BLANK : case VAR_CHAR : case VAR_FUNC : free_string( (char*) *pntr, MEM_TABLE ); *pntr = (void *) alloc_string( argument, MEM_TABLE ); pntr = (void **) table_pntr( i,0,j ); sprintf( tmp, "%s on %s %s set to:\r\n%s\r\n", table_field[i][k], table_name[i], (char*) *pntr, argument ); break; case VAR_INT : n = atoi( argument ); *pntr = (void *) n; pntr = (void **) table_pntr( i,0,j ); sprintf( tmp, "%s on %s %s set to %d.\r\n", table_field[i][k], table_name[i], (char*) *pntr, n ); break; case VAR_CENT : n = (int) (100 * atof( argument )); *pntr = (void *) n; pntr = (void **) table_pntr( i,0,j ); sprintf( tmp, "%s on %s %s set to %.2f.\r\n", table_field[i][k], table_name[i], (char*) *pntr, (float) n/100 ); break; case VAR_CC : { class type_field cat_field = { "category", MAX_ENTRY_CMD_CAT, &cmd_cat_table[0].name, &cmd_cat_table[1].name, (int*) pntr }; pntr = (void **) table_pntr( i,0,j ); cat_field.set( ch, (char*) *pntr, argument ); return; } case VAR_SKILL : length = strlen( argument ); for( n = 0; n < table_max[TABLE_SKILL]; n++ ) if( !strncasecmp( argument, skill_table[n].name, length ) ) break; if( n == table_max[ TABLE_SKILL ] ) { if( strncasecmp( argument, "none", length ) ) { send( "Unknown skill.\r\n", ch ); return; } n = -1; } *pntr = (void *) n; pntr = (void **) table_pntr( i,0,j ); sprintf( tmp, "%s on %s %s set to %s.\r\n", table_field[i][k], table_name[i], (char*) *pntr, n == -1 ? "none" : skill_table[n].name ); break; case VAR_SA : length = strlen( argument ); for( n = 0; n < table_max[TABLE_SPELL_ACT]; n++ ) if( !strncasecmp( argument, spell_act_table[n].name, length ) ) break; if( n == table_max[TABLE_SPELL_ACT] ) { send( "No spell action matching that name found.\r\n", ch ); return; } *pntr = (void *) n; pntr = (void **) table_pntr( i,0,j ); sprintf( tmp, "%s on %s %s set to %s.\r\n", table_field[i][k], table_name[i], (char*) *pntr, spell_act_table[n].name ); break; case VAR_SCAT : { class type_field scat_field = { "category", MAX_SKILL_CAT, &skill_cat_name[0], &skill_cat_name[1], (int*) pntr }; pntr = (void **) table_pntr( i,0,j ); scat_field.set( ch, (char*) *pntr, argument ); return; } case VAR_OBJ : if( !strcasecmp( argument, "nothing" ) ) { send( ch, "Field set to nothing.\r\n" ); *pntr = (void *) 0; *(pntr+1) = (void *) 1; return; } /* if( ( obj = one_object( ch, argument ) ) == NULL ) { send( "You don't have that object.\r\n", ch ); return; } (int) *pntr = obj->pIndexData->vnum; (int) *(pntr+1) = obj->selected; send( ch, "Object set.\r\n" ); */ return; case VAR_LEECH : case VAR_DICE : { class dice_field entry = { table_field[i][k], LEVEL_MOB, (int*) pntr }; pntr = (void **) table_pntr( i,0,j ); entry.set( ch, (char*) *pntr, argument ); return; } case CNST_CHAR : send( ch, "That entry is not setable.\r\n" ); return; } *tmp = toupper( *tmp ); send( ch, tmp ); } void do_tstat( char_data* ch, char* ) { char tmp [ FOUR_LINES ]; wizard_data* imm = (wizard_data*) ch; obj_clss_data* obj_clss; int table = imm->table_edit[0]; int entry = imm->table_edit[1]; int col, k, n; void** pntr; bool single; single = ( table != TABLE_SKILL && table != TABLE_CLSS && table != TABLE_PLYR_RACE && table != TABLE_SPELL_DATA && table != TABLE_NATION ); for( k = col = 0; *table_field[table][k] != '\0'; k++, col++ ) { pntr = (void **) table_pntr( table,k,entry ); sprintf( tmp, "%15s : ", table_field[table][k] ); switch( entry_type( table,k ) ) { case VAR_FORMULA : case VAR_CHAR : case CNST_CHAR : case VAR_FUNC : case VAR_BLANK : strcpy( &tmp[18], (char*) *pntr ); break; case VAR_BOOL : sprintf( &tmp[18], "%s", *pntr ? "true" : "false" ); break; case VAR_TEMP : case VAR_INT : sprintf( &tmp[18], "%d", (int) *pntr ); break; case VAR_CENT : n = (int) *pntr; sprintf( &tmp[18], "%.2f", (float) n/100 ); break; case VAR_AFF_LOC : strcpy( &tmp[18], affect_location[ int( *pntr ) ] ); break; case VAR_SIZE : strcpy( &tmp[18], size_name[ (int) *pntr ] ); break; case VAR_SCAT : strcpy( &tmp[18], skill_cat_name[ (int) *pntr ] ); break; case VAR_STYPE : strcpy( &tmp[18], stype_name[ (int) *pntr ] ); break; case VAR_SKILL : sprintf( &tmp[18], "%s", (int) *pntr == -1 ? "none" : skill_table[(int) *pntr].name ); break; case VAR_SA : if( int( *pntr ) >= 0 && int( *pntr ) < table_max[ TABLE_SPELL_ACT ] ) strcpy( &tmp[18], spell_act_table[(int) *pntr].name ); else sprintf( &tmp[18], "%d (Bug)", int( *pntr ) ); break; case VAR_CC : strcpy( &tmp[18], cmd_cat_table[(int) *pntr].name ); break; case VAR_POS : strcpy( &tmp[18], position_name[ int(*pntr) ] ); break; case VAR_SEX : strcpy( &tmp[18], sex_name[ int(*pntr) ] ); break; case VAR_OBJ : obj_clss = get_obj_index( int( *pntr ) ); strcpy( &tmp[18], obj_clss == NULL ? "nothing" : obj_clss->Name( int( *(pntr+1) ) ) ); break; case VAR_AFF : affect_flags.sprint( &tmp[18], (int*) pntr ); break; case VAR_ALIGN : abv_align_flags.sprint( &tmp[18], (int*) pntr ); break; case VAR_LANG : lang_flags.sprint( &tmp[18], (int*) pntr ); break; case VAR_PERM : permission_flags.sprint( &tmp[18], (int*) pntr ); break; case VAR_LOC : if( *((int*) pntr) == 0 ) strcpy( &tmp[18], "anywhere" ); else location_flags.sprint( &tmp[18], (int*) pntr ); break; case VAR_DICE : sprintf_dice( &tmp[18], int( *pntr ) ); break; case VAR_LEECH : sprintf_leech( &tmp[18], int( *pntr ) ); break; } if( single ) { strcat( tmp, "\r\n" ); page( ch, tmp ); } else { if( strlen( tmp ) > 30 ) { page( ch, "%s %s\r\n", col%2 ==1 ? "\r\n" : "", tmp ); col = 1; } else if( col%2 != 1 ) page( ch, " %-30s", tmp ); else page( ch, "%s\r\n", tmp ); } } if( !single && col%2 == 1 ) page( ch, "\r\n" ); if( table != TABLE_SPELL_ACT ) return; bool found = FALSE; page( ch, "\r\nUsed By:\r\n" ); for( int i = 0; i < MAX_SPELL; i++ ) for( int j = 0; j < spell_table[i].wait; j++ ) if( spell_table[i].action[j] == entry ) { found = TRUE; page( ch, " %s\r\n", spell_table[i].name ); break; } if( !found ) page( ch, " nothing\r\n" ); } /* * ADDING/REMOVING ENTRIES */ void init_entry( int i, char* name ) { void** pntr; int j = table_max[i]; int k; pntr = (void **) table_pntr( i,0,j ); *pntr = (void*) alloc_string( name, MEM_TABLE ); for( k = 1; *table_field[i][k] != '\0'; k++ ) { pntr = (void**) table_pntr( i,k,j ); switch( entry_type( i,k ) ) { case VAR_CHAR : case VAR_FUNC : *pntr = (void*) empty_string; break; case VAR_INT : case VAR_SA : case VAR_SIZE : case VAR_CC : case VAR_OBJ : case VAR_STYPE : *pntr = 0; break; } } table_max[i]++; return; } void sort_table( char_data* ch, int table ) { int max = table_max[table]; int min; int i; int j; if( table > TABLE_SOC_VYAN && table != TABLE_COMMAND && table != TABLE_SPELL_ACT ) { send( ch, "That would destroy the universe as we now know it.\r\n" ); return; } for( i = 0; i < max-1; i++ ) { min = i; for( j = i; j < max; j++ ) if( strcasecmp( entry_name( table, j ), entry_name( table, min ) ) < 0 ) min = j; if( min != i ) swap_entries( table, i, min ); } send( ch, "%s table sorted.\r\n", table_name[table] ); return; } /* * DELETING ENTRIES */ bool extract_nation( char_data* ch, int nation ) { int i; if( nation+1 != table_max[ TABLE_NATION ] ) { send( ch, "You may only delete the last entry of that table.\r\n" ); return FALSE; } for( i = 0; i < MAX_SPECIES; i++ ) if( species_list[i] != NULL && species_list[i]->nation == nation ) { send( ch, "Mobs belonging to that nation still exist.\r\n" ); return FALSE; } return TRUE; } void remove_entry( char_data* ch, int table, int entry ) { wizard_data* imm; int i; if( table > TABLE_SOC_VYAN && table != TABLE_COMMAND && table != TABLE_NATION ) { send( ch, "That table cannot have entries deleted from it.\r\n" ); return; } if( table == TABLE_NATION && !extract_nation( ch, entry ) ) return; send( ch, "Entry %s removed from table %s.\r\n", entry_name( table, entry ), table_name[table] ); for( i = 0; i < player_list; i++ ) { if( player_list[i]->Is_Valid( ) && ( imm = wizard( player_list[i] ) ) != NULL && imm->table_edit[0] == table && imm->table_edit[1] == entry ) { send( imm, "The table entry you were editing was deleted.\r\n" ); imm->table_edit[0] = 0; imm->table_edit[1] = 0; } } for( i = entry+1; i < table_max[table]; i++ ) swap_entries( table, i-1, i ); table_max[table]--; } /* * SWAPPING OF ENTRIES */ void swap_entries( int table, int e1, int e2 ) { int size = table_size[table]; char* temp; void* pntr1 = table_pntr( table,0,e1 ); void* pntr2 = table_pntr( table,0,e2 ); wizard_data* imm; temp = new char[size]; memcpy( temp, pntr1, size ); memcpy( pntr1, pntr2, size ); memcpy( pntr2, temp, size ); delete [] temp; for( int i = 0; i < player_list; i++ ) if( player_list[i]->Is_Valid( ) && ( imm = wizard( player_list[i] ) ) != NULL && imm->table_edit[0] == table ) exchange( imm->table_edit[1], e1, e2 ); if( table == TABLE_SPELL_ACT ) for( int i = 0; i < MAX_SPELL; i++ ) for( int j = 0; j < 5; j++ ) exchange( spell_table[i].action[j], e1, e2 ); }