From eb103fec101bac54e16df0c72fb2a85ee45e5723 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Fri, 15 Aug 2014 00:21:17 -0400 Subject: split dump file loading out to a separate file (and class) --- crawl-ref/source/MSVC/crawl.vcxproj | 2 + crawl-ref/source/MSVC/crawl.vcxproj.filters | 2 + crawl-ref/source/Makefile.obj | 1 + crawl-ref/source/main.cc | 1 + crawl-ref/source/wiz-dump.cc | 389 ++++++++++++++++++++++++++++ crawl-ref/source/wiz-dump.h | 32 +++ crawl-ref/source/wiz-you.cc | 368 +------------------------- crawl-ref/source/wiz-you.h | 6 +- 8 files changed, 440 insertions(+), 361 deletions(-) create mode 100644 crawl-ref/source/wiz-dump.cc create mode 100644 crawl-ref/source/wiz-dump.h diff --git a/crawl-ref/source/MSVC/crawl.vcxproj b/crawl-ref/source/MSVC/crawl.vcxproj index bb74832216..3b1f833531 100644 --- a/crawl-ref/source/MSVC/crawl.vcxproj +++ b/crawl-ref/source/MSVC/crawl.vcxproj @@ -596,6 +596,7 @@ perl.exe "util/gen-cflg.pl" compflag.h "<UNKNOWN>" "<UNKNOWN>" + @@ -921,6 +922,7 @@ perl.exe "util/gen-cflg.pl" compflag.h "<UNKNOWN>" "<UNKNOWN>" + diff --git a/crawl-ref/source/MSVC/crawl.vcxproj.filters b/crawl-ref/source/MSVC/crawl.vcxproj.filters index d47cf34e87..37bbcd2967 100644 --- a/crawl-ref/source/MSVC/crawl.vcxproj.filters +++ b/crawl-ref/source/MSVC/crawl.vcxproj.filters @@ -287,6 +287,7 @@ + @@ -611,6 +612,7 @@ + diff --git a/crawl-ref/source/Makefile.obj b/crawl-ref/source/Makefile.obj index 8b3d64d623..8783f2a821 100644 --- a/crawl-ref/source/Makefile.obj +++ b/crawl-ref/source/Makefile.obj @@ -240,6 +240,7 @@ viewgeom.o \ viewmap.o \ wcwidth.o \ wiz-dgn.o \ +wiz-dump.o \ wiz-fsim.o \ wiz-item.o \ wiz-mon.o \ diff --git a/crawl-ref/source/main.cc b/crawl-ref/source/main.cc index 02316dc486..87920ecc8a 100644 --- a/crawl-ref/source/main.cc +++ b/crawl-ref/source/main.cc @@ -145,6 +145,7 @@ #include "viewgeom.h" #include "viewmap.h" #include "wiz-dgn.h" +#include "wiz-dump.h" #include "wiz-fsim.h" #include "wiz-item.h" #include "wiz-mon.h" diff --git a/crawl-ref/source/wiz-dump.cc b/crawl-ref/source/wiz-dump.cc new file mode 100644 index 0000000000..00131575db --- /dev/null +++ b/crawl-ref/source/wiz-dump.cc @@ -0,0 +1,389 @@ +/** + * @file + * @brief Wizmode character dump loading +**/ + +#include "AppHdr.h" + +#include "wiz-dump.h" + +#include +#include + +#include "chardump.h" +#include "dbg-util.h" +#include "defines.h" +#include "enum.h" +#include "env.h" +#include "externs.h" +#include "items.h" +#include "itemname.h" +#include "libutil.h" +#include "makeitem.h" +#include "message.h" +#include "player.h" +#include "religion.h" +#include "skills.h" +#include "skills2.h" +#include "strings.h" +#include "unicode.h" +#include "wiz-you.h" + +static item_def _item_from_string(string s) +{ + item_def ret; + if (s.length() == 0) + return ret; + + if (s[0] == '+' || s[0] == '-') + { + size_t space = s.find(' '); + if (space == string::npos) + return ret; + + ret.plus = atoi(s.substr(1).c_str()); + if (s[0] == '-') + ret.plus = -ret.plus; + + s = s.substr(space + 1); + if (s.length() == 0) + return ret; + } + + size_t end = s.find_first_of("({"); + if (end == string::npos) + end = s.length(); + else + end--; + + string base_name = s.substr(0, end); + item_kind parsed = item_kind_by_name(base_name); + if (parsed.base_type != OBJ_UNASSIGNED) + { + ret.base_type = parsed.base_type; + ret.sub_type = parsed.sub_type; + /* pluses for item_kinds are only valid for manuals and runes + * so we can skip them here for now */ + } + + ret.quantity = 1; + item_colour(ret); + + while (end < s.length()) + { + size_t begin_brand = s.find_first_not_of("{(, ", end); + if (begin_brand == string::npos) + break; + size_t end_brand = s.find_first_of("}), ", begin_brand); + if (end_brand == begin_brand) + break; + else if (end_brand == string::npos) + end_brand = s.length(); + string brand_name = s.substr(begin_brand, end_brand - begin_brand); + + bool found = false; + switch (ret.base_type) + { + case OBJ_WEAPONS: + for (int i = SPWPN_NORMAL; i < NUM_SPECIAL_WEAPONS; ++i) + { + ret.special = i; + if (brand_name == weapon_brand_name(ret, true)) + { + found = true; + break; + } + } + if (!found) + ret.special = SPWPN_NORMAL; + break; + case OBJ_ARMOUR: + for (int i = SPARM_NORMAL; i < NUM_SPECIAL_ARMOURS; ++i) + { + ret.special = i; + if (brand_name == armour_ego_name(ret, true)) + { + found = true; + break; + } + } + if (!found) + ret.special = SPARM_NORMAL; + break; + // XXX + default: + break; + } + + end = end_brand; + } + + return ret; +} + +bool chardump_parser::_check_skill(const vector &tokens) +{ + size_t size = tokens.size(); + // * Level 25.0(24.4) Dodging + if (size <= 3 || tokens[1] != "Level") + return false; + + skill_type skill = skill_from_name(lowercase_string(tokens[3]).c_str()); + double amount = atof(tokens[2].c_str()); + set_skill_level(skill, amount); + if (tokens[0] == "+") + you.train[skill] = 1; + else if (tokens[0] == "*") + you.train[skill] = 2; + else + you.train[skill] = 0; + + redraw_skill(skill); + + return true; +} + +bool chardump_parser::_check_stats1(const vector &tokens) +{ + size_t size = tokens.size(); + // HP 121/199 AC 75 Str 35 XL: 27 + if (size <= 7 || tokens[0] != "HP") + return false; + + bool found = false; + for (size_t k = 1; k < size; k++) + { + if (tokens[k] == "Str") + { + you.base_stats[STAT_STR] = debug_cap_stat(atoi(tokens[k+1].c_str())); + you.redraw_stats.init(true); + you.redraw_evasion = true; + found = true; + } + else if (tokens[k] == "XL:") + { + set_xl(atoi(tokens[k+1].c_str()), false); + found = true; + } + } + + return found; +} + +bool chardump_parser::_check_stats2(const vector &tokens) +{ + size_t size = tokens.size(); + // MP 45/45 EV 13 Int 12 God: Makhleb [******] + if (size <= 8 || tokens[0] != "MP") + return false; + + bool found = false; + for (size_t k = 1; k < size; k++) + { + if (tokens[k] == "Int") + { + you.base_stats[STAT_INT] = debug_cap_stat(atoi(tokens[k+1].c_str())); + you.redraw_stats.init(true); + you.redraw_evasion = true; + found = true; + } + else if (tokens[k] == "God:") + { + god_type god = find_earliest_match(lowercase_string(tokens[k+1]), + (god_type) 1, NUM_GODS, + _always_true, + bind2nd(ptr_fun(god_name), + false)); + join_religion(god, true); + + string piety = tokens[k+2]; + int piety_levels = std::count(piety.begin(), piety.end(), '*'); + wizard_set_piety_to(piety_levels > 0 + ? piety_breakpoint(piety_levels - 1) + : 15); + } + } + + return found; +} + +bool chardump_parser::_check_stats3(const vector &tokens) +{ + size_t size = tokens.size(); + // Gold 15872 SH 59 Dex 9 Spells: 0 memorised, 26 levels left + if (size <= 5 || tokens[0] != "Gold") + return false; + + bool found; + for (size_t k = 0; k < size; k++) + { + if (tokens[k] == "Dex") + { + you.base_stats[STAT_DEX] = debug_cap_stat(atoi(tokens[k+1].c_str())); + you.redraw_stats.init(true); + you.redraw_evasion = true; + found = true; + } + else if (tokens[k] == "Gold") + you.set_gold(atoi(tokens[k+1].c_str())); + } + + return found; +} + +bool chardump_parser::_check_char(const vector &tokens) +{ + size_t size = tokens.size(); + + if (size <= 8) + return false; + + for (size_t k = 1; k < size; k++) + { + if (tokens[k] == "Turns:") + { + string race = tokens[k-2].substr(1); + string role = tokens[k-1].substr(0, tokens[k-1].length() - 1); + + wizard_change_species_to(find_species_from_string(race)); + wizard_change_job_to(find_job_from_string(role)); + return true; + } + } + + return false; +} + +bool chardump_parser::_check_equipment(const vector &tokens, + bool in_equipment) +{ + size_t size = tokens.size(); + + if (size <= 0) + return false; + + size_t offset; + if (tokens[0] == "rFire") + offset = 9; + else if (tokens[0] == "rCold") + offset = 9; + else if (tokens[0] == "rNeg") + offset = 9; + else if (tokens[0] == "rPois") + offset = 7; + else if (tokens[0] == "rElec") + offset = 7; + else if (tokens[0] == "SustAb") + offset = 8; + else if (tokens[0] == "rMut") + offset = 7; + else if (tokens[0] == "Saprov") + offset = 9; + else if (tokens[0] == "MR") + offset = 5; + else if (in_equipment) + offset = 3; + else + return false; + + if (size < offset) + return false; + + string item_desc = tokens[offset - 1]; + for (vector::const_iterator it = tokens.begin() + offset; + it != tokens.end(); + ++it) + { + item_desc.append(" "); + item_desc.append(*it); + } + + item_def item = _item_from_string(item_desc); + if (item.base_type == OBJ_UNASSIGNED) + mprf("unknown item: %s", item_desc.c_str()); + else + { + int mitm_slot = get_mitm_slot(); + if (mitm_slot != NON_ITEM) + { + mitm[mitm_slot] = item; + move_item_to_grid(&mitm_slot, you.pos()); + } + } + + return true; +} + +void chardump_parser::_modify_character(const string &inputdata) +{ + vector tokens = split_string(" ", inputdata); + static bool in_equipment = false; + + if (_check_skill(tokens)) + return; + if (_check_stats1(tokens)) + return; + if (_check_stats2(tokens)) + return; + if (_check_stats3(tokens)) + return; + if (_check_char(tokens)) + return; + + if (_check_equipment(tokens, in_equipment)) + { + in_equipment = true; + return; + } + else + in_equipment = false; +} + +/** + * Load a character from a dump file. + * + * @param filename The name of the file to open. + * @pre The file either does not exist, or is a complete + * dump or morgue file. + * @returns True if the file existed and could be opened. + * @post The player's stats, level, skills, training, and gold are + * those listed in the dump file. + */ +bool chardump_parser::_parse_from_file(const string &full_filename) +{ + FileLineInput f(full_filename.c_str()); + if (f.eof()) + return false; + + you.init_skills(); + + while (!f.eof()) + _modify_character(f.get_line()); + + init_skill_order(); + init_can_train(); + init_train(); + init_training(); + return true; +} + +bool chardump_parser::parse() +{ + return _parse_from_file(filename) + || _parse_from_file(morgue_directory() + filename); +} + +void wizard_load_dump_file() +{ + char filename[80]; + msgwin_get_line_autohist("Which dump file? ", filename, sizeof(filename)); + + if (filename[0] == '\0') + canned_msg(MSG_OK); + else + { + chardump_parser parser(filename); + if (!parser.parse()) + canned_msg(MSG_NOTHING_THERE); + } +} diff --git a/crawl-ref/source/wiz-dump.h b/crawl-ref/source/wiz-dump.h new file mode 100644 index 0000000000..3ab44a6e9b --- /dev/null +++ b/crawl-ref/source/wiz-dump.h @@ -0,0 +1,32 @@ +/** + * @file + * @brief Wizmode character dump loading +**/ + +#ifndef WIZDUMP_H +#define WIZDUMP_H + +class chardump_parser { +public: + chardump_parser(const string &f) : filename(f) { } + + bool parse(); + +private: + bool _parse_from_file(const string &full_filename); + + void _modify_character(const string &line); + + bool _check_skill(const vector &tokens); + bool _check_stats1(const vector &tokens); + bool _check_stats2(const vector &tokens); + bool _check_stats3(const vector &tokens); + bool _check_char(const vector &tokens); + bool _check_equipment(const vector &tokens, bool in_equipment); + + string filename; +}; + +void wizard_load_dump_file(); + +#endif diff --git a/crawl-ref/source/wiz-you.cc b/crawl-ref/source/wiz-you.cc index f278594aa8..f5542d6adc 100644 --- a/crawl-ref/source/wiz-you.cc +++ b/crawl-ref/source/wiz-you.cc @@ -56,7 +56,7 @@ static void _swap_equip(equipment_type a, equipment_type b) you.melded.set(b, tmp); } -static job_type _find_job(string job) +job_type find_job_from_string(const string &job) { string spec = lowercase_string(job); @@ -84,7 +84,7 @@ static job_type _find_job(string job) return j; } -static species_type _find_species(string species) +species_type find_species_from_string(const string &species) { string spec = lowercase_string(species); @@ -112,7 +112,7 @@ static species_type _find_species(string species) return sp; } -static void _wizard_change_species_to(species_type sp) +void wizard_change_species_to(species_type sp) { // Can't use magic cookies or placeholder species. if (!is_valid_species(sp)) @@ -264,7 +264,7 @@ static void _wizard_change_species_to(species_type sp) redraw_screen(); } -static void _wizard_change_job_to(job_type job) +void wizard_change_job_to(job_type job) { you.char_class = job; you.class_name = get_job_name(job); @@ -280,9 +280,9 @@ void wizard_change_species() if (specs[0] == '\0') return; - species_type sp = _find_species(specs); + species_type sp = find_species_from_string(specs); - _wizard_change_species_to(sp); + wizard_change_species_to(sp); } #endif @@ -411,7 +411,7 @@ void wizard_set_hunger_state() mpr("Ghouls can never be full or above!"); } -static void _wizard_set_piety_to(int newpiety, bool force = false) +void wizard_set_piety_to(int newpiety, bool force) { if (newpiety < 0 || newpiety > MAX_PIETY) { @@ -493,7 +493,7 @@ void wizard_set_piety() return; } - _wizard_set_piety_to(atoi(buf)); + wizard_set_piety_to(atoi(buf)); } //--------------------------------------------------------------- @@ -1076,358 +1076,6 @@ void wizard_transform() mpr("Transformation failed."); } -static item_def _item_from_string(string s) -{ - item_def ret; - if (s.length() == 0) - return ret; - - if (s[0] == '+' || s[0] == '-') - { - size_t space = s.find(' '); - if (space == string::npos) - return ret; - - ret.plus = atoi(s.substr(1).c_str()); - if (s[0] == '-') - ret.plus = -ret.plus; - - s = s.substr(space + 1); - if (s.length() == 0) - return ret; - } - - size_t end = s.find_first_of("({"); - if (end == string::npos) - end = s.length(); - else - end--; - - string base_name = s.substr(0, end); - item_kind parsed = item_kind_by_name(base_name); - if (parsed.base_type != OBJ_UNASSIGNED) - { - ret.base_type = parsed.base_type; - ret.sub_type = parsed.sub_type; - /* pluses for item_kinds are only valid for manuals and runes - * so we can skip them here for now */ - } - - ret.quantity = 1; - item_colour(ret); - - while (end < s.length()) - { - size_t begin_brand = s.find_first_not_of("{(, ", end); - if (begin_brand == string::npos) - break; - size_t end_brand = s.find_first_of("}), ", begin_brand); - if (end_brand == begin_brand) - break; - else if (end_brand == string::npos) - end_brand = s.length(); - string brand_name = s.substr(begin_brand, end_brand - begin_brand); - - bool found = false; - switch (ret.base_type) - { - case OBJ_WEAPONS: - for (int i = SPWPN_NORMAL; i < NUM_SPECIAL_WEAPONS; ++i) - { - ret.special = i; - if (brand_name == weapon_brand_name(ret, true)) - { - found = true; - break; - } - } - if (!found) - ret.special = SPWPN_NORMAL; - break; - case OBJ_ARMOUR: - for (int i = SPARM_NORMAL; i < NUM_SPECIAL_ARMOURS; ++i) - { - ret.special = i; - if (brand_name == armour_ego_name(ret, true)) - { - found = true; - break; - } - } - if (!found) - ret.special = SPARM_NORMAL; - break; - // XXX - default: - break; - } - - end = end_brand; - } - - return ret; -} - -static bool _chardump_check_skill(const vector &tokens) -{ - size_t size = tokens.size(); - // * Level 25.0(24.4) Dodging - if (size <= 3 || tokens[1] != "Level") - return false; - - skill_type skill = skill_from_name(lowercase_string(tokens[3]).c_str()); - double amount = atof(tokens[2].c_str()); - set_skill_level(skill, amount); - if (tokens[0] == "+") - you.train[skill] = 1; - else if (tokens[0] == "*") - you.train[skill] = 2; - else - you.train[skill] = 0; - - redraw_skill(skill); - - return true; -} - -static bool _chardump_check_stats1(const vector &tokens) -{ - size_t size = tokens.size(); - // HP 121/199 AC 75 Str 35 XL: 27 - if (size <= 7 || tokens[0] != "HP") - return false; - - bool found = false; - for (size_t k = 1; k < size; k++) - { - if (tokens[k] == "Str") - { - you.base_stats[STAT_STR] = debug_cap_stat(atoi(tokens[k+1].c_str())); - you.redraw_stats.init(true); - you.redraw_evasion = true; - found = true; - } - else if (tokens[k] == "XL:") - { - set_xl(atoi(tokens[k+1].c_str()), false); - found = true; - } - } - - return found; -} - -static bool _chardump_check_stats2(const vector &tokens) -{ - size_t size = tokens.size(); - // MP 45/45 EV 13 Int 12 God: Makhleb [******] - if (size <= 8 || tokens[0] != "MP") - return false; - - bool found = false; - for (size_t k = 1; k < size; k++) - { - if (tokens[k] == "Int") - { - you.base_stats[STAT_INT] = debug_cap_stat(atoi(tokens[k+1].c_str())); - you.redraw_stats.init(true); - you.redraw_evasion = true; - found = true; - } - else if (tokens[k] == "God:") - { - god_type god = find_earliest_match(lowercase_string(tokens[k+1]), - (god_type) 1, NUM_GODS, - _always_true, - bind2nd(ptr_fun(god_name), - false)); - join_religion(god, true); - - string piety = tokens[k+2]; - int piety_levels = std::count(piety.begin(), piety.end(), '*'); - _wizard_set_piety_to(piety_levels > 0 - ? piety_breakpoint(piety_levels - 1) - : 15); - } - } - - return found; -} - -static bool _chardump_check_stats3(const vector &tokens) -{ - size_t size = tokens.size(); - // Gold 15872 SH 59 Dex 9 Spells: 0 memorised, 26 levels left - if (size <= 5 || tokens[0] != "Gold") - return false; - - bool found; - for (size_t k = 0; k < size; k++) - { - if (tokens[k] == "Dex") - { - you.base_stats[STAT_DEX] = debug_cap_stat(atoi(tokens[k+1].c_str())); - you.redraw_stats.init(true); - you.redraw_evasion = true; - found = true; - } - else if (tokens[k] == "Gold") - you.set_gold(atoi(tokens[k+1].c_str())); - } - - return found; -} - -static bool _chardump_check_char(const vector &tokens) -{ - size_t size = tokens.size(); - - if (size <= 8) - return false; - - for (size_t k = 1; k < size; k++) - { - if (tokens[k] == "Turns:") - { - string race = tokens[k-2].substr(1); - string role = tokens[k-1].substr(0, tokens[k-1].length() - 1); - - _wizard_change_species_to(_find_species(race)); - _wizard_change_job_to(_find_job(role)); - return true; - } - } - - return false; -} - -static bool _chardump_check_equipment(const vector &tokens, - bool in_equipment) -{ - size_t size = tokens.size(); - - if (size <= 0) - return false; - - size_t offset; - if (tokens[0] == "rFire") - offset = 9; - else if (tokens[0] == "rCold") - offset = 9; - else if (tokens[0] == "rNeg") - offset = 9; - else if (tokens[0] == "rPois") - offset = 7; - else if (tokens[0] == "rElec") - offset = 7; - else if (tokens[0] == "SustAb") - offset = 8; - else if (tokens[0] == "rMut") - offset = 7; - else if (tokens[0] == "Saprov") - offset = 9; - else if (tokens[0] == "MR") - offset = 5; - else if (in_equipment) - offset = 3; - else - return false; - - if (size < offset) - return false; - - string item_desc = tokens[offset - 1]; - for (vector::const_iterator it = tokens.begin() + offset; - it != tokens.end(); - ++it) - { - item_desc.append(" "); - item_desc.append(*it); - } - - item_def item = _item_from_string(item_desc); - if (item.base_type == OBJ_UNASSIGNED) - mprf("unknown item: %s", item_desc.c_str()); - else - { - int mitm_slot = get_mitm_slot(); - if (mitm_slot != NON_ITEM) - { - mitm[mitm_slot] = item; - move_item_to_grid(&mitm_slot, you.pos()); - } - } - - return true; -} - -static void _wizard_modify_character(string inputdata) -{ - vector tokens = split_string(" ", inputdata); - static bool in_equipment = false; - - if (_chardump_check_skill(tokens)) - return; - if (_chardump_check_stats1(tokens)) - return; - if (_chardump_check_stats2(tokens)) - return; - if (_chardump_check_stats3(tokens)) - return; - if (_chardump_check_char(tokens)) - return; - - if (_chardump_check_equipment(tokens, in_equipment)) - { - in_equipment = true; - return; - } - else - in_equipment = false; -} - -/** - * Load a character from a dump file. - * - * @param filename The name of the file to open. - * @pre The file either does not exist, or is a complete - * dump or morgue file. - * @returns True if the file existed and could be opened. - * @post The player's stats, level, skills, training, and gold are - * those listed in the dump file. - */ -static bool _load_dump_file(const char *filename) -{ - FileLineInput f(filename); - if (f.eof()) - return false; - - you.init_skills(); - - while (!f.eof()) - _wizard_modify_character(f.get_line()); - - init_skill_order(); - init_can_train(); - init_train(); - init_training(); - return true; -} - -void wizard_load_dump_file() -{ - char filename[80]; - msgwin_get_line_autohist("Which dump file? ", filename, sizeof(filename)); - - if (filename[0] == '\0') - canned_msg(MSG_OK); - else if (!_load_dump_file(filename) - && !_load_dump_file((morgue_directory() + filename).c_str())) - { - canned_msg(MSG_NOTHING_THERE); - } -} - void wizard_join_religion() { god_type god = choose_god(); diff --git a/crawl-ref/source/wiz-you.h b/crawl-ref/source/wiz-you.h index f8ac4ca0cf..7af0e88935 100644 --- a/crawl-ref/source/wiz-you.h +++ b/crawl-ref/source/wiz-you.h @@ -13,6 +13,7 @@ void wizard_memorise_spec_spell(); void wizard_heal(bool super_heal); void wizard_set_hunger_state(); void wizard_set_piety(); +void wizard_set_piety_to(int new_piety, bool force = false); void wizard_exercise_skill(); void wizard_set_abyss(); void wizard_set_skill_level(skill_type skill = SK_NONE); @@ -29,7 +30,10 @@ void wizard_toggle_xray_vision(); void wizard_god_wrath(); void wizard_god_mollify(); void wizard_transform(); -void wizard_load_dump_file(); void wizard_join_religion(); +species_type find_species_from_string(const string &species_str); +void wizard_change_species_to(species_type sp); +job_type find_job_from_string(const string &job_str); +void wizard_change_job_to(job_type job); #endif -- cgit v1.2.3