diff options
author | Matthew Cline <zelgadis@sourceforge.net> | 2009-11-06 19:26:31 -0800 |
---|---|---|
committer | Matthew Cline <zelgadis@sourceforge.net> | 2009-11-06 19:26:31 -0800 |
commit | be871d682e8087ab38c5e9e054190daf6f81fff2 (patch) | |
tree | e31a44ad0f851c3946f6d665021bb9b206dd5a66 /crawl-ref/source/dbg-util.cc | |
parent | 8051b93a756f55ba7985f4e6ffe4a833ce0b41cb (diff) | |
download | crawl-ref-be871d682e8087ab38c5e9e054190daf6f81fff2.tar.gz crawl-ref-be871d682e8087ab38c5e9e054190daf6f81fff2.zip |
Split up debug.cc
Diffstat (limited to 'crawl-ref/source/dbg-util.cc')
-rw-r--r-- | crawl-ref/source/dbg-util.cc | 413 |
1 files changed, 413 insertions, 0 deletions
diff --git a/crawl-ref/source/dbg-util.cc b/crawl-ref/source/dbg-util.cc new file mode 100644 index 0000000000..1ccabe928d --- /dev/null +++ b/crawl-ref/source/dbg-util.cc @@ -0,0 +1,413 @@ +/* + * File: dbg-util.cc + * Summary: Miscellaneous debugging functions. + * Written by: Linley Henzell and Jesse Jones + */ + +#include "AppHdr.h" + +#include "dbg-util.h" + +#include "artefact.h" +#include "cio.h" +#include "coord.h" +#include "dungeon.h" +#include "monstuff.h" +#include "mon-util.h" +#include "religion.h" +#include "shopping.h" +#include "skills2.h" +#include "spl-util.h" + +//--------------------------------------------------------------- +// +// debug_prompt_for_int +// +// If nonneg, then it returns a non-negative number or -1 on fail +// If !nonneg, then it returns an integer, and 0 on fail +// +//--------------------------------------------------------------- +int debug_prompt_for_int( const char *prompt, bool nonneg ) +{ + char specs[80]; + + mpr(prompt, MSGCH_PROMPT); + get_input_line( specs, sizeof( specs ) ); + + if (specs[0] == '\0') + return (nonneg ? -1 : 0); + + char *end; + int ret = strtol( specs, &end, 10 ); + + if (ret < 0 && nonneg || ret == 0 && end == specs) + ret = (nonneg ? -1 : 0); + + return (ret); +} + +monster_type debug_prompt_for_monster(void) +{ + char specs[80]; + + mpr("Which monster by name? ", MSGCH_PROMPT); + if (!cancelable_get_line_autohist(specs, sizeof specs)) + { + if (specs[0] == '\0') + return (MONS_NO_MONSTER); + + return (get_monster_by_name(specs)); + } + return (MONS_NO_MONSTER); +} + +void debug_dump_levgen() +{ + CrawlHashTable &props = env.properties; + + std::string method; + std::string type; + + if (Generating_Level) + { + mpr("Currently generating level."); + extern std::string dgn_Build_Method; + method = dgn_Build_Method; + type = dgn_Layout_Type; + } + else + { + if (!props.exists(BUILD_METHOD_KEY)) + method = "ABSENT"; + else + method = props[BUILD_METHOD_KEY].get_string(); + + if (!props.exists(LAYOUT_TYPE_KEY)) + type = "ABSENT"; + else + type = props[LAYOUT_TYPE_KEY].get_string(); + } + + mprf("dgn_Build_Method = %s", method.c_str()); + mprf("dgn_Layout_Type = %s", type.c_str()); + + std::string extra; + + if (!props.exists(LEVEL_EXTRAS_KEY)) + extra = "ABSENT"; + else + { + const CrawlVector &vec = props[LEVEL_EXTRAS_KEY].get_vector(); + + for (unsigned int i = 0; i < vec.size(); ++i) + extra += vec[i].get_string() + ", "; + } + + mprf("Level extras: %s", extra.c_str()); + + mpr("Level vaults:"); + if (!props.exists(LEVEL_VAULTS_KEY)) + mpr("ABSENT"); + else + { + const CrawlHashTable &vaults = props[LEVEL_VAULTS_KEY].get_table(); + CrawlHashTable::const_iterator i = vaults.begin(); + + for (; i != vaults.end(); ++i) + mprf(" %s: %s", i->first.c_str(), + i->second.get_string().c_str()); + } + mpr(""); + + mpr("Temp vaults:"); + if (!props.exists(TEMP_VAULTS_KEY)) + mpr("ABSENT"); + else + { + const CrawlHashTable &vaults = props[TEMP_VAULTS_KEY].get_table(); + CrawlHashTable::const_iterator i = vaults.begin(); + + for (; i != vaults.end(); ++i) + { + mprf(" %s: %s", i->first.c_str(), + i->second.get_string().c_str()); + } + } + mpr(""); +} + +void error_message_to_player(void) +{ + mpr("Oh dear. There appears to be a bug in the program."); + mpr("I suggest you leave this level then save as soon as possible."); + +} + +std::string debug_coord_str(const coord_def &pos) +{ + return make_stringf("(%d, %d)%s", pos.x, pos.y, + !in_bounds(pos) ? " <OoB>" : ""); +} + +std::string debug_mon_str(const monsters* mon) +{ + const int midx = monster_index(mon); + if (invalid_monster_index(midx)) + return make_stringf("Invalid monster index %d", midx); + + std::string out = "Monster '" + mon->full_name(DESC_PLAIN, true) + "' "; + out += make_stringf("%s [midx = %d]", debug_coord_str(mon->pos()).c_str(), + midx); + + return (out); +} + +void debug_dump_mon(const monsters* mon, bool recurse) +{ + const int midx = monster_index(mon); + if (invalid_monster_index(midx) || invalid_monster_type(mon->type)) + return; + + fprintf(stderr, "<<<<<<<<<" EOL); + + fprintf(stderr, "Name: %s" EOL, mon->name(DESC_PLAIN, true).c_str()); + fprintf(stderr, "Base name: %s" EOL, + mon->base_name(DESC_PLAIN, true).c_str()); + fprintf(stderr, "Full name: %s" EOL EOL, + mon->full_name(DESC_PLAIN, true).c_str()); + + if (in_bounds(mon->pos())) + { + std::string feat = + raw_feature_description(grd(mon->pos()), NUM_TRAPS, true); + fprintf(stderr, "On/in/over feature: %s" EOL EOL, feat.c_str()); + } + + fprintf(stderr, "Foe: "); + if (mon->foe == MHITNOT) + fprintf(stderr, "none"); + else if (mon->foe == MHITYOU) + fprintf(stderr, "player"); + else if (invalid_monster_index(mon->foe)) + fprintf(stderr, "invalid monster index %d", mon->foe); + else if (mon->foe == midx) + fprintf(stderr, "self"); + else + fprintf(stderr, "%s", debug_mon_str(&menv[mon->foe]).c_str()); + + fprintf(stderr, EOL); + + fprintf(stderr, "Target: "); + if (mon->target.origin()) + fprintf(stderr, "none" EOL); + else + fprintf(stderr, "%s" EOL, debug_coord_str(mon->target).c_str()); + + int target = MHITNOT; + fprintf(stderr, "At target: "); + if (mon->target.origin()) + fprintf(stderr, "N/A"); + else if (mon->target == you.pos()) + { + fprintf(stderr, "player"); + target = MHITYOU; + } + else if (mon->target == mon->pos()) + { + fprintf(stderr, "self"); + target = midx; + } + else if (in_bounds(mon->target)) + { + target = mgrd(mon->target); + + if (target == NON_MONSTER) + fprintf(stderr, "nothing"); + else if (target == midx) + fprintf(stderr, "improperly linked self"); + else if (target == mon->foe) + fprintf(stderr, "same as foe"); + else if (invalid_monster_index(target)) + fprintf(stderr, "invalid monster index %d", target); + else + fprintf(stderr, "%s", debug_mon_str(&menv[target]).c_str()); + } + else + fprintf(stderr, "<OoB>"); + + fprintf(stderr, EOL); + + if (mon->is_patrolling()) + { + fprintf(stderr, "Patrolling: %s" EOL EOL, + debug_coord_str(mon->patrol_point).c_str()); + } + + if (mon->travel_target != MTRAV_NONE) + { + fprintf(stderr, EOL "Travelling:" EOL); + fprintf(stderr, " travel_target = %d" EOL, mon->travel_target); + fprintf(stderr, " travel_path.size() = %lu" EOL, + (long unsigned int) mon->travel_path.size()); + + if (mon->travel_path.size() > 0) + { + fprintf(stderr, " next travel step: %s" EOL, + debug_coord_str(mon->travel_path.back()).c_str()); + fprintf(stderr, " last travel step: %s" EOL, + debug_coord_str(mon->travel_path.front()).c_str()); + } + } + fprintf(stderr, EOL); + + fprintf(stderr, "Inventory:" EOL); + for (int i = 0; i < NUM_MONSTER_SLOTS; ++i) + { + const int idx = mon->inv[i]; + + if (idx == NON_ITEM) + continue; + + fprintf(stderr, " slot #%d: ", i); + + if (idx < 0 || idx > MAX_ITEMS) + { + fprintf(stderr, "invalid item index %d" EOL, idx); + continue; + } + const item_def &item(mitm[idx]); + + if (!item.is_valid()) + { + fprintf(stderr, "invalid item" EOL); + continue; + } + + fprintf(stderr, "%s", item.name(DESC_PLAIN, false, true).c_str()); + + if (!item.held_by_monster()) + { + fprintf(stderr, " [not held by monster, pos = %s]", + debug_coord_str(item.pos).c_str()); + } + else if (item.holding_monster() != mon) + { + fprintf(stderr, " [held by other monster: %s]", + debug_mon_str(item.holding_monster()).c_str()); + } + + fprintf(stderr, EOL); + } + fprintf(stderr, EOL); + + if (mon->can_use_spells()) + { + fprintf(stderr, "Spells:" EOL); + + for (int i = 0; i < NUM_MONSTER_SPELL_SLOTS; ++i) + { + spell_type spell = mon->spells[i]; + + if (spell == SPELL_NO_SPELL) + continue; + + fprintf(stderr, " slot #%d: ", i); + if (!is_valid_spell(spell)) + fprintf(stderr, "Invalid spell #%d" EOL, (int) spell); + else + fprintf(stderr, "%s" EOL, spell_title(spell)); + } + fprintf(stderr, EOL); + } + + fprintf(stderr, "attitude: %d, behaviour: %d, number: %d, flags: 0x%lx" EOL, + mon->attitude, mon->behaviour, mon->number, mon->flags); + + fprintf(stderr, "colour: %d, foe_memory: %d, shield_blocks:%d, " + "experience: %lu" EOL, + mon->colour, mon->foe_memory, mon->shield_blocks, + mon->experience); + + fprintf(stderr, "god: %s, seen_context: %s" EOL, + god_name(mon->god).c_str(), mon->seen_context.c_str()); + + fprintf(stderr, ">>>>>>>>>" EOL EOL); + + if (!recurse) + return; + + if (!invalid_monster_index(mon->foe) && mon->foe != midx + && !invalid_monster_type(menv[mon->foe].type)) + { + fprintf(stderr, "Foe:" EOL); + debug_dump_mon(&menv[mon->foe], false); + } + + if (!invalid_monster_index(target) && target != midx + && target != mon->foe + && !invalid_monster_type(menv[target].type)) + { + fprintf(stderr, "Target:" EOL); + debug_dump_mon(&menv[target], false); + } +} + +//--------------------------------------------------------------- +// +// debug_prompt_for_skill +// +//--------------------------------------------------------------- +int debug_prompt_for_skill( const char *prompt ) +{ + char specs[80]; + + mpr(prompt, MSGCH_PROMPT); + get_input_line( specs, sizeof( specs ) ); + + if (specs[0] == '\0') + return (-1); + + int skill = -1; + + for (int i = 0; i < NUM_SKILLS; ++i) + { + // Avoid the bad values. + if (is_invalid_skill(i)) + continue; + + char sk_name[80]; + strncpy( sk_name, skill_name(i), sizeof( sk_name ) ); + + char *ptr = strstr( strlwr(sk_name), strlwr(specs) ); + if (ptr != NULL) + { + if (ptr == sk_name && strlen(specs) > 0) + { + // We prefer prefixes over partial matches. + skill = i; + break; + } + else + skill = i; + } + } + + return (skill); +} + +std::string debug_art_val_str(const item_def& item) +{ + ASSERT(is_artefact(item)); + + return make_stringf("art val: %d, item val: %d", + artefact_value(item), item_value(item, true)); +} + +int debug_cap_stat(int stat) +{ + return (stat < 1 ? 1 : + stat > 127 ? 127 + : stat); +} + + |