diff options
author | haranp <haranp@c06c8d41-db1a-0410-9941-cceddc491573> | 2006-09-20 18:46:02 +0000 |
---|---|---|
committer | haranp <haranp@c06c8d41-db1a-0410-9941-cceddc491573> | 2006-09-20 18:46:02 +0000 |
commit | 4a3ba595de28a6df1e6d195243c7208a96055ee3 (patch) | |
tree | bb7097b0ebae2210f825e36b662ad43349be2b5b | |
parent | 2a128adc38347ed9bec56ea55ef65c46cf6dcf69 (diff) | |
download | crawl-ref-4a3ba595de28a6df1e6d195243c7208a96055ee3.tar.gz crawl-ref-4a3ba595de28a6df1e6d195243c7208a96055ee3.zip |
Integrated the inscription patch, *except* for the keybindings issue.
Also, made a minor change to files.cc - I couldn't reload savefiles
the way it was set up before.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/branches/stone_soup@53 c06c8d41-db1a-0410-9941-cceddc491573
46 files changed, 1217 insertions, 87 deletions
diff --git a/crawl-ref/source/AppHdr.h b/crawl-ref/source/AppHdr.h index e9b38ff160..c60bd55aca 100644 --- a/crawl-ref/source/AppHdr.h +++ b/crawl-ref/source/AppHdr.h @@ -297,7 +297,7 @@ // mv: (new 9 Aug 01) turns off missile trails, might be slow on some computers // #define MISSILE_TRAILS_OFF -// bwr: allow player to destroy items in inventory (but not equiped items) +// bwr: allow player to destroy items in inventory (but not equipped items) // See comment at items.cc::cmd_destroy_item() for details/issues. // #define ALLOW_DESTROY_ITEM_COMMAND @@ -320,7 +320,7 @@ // be dumped in the current directory. // // #define SAVE_DIR_PATH "/opt/crawl/lib/" - #define SAVE_DIR_PATH "" + // #define SAVE_DIR_PATH "" // will make this little thing go away. Define SAVE_PACKAGE_CMD // to a command to compress and bundle the save game files into a diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index 95618e83c0..51da4597d0 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -107,6 +107,7 @@ #include "mon-util.h" #include "mutation.h" #include "newgame.h" +#include "notes.h" #include "ouch.h" #include "output.h" #include "overmap.h" @@ -139,6 +140,10 @@ char info[ INFO_SIZE ]; // messaging queue extern'd everywhere {dlb} int stealth; // externed in view.h // no it is not {dlb} char use_colour = 1; +int autoprayer_on = 0; +int just_autoprayed = 0; +int about_to_autopray = 0; + FixedVector< char, NUM_STATUE_TYPES > Visible_Statue; // set to true once a new game starts or an old game loads @@ -952,8 +957,27 @@ static void input(void) you.turn_is_over = 0; perform_activity(); } - else - { + else if (autoprayer_on && you.duration[DUR_PRAYER] == 0 && + just_autoprayed == 0 && you.religion != GOD_NO_GOD && + i_feel_safe()) { + keyin = 'p'; + just_autoprayed = 1; + about_to_autopray = 0; + } + else { + if ( just_autoprayed == 1 && you.duration[DUR_PRAYER] == 0 ) { + /* oops */ + mpr("Autoprayer failed, deactivating.", MSGCH_WARN); + autoprayer_on = 0; + } + just_autoprayed = 0; + if ( autoprayer_on && about_to_autopray && + you.religion != GOD_NO_GOD && + you.duration[DUR_PRAYER] == 0 ) { + mpr("Autoprayer not resuming prayer.", MSGCH_WARN); + about_to_autopray = 0; + } + if (you.running < 0) // Travel and explore travel(&keyin, &move_x, &move_y); @@ -1180,6 +1204,31 @@ static void input(void) mpr(info); break; + case CMD_TOGGLE_AUTOPRAYER: + case CONTROL('V'): + autoprayer_on = !autoprayer_on; + strcpy(info, "Autoprayer is now "); + strcat(info, (autoprayer_on) ? "on" : "off"); + strcat(info, "."); + mpr(info); + break; + + case CONTROL('T'): + case CMD_TOGGLE_NOFIZZLE: + if ( Options.confirm_spell_fizzle ) { + fizzlecheck_on = !fizzlecheck_on; + strcpy(info, "Fizzle confirmation is now "); + strcat(info, (fizzlecheck_on) ? "on" : "off"); + strcat(info, "."); + mpr(info); + } + break; + + case ':': + case CMD_MAKE_NOTE: + make_user_note(); + break; + case CONTROL('C'): case CMD_CLEAR_MAP: if (you.level_type != LEVEL_LABYRINTH && you.level_type != LEVEL_ABYSS) @@ -1333,7 +1382,7 @@ static void input(void) { int index=0; - if (armour_prompt("Take off which item?", &index)) + if (armour_prompt("Take off which item?", &index, OPER_TAKEOFF)) takeoff_armour(index); } break; @@ -1632,6 +1681,11 @@ static void input(void) list_weapons(); return; + case '{': + case CMD_INSCRIBE_ITEM: + inscribe_item(); + break; + case ']': case CMD_LIST_ARMOUR: list_armour(); @@ -1865,7 +1919,8 @@ static void input(void) you.duration[DUR_PRAYER]--; else if (you.duration[DUR_PRAYER] == 1) { - god_speaks(you.religion, "Your prayer is over."); + mpr( "Your prayer is over.", MSGCH_PRAY, you.religion ); + about_to_autopray = 1; you.duration[DUR_PRAYER] = 0; } @@ -2852,13 +2907,14 @@ static bool initialise(void) you.your_name[kNameLen - 1] = 0; #endif + activate_notes(true); return (ret); } // An attempt to tone down berserk a little bit. -- bwross // // This function does the accounting for not attacking while berserk -// This gives a triangluar number function for the additional penalty +// This gives a triangular number function for the additional penalty // Turn: 1 2 3 4 5 6 7 8 // Penalty: 1 3 6 10 15 21 28 36 // diff --git a/crawl-ref/source/chardump.cc b/crawl-ref/source/chardump.cc index 5beb0e7ab7..2eb3fd8c47 100644 --- a/crawl-ref/source/chardump.cc +++ b/crawl-ref/source/chardump.cc @@ -49,6 +49,7 @@ #include "items.h" #include "macro.h" #include "mutation.h" +#include "notes.h" #include "output.h" #include "player.h" #include "randart.h" @@ -476,6 +477,19 @@ static void dump_stats2( std::string & text, bool calc_unid) text += EOL EOL; } +static void dump_notes( std::string& text ) +{ + if ( note_list.size() == 0 || Options.use_notes == false ) + return; + + text += EOL "-----" EOL "Notes" EOL "-----" EOL; + for ( unsigned i = 0; i < note_list.size(); ++i ) { + text += describe_note(note_list[i]); + text += EOL; + } + text += EOL; +} + //--------------------------------------------------------------- // // dump_location @@ -1038,6 +1052,8 @@ bool dump_char( const char fname[30], bool show_prices ) // $$$ a try block? dump_location(text); dump_religion(text); + dump_notes(text); + switch (you.burden_state) { case BS_OVERLOADED: diff --git a/crawl-ref/source/clua.cc b/crawl-ref/source/clua.cc index 41e703c2b0..f41987f04a 100644 --- a/crawl-ref/source/clua.cc +++ b/crawl-ref/source/clua.cc @@ -1877,6 +1877,11 @@ static option_handler handlers[] = { "easy_armour", &Options.easy_armour, option_hboolean }, { "easy_butcher", &Options.easy_butcher, option_hboolean }, { "terse_hand", &Options.terse_hand, option_hboolean }, + { "confirm_self_target", &Options.confirm_self_target, option_hboolean }, + { "confirm_spell_fizzle", &Options.confirm_spell_fizzle, option_hboolean }, + { "safe_autopickup", &Options.safe_autopickup, option_hboolean }, + { "note_skill_max", &Options.note_skill_max, option_hboolean }, + { "use_notes", &Options.use_notes, option_hboolean }, { "delay_message_clear", &Options.delay_message_clear, option_hboolean }, { "no_dark_brand", &Options.no_dark_brand, option_hboolean }, { "auto_list", &Options.auto_list, option_hboolean }, @@ -1887,6 +1892,7 @@ static option_handler handlers[] = { "show_waypoints", &Options.show_waypoints, option_hboolean }, { "item_colour", &Options.item_colour, option_hboolean }, { "target_zero_exp", &Options.target_zero_exp, option_hboolean }, + { "safe_zero_exp", &Options.safe_zero_exp, option_hboolean }, { "target_wrap", &Options.target_wrap, option_hboolean }, { "easy_exit_menu", &Options.easy_exit_menu, option_hboolean }, { "dos_use_background_intensity", &Options.dos_use_background_intensity, diff --git a/crawl-ref/source/direct.cc b/crawl-ref/source/direct.cc index 753adf3207..665ebef4e8 100644 --- a/crawl-ref/source/direct.cc +++ b/crawl-ref/source/direct.cc @@ -45,6 +45,8 @@ #include "macro.h" #endif +int fizzlecheck_on = 1; + enum LOSSelect { LOS_ANY = 0x00, @@ -127,7 +129,8 @@ static bool is_mapped(int x, int y) // // targetting mode is handled by look_around() //--------------------------------------------------------------- -void direction( struct dist &moves, int restrict, int mode ) + +void direction2( struct dist &moves, int restrict, int mode ) { bool dirChosen = false; bool targChosen = false; @@ -320,6 +323,35 @@ void direction( struct dist &moves, int restrict, int mode ) moves.ty = you.y_pos + moves.dy * my; } +/* safe version of direction */ +void direction( struct dist &moves, int restrict, int mode, + bool confirm_fizzle ) +{ + while ( 1 ) { + direction2( moves, restrict, mode ); + if ( moves.isMe && Options.confirm_self_target == true && + mode != TARG_FRIEND ) { + if ( yesno("Really target yourself? ", false, 'n') ) + return; + else + mpr("Choose a better target.", MSGCH_PROMPT); + } + else if ( confirm_fizzle && !moves.isValid && fizzlecheck_on && + Options.confirm_spell_fizzle ) + { + if ( yesno("Really fizzle? ", false, 'n') ) + return; + else + mpr("Try again.", MSGCH_PROMPT); + } + else + { + return; + } + } +} + + // Attempts to describe a square that's not in line-of-sight. If // there's a stash on the square, announces the top item and number // of items, otherwise, if there's a stair that's in the travel diff --git a/crawl-ref/source/direct.h b/crawl-ref/source/direct.h index d3aec5816a..dbd60ad240 100644 --- a/crawl-ref/source/direct.h +++ b/crawl-ref/source/direct.h @@ -28,7 +28,7 @@ #define DIR_DIR 2 void direction( struct dist &moves, int restricts = DIR_NONE, - int mode = TARG_ANY ); + int mode = TARG_ANY, bool confirm_fizzle = false ); // last updated 12may2000 {dlb} /* *********************************************************************** diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index 2c38be36da..d7bbff003b 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -43,6 +43,7 @@ #include "mon-util.h" #include "mon-pick.h" #include "monplace.h" +#include "notes.h" #include "player.h" #include "randart.h" #include "spl-book.h" @@ -485,6 +486,7 @@ int items( int allow_uniques, // not just true-false, mitm[p].slot = 0; mitm[p].orig_monnum = 0; mitm[p].orig_place = 0; + mitm[p].inscription = std::string(); // cap item_level unless an acquirement-level item {dlb}: if (item_level > 50 && item_level != MAKE_GOOD_ITEM) @@ -2585,6 +2587,7 @@ void give_item(int mid, int level_number) //mv: cleanup+minor changes mitm[bp].special = 0; mitm[bp].orig_place = 0; mitm[bp].orig_monnum = 0; + mitm[bp].inscription = std::string(); // this flags things to "goto give_armour" below ... {dlb} mitm[bp].base_type = 101; @@ -3238,6 +3241,7 @@ void give_item(int mid, int level_number) //mv: cleanup+minor changes mitm[bp].link = NON_ITEM; mitm[bp].orig_place = 0; mitm[bp].orig_monnum = 0; + mitm[bp].inscription = std::string(); item_race = MAKE_ITEM_RANDOM_RACE; give_level = 1 + (level_number / 2); @@ -6697,6 +6701,9 @@ static void place_spec_shop( int level_number, int j = 0; // loop variable int item_level; + bool note_status = notes_are_active(); + activate_notes(false); + for (i = 0; i < MAX_SHOPS; i++) { if (env.shop[i].type == SHOP_UNASSIGNED) @@ -6792,6 +6799,8 @@ static void place_spec_shop( int level_number, env.shop[i].y = shop_y; grd[shop_x][shop_y] = DNGN_ENTER_SHOP; + + activate_notes(note_status); } // end place_spec_shop() static unsigned char item_in_shop(unsigned char shop_type) diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc index d021041131..e7a76e9cfe 100644 --- a/crawl-ref/source/effects.cc +++ b/crawl-ref/source/effects.cc @@ -507,7 +507,7 @@ bool acquirement(unsigned char force_class, int agent) if (class_wanted == OBJ_FOOD) { - // food is a little less predicatable now -- bwr + // food is a little less predictable now -- bwr if (you.species == SP_GHOUL) { @@ -516,7 +516,7 @@ bool acquirement(unsigned char force_class, int agent) } else { - // Meat is better than bread (except for herbivors), and + // Meat is better than bread (except for herbivores), and // by choosing it as the default we don't have to worry // about special cases for carnivorous races (ie kobold) type_wanted = FOOD_MEAT_RATION; @@ -525,7 +525,7 @@ bool acquirement(unsigned char force_class, int agent) type_wanted = FOOD_BREAD_RATION; // If we have some regular rations, then we're probably be more - // interested in faster foods (escpecially royal jelly)... + // interested in faster foods (especially royal jelly)... // otherwise the regular rations should be a good enough offer. if (already_has[FOOD_MEAT_RATION] + already_has[FOOD_BREAD_RATION] >= 2 || coinflip()) @@ -903,7 +903,7 @@ bool acquirement(unsigned char force_class, int agent) if (best_any >= SK_FIGHTING && best_any <= SK_STAVES) { - // Fighter mage's get the fighting enchantment books + // Fighter mages get the fighting enchantment books if (!you.had_book[BOOK_WAR_CHANTS]) type_wanted = BOOK_WAR_CHANTS; else if (!you.had_book[BOOK_TUKIMA]) @@ -1231,7 +1231,7 @@ bool acquirement(unsigned char force_class, int agent) } else { - // keep reseting seed until it's good: + // keep resetting seed until it's good: for (; brand == SPWPN_HOLY_WRATH || brand == SPWPN_DISRUPTION; brand = get_weapon_brand(mitm[thing_created])) diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index c084ec3154..e32fea0575 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -643,7 +643,83 @@ enum command_type CMD_INTERLEVEL_TRAVEL, CMD_FIX_WAYPOINT, - CMD_CLEAR_MAP + CMD_CLEAR_MAP, + CMD_INSCRIBE_ITEM, + CMD_TOGGLE_NOFIZZLE, + CMD_TOGGLE_AUTOPRAYER, + CMD_MAKE_NOTE, + + CMD_PERFORM_ACTIVITY, + + /* overmap commands */ + CMD_MAP_CLEAR_MAP, + CMD_MAP_ADD_WAYPOINT, + CMD_MAP_EXCLUDE_AREA, + CMD_MAP_CLEAR_EXCLUDES, + + CMD_MAP_MOVE_LEFT, + CMD_MAP_MOVE_DOWN, + CMD_MAP_MOVE_UP, + CMD_MAP_MOVE_RIGHT, + CMD_MAP_MOVE_UP_LEFT, + CMD_MAP_MOVE_DOWN_LEFT, + CMD_MAP_MOVE_UP_RIGHT, + CMD_MAP_MOVE_DOWN_RIGHT, + + CMD_MAP_JUMP_LEFT, + CMD_MAP_JUMP_DOWN, + CMD_MAP_JUMP_UP, + CMD_MAP_JUMP_RIGHT, + CMD_MAP_JUMP_UP_LEFT, + CMD_MAP_JUMP_DOWN_LEFT, + CMD_MAP_JUMP_UP_RIGHT, + CMD_MAP_JUMP_DOWN_RIGHT, + + CMD_MAP_SCROLL_DOWN, + CMD_MAP_SCROLL_UP, + + CMD_MAP_FIND_UPSTAIR, + CMD_MAP_FIND_DOWNSTAIR, + CMD_MAP_FIND_YOU, + CMD_MAP_FIND_PORTAL, + CMD_MAP_FIND_TRAP, + CMD_MAP_FIND_ALTAR, + CMD_MAP_FIND_EXCLUDED, + CMD_MAP_FIND_F, + CMD_MAP_FIND_WAYPOINT, + CMD_MAP_FIND_STASH, + + CMD_MAP_GOTO_TARGET, + + CMD_MAP_EXIT_MAP, + + /* targeting commands */ + CMD_TARGET_DOWN_LEFT, + CMD_TARGET_DOWN, + CMD_TARGET_DOWN_RIGHT, + CMD_TARGET_LEFT, + CMD_TARGET_RIGHT, + CMD_TARGET_UP_LEFT, + CMD_TARGET_UP, + CMD_TARGET_UP_RIGHT, + CMD_TARGET_CYCLE_TARGET_MODE, + CMD_TARGET_PREV_TARGET, + CMD_TARGET_SELECT, + CMD_TARGET_OBJ_CYCLE_BACK, + CMD_TARGET_OBJ_CYCLE_FORWARD, + CMD_TARGET_CYCLE_FORWARD, + CMD_TARGET_CYCLE_BACK, + CMD_TARGET_CENTER, + CMD_TARGET_CANCEL, + CMD_TARGET_OLD_SPACE, + CMD_TARGET_FIND_TRAP, + CMD_TARGET_FIND_PORTAL, + CMD_TARGET_FIND_ALTAR, + CMD_TARGET_FIND_UPSTAIR, + CMD_TARGET_FIND_DOWNSTAIR, + CMD_TARGET_FIND_YOU, + CMD_TARGET_DESCRIBE + }; enum confirm_level_type @@ -1598,6 +1674,7 @@ enum msg_channel_type MSGCH_PLAIN, // regular text MSGCH_PROMPT, // various prompts MSGCH_GOD, // god/religion (param is god) + MSGCH_PRAY, // praying messages (param is god) MSGCH_DURATION, // effect down/warnings MSGCH_DANGER, // serious life threats (ie very large HP attacks) MSGCH_WARN, // much less serious threats @@ -2534,6 +2611,24 @@ enum object_selector OSEL_WIELD = -2 }; +enum operation_types +{ + OPER_WIELD = 'w', + OPER_QUAFF = 'q', + OPER_DROP = 'd', + OPER_EAT = 'e', + OPER_TAKEOFF = 'T', + OPER_WEAR = 'W', + OPER_PUTON = 'P', + OPER_REMOVE = 'R', + OPER_READ = 'r', + OPER_MEMORISE = 'M', + OPER_ZAP = 'z', + OPER_THROW = 't', + OPER_EXAMINE = 'v', + OPER_ANY = 0 +}; + enum orb_type { ORB_ZOT // 0 diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index 525ec77614..0267e63f93 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -240,6 +240,8 @@ struct item_def unsigned short orig_place; short orig_monnum; + + std::string inscription; item_def() : base_type(0), sub_type(0), plus(0), plus2(0), special(0L), colour(0), flags(0L), quantity(0), @@ -669,6 +671,13 @@ struct game_options bool easy_open; // open doors with movement bool easy_armour; // allow auto-removing of armour bool easy_butcher; // open doors with movement + bool confirm_self_target; // require confirmation before selftarget + bool confirm_spell_fizzle; // require confirm before cancel + bool safe_autopickup; // don't autopickup when monsters visible + bool note_skill_max; // take note when skills reach new max + bool use_notes; // take (and dump) notes + int note_hp_percent; // percentage hp for notetaking + int ood_interesting; // how many levels OOD is noteworthy? int easy_confirm; // make yesno() confirming easier int easy_quit_item_prompts; // make item prompts quitable on space int colour[16]; // macro fg colours to other colours @@ -708,7 +717,13 @@ struct game_options int sc_entries; // # of score entries int sc_format; // Format for score entries + + std::string map_file_name; // name of mapping file to use std::vector<text_pattern> banned_objects; // Objects we'll never pick up + std::vector<std::pair<text_pattern, std::string> > autoinscriptions; + std::vector<text_pattern> note_items; // Objects to note + std::vector<int> note_skill_levels; // Skill levels to note + bool pickup_thrown; // Pickup thrown missiles bool pickup_dropped; // Pickup dropped objects int travel_delay; // How long to pause between travel moves @@ -746,6 +761,7 @@ struct game_options int dump_item_origins; // Show where items came from? int dump_item_origin_price; + bool safe_zero_exp; // If true, you feel safe around 0xp monsters bool target_zero_exp; // If true, targeting targets zero-exp // monsters. bool target_wrap; // Wrap around from last to first target @@ -847,4 +863,7 @@ struct scorefile_entry int num_runes; // total number of runes in inventory }; +extern int autoprayer_on; // defined in acr.cc +extern int fizzlecheck_on; // defined in direct.cc + #endif // EXTERNS_H diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc index a478f6002a..3a75fd7c9c 100644 --- a/crawl-ref/source/fight.cc +++ b/crawl-ref/source/fight.cc @@ -1023,17 +1023,17 @@ bool you_attack(int monster_attacked, bool unarmed_attacks) } } - if (defender->type == MONS_JELLY - || defender->type == MONS_BROWN_OOZE - || defender->type == MONS_ACID_BLOB - || defender->type == MONS_ROYAL_JELLY) - { - weapon_acid(5); - } - /* remember, damage_done is still useful! */ if (hit) { + if (defender->type == MONS_JELLY + || defender->type == MONS_BROWN_OOZE + || defender->type == MONS_ACID_BLOB + || defender->type == MONS_ROYAL_JELLY) + { + weapon_acid(5); + } + int specdam = 0; if (ur_armed diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc index 6c13965702..353f731c5f 100644 --- a/crawl-ref/source/files.cc +++ b/crawl-ref/source/files.cc @@ -74,6 +74,7 @@ #include "monstuff.h" #include "mon-util.h" #include "mstuff2.h" +#include "notes.h" #include "player.h" #include "randart.h" #include "skills2.h" @@ -987,6 +988,7 @@ void save_game(bool leave_game) #endif char killFile[kFileNameSize + 4]; char travelCacheFile[kFileNameSize + 4]; + char notesFile[kFileNameSize + 4]; #ifdef CLUA_BINDINGS char luaFile[kFileNameSize + 4]; #endif @@ -1008,6 +1010,7 @@ void save_game(bool leave_game) strcpy(luaFile, name_buff); #endif strcpy(killFile, name_buff); + strcpy(notesFile, name_buff); strcpy(travelCacheFile, name_buff); snprintf( charFile, sizeof(charFile), "%s.sav", name_buff ); @@ -1024,6 +1027,7 @@ void save_game(bool leave_game) #endif strcpy(killFile, charFile); strcpy(travelCacheFile, charFile); + strcpy(notesFile, charFile); strcat(charFile, ".sav"); #ifdef DOS @@ -1036,6 +1040,7 @@ void save_game(bool leave_game) #endif strupr(killFile); strupr(travelCacheFile); + strupr(notesFile); #endif #endif @@ -1047,6 +1052,7 @@ void save_game(bool leave_game) #endif strcat(killFile, ".kil"); strcat(travelCacheFile, ".tc"); + strcat(notesFile, ".nts"); #ifdef STASH_TRACKING FILE *stashf = fopen(stashFile, "wb"); @@ -1093,6 +1099,18 @@ void save_game(bool leave_game) #endif } + FILE *notesf = fopen(notesFile, "wb"); + if (notesf) + { + save_notes(notesf); + fclose(notesf); + +#ifdef SHARED_FILES_CHMOD_PRIVATE + // change mode (unices) + chmod(notesFile, SHARED_FILES_CHMOD_PRIVATE); +#endif + } + FILE *saveFile = fopen(charFile, "wb"); if (saveFile == NULL) @@ -1260,6 +1278,7 @@ void restore_game(void) char char_f[kFileNameSize]; char kill_f[kFileNameSize]; char travel_f[kFileNameSize]; + char notes_f[kFileNameSize]; #ifdef STASH_TRACKING char stash_f[kFileNameSize]; #endif @@ -1268,7 +1287,8 @@ void restore_game(void) char lua_f[kFileNameSize]; #endif -#ifdef SAVE_DIR_PATH + //#ifdef SAVE_DIR_PATH -- haranp change -- this is weird +#ifdef SAVE_PACKAGE_CMD snprintf( char_f, sizeof(char_f), SAVE_DIR_PATH "%s%d", you.your_name, (int) getuid() ); #else @@ -1278,6 +1298,7 @@ void restore_game(void) strcpy(kill_f, char_f); strcpy(travel_f, char_f); + strcpy(notes_f, char_f); #ifdef CLUA_BINDINGS strcpy(lua_f, char_f); strcat(lua_f, ".lua"); @@ -1289,6 +1310,7 @@ void restore_game(void) strcat(kill_f, ".kil"); strcat(travel_f, ".tc"); strcat(char_f, ".sav"); + strcat(notes_f, ".nts"); #ifdef DOS strupr(char_f); @@ -1297,6 +1319,7 @@ void restore_game(void) #endif strupr(kill_f); strupr(travel_f); + strupr(notes_f); #ifdef CLUA_BINDINGS strupr(lua_f); #endif @@ -1360,6 +1383,13 @@ void restore_game(void) you.kills.load(killFile); fclose(killFile); } + + FILE *notesFile = fopen(notes_f, "rb"); + if (notesFile) + { + load_notes(notesFile); + fclose(notesFile); + } } static bool determine_version( FILE *restoreFile, diff --git a/crawl-ref/source/food.cc b/crawl-ref/source/food.cc index eee0cd6a78..d8a0765a25 100644 --- a/crawl-ref/source/food.cc +++ b/crawl-ref/source/food.cc @@ -542,7 +542,9 @@ bool prompt_eat_from_inventory(void) } int which_inventory_slot = - prompt_invent_item( "Eat which item?", OBJ_FOOD ); + prompt_invent_item( "Eat which item?", OBJ_FOOD, + true, true, true, '\0', NULL, + OPER_EAT ); if (which_inventory_slot == PROMPT_ABORT) { canned_msg( MSG_OK ); diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc index f4e4a7331b..8dc252a10f 100644 --- a/crawl-ref/source/initfile.cc +++ b/crawl-ref/source/initfile.cc @@ -35,6 +35,8 @@ game_options Options; +extern int autopickup_on; + extern void (*viewwindow) (char, bool); extern unsigned char (*mapch) (unsigned char); extern unsigned char (*mapch2) (unsigned char); @@ -121,7 +123,7 @@ static int str_to_channel_colour( const std::string &str ) static const std::string message_channel_names[ NUM_MESSAGE_CHANNELS ] = { - "plain", "prompt", "god", "duration", "danger", "warning", "food", + "plain", "prompt", "god", "pray", "duration", "danger", "warning", "food", "recovery", "sound", "talk", "intrinsic_gain", "mutation", "monster_spell", "monster_enchant", "monster_damage", "rotten_meat", "equipment", "diagnostic", @@ -377,6 +379,13 @@ void reset_options(bool clear_name) Options.easy_quit_item_prompts = false; Options.hp_warning = 10; Options.hp_attention = 25; + Options.confirm_self_target = false; + Options.confirm_spell_fizzle = false; + Options.safe_autopickup = false; + Options.use_notes = false; + Options.note_skill_max = false; + Options.note_hp_percent = 0; + Options.ood_interesting = 8; Options.terse_hand = true; Options.auto_list = false; Options.delay_message_clear = false; @@ -405,6 +414,7 @@ void reset_options(bool clear_name) Options.stash_tracking = STM_NONE; #endif Options.explore_stop = ES_ITEM | ES_STAIR | ES_SHOP | ES_ALTAR; + Options.safe_zero_exp = true; Options.target_zero_exp = true; Options.target_wrap = false; Options.target_oos = true; @@ -473,11 +483,16 @@ void reset_options(bool clear_name) // Clear vector options. Options.banned_objects.clear(); + Options.autoinscriptions.clear(); + Options.note_items.clear(); + Options.note_skill_levels.clear(); Options.stop_travel.clear(); Options.sound_mappings.clear(); Options.menu_colour_mappings.clear(); Options.drop_filter.clear(); + Options.map_file_name.clear(); + Options.named_options.clear(); // Map each category to itself. The user can override in init.txt @@ -879,7 +894,9 @@ void parse_option_line(const std::string &str, bool runscript) if (key != "name" && key != "crawl_dir" && key != "race" && key != "class" && key != "ban_pickup" && key != "stop_travel" && key != "sound" - && key != "drop_filter" && key != "lua_file") + && key != "drop_filter" && key != "lua_file" + && key != "note_items" && key != "autoinscribe" + && key != "map_file_name" ) { tolower_string( field ); } @@ -943,6 +960,21 @@ void parse_option_line(const std::string &str, bool runscript) { Options.ascii_display = read_bool( field, Options.ascii_display ); } + else if (key == "default_autopickup") + { + // should autopickup default to on or off? + autopickup_on = read_bool( field, autopickup_on ); + } + else if (key == "default_autoprayer") + { + // should autoprayer default to on or off? + autoprayer_on = read_bool( field, autoprayer_on ); + } + else if (key == "default_fizzlecheck") + { + // should fizzlecheck default to on or off? + fizzlecheck_on = read_bool( field, fizzlecheck_on ); + } else if (key == "detailed_stat_dump") { Options.detailed_stat_dump = @@ -1180,6 +1212,20 @@ void parse_option_line(const std::string &str, bool runscript) field.c_str() ); } } + else if (key == "ood_interesting") + { + Options.ood_interesting = atoi( field.c_str() ); + } + else if (key == "note_hp_percent") + { + Options.note_hp_percent = atoi( field.c_str() ); + if (Options.note_hp_percent < 0 || Options.note_hp_percent > 100) + { + Options.note_hp_percent = 0; + fprintf( stderr, "Bad HP note percentage -- %s\n", + field.c_str() ); + } + } else if (key == "hp_attention") { Options.hp_attention = atoi( field.c_str() ); @@ -1221,6 +1267,26 @@ void parse_option_line(const std::string &str, bool runscript) { Options.auto_list = read_bool( field, Options.auto_list ); } + else if (key == "confirm_self_target") + { + Options.confirm_self_target = read_bool( field, Options.confirm_self_target ); + } + else if (key == "confirm_spell_fizzle") + { + Options.confirm_spell_fizzle = read_bool( field, Options.confirm_spell_fizzle ); + } + else if (key == "safe_autopickup") + { + Options.safe_autopickup = read_bool( field, Options.safe_autopickup ); + } + else if (key == "use_notes") + { + Options.use_notes = read_bool( field, Options.use_notes ); + } + else if (key == "note_skill_max") + { + Options.note_skill_max = read_bool( field, Options.note_skill_max ); + } else if (key == "delay_message_clear") { Options.delay_message_clear = read_bool( field, Options.delay_message_clear ); @@ -1275,6 +1341,37 @@ void parse_option_line(const std::string &str, bool runscript) { append_vector(Options.banned_objects, split_string(",", field)); } + else if (key == "note_items") + { + append_vector(Options.note_items, split_string(",", field)); + } + else if (key == "autoinscribe") + { + std::vector<std::string> thesplit = + split_string(":", field); + Options.autoinscriptions.push_back( + std::pair<text_pattern,std::string>(thesplit[0], + thesplit[1])); + } + else if (key == "map_file_name") + { + Options.map_file_name = field; + } + else if (key == "note_skill_levels") + { + std::vector<std::string> thesplit = split_string(",", field); + for ( unsigned i = 0; i < thesplit.size(); ++i ) { + int num = atoi(thesplit[i].c_str()); + if ( num > 0 && num <= 27 ) { + Options.note_skill_levels.push_back(num); + } + else { + fprintf(stderr, "Bad skill level to note -- %s\n", + thesplit[i].c_str()); + continue; + } + } + } else if (key == "pickup_thrown") { Options.pickup_thrown = read_bool(field, Options.pickup_thrown); @@ -1534,6 +1631,10 @@ void parse_option_line(const std::string &str, bool runscript) if (Options.dump_item_origin_price < -1) Options.dump_item_origin_price = -1; } + else if (key == "safe_zero_exp") + { + Options.safe_zero_exp = read_bool(field, Options.safe_zero_exp); + } else if (key == "target_zero_exp") { Options.target_zero_exp = read_bool(field, Options.target_zero_exp); diff --git a/crawl-ref/source/invent.cc b/crawl-ref/source/invent.cc index 2145f80f72..dae6894d2a 100644 --- a/crawl-ref/source/invent.cc +++ b/crawl-ref/source/invent.cc @@ -291,6 +291,13 @@ std::string item_class_name( int type, bool terse ) return (""); } +class MenuEntryPtrComparer { +public: + bool operator() (const MenuEntry* a, const MenuEntry* b ) const { + return *a < *b; + } +}; + void populate_item_menu( Menu *menu, const std::vector<item_def> &items, void (*callback)(MenuEntry *me) ) { @@ -301,22 +308,35 @@ void populate_item_menu( Menu *menu, const std::vector<item_def> &items, inv_class[ items[i].base_type ]++; menu_letter ckey; + std::vector<InvEntry*> items_in_class; + for (int i = 0; i < NUM_OBJECT_CLASSES; ++i) { if (!inv_class[i]) continue; menu->add_entry( new MenuEntry( item_class_name(i), MEL_SUBTITLE ) ); + items_in_class.clear(); + for (int j = 0, count = items.size(); j < count; ++j) { if (items[j].base_type != i) continue; + items_in_class.push_back( new InvEntry(items[j]) ); + } - InvEntry *ie = new InvEntry( items[j] ); + std::sort( items_in_class.begin(), items_in_class.end(), + MenuEntryPtrComparer() ); + + for (unsigned int j = 0; j < items_in_class.size(); ++j) + { + InvEntry *ie = items_in_class[j]; ie->hotkeys[0] = ckey++; - callback(ie); + callback(ie); menu->add_entry( ie ); + } + } } @@ -338,17 +358,29 @@ std::vector<SelItem> select_items( std::vector<item_def*> &items, menu.set_title( new MenuEntry(title) ); char ckey = 'a'; + + std::vector<InvEntry*> items_in_class; + for (int i = 0; i < NUM_OBJECT_CLASSES; ++i) { if (!inv_class[i]) continue; menu.add_entry( new MenuEntry( item_class_name(i), MEL_SUBTITLE ) ); + + items_in_class.clear(); for (int j = 0, count = items.size(); j < count; ++j) { if (items[j]->base_type != i) continue; - - InvEntry *ie = new InvEntry( *items[j] ); + items_in_class.push_back( new InvEntry( *items[j]) ); + } + /* sort the items inside a class */ + std::sort( items_in_class.begin(), items_in_class.end(), + MenuEntryPtrComparer() ); + + for (unsigned int j = 0; j < items_in_class.size(); ++j) + { + InvEntry *ie = items_in_class[j]; ie->hotkeys[0] = ckey; menu.add_entry( ie ); @@ -701,6 +733,53 @@ std::vector<SelItem> prompt_invent_items( return items; } +/*** HP CHANGE ***/ +int digit_to_index( char digit, int type, operation_types oper ) { + + int i; + unsigned int j; + char iletter = (char)(oper); + + for ( i = 0; i < ENDOFPACK; ++i ) { + if (is_valid_item(you.inv[i])) { + const std::string& r(you.inv[i].inscription); + /* note that r.size() is unsigned */ + for ( j = 0; j + 2 < r.size(); ++j ) { + if ( r[j] == '@' && + (r[j+1] == iletter || r[j+1] == '*') && + r[j+2] == digit ) { + return i; + } + } + } + } + return -1; +} + +/* return true if user OK'd it (or no warning), false otherwise */ +static bool check_warning_inscriptions( const item_def& item, + operation_types oper ) +{ + unsigned int i; + char iletter = (char)(oper); + char name[ITEMNAME_SIZE]; + char prompt[ITEMNAME_SIZE + 100]; + item_name(item, DESC_INVENTORY, name, false); + strcpy( prompt, "Really choose "); + strncat( prompt, name, ITEMNAME_SIZE ); + strcat( prompt, "?"); + + const std::string& r(item.inscription); + for ( i = 0; i + 1 < r.size(); ++i ) { + if ( r[i] == '!' && + (r[i+1] == iletter || r[i+1] == '*') ) { + + return yesno(prompt, false, 'n'); + } + } + return true; +} + // This function prompts the user for an item, handles the '?' and '*' // listings, and returns the inventory slot to the caller (which if // must_exist is true (the default) will be an assigned item, with @@ -714,7 +793,8 @@ int prompt_invent_item( const char *prompt, int type_expect, bool must_exist, bool allow_auto_list, bool allow_easy_quit, const char other_valid_char, - int *const count ) + int *const count, + operation_types oper ) { unsigned char keyin = 0; int ret = -1; @@ -811,6 +891,17 @@ int prompt_invent_item( const char *prompt, int type_expect, need_prompt = false; need_getch = false; } + /*** HP CHANGE ***/ + else if ( count == NULL && isdigit( keyin ) ) + { + /* scan for our item */ + int res = digit_to_index( keyin, type_expect, oper ); + if ( res != -1 ) { + ret = res; + if ( check_warning_inscriptions( you.inv[ret], oper ) ) + break; + } + } else if (keyin == ESCAPE || (Options.easy_quit_item_prompts && allow_easy_quit @@ -825,8 +916,11 @@ int prompt_invent_item( const char *prompt, int type_expect, if (must_exist && !is_valid_item( you.inv[ret] )) mpr( "You do not have any such object." ); - else - break; + else { + if ( check_warning_inscriptions( you.inv[ret], oper ) ) { + break; + } + } } else if (!isspace( keyin )) { @@ -993,17 +1087,21 @@ const char *command_string( int i ) (i == 340) ? "# : dump character to file" : (i == 350) ? "= : reassign inventory/spell letters" : (i == 360) ? "\' : wield item a, or switch to b" : + (i == 370) ? ": : make a note" : #ifdef USE_MACROS (i == 380) ? "` : add macro" : (i == 390) ? "~ : save macros" : #endif (i == 400) ? "] : display worn armour" : (i == 410) ? "\" : display worn jewellery" : + (i == 415) ? "{ : inscribe an item" : (i == 420) ? "Ctrl-P : see old messages" : #ifdef PLAIN_TERM (i == 430) ? "Ctrl-R : Redraw screen" : #endif (i == 440) ? "Ctrl-A : toggle autopickup" : + (i == 445) ? "Ctrl-M : toggle autoprayer" : + (i == 447) ? "Ctrl-T : toggle fizzle" : (i == 450) ? "Ctrl-X : Save game without query" : #ifdef ALLOW_DESTROY_ITEM_COMMAND diff --git a/crawl-ref/source/invent.h b/crawl-ref/source/invent.h index 624e603fc1..0bde6b0bed 100644 --- a/crawl-ref/source/invent.h +++ b/crawl-ref/source/invent.h @@ -15,6 +15,7 @@ #include <stddef.h> #include <vector> #include "menu.h" +#include "enum.h" #define PROMPT_ABORT -1 #define PROMPT_GOT_SPECIAL -2 @@ -38,7 +39,8 @@ int prompt_invent_item( const char *prompt, int type_expect, bool allow_auto_list = true, bool allow_easy_quit = true, const char other_valid_char = '\0', - int *const count = NULL ); + int *const count = NULL, + operation_types oper = OPER_ANY ); std::vector<SelItem> select_items( std::vector<item_def*> &items, const char *title ); diff --git a/crawl-ref/source/it_use3.cc b/crawl-ref/source/it_use3.cc index 272cf8ba2b..7f6eee39a1 100644 --- a/crawl-ref/source/it_use3.cc +++ b/crawl-ref/source/it_use3.cc @@ -251,7 +251,7 @@ static void reaching_weapon_attack(void) mpr("Attack whom?", MSGCH_PROMPT); - direction( beam, DIR_TARGET, TARG_ENEMY ); + direction( beam, DIR_TARGET, TARG_ENEMY, true ); if (!beam.isValid) return; diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index c1b37124ab..1f5e1167f0 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -188,7 +188,8 @@ bool wield_weapon(bool auto_wield, int slot, bool show_weff_messages) { if (!auto_wield) item_slot = prompt_invent_item( "Wield which item (- for none)?", - OSEL_WIELD, true, true, true, '-' ); + OSEL_WIELD, true, true, true, '-', + NULL, OPER_WIELD); else item_slot = PROMPT_GOT_SPECIAL; @@ -570,7 +571,7 @@ void wield_effects(int item_wield_2, bool showMsgs) // something legit. // //--------------------------------------------------------------- -bool armour_prompt( const std::string & mesg, int *index ) +bool armour_prompt( const std::string & mesg, int *index, operation_types oper) { ASSERT(index != NULL); @@ -583,7 +584,9 @@ bool armour_prompt( const std::string & mesg, int *index ) canned_msg(MSG_TOO_BERSERK); else { - slot = prompt_invent_item( mesg.c_str(), OBJ_ARMOUR ); + slot = prompt_invent_item( mesg.c_str(), OBJ_ARMOUR, + true, true, true, '\0', NULL, + oper ); if (slot != PROMPT_ABORT) { @@ -615,7 +618,7 @@ void wear_armour(void) { int armour_wear_2; - if (!armour_prompt("Wear which item?", &armour_wear_2)) + if (!armour_prompt("Wear which item?", &armour_wear_2, OPER_WEAR)) return; do_wear_armour( armour_wear_2, false ); @@ -996,7 +999,9 @@ void throw_anything(void) return; } - throw_slot = prompt_invent_item( "Throw which item?", OBJ_MISSILES ); + throw_slot = prompt_invent_item( "Throw which item?", OBJ_MISSILES, + true, true, true, '\0', NULL, + OPER_THROW ); if (throw_slot == PROMPT_ABORT) { canned_msg( MSG_OK ); @@ -2122,7 +2127,8 @@ bool remove_ring(int slot) { int equipn = slot == -1? prompt_invent_item( "Remove which piece of jewellery?", - OBJ_JEWELLERY ) + OBJ_JEWELLERY, true, true, true, + '\0', NULL, OPER_REMOVE) : slot; if (equipn == PROMPT_ABORT) @@ -2280,7 +2286,9 @@ void zap_wand(void) return; } - item_slot = prompt_invent_item( "Zap which item?", OBJ_WANDS ); + item_slot = prompt_invent_item( "Zap which item?", OBJ_WANDS, + true, true, true, '\0', NULL, + OPER_ZAP ); if (item_slot == PROMPT_ABORT) { canned_msg( MSG_OK ); @@ -2405,6 +2413,28 @@ void zap_wand(void) you.turn_is_over = 1; } // end zap_wand() +/*** HP CHANGE ***/ +void inscribe_item() +{ + int item_slot; + char buf[79]; + if (inv_count() < 1) + { + mpr("You don't have anything to inscribe."); + return; + } + item_slot = prompt_invent_item( "Inscribe which item? ", OSEL_ANY ); + if (item_slot == PROMPT_ABORT) + { + canned_msg( MSG_OK ); + return; + } + mpr( "Inscribe with what? ", MSGCH_PROMPT ); + get_input_line( buf, sizeof(buf) ); + you.inv[item_slot].inscription = std::string(buf); + you.wield_change = true; +} + void drink(void) { int item_slot; @@ -2434,7 +2464,9 @@ void drink(void) return; } - item_slot = prompt_invent_item( "Drink which item?", OBJ_POTIONS ); + item_slot = prompt_invent_item( "Drink which item?", OBJ_POTIONS, + true, true, true, '\0', NULL, + OPER_QUAFF ); if (item_slot == PROMPT_ABORT) { canned_msg( MSG_OK ); @@ -3255,7 +3287,9 @@ void read_scroll(void) void original_name(void) { - int item_slot = prompt_invent_item( "Examine which item?", -1 ); + int item_slot = prompt_invent_item( "Examine which item?", -1, + true, true, true, '\0', NULL, + OPER_EXAMINE ); if (item_slot == PROMPT_ABORT) { canned_msg( MSG_OK ); diff --git a/crawl-ref/source/item_use.h b/crawl-ref/source/item_use.h index 93d3ec3098..37705bd96d 100644 --- a/crawl-ref/source/item_use.h +++ b/crawl-ref/source/item_use.h @@ -16,13 +16,15 @@ #include <string> #include "externs.h" +#include "enum.h" // last updated 12may2000 {dlb} /* *********************************************************************** * called from: acr - item_use * *********************************************************************** */ -bool armour_prompt(const std::string & mesg, int *index); +bool armour_prompt(const std::string & mesg, int *index, + operation_types oper); // last updated 12may2000 {dlb} @@ -133,4 +135,6 @@ bool enchant_weapon( int which_stat, bool quiet = false ); bool throw_it(struct bolt &pbolt, int throw_2, monsters *dummy_target = NULL); +void inscribe_item(); + #endif diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc index 89c7441b45..899e973669 100644 --- a/crawl-ref/source/itemname.cc +++ b/crawl-ref/source/itemname.cc @@ -31,6 +31,7 @@ #include "itemprop.h" #include "macro.h" #include "mon-util.h" +#include "notes.h" #include "randart.h" #include "skills2.h" #include "stuff.h" @@ -264,6 +265,13 @@ char item_name( const item_def &item, char descrip, char buff[ ITEMNAME_SIZE ], strncat( buff, " (around neck)", ITEMNAME_SIZE ); } } + /*** HP CHANGE -- warning -- possible stack overflow error ***/ + if ( item.inscription.size() > 0 ) // has an inscription + { + strncat( buff, " {", 2 ); + strncat( buff, item.inscription.c_str(), ITEMNAME_SIZE ); + strncat( buff, "}", 1 ); + } return (1); } // end item_name() @@ -2419,3 +2427,22 @@ static char retlet( int sed ) static const char consonants[] = "bcdfghjklmnpqrstvwxzcdfghlmnrstlmnrst"; return (consonants[ sed % (sizeof(consonants) - 1) ]); } + +bool is_interesting_item( const item_def& item ) { + if ( is_random_artefact(item) || + is_unrandom_artefact(item) || + is_fixed_artefact(item) ) + return true; + + char name[ITEMNAME_SIZE]; + item_name(item, DESC_PLAIN, name, false); + std::string iname(name); + for (unsigned i = 0; i < Options.note_items.size(); ++i) + if (Options.note_items[i].matches(iname)) + return true; + return false; +} + +bool fully_identified( const item_def& item ) { + return item_ident( item, ISFLAG_IDENT_MASK ); +} diff --git a/crawl-ref/source/itemname.h b/crawl-ref/source/itemname.h index 5e7cc49bfe..8622ebbb7f 100644 --- a/crawl-ref/source/itemname.h +++ b/crawl-ref/source/itemname.h @@ -75,7 +75,7 @@ void quant_name( const item_def &item, int quant, char des, bool item_cursed( const item_def &item ); bool item_known_cursed( const item_def &item ); bool item_known_uncursed( const item_def &item ); -// bool fully_indentified( const item_def &item ); +bool fully_identified( const item_def &item ); bool item_type_known( const item_def &item ); @@ -109,5 +109,6 @@ void set_ident_type( char cla, int ty, char setting, bool force = false ); * *********************************************************************** */ bool hide2armour( unsigned char *which_subtype ); +bool is_interesting_item( const item_def& item ); #endif diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc index 7c7a822343..190c5dd690 100644 --- a/crawl-ref/source/items.cc +++ b/crawl-ref/source/items.cc @@ -58,6 +58,8 @@ static void autopickup(void); static bool is_stackable_item( const item_def &item ); +static void autoinscribe_item( item_def& item ); +static void autoinscribe_items( void ); // Used to be called "unlink_items", but all it really does is make // sure item coordinates are correct to the stack they're in. -- bwr @@ -472,6 +474,7 @@ static void item_cleanup(item_def &item) item.quantity = 0; item.orig_place = 0; item.orig_monnum = 0; + item.inscription = std::string(); } void destroy_item( int dest ) @@ -717,7 +720,8 @@ void item_check(char keyin) mpr("There are no items here."); return; } - + + autoinscribe_items(); autopickup(); origin_set(you.x_pos, you.y_pos); @@ -1487,6 +1491,10 @@ int move_item_to_player( int obj, int quant_got, bool quiet ) item.y = -1; item.link = freeslot; + /*** HP CHANGE: do autoinscribe ***/ + autoinscribe_item( item ); + + origin_freeze(item, you.x_pos, you.y_pos); item.quantity = quant_got; @@ -2913,6 +2921,24 @@ void handle_time( long time_delta ) int autopickup_on = 1; +static void autoinscribe_item( item_def& item ) +{ + char name[ITEMNAME_SIZE]; + item_name(item, DESC_INVENTORY, name, false); + + std::string iname = name; + + /* if there's an inscription already do nothing */ + if ( item.inscription.size() > 0 ) + return; + + for ( unsigned i = 0; i < Options.autoinscriptions.size(); ++i ) { + if ( Options.autoinscriptions[i].first.matches(iname) ) { + item.inscription += Options.autoinscriptions[i].second; + } + } +} + static bool is_banned(const item_def &item) { static char name[ITEMNAME_SIZE]; item_name(item, DESC_INVENTORY, name, false); @@ -2925,6 +2951,19 @@ static bool is_banned(const item_def &item) { return false; } +static void autoinscribe_items() +{ + int o, next; + o = igrd[you.x_pos][you.y_pos]; + + while (o != NON_ITEM) + { + next = mitm[o].link; + autoinscribe_item( mitm[o] ); + o = next; + } +} + static void autopickup(void) { //David Loewenstern 6/99 @@ -2943,20 +2982,26 @@ static void autopickup(void) if (player_is_levitating() && !wearing_amulet(AMU_CONTROLLED_FLIGHT)) return; + if ( Options.safe_autopickup && !i_feel_safe() ) + return; + o = igrd[you.x_pos][you.y_pos]; while (o != NON_ITEM) { next = mitm[o].link; - if ( ((mitm[o].flags & ISFLAG_THROWN) && Options.pickup_thrown) || + if ( + (strstr(mitm[o].inscription.c_str(), "=g") != 0) || ( + + ((mitm[o].flags & ISFLAG_THROWN) && Options.pickup_thrown) || ( (Options.autopickups & (1L << mitm[o].base_type) #ifdef CLUA_BINDINGS || clua.callbooleanfn(false, "ch_autopickup", "u", &mitm[o]) #endif ) && (Options.pickup_dropped || !(mitm[o].flags & ISFLAG_DROPPED)) - && !is_banned(mitm[o]))) + && !is_banned(mitm[o])))) { mitm[o].flags &= ~(ISFLAG_THROWN | ISFLAG_DROPPED); diff --git a/crawl-ref/source/libunix.cc b/crawl-ref/source/libunix.cc index 72441dfd3d..76d4025670 100644 --- a/crawl-ref/source/libunix.cc +++ b/crawl-ref/source/libunix.cc @@ -300,7 +300,7 @@ void init_key_to_command() key_to_command_table[ (int) CONTROL('S') ] = CMD_MARK_STASH; key_to_command_table[ (int) CONTROL('T') ] = CMD_NO_CMD; key_to_command_table[ (int) CONTROL('U') ] = CMD_OPEN_DOOR_UP_LEFT; - key_to_command_table[ (int) CONTROL('V') ] = CMD_NO_CMD; + key_to_command_table[ (int) CONTROL('V') ] = CMD_TOGGLE_AUTOPRAYER; key_to_command_table[ (int) CONTROL('W') ] = CMD_FIX_WAYPOINT; key_to_command_table[ (int) CONTROL('X') ] = CMD_SAVE_GAME_NOW; key_to_command_table[ (int) CONTROL('Y') ] = CMD_OPEN_DOOR_UP_RIGHT; @@ -312,7 +312,7 @@ void init_key_to_command() key_to_command_table[(int) '>'] = CMD_GO_DOWNSTAIRS; key_to_command_table[(int) '@'] = CMD_DISPLAY_CHARACTER_STATUS; key_to_command_table[(int) ','] = CMD_PICKUP; - key_to_command_table[(int) ':'] = CMD_NO_CMD; + key_to_command_table[(int) ':'] = CMD_MAKE_NOTE; key_to_command_table[(int) ';'] = CMD_INSPECT_FLOOR; key_to_command_table[(int) '!'] = CMD_SHOUT; key_to_command_table[(int) '^'] = CMD_DISPLAY_RELIGION; diff --git a/crawl-ref/source/makefile.obj b/crawl-ref/source/makefile.obj index 8cadd1cebd..1152939993 100644 --- a/crawl-ref/source/makefile.obj +++ b/crawl-ref/source/makefile.obj @@ -41,6 +41,7 @@ mon-util.o \ mstuff2.o \ mutation.o \ newgame.o \ +notes.o \ ouch.o \ output.o \ overmap.o \ diff --git a/crawl-ref/source/menu.h b/crawl-ref/source/menu.h index 05e4796383..4552851bb4 100644 --- a/crawl-ref/source/menu.h +++ b/crawl-ref/source/menu.h @@ -66,6 +66,10 @@ struct MenuEntry } virtual ~MenuEntry() { } + bool operator<( const MenuEntry& rhs ) const { + return text < rhs.text; + } + void add_hotkey( int key ) { if (key && !is_hotkey(key)) diff --git a/crawl-ref/source/message.cc b/crawl-ref/source/message.cc index 353a069abc..a7a117febe 100644 --- a/crawl-ref/source/message.cc +++ b/crawl-ref/source/message.cc @@ -116,9 +116,9 @@ static char channel_to_colour( int channel, int param ) { case MSGCOL_PLAIN: // note that if the plain channel is muted, then we're protecting - // the player from having that spead to other other channels here. + // the player from having that spread to other channels here. // The intent of plain is to give non-coloured messages, not to - // supress them. + // suppress them. if (Options.channels[ MSGCH_PLAIN ] >= MSGCOL_DEFAULT) ret = LIGHTGREY; else @@ -130,6 +130,7 @@ static char channel_to_colour( int channel, int param ) switch (channel) { case MSGCH_GOD: + case MSGCH_PRAY: ret = (Options.channels[ channel ] == MSGCOL_DEFAULT) ? god_colour( param ) : god_message_altar_colour( param ); @@ -180,7 +181,7 @@ static char channel_to_colour( int channel, int param ) break; case MSGCH_DIAGNOSTICS: - ret = DARKGREY; // makes is easier to ignore at times -- bwr + ret = DARKGREY; // makes it easier to ignore at times -- bwr break; case MSGCH_PLAIN: diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index 4fd3083df2..30e612cbc5 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -13,6 +13,7 @@ #include "AppHdr.h" #include "misc.h" +#include "notes.h" #include <string.h> #if !(defined(__IBMCPP__) || defined(__BCPLUSPLUS__)) @@ -45,6 +46,7 @@ #include "monplace.h" #include "mon-util.h" #include "monstuff.h" +#include "notes.h" #include "ouch.h" #include "player.h" #include "shopping.h" @@ -57,6 +59,7 @@ #include "travel.h" #include "view.h" +extern FixedVector<char, 10> Visible_Statue; // defined in acr.cc bool scramble(void); bool trap_item(char base_type, char sub_type, char beam_x, char beam_y); @@ -1122,6 +1125,7 @@ void new_level(void) env.rock_colour = (mcolour[env.mons_alloc[8]] == BLACK) ? LIGHTGREY : mcolour[env.mons_alloc[8]]; + take_note(Note(NOTE_DUNGEON_LEVEL_CHANGE, LEVEL_PANDEMONIUM, 0xFF)); } else if (you.level_type == LEVEL_ABYSS) { @@ -1132,14 +1136,19 @@ void new_level(void) env.rock_colour = (mcolour[env.mons_alloc[8]] == BLACK) ? LIGHTGREY : mcolour[env.mons_alloc[8]]; + take_note(Note(NOTE_DUNGEON_LEVEL_CHANGE, LEVEL_ABYSS, 0xFF)); } else if (you.level_type == LEVEL_LABYRINTH) { cprintf("- a Labyrinth "); + take_note(Note(NOTE_DUNGEON_LEVEL_CHANGE, LEVEL_LABYRINTH, 0xFF)); } else { // level_type == LEVEL_DUNGEON + take_note(Note(NOTE_DUNGEON_LEVEL_CHANGE, + you.where_are_you, curr_subdungeon_level)); + if (!player_in_branch( BRANCH_VESTIBULE_OF_HELL )) cprintf( "%d", curr_subdungeon_level ); @@ -1960,3 +1969,42 @@ bolt::bolt() : range(0), rangeMax(0), type(SYM_ZAP), colour(BLACK), in_explosion_phase(false), smart_monster(false), can_see_invis(false), is_friendly(false), foe_ratio(0) { } + +bool i_feel_safe() +{ + /* This is probably unnecessary, but I'm not sure that + you're always at least 9 away from a wall */ + int ystart = you.y_pos - 9, xstart = you.x_pos - 9; + int yend = you.y_pos + 9, xend = you.x_pos + 9; + if ( xstart < 0 ) xstart = 0; + if ( ystart < 0 ) ystart = 0; + if ( xend >= GXM ) xend = 0; + if ( ystart >= GYM ) yend = 0; + + /* statue check */ + if ( Visible_Statue[STATUE_SILVER] || + Visible_Statue[STATUE_ORANGE_CRYSTAL] ) + return false; + + /* monster check */ + for ( int y = ystart; y < yend; ++y ) { + for ( int x = xstart; x < xend; ++x ) { + /* if you can see a nonfriendly monster then you feel + unsafe */ + if ( see_grid(x,y) ) { + const unsigned char targ_monst = mgrd[x][y]; + if ( targ_monst != NON_MONSTER ) { + struct monsters *mon = &menv[targ_monst]; + if ( !mons_friendly(mon) && + player_monster_visible(mon) && + !mons_is_mimic(mon->type) && + (!Options.safe_zero_exp || + !mons_class_flag( mon->type, M_NO_EXP_GAIN ))) { + return false; + } + } + } + } + } + return true; +} diff --git a/crawl-ref/source/misc.h b/crawl-ref/source/misc.h index 3f109eed6b..75ef84b700 100644 --- a/crawl-ref/source/misc.h +++ b/crawl-ref/source/misc.h @@ -140,4 +140,10 @@ const char *grid_item_destruction_message( unsigned char grid ); void curare_hits_player(int agent, int degree); +// last updated 24aug2006 {hp} +/* *********************************************************************** + * called from: items + * *********************************************************************** */ +bool i_feel_safe(); + #endif diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index f8305f5e4d..467a197392 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -40,8 +40,10 @@ #include "misc.h" #include "monplace.h" #include "monspeak.h" +#include "mon-pick.h" #include "mon-util.h" #include "mstuff2.h" +#include "notes.h" #include "player.h" #include "randart.h" #include "religion.h" @@ -69,7 +71,7 @@ static bool immobile_monster[MAX_MONSTERS]; #define FAR_AWAY 1000000 // used in monster_move() -// This function creates an arteficial item to represent a mimic's appearance. +// This function creates an artificial item to represent a mimic's appearance. // Eventually, mimics could be redone to be more like Dancing wepaons... // there'd only be one type and it would look like the item it carries. -- bwr void get_mimic_item( const struct monsters *mimic, item_def &item ) @@ -317,6 +319,20 @@ static void place_monster_corpse(struct monsters *monster) move_item_to_grid( &o, monster->x, monster->y ); } // end place_monster_corpse() +static int ood_limit() { + return Options.ood_interesting; +} + +static bool is_interesting_monster( const struct monsters *monster ) { + if ( mons_is_unique(monster->type) ) + return true; + if ( you.where_are_you == BRANCH_MAIN_DUNGEON && + mons_level(monster->type) >= you.your_level + ood_limit() && + mons_level(monster->type) < 99 ) + return true; + return false; +} + void monster_die(struct monsters *monster, char killer, int i) { int dmi; // dead monster's inventory @@ -676,7 +692,7 @@ void monster_die(struct monsters *monster, char killer, int i) (tmp == 1) ? " says, \"I'll get you next time!\"" : (tmp == 2) ? " says, \"This isn't over yet!\"" : (tmp == 3) ? " says, \"I'll be back!\"" : - (tmp == 4) ? " says, \"This isn't the end, its only just beginning!\"" : + (tmp == 4) ? " says, \"This isn't the end, it's only just beginning!\"" : (tmp == 5) ? " says, \"Kill me? I think not!\"" : " says, \"You cannot defeat me so easily!\"", MSGCH_TALK ); @@ -689,6 +705,13 @@ void monster_die(struct monsters *monster, char killer, int i) if (killer != KILL_RESET && killer != KILL_DISMISSED) { + + if ( is_interesting_monster(monster) ) { + char namebuf[ITEMNAME_SIZE]; + moname(monster->type, true, DESC_NOCAP_A, namebuf); + take_note(Note(NOTE_KILL_MONSTER, monster->type, 0, namebuf)); + } + you.kills.record_kill(monster, killer, pet_kill); if (mons_has_ench(monster, ENCH_ABJ_I, ENCH_ABJ_VI)) @@ -830,6 +853,7 @@ static bool jelly_divide(struct monsters * parent) child->behaviour = parent->behaviour; /* Look at this! */ child->foe = parent->foe; child->attitude = parent->attitude; + /* FIXME - hp: copy enchantments? */ child->x = parent->x + jex; child->y = parent->y + jey; diff --git a/crawl-ref/source/mutation.cc b/crawl-ref/source/mutation.cc index 027a810432..248eb742e5 100644 --- a/crawl-ref/source/mutation.cc +++ b/crawl-ref/source/mutation.cc @@ -36,6 +36,7 @@ #include "defines.h" #include "effects.h" #include "macro.h" +#include "notes.h" #include "ouch.h" #include "player.h" #include "skills2.h" @@ -896,6 +897,11 @@ void display_mutations(void) j++; break; + case SP_SPRIGGAN: + cprintf("You can see invisible." EOL); + j++; + break; + case SP_NAGA: // breathe poison replaces spit poison: if (!you.mutation[MUT_BREATHE_POISON]) @@ -1519,6 +1525,8 @@ bool mutate(int which_mutation, bool failMsg) mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION); you.mutation[mutat]++; calc_hp(); + /* special-case check */ + take_note(Note(NOTE_GET_MUTATION, mutat, you.mutation[mutat])); return true; case MUT_ROBUST: @@ -1530,6 +1538,8 @@ bool mutate(int which_mutation, bool failMsg) mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION); you.mutation[mutat]++; calc_hp(); + /* special-case check */ + take_note(Note(NOTE_GET_MUTATION, mutat, you.mutation[mutat])); return true; case MUT_BLACK_SCALES: @@ -1567,6 +1577,7 @@ bool mutate(int which_mutation, bool failMsg) you.mutation[mutat]++; + take_note(Note(NOTE_GET_MUTATION, mutat, you.mutation[mutat])); /* remember, some mutations don't get this far (eg frail) */ return true; } // end mutation() @@ -1699,6 +1710,8 @@ bool delete_mutation(int which_mutation) if (you.mutation[mutat] > 0) you.mutation[mutat]--; calc_hp(); + /* special-case check */ + take_note(Note(NOTE_LOSE_MUTATION, mutat, you.mutation[mutat])); return true; case MUT_ROBUST: @@ -1706,6 +1719,8 @@ bool delete_mutation(int which_mutation) if (you.mutation[mutat] > 0) you.mutation[mutat]--; calc_hp(); + /* special-case check */ + take_note(Note(NOTE_LOSE_MUTATION, mutat, you.mutation[mutat])); return true; case MUT_BLACK_SCALES: @@ -1766,6 +1781,7 @@ bool delete_mutation(int which_mutation) if (you.mutation[mutat] > 0) you.mutation[mutat]--; + take_note(Note(NOTE_LOSE_MUTATION, mutat, you.mutation[mutat])); return true; } // end delete_mutation() diff --git a/crawl-ref/source/newgame.cc b/crawl-ref/source/newgame.cc index 3a4a4e7a3d..fe504b8198 100644 --- a/crawl-ref/source/newgame.cc +++ b/crawl-ref/source/newgame.cc @@ -2386,7 +2386,7 @@ static void create_wanderer( void ) SK_INVOCATIONS, SK_EVOCATIONS }; const int num_util_skills = sizeof(util_skills) / sizeof(int); - // Long swords is missing to increae it's rarity because we + // Long swords is missing to increase its rarity because we // can't give out a long sword to a starting character (they're // all too good)... Staves is also removed because it's not // one of the fighter options.-- bwr @@ -2488,9 +2488,9 @@ static void create_wanderer( void ) you.skills[ skill ] = 1; } - int wpn_skill = SK_FIGHTING; // prefered weapon type - int wpn_skill_size = 0; // level of skill in prefered weapon type - int num_wpn_skills = 0; // used to choose prefered weapon + int wpn_skill = SK_FIGHTING; // preferred weapon type + int wpn_skill_size = 0; // level of skill in preferred weapon type + int num_wpn_skills = 0; // used to choose preferred weapon int total_wpn_skills = 0; // used to choose template // This algorithm is the same as the one used to pick a random @@ -2647,7 +2647,7 @@ static void create_wanderer( void ) // Create a default launcher template, but the // quantity may be reset to 0 if we don't want one -- bwr - // thorwing weapons are lowered to -1 to make them + // throwing weapons are lowered to -1 to make them // not as good as the one's hunters get, ammo is // also much smaller -- bwr you.inv[1].quantity = 1; @@ -3421,7 +3421,7 @@ void give_items_skills() else { // Players get dodging or armour skill depending on their - // starting armour now (note: the armour has to be quiped + // starting armour now (note: the armour has to be equipped // for this function to work) you.skills[(player_light_armour()? SK_DODGING : SK_ARMOUR)] = 2; diff --git a/crawl-ref/source/notes.cc b/crawl-ref/source/notes.cc new file mode 100644 index 0000000000..922ae901d8 --- /dev/null +++ b/crawl-ref/source/notes.cc @@ -0,0 +1,320 @@ +#include <vector> + +#include "AppHdr.h" +#include "notes.h" + +#include "files.h" +#include "message.h" +#include "mutation.h" +#include "religion.h" +#include "skills2.h" +#include "spl-util.h" +#include "stash.h" + +std::vector<Note> note_list; + +/* I can't believe I'm writing code this bad */ +static int real_god_power( int religion, int idx ) { + switch ( religion ) { + case GOD_NO_GOD: + case GOD_XOM: + case GOD_NEMELEX_XOBEH: + return -1; + case GOD_ZIN: + case GOD_SHINING_ONE: + case GOD_YREDELEMNUL: + case GOD_MAKHLEB: + case GOD_ELYVILON: + return idx; + case GOD_KIKUBAAQUDGHA: + if ( idx < 3 ) + return idx; + if ( idx == 3 ) + return -1; + return idx-1; + case GOD_VEHUMET: + return ( idx == 4 ? -1 : idx ); + case GOD_OKAWARU: + if ( idx < 2 ) + return idx; + if ( idx == 2 || idx == 3 ) + return -1; + return idx - 2; + case GOD_SIF_MUNA: + if ( idx == 0 || idx == 2 || idx == 4 ) return -1; + if ( idx == 1 ) return 0; + if ( idx == 3 ) return 1; + case GOD_TROG: + if ( idx == 2 || idx == 4 ) return -1; + if ( idx < 2 ) return idx; + if ( idx == 3 ) return idx-1; + default: + return -1; + } +} + +static bool is_noteworthy_skill_level( int level ) { + unsigned i; + for ( i = 0; i < Options.note_skill_levels.size(); ++i ) + if ( level == Options.note_skill_levels[i] ) + return true; + return false; +} + +static bool is_highest_skill( int skill ) { + for ( int i = 0; i < NUM_SKILLS; ++i ) { + if ( i == skill ) + continue; + if ( you.skills[i] >= you.skills[skill] ) + return false; + } + return true; +} + +static bool is_noteworthy_hp( int hp, int maxhp ) { + return (hp > 0 && Options.note_hp_percent && + hp <= (maxhp * Options.note_hp_percent) / 100); +} + +/* Is a note worth taking? + This function assumes that game state has not changed since + the note was taken, e.g. you.* is valid. + */ +static bool is_noteworthy( const Note& note ) { + /* should really make this more user-configurable */ + + /* always noteworthy */ + if ( note.type == NOTE_XP_LEVEL_CHANGE || + note.type == NOTE_GET_GOD || + note.type == NOTE_GOD_GIFT || + note.type == NOTE_GET_MUTATION || + note.type == NOTE_LOSE_MUTATION || + note.type == NOTE_KILL_MONSTER || + note.type == NOTE_USER_NOTE || + note.type == NOTE_LOSE_GOD ) + return true; + + /* never noteworthy, hooked up for fun or future use */ + if ( note.type == NOTE_GET_ITEM || + note.type == NOTE_MP_CHANGE || + note.type == NOTE_MAXHP_CHANGE || + note.type == NOTE_MAXMP_CHANGE ) + return false; + + /* god powers might be noteworthy if it's an actual power */ + if ( note.type == NOTE_GOD_POWER && + real_god_power(note.first, note.second) == -1 ) + return false; + + /* hp noteworthiness is handled in its own function */ + if ( note.type == NOTE_HP_CHANGE && + !is_noteworthy_hp(note.first, note.second) ) + return false; + + /* skills are noteworthy if in the skill value list or if + it's a new maximal skill (depending on options) */ + if ( note.type == NOTE_GAIN_SKILL ) { + if ( is_noteworthy_skill_level(note.second) ) + return true; + if ( Options.note_skill_max && is_highest_skill(note.first) ) + return true; + return false; + } + + /* entering dlevel 1 is not noteworthy */ + if ( note.type == NOTE_DUNGEON_LEVEL_CHANGE && + note.first == BRANCH_MAIN_DUNGEON && note.second == 1 ) + return false; + + unsigned i; + for ( i = 0; i < note_list.size(); ++i ) { + if ( note_list[i].type != note.type ) + continue; + const Note& rnote( note_list[i] ); + switch ( note.type ) { + case NOTE_DUNGEON_LEVEL_CHANGE: + if ( rnote.first == note.first && rnote.second == note.second && + !(note.first == LEVEL_LABYRINTH && note.second == 0xFF) ) + return false; + break; + case NOTE_LEARN_SPELL: + if (spell_difficulty(rnote.first) >= spell_difficulty(note.first)) + return false; + break; + case NOTE_GOD_POWER: + if ( rnote.first == note.first && rnote.second == note.second ) + return false; + break; + case NOTE_ID_ITEM: + /* re-id'ing an item, e.g. second copy of book, isn't + noteworthy */ + if ( rnote.name == note.name ) + return false; + break; + case NOTE_HP_CHANGE: + /* not if we have a recent warning */ + if ( (note.turn - rnote.turn < 5) && + /* unless we've lost half our HP since then */ + (note.first * 2 >= rnote.first) ) + return false; + break; + default: + mpr("Buggy note passed"); + break; + } + } + return true; +} + +const char* number_to_ordinal( int number ) { + const char* ordinals[5] = { "first", "second", "third", "fourth", + "fifth" }; + if ( number < 1) + return "[unknown ordinal (too small)]"; + if ( number > 5 ) + return "[unknown ordinal (too big)]"; + return ordinals[number-1]; +} + +std::string describe_note( const Note& note ) { + char buf[200], buf2[50]; + switch ( note.type ) { + case NOTE_HP_CHANGE: + sprintf(buf, "Had %d/%d hit points", note.first, note.second); + break; + case NOTE_MP_CHANGE: + sprintf(buf, "Had %d/%d mana", note.first, note.second); + break; + case NOTE_MAXHP_CHANGE: + sprintf(buf, "Reached %d max hit points", note.first); + break; + case NOTE_MAXMP_CHANGE: + sprintf(buf, "Reached %d max mana", note.first); + break; + case NOTE_XP_LEVEL_CHANGE: + sprintf(buf, "Reached XP level %d. %s", note.first, note.name.c_str()); + break; + case NOTE_DUNGEON_LEVEL_CHANGE: + sprintf(buf, "Entered %s", + branch_level_name(note.first, note.second).c_str()); + break; + case NOTE_LEARN_SPELL: + sprintf(buf, "Learned a level %d spell: %s", + spell_difficulty(note.first), spell_title(note.first)); + break; + case NOTE_GET_GOD: + sprintf(buf, "Became a worshipper of %s", + god_name(note.first, true)); + break; + case NOTE_LOSE_GOD: + sprintf(buf, "Fell from the grace of %s", + god_name(note.first)); + break; + case NOTE_GOD_GIFT: + sprintf(buf, "Received a gift from %s", + god_name(note.first)); + break; + case NOTE_ID_ITEM: + sprintf(buf, "Identified %s", note.name.c_str()); + break; + case NOTE_GET_ITEM: + sprintf(buf, "Got %s", note.name.c_str()); + break; + case NOTE_GAIN_SKILL: + sprintf(buf, "Reached skill %d in %s", + note.second, skill_name(note.first)); + break; + case NOTE_KILL_MONSTER: + sprintf(buf, "Defeated %s", note.name.c_str()); + break; + case NOTE_GOD_POWER: + sprintf(buf, "Acquired %s's %s power", god_name(note.first), + number_to_ordinal(real_god_power(note.first, note.second)+1)); + break; + case NOTE_GET_MUTATION: + sprintf(buf, "Gained mutation: %s", + mutation_name(note.first, note.second == 0 ? 1 : note.second)); + break; + case NOTE_LOSE_MUTATION: + sprintf(buf, "Lost mutation: %s", + mutation_name(note.first, + note.second == 3 ? 3 : note.second+1)); + break; + case NOTE_USER_NOTE: + sprintf(buf, "%s", note.name.c_str()); + break; + default: + sprintf(buf, "Buggy note description"); + break; + } + sprintf(buf2, "Turn %ld: ", note.turn ); + return std::string(buf2) + std::string(buf); +} + +Note::Note() { + turn = you.num_turns; +} + +Note::Note( NOTE_TYPES t, int f, int s, const char* n ) : + type(t), first(f), second(s) { + if (n) + name = std::string(n); + turn = you.num_turns; +} + +void Note::save( FILE* fp ) const { + writeLong( fp, type ); + writeLong( fp, turn ); + writeLong( fp, first ); + writeLong( fp, second ); + writeString( fp, name ); +} + +void Note::load( FILE* fp ) { + type = (NOTE_TYPES)(readLong( fp )); + turn = readLong( fp ); + first = readLong( fp ); + second = readLong( fp ); + name = readString( fp ); +} + +bool notes_active = false; + +bool notes_are_active() { + return notes_active; +} + +void take_note( const Note& note ) { + if ( notes_active && is_noteworthy( note ) ) + note_list.push_back( note ); +} + +void activate_notes( bool active ) { + notes_active = active; +} + +void save_notes( FILE* fp ) { + writeLong( fp, note_list.size() ); + for ( unsigned i = 0; i < note_list.size(); ++i ) + note_list[i].save(fp); +} + +void load_notes( FILE* fp ) { + long num_notes = readLong(fp); + for ( long i = 0; i < num_notes; ++i ) { + Note new_note; + new_note.load(fp); + note_list.push_back(new_note); + } +} + +void make_user_note() { + mpr("Enter note: ", MSGCH_PROMPT); + char buf[400]; + bool validline = cancelable_get_line(buf, sizeof(buf)); + if ( !validline || (!*buf) ) + return; + Note unote(NOTE_USER_NOTE); + unote.name = std::string(buf); + take_note(unote); +} diff --git a/crawl-ref/source/notes.h b/crawl-ref/source/notes.h new file mode 100644 index 0000000000..165ca6cf13 --- /dev/null +++ b/crawl-ref/source/notes.h @@ -0,0 +1,61 @@ +/* + * File: notes.cc + * Summary: Notetaking stuff + * Written by: Haran Pilpel + * + * Change History (most recent first): + * + * <1> -/--/-- PH Created + */ + +#ifndef NOTES_H +#define NOTES_H + +#include <string> +#include <vector> +#include <stdio.h> + +enum NOTE_TYPES { + NOTE_HP_CHANGE = 0, /* needs: new hp, max hp */ + NOTE_MAXHP_CHANGE, /* needs: new maxhp */ + NOTE_MP_CHANGE, /* needs: new mp, max mp */ + NOTE_MAXMP_CHANGE, /* needs: new maxmp */ + NOTE_XP_LEVEL_CHANGE, /* needs: new xplevel */ + NOTE_DUNGEON_LEVEL_CHANGE, /* needs: branch, subdepth */ + NOTE_LEARN_SPELL, /* needs: spell idx */ + NOTE_GET_GOD, /* needs: god id */ + NOTE_GOD_GIFT, /* needs: god id */ + NOTE_GOD_POWER, /* needs: god id, idx */ + NOTE_GET_MUTATION, /* needs: mutation idx */ + NOTE_LOSE_MUTATION, /* needs: mutation idx */ + NOTE_ID_ITEM, /* needs: item name (string) */ + /* NOT HOOKED YET */ + NOTE_GET_ITEM, /* needs: item name (string) */ + NOTE_GAIN_SKILL, /* needs: skill id, level */ + NOTE_KILL_MONSTER, /* needs: monster name (string) */ + NOTE_USER_NOTE, /* needs: description string */ + NOTE_LOSE_GOD, /* needs: god id */ + NOTE_NUM_TYPES +}; + +struct Note { + Note(); + Note( NOTE_TYPES t, int f = 0, int s = 0, const char* n = 0 ); + NOTE_TYPES type; + int first, second; + long turn; + std::string name; + void load( FILE* fp ); + void save( FILE* fp ) const; +}; + +extern std::vector<Note> note_list; +std::string describe_note( const Note& note ); +void activate_notes( bool active ); +bool notes_are_active(); +void take_note( const Note& note ); +void save_notes( FILE* fp ); +void load_notes( FILE* fp ); +void make_user_note(); + +#endif diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc index 5fa0ff13bd..073e9721be 100644 --- a/crawl-ref/source/ouch.cc +++ b/crawl-ref/source/ouch.cc @@ -74,6 +74,7 @@ #include "items.h" #include "macro.h" #include "mon-util.h" +#include "notes.h" #include "player.h" #include "randart.h" #include "religion.h" @@ -266,7 +267,7 @@ void splash_with_acid( char acid_strength ) char splc = 0; int dam = 0; - const bool wearing_cloak = (you.equip[EQ_CLOAK] == -1); + const bool wearing_cloak = (you.equip[EQ_CLOAK] != -1); for (splc = EQ_CLOAK; splc <= EQ_BODY_ARMOUR; splc++) { @@ -509,6 +510,11 @@ void lose_level(void) calc_hp(); calc_mp(); + char buf[200]; + sprintf(buf, "HP: %d/%d MP: %d/%d", + you.hp, you.hp_max, you.magic_points, you.max_magic_points); + take_note(Note(NOTE_XP_LEVEL_CHANGE, you.experience_level, 0, buf)); + you.redraw_experience = 1; } // end lose_level() @@ -642,6 +648,7 @@ void ouch( int dam, int death_source, char death_type, const char *aux ) { mpr( "* * * LOW HITPOINT WARNING * * *", MSGCH_DANGER ); } + take_note(Note(NOTE_HP_CHANGE, you.hp, you.hp_max)); if (you.hp > 0) return; @@ -979,6 +986,7 @@ void end_game( struct scorefile_entry &se ) unlink( (basefile + ".st").c_str() ); unlink( (basefile + ".kil").c_str() ); unlink( (basefile + ".tc").c_str() ); + unlink( (basefile + ".nts").c_str() ); #ifdef CLUA_BINDINGS unlink( (basefile + ".lua").c_str() ); #endif diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index 91ee0dea54..833528aed9 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -38,6 +38,7 @@ #include "misc.h" #include "mon-util.h" #include "mutation.h" +#include "notes.h" #include "output.h" #include "randart.h" #include "religion.h" @@ -2404,6 +2405,11 @@ void level_change(void) if (you.experience_level > you.max_level) you.max_level = you.experience_level; + + char buf[200]; + sprintf(buf, "HP: %d/%d MP: %d/%d", + you.hp, you.hp_max, you.magic_points, you.max_magic_points); + take_note(Note(NOTE_XP_LEVEL_CHANGE, you.experience_level, 0, buf)); if (you.religion == GOD_XOM) Xom_acts(true, you.experience_level, true); @@ -2493,7 +2499,7 @@ int check_stealth(void) stealth /= 2; // splashy-splashy } - // Radiating silence is the negative compliment of shouting all the + // Radiating silence is the negative complement of shouting all the // time... a sudden change from background noise to no noise is going // to clue anything in to the fact that something is very wrong... // a personal silence spell would naturally be different, but this @@ -3269,6 +3275,7 @@ void dec_hp(int hp_loss, bool fatal) if (!fatal && you.hp < 1) you.hp = 1; + // take_note(Note(NOTE_HP_CHANGE, you.hp, you.hp_max)); you.redraw_hit_points = 1; return; @@ -3284,6 +3291,7 @@ void dec_mp(int mp_loss) if (you.magic_points < 0) you.magic_points = 0; + take_note(Note(NOTE_MP_CHANGE, you.magic_points, you.max_magic_points)); you.redraw_magic_points = 1; return; @@ -3331,6 +3339,7 @@ void inc_mp(int mp_gain, bool max_too) if (you.magic_points > you.max_magic_points) you.magic_points = you.max_magic_points; + take_note(Note(NOTE_MP_CHANGE, you.magic_points, you.max_magic_points)); you.redraw_magic_points = 1; return; @@ -3351,6 +3360,9 @@ void inc_hp(int hp_gain, bool max_too) if (you.hp > you.hp_max) you.hp = you.hp_max; + // to avoid message spam, no information when HP increases + // take_note(Note(NOTE_HP_CHANGE, you.hp, you.hp_max)); + you.redraw_hit_points = 1; } // end inc_hp() @@ -3392,6 +3404,7 @@ void inc_max_hp( int hp_gain ) you.base_hp2 += hp_gain; calc_hp(); + take_note(Note(NOTE_MAXHP_CHANGE, you.hp_max)); you.redraw_hit_points = 1; } @@ -3400,6 +3413,7 @@ void dec_max_hp( int hp_loss ) you.base_hp2 -= hp_loss; calc_hp(); + take_note(Note(NOTE_MAXHP_CHANGE, you.hp_max)); you.redraw_hit_points = 1; } @@ -3408,6 +3422,7 @@ void inc_max_mp( int mp_gain ) you.base_magic_points2 += mp_gain; calc_mp(); + take_note(Note(NOTE_MAXMP_CHANGE, you.max_magic_points)); you.redraw_magic_points = 1; } @@ -3416,6 +3431,7 @@ void dec_max_mp( int mp_loss ) you.base_magic_points2 -= mp_loss; calc_mp(); + take_note(Note(NOTE_MAXMP_CHANGE, you.max_magic_points)); you.redraw_magic_points = 1; } @@ -3427,6 +3443,7 @@ void deflate_hp(int new_level, bool floor) else if (!floor && you.hp > new_level) you.hp = new_level; + // take_note(Note(NOTE_HP_CHANGE, you.hp, you.hp_max)); // must remain outside conditional, given code usage {dlb} you.redraw_hit_points = 1; @@ -3449,6 +3466,9 @@ void set_hp(int new_amount, bool max_too) if (you.hp > you.hp_max) you.hp = you.hp_max; + // take_note(Note(NOTE_HP_CHANGE, you.hp, you.hp_max)); + if ( max_too ) + take_note(Note(NOTE_MAXHP_CHANGE, you.hp_max)); // must remain outside conditional, given code usage {dlb} you.redraw_hit_points = 1; @@ -3471,7 +3491,10 @@ void set_mp(int new_amount, bool max_too) if (you.magic_points > you.max_magic_points) you.magic_points = you.max_magic_points; - + + take_note(Note(NOTE_MP_CHANGE, you.magic_points, you.max_magic_points)); + if ( max_too ) + take_note(Note(NOTE_MAXMP_CHANGE, you.max_magic_points)); // must remain outside conditional, given code usage {dlb} you.redraw_magic_points = 1; diff --git a/crawl-ref/source/shopping.cc b/crawl-ref/source/shopping.cc index cff3ce8f51..54b857947f 100644 --- a/crawl-ref/source/shopping.cc +++ b/crawl-ref/source/shopping.cc @@ -30,6 +30,7 @@ #include "itemname.h" #include "itemprop.h" #include "macro.h" +#include "notes.h" #include "player.h" #include "randart.h" #include "spl-book.h" @@ -80,6 +81,8 @@ char in_a_shop( char shoppy, id_arr id ) shop_print(info, 20); more3(); + + activate_notes(false); /* should do a better job here */ shop_init_id(shoppy, shop_id); /* ************************************* @@ -263,6 +266,7 @@ char in_a_shop( char shoppy, id_arr id ) #endif shop_uninit_id( shoppy, shop_id ); + activate_notes(true); return 0; } @@ -372,6 +376,19 @@ static void purchase( int shop, int item_got, int cost ) you.gold -= cost; origin_purchased(mitm[item_got]); + + if ( fully_identified(mitm[item_got]) && + is_interesting_item(mitm[item_got]) ) { + + activate_notes(true); + + char buf[ITEMNAME_SIZE]; + item_name( mitm[item_got], DESC_NOCAP_A, buf ); + take_note(Note(NOTE_ID_ITEM, 0, 0, buf)); + + activate_notes(false); + } + int num = move_item_to_player( item_got, mitm[item_got].quantity, true ); // Shopkeepers will now place goods you can't carry outside the shop. diff --git a/crawl-ref/source/skills.cc b/crawl-ref/source/skills.cc index db7fe62372..7c47992ed5 100644 --- a/crawl-ref/source/skills.cc +++ b/crawl-ref/source/skills.cc @@ -21,6 +21,7 @@ #include "externs.h" #include "macro.h" +#include "notes.h" #include "player.h" #include "skills2.h" #include "stuff.h" @@ -401,6 +402,7 @@ static int exercise2( int exsk ) mpr(info, MSGCH_INTRINSIC_GAIN); you.skills[exsk]++; + take_note(Note(NOTE_GAIN_SKILL, exsk, you.skills[exsk])); // Recalculate this skill's order for tie breaking skills // at its new level. See skills2.cc::init_skill_order() diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc index a559b66f84..9a9ef6e2f1 100644 --- a/crawl-ref/source/spells1.cc +++ b/crawl-ref/source/spells1.cc @@ -66,7 +66,7 @@ void blink(void) { mpr("Blink to where?", MSGCH_PROMPT); - direction( beam, DIR_TARGET ); + direction( beam, DIR_TARGET, TARG_ANY, true ); if (!beam.isValid) { @@ -172,7 +172,7 @@ void fireball(int power) message_current_target(); - direction( fire_ball, DIR_NONE, TARG_ENEMY ); + direction( fire_ball, DIR_NONE, TARG_ENEMY, true ); if (!fire_ball.isValid) canned_msg(MSG_SPELL_FIZZLES); @@ -198,7 +198,7 @@ void cast_fire_storm(int powc) mpr("Where?"); - direction( targ, DIR_TARGET, TARG_ENEMY ); + direction( targ, DIR_TARGET, TARG_ENEMY, true ); beam.target_x = targ.tx; beam.target_y = targ.ty; @@ -423,7 +423,7 @@ void conjure_flame(int pow) done_first_message = true; } - direction( spelld, DIR_TARGET, TARG_ENEMY ); + direction( spelld, DIR_TARGET, TARG_ENEMY, true ); if (!spelld.isValid) { @@ -465,7 +465,7 @@ void stinking_cloud( int pow ) message_current_target(); - direction( spelld, DIR_NONE, TARG_ENEMY ); + direction( spelld, DIR_NONE, TARG_ENEMY, true ); if (!spelld.isValid) { @@ -502,7 +502,7 @@ void cast_big_c(int pow, char cty) struct dist cdis; mpr("Where do you want to put it?", MSGCH_PROMPT); - direction( cdis, DIR_TARGET, TARG_ENEMY ); + direction( cdis, DIR_TARGET, TARG_ENEMY, true ); if (!cdis.isValid) { @@ -525,7 +525,7 @@ static char healing_spell( int healed ) struct dist bmove; mpr("Which direction?", MSGCH_PROMPT); - direction( bmove, DIR_DIR, TARG_FRIEND ); + direction( bmove, DIR_DIR, TARG_FRIEND, true ); if (!bmove.isValid) { diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc index 3c61fc2aa7..08ee5daeac 100644 --- a/crawl-ref/source/spells2.cc +++ b/crawl-ref/source/spells2.cc @@ -1006,7 +1006,7 @@ int vampiric_drain(int pow) dirc: mpr("Which direction?", MSGCH_PROMPT); - direction( vmove, DIR_DIR, TARG_ENEMY ); + direction( vmove, DIR_DIR, TARG_ENEMY, true ); if (!vmove.isValid) { @@ -1090,7 +1090,7 @@ char burn_freeze(int pow, char flavour) while (mgr == NON_MONSTER) { mpr("Which direction?", MSGCH_PROMPT); - direction( bmove, DIR_DIR, TARG_ENEMY ); + direction( bmove, DIR_DIR, TARG_ENEMY, true ); if (!bmove.isValid) { @@ -1190,7 +1190,7 @@ int summon_elemental(int pow, int restricted_type, { mpr("Summon from material in which direction?", MSGCH_PROMPT); - direction( smove, DIR_DIR ); + direction( smove, DIR_DIR, TARG_ANY, true ); if (!smove.isValid) { diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc index 1d6f710b05..30c4957f9a 100644 --- a/crawl-ref/source/spells3.cc +++ b/crawl-ref/source/spells3.cc @@ -192,7 +192,7 @@ bool cast_smiting(int power) mpr("Smite whom?", MSGCH_PROMPT); - direction( beam, DIR_TARGET, TARG_ENEMY ); + direction( beam, DIR_TARGET, TARG_ENEMY, true ); if (!beam.isValid || mgrd[beam.tx][beam.ty] == NON_MONSTER @@ -231,7 +231,7 @@ bool airstrike(int power) mpr("Strike whom?", MSGCH_PROMPT); - direction( beam, DIR_TARGET, TARG_ENEMY ); + direction( beam, DIR_TARGET, TARG_ENEMY, true ); if (!beam.isValid || mgrd[beam.tx][beam.ty] == NON_MONSTER diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc index 076be063a6..612e63fc9b 100644 --- a/crawl-ref/source/spells4.cc +++ b/crawl-ref/source/spells4.cc @@ -492,7 +492,7 @@ static void cast_detect_magic(int pow) } mpr("Which direction?", MSGCH_PROMPT); - direction( bmove, DIR_DIR ); + direction( bmove, DIR_DIR, TARG_ANY, true ); if (!bmove.isValid) { @@ -1915,7 +1915,7 @@ void cast_evaporate(int pow) message_current_target(); - direction( spelld, DIR_NONE, TARG_ENEMY ); + direction( spelld, DIR_NONE, TARG_ENEMY, true ); if (!spelld.isValid) { @@ -2362,7 +2362,7 @@ void cast_fragmentation(int pow) // jmf: ripped idea from airstrike const char *what = NULL; mpr("Fragment what (e.g. a wall)?", MSGCH_PROMPT); - direction( beam, DIR_TARGET, TARG_ENEMY ); + direction( beam, DIR_TARGET, TARG_ENEMY, true ); if (!beam.isValid) { @@ -2870,7 +2870,7 @@ void cast_apportation(int pow) mpr("Pull items from where?"); - direction( beam, DIR_TARGET ); + direction( beam, DIR_TARGET, TARG_ANY, true ); if (!beam.isValid) { diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc index fb6d60bf62..dd99876d4d 100644 --- a/crawl-ref/source/spl-cast.cc +++ b/crawl-ref/source/spl-cast.cc @@ -738,7 +738,8 @@ bool your_spells( int spc2, int powc, bool allow_fail ) { char str_pass[ ITEMNAME_SIZE ]; - set_ident_flags( you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_TYPE ); + // changed from ISFLAG_KNOW_TYPE + set_ident_flags( you.inv[you.equip[EQ_WEAPON]], ISFLAG_IDENT_MASK); strcpy(info, "You are wielding "); in_name(you.equip[EQ_WEAPON], DESC_NOCAP_A, str_pass); diff --git a/crawl-ref/source/spl-util.cc b/crawl-ref/source/spl-util.cc index d024fada5b..3f9c408bbf 100644 --- a/crawl-ref/source/spl-util.cc +++ b/crawl-ref/source/spl-util.cc @@ -28,6 +28,7 @@ #include "macro.h" #include "misc.h" #include "monstuff.h" +#include "notes.h" #include "player.h" #include "spl-book.h" #include "view.h" @@ -122,6 +123,8 @@ bool add_spell_to_memory( int spell ) you.spell_no++; + take_note(Note(NOTE_LEARN_SPELL, spell)); + return (true); } @@ -462,7 +465,7 @@ int apply_one_neighbouring_square(int (*func) (int, int, int, int), int power) struct dist bmove; mpr("Which direction? [ESC to cancel]", MSGCH_PROMPT); - direction( bmove, DIR_DIR, TARG_ENEMY ); + direction( bmove, DIR_DIR, TARG_ENEMY, true ); if (!bmove.isValid) { @@ -679,7 +682,7 @@ char spell_direction( struct dist &spelld, struct bolt &pbolt, message_current_target(); - direction( spelld, restrict, mode ); + direction( spelld, restrict, mode, true ); if (!spelld.isValid) { diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc index 1b241bb807..e15a2e66bc 100644 --- a/crawl-ref/source/stuff.cc +++ b/crawl-ref/source/stuff.cc @@ -59,6 +59,7 @@ #include "monstuff.h" #include "mon-util.h" #include "mt19937ar.h" +#include "notes.h" #include "player.h" #include "output.h" #include "skills2.h" @@ -501,7 +502,10 @@ void redraw_screen(void) if (Options.delay_message_clear) mesclr( true ); + bool note_status = notes_are_active(); + activate_notes(false); new_level(); + activate_notes(note_status); viewwindow(1, false); #endif diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc index 25e4382274..43eb0a83a5 100644 --- a/crawl-ref/source/tags.cc +++ b/crawl-ref/source/tags.cc @@ -225,7 +225,7 @@ float unmarshallFloat(struct tagHeader &th) } // string -- marshall length & string data -void marshallString(struct tagHeader &th, char *data, int maxSize) +void marshallString(struct tagHeader &th, const char *data, int maxSize) { // allow for very long strings. short len = strlen(data); @@ -743,6 +743,8 @@ static void tag_construct_you_items(struct tagHeader &th) marshallShort(th,you.inv[i].plus2); marshallShort(th, you.inv[i].orig_place); marshallShort(th, you.inv[i].orig_monnum); + /*** HP CHANGE ***/ + marshallString(th, you.inv[i].inscription.c_str(), 80); } // item descrip for each type & subtype @@ -1276,6 +1278,7 @@ static void tag_read_you_items(struct tagHeader &th, char minorVersion) for (i = 0; i < count_c; ++i) { you.inv[i].orig_monnum = you.inv[i].orig_place = 0; + you.inv[i].inscription = std::string(); if (minorVersion < 1) { you.inv[i].base_type = (unsigned char) unmarshallByte(th); @@ -1304,6 +1307,10 @@ static void tag_read_you_items(struct tagHeader &th, char minorVersion) { you.inv[i].orig_place = unmarshallShort(th); you.inv[i].orig_monnum = unmarshallShort(th); + /*** HP CHANGE ***/ + char insstring[80]; + unmarshallString(th, insstring, 80); + you.inv[i].inscription = std::string(insstring); } } @@ -1495,6 +1502,8 @@ static void tag_construct_level_items(struct tagHeader &th) marshallShort(th, mitm[i].orig_place); marshallShort(th, mitm[i].orig_monnum); + /*** HP CHANGE ***/ + marshallString(th, mitm[i].inscription.c_str(), 80); } } @@ -1692,11 +1701,16 @@ static void tag_read_level_items(struct tagHeader &th, char minorVersion) { mitm[i].orig_place = unmarshallShort(th); mitm[i].orig_monnum = unmarshallShort(th); + /*** HP CHANGE ***/ + char insstring[80]; + unmarshallString(th, insstring, 80); + mitm[i].inscription = std::string(insstring); } else { mitm[i].orig_place = 0; mitm[i].orig_monnum = 0; + mitm[i].inscription = std::string(); } } } diff --git a/crawl-ref/source/tags.h b/crawl-ref/source/tags.h index 7c84709ebf..443f77edd2 100644 --- a/crawl-ref/source/tags.h +++ b/crawl-ref/source/tags.h @@ -37,7 +37,7 @@ void marshallShort(struct tagHeader &th, short data); void marshallLong(struct tagHeader &th, long data); void marshallFloat(struct tagHeader &th, float data); void marshallBoolean(struct tagHeader &th, bool data); -void marshallString(struct tagHeader &th, char *data, int maxSize = 0); +void marshallString(struct tagHeader &th, const char *data, int maxSize = 0); // last updated 22jan2001 {gdl} /* *********************************************************************** |