diff options
-rw-r--r-- | crawl-ref/docs/options_guide.txt | 12 | ||||
-rw-r--r-- | crawl-ref/init.txt | 1 | ||||
-rw-r--r-- | crawl-ref/source/direct.cc | 18 | ||||
-rw-r--r-- | crawl-ref/source/externs.h | 1 | ||||
-rw-r--r-- | crawl-ref/source/initfile.cc | 6 | ||||
-rw-r--r-- | crawl-ref/source/item_use.cc | 141 | ||||
-rw-r--r-- | crawl-ref/source/libgui.cc | 112 | ||||
-rw-r--r-- | crawl-ref/source/player.cc | 9 | ||||
-rw-r--r-- | crawl-ref/source/player.h | 4 |
9 files changed, 226 insertions, 78 deletions
diff --git a/crawl-ref/docs/options_guide.txt b/crawl-ref/docs/options_guide.txt index 2cc5ec8e8e..6e5cd36731 100644 --- a/crawl-ref/docs/options_guide.txt +++ b/crawl-ref/docs/options_guide.txt @@ -79,11 +79,11 @@ The contents of this text are: 4-o Tiles Options. show_items, title_screen, tile_player_col, tile_monster_col, tile_neutral_col, tile_friendly_col, - tile_item_col, tile_unseen_col, tile_floor_col, tile_wall_col, - tile_mapped_wall_col, tile_door_col, tile_downstairs_col, - tile_upstairs_col, tile_feature_col, tile_trap_col, - tile_water_col, tile_lava_col, tile_excluded_col, - tile_excl_centre_col + tile_plant_col, tile_item_col, tile_unseen_col, tile_floor_col, + tile_wall_col, tile_mapped_wall_col, tile_door_col, + tile_downstairs_col, tile_upstairs_col, tile_feature_col, + tile_trap_col, tile_water_col, tile_lava_col, + tile_excluded_col, tile_excl_centre_col 5- Character Dump. 5-a Items and Kills. kill_map, dump_kill_places, dump_item_origins, @@ -1308,6 +1308,7 @@ tile_player_col = white tile_monster_col = red tile_neutral_col = red tile_friendly_col = lightred +tile_plant_col = darkgreen tile_item_col = green tile_unseen_col = black tile_floor_col = lightgrey @@ -1330,6 +1331,7 @@ tile_excl_centre_col = darkblue tile_monster_col - colour of hostile monsters tile_neutral_col - colour of neutral monsters tile_friendly_col - colour of friendly monsters + tile_plant_col - colour of zero xp monsters (plant and fungus) tile_item_col - colour of known or detected items tile_unseen_col - colour of unseen areas (usually stone) tile_wall_col - colour of any wall type diff --git a/crawl-ref/init.txt b/crawl-ref/init.txt index 6a3eaee841..d32ddad404 100644 --- a/crawl-ref/init.txt +++ b/crawl-ref/init.txt @@ -284,6 +284,7 @@ tile_show_items = !?/%=([)X}+\_. # tile_monster_col = red # tile_neutral_col = red # tile_friendly_col = lightred +# tile_plant_col = darkgreen # tile_item_col = green # tile_unseen_col = black # tile_floor_col = lightgrey diff --git a/crawl-ref/source/direct.cc b/crawl-ref/source/direct.cc index 3b89368585..ac34d64f0a 100644 --- a/crawl-ref/source/direct.cc +++ b/crawl-ref/source/direct.cc @@ -1098,9 +1098,9 @@ static void describe_oos_square(int x, int y) bool in_vlos(int x, int y) { - return in_los_bounds(x, y) - && (env.show(view2show(coord_def(x, y))) - || coord_def(x, y) == grid2view(you.pos())); + return (in_los_bounds(x, y) + && (env.show(view2show(coord_def(x, y))) + || coord_def(x, y) == grid2view(you.pos()))); } bool in_vlos(const coord_def &pos) @@ -1115,28 +1115,30 @@ bool in_los(int x, int y) static bool find_monster( int x, int y, int mode, int range = -1) { + // target the player for friendly and general spells if ((mode == TARG_FRIEND || mode == TARG_ANY) && x == you.x_pos && y == you.y_pos) { return (true); } - + // don't target out of range if (!_is_target_in_range(x, y, range)) return (false); - + const int targ_mon = mgrd[ x ][ y ]; - + // No monster or outside LOS. if (targ_mon == NON_MONSTER || !in_los(x,y)) return (false); - + // Unseen monsters in shallow water show a "strange disturbance" // (unless flying!) if (!player_monster_visible(&menv[targ_mon])) { // since you can't see the monster, assume it's not a friend - return (mode != TARG_FRIEND && grd[x][y] == DNGN_SHALLOW_WATER + return (mode != TARG_FRIEND + && grd[x][y] == DNGN_SHALLOW_WATER && !mons_flies(&menv[targ_mon])); } diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index dc11da94f0..7f3ff99de4 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -1778,6 +1778,7 @@ public: char tile_monster_col; char tile_neutral_col; char tile_friendly_col; + char tile_plant_col; char tile_item_col; char tile_unseen_col; char tile_floor_col; diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc index cf0edbb097..519f5feb15 100644 --- a/crawl-ref/source/initfile.cc +++ b/crawl-ref/source/initfile.cc @@ -813,6 +813,7 @@ void game_options::reset_options() tile_monster_col = MAP_RED; tile_neutral_col = MAP_RED; tile_friendly_col = MAP_LTRED; + tile_plant_col = MAP_DKGREEN; tile_item_col = MAP_GREEN; tile_unseen_col = MAP_BLACK; tile_floor_col = MAP_LTGREY; @@ -2580,6 +2581,11 @@ void game_options::read_option_line(const std::string &str, bool runscript) tile_friendly_col = _str_to_tile_colour(field); } + else if (key == "tile_plant_col") + { + tile_plant_col = + _str_to_tile_colour(field); + } else if (key == "tile_item_col") { tile_item_col = diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index 5070a8ad6c..80a7f25787 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -184,6 +184,51 @@ bool can_wield(const item_def *weapon, bool say_reason, #undef SAY } +static bool _valid_weapon_swap(const item_def &item) +{ + // weapons and staves are valid weapons + if (item.base_type == OBJ_WEAPONS || item.base_type == OBJ_STAVES) + return true; + + // misc. items need to be wielded to be evoked + if (item.base_type == OBJ_MISCELLANY && item.sub_type != MISC_RUNE_OF_ZOT) + return true; + + // some missiles need to be wielded for spells + if (item.base_type == OBJ_MISSILES) + { + if (item.sub_type == MI_STONE) + return (player_knows_spell(SPELL_SANDBLAST)); + + if (item.sub_type == MI_ARROW) + return (player_knows_spell(SPELL_STICKS_TO_SNAKES)); + + return false; + } + + // Boneshards + if (item.base_type == OBJ_CORPSES) + { + return (item.sub_type == CORPSE_SKELETON + && player_knows_spell(SPELL_BONE_SHARDS)); + } + + // Sublimation of Blood + if (!player_knows_spell(SPELL_SUBLIMATION_OF_BLOOD)) + return false; + + if (item.base_type == OBJ_FOOD) + return (item.sub_type == FOOD_CHUNK); + + if (item.base_type == OBJ_POTIONS && item_type_known(item)) + { + return (item.sub_type == POT_BLOOD + || item.sub_type == POT_BLOOD_COAGULATED); + } + + return false; +} + bool wield_weapon(bool auto_wield, int slot, bool show_weff_messages) { if (inv_count() < 1) @@ -210,21 +255,18 @@ bool wield_weapon(bool auto_wield, int slot, bool show_weff_messages) // If the swap slot has a bad (but valid) item in it, // the swap will be to bare hands. - const bool good_swap = (item_slot == PROMPT_GOT_SPECIAL) - || you.inv[item_slot].base_type == OBJ_WEAPONS - || you.inv[item_slot].base_type == OBJ_STAVES - || (you.inv[item_slot].base_type == OBJ_MISCELLANY - && you.inv[item_slot].sub_type != MISC_RUNE_OF_ZOT); + const bool good_swap = (item_slot == PROMPT_GOT_SPECIAL + || _valid_weapon_swap(you.inv[item_slot])); // Prompt if not using the auto swap command, or if the swap slot // is empty. - if (item_slot != PROMPT_GOT_SPECIAL && - (!auto_wield || !is_valid_item(you.inv[item_slot]) || !good_swap)) + if (item_slot != PROMPT_GOT_SPECIAL + && (!auto_wield || !is_valid_item(you.inv[item_slot]) || !good_swap)) { if (!auto_wield) item_slot = prompt_invent_item( "Wield which item (- for none, * to show all)?", - MT_INVLIST, OSEL_WIELD, + MT_INVLIST, OSEL_WIELD, true, true, true, '-', NULL, OPER_WIELD); else item_slot = PROMPT_GOT_SPECIAL; @@ -4534,21 +4576,36 @@ void tile_use_item(int idx, InvAction act) } else if (act == INV_USE2) // secondary item use { - if (you.inv[idx].base_type == OBJ_WEAPONS - && is_throwable(you.inv[idx], player_size(PSIZE_BODY))) + const item_def item = you.inv[idx]; + + if (item.base_type == OBJ_WEAPONS + && is_throwable(item, player_size(PSIZE_BODY))) { - fire_thing(idx); // fire weapons + if (check_warning_inscriptions(item, OPER_FIRE)) + fire_thing(idx); // fire weapons } - else if (you.inv[idx].base_type == OBJ_MISCELLANY - || you.inv[idx].base_type == OBJ_STAVES - && item_is_rod(you.inv[idx])) // unwield rods/misc. items + else if (item.base_type == OBJ_MISCELLANY + || item.base_type == OBJ_STAVES + && item_is_rod(item)) // unwield rods/misc. items { if (you.equip[EQ_WEAPON] == idx - && check_warning_inscriptions(you.inv[idx], OPER_WIELD)) + && check_warning_inscriptions(item, OPER_WIELD)) { wield_weapon(true, PROMPT_GOT_SPECIAL); // unwield } } + else if (you.equip[EQ_WEAPON] == idx + && check_warning_inscriptions(item, OPER_WIELD)) + { + wield_weapon(true, PROMPT_GOT_SPECIAL); // unwield + } + else if (_valid_weapon_swap(item) + && check_warning_inscriptions(item, OPER_WIELD)) + { + // secondary wield for several spells and such + wield_weapon(true, idx); // wield + } + return; } else if (act != INV_USE) @@ -4557,7 +4614,7 @@ void tile_use_item(int idx, InvAction act) // Equipped? bool equipped = false; bool equipped_weapon = false; - for (unsigned int i=0; i< NUM_EQUIP;i++) + for (unsigned int i = 0; i < NUM_EQUIP; i++) { if (you.equip[i] == idx) { @@ -4569,16 +4626,17 @@ void tile_use_item(int idx, InvAction act) } TileMoveInvCursor(-1); + const item_def item = you.inv[idx]; // Special case for folks who are wielding something // that they shouldn't be wielding. // Note that this is only a problem for equipables // (otherwise it would only waste a turn) if (you.equip[EQ_WEAPON] == idx - && (you.inv[idx].base_type == OBJ_ARMOUR - || you.inv[idx].base_type == OBJ_JEWELLERY)) + && (item.base_type == OBJ_ARMOUR + || item.base_type == OBJ_JEWELLERY)) { - if (!check_warning_inscriptions(you.inv[idx], OPER_WIELD)) + if (!check_warning_inscriptions(item, OPER_WIELD)) return; wield_weapon(true, PROMPT_GOT_SPECIAL); @@ -4586,7 +4644,7 @@ void tile_use_item(int idx, InvAction act) } // Use it - const int type = you.inv[idx].base_type; + const int type = item.base_type; switch (type) { case OBJ_WEAPONS: @@ -4595,82 +4653,83 @@ void tile_use_item(int idx, InvAction act) // wield any unwielded item of these types if (!equipped) { - if (check_warning_inscriptions(you.inv[idx], OPER_WIELD)) + if (check_warning_inscriptions(item, OPER_WIELD)) wield_weapon(true, idx); return; } // evoke misc. items and rods - if (type == OBJ_MISCELLANY || item_is_rod(you.inv[idx])) + if (type == OBJ_MISCELLANY || item_is_rod(item)) { - if (check_warning_inscriptions(you.inv[idx], OPER_EVOKE)) + if (check_warning_inscriptions(item, OPER_EVOKE)) evoke_wielded(); return; } // unwield staves or weapons - if (check_warning_inscriptions(you.inv[idx], OPER_WIELD)) + if (check_warning_inscriptions(item, OPER_WIELD)) wield_weapon(true, PROMPT_GOT_SPECIAL); // unwield return; - + case OBJ_MISSILES: - fire_thing(idx); + if (check_warning_inscriptions(item, OPER_FIRE)) + fire_thing(idx); return; case OBJ_ARMOUR: if (equipped && !equipped_weapon) { - if (check_warning_inscriptions(you.inv[idx], OPER_TAKEOFF)) + if (check_warning_inscriptions(item, OPER_TAKEOFF)) takeoff_armour(idx); } - else if (check_warning_inscriptions(you.inv[idx], OPER_WEAR)) + else if (check_warning_inscriptions(item, OPER_WEAR)) wear_armour(idx); return; case OBJ_WANDS: - if (check_warning_inscriptions(you.inv[idx], OPER_ZAP)) + if (check_warning_inscriptions(item, OPER_ZAP)) zap_wand(idx); return; case OBJ_CORPSES: if (you.species != SP_VAMPIRE - || you.inv[idx].sub_type == CORPSE_SKELETON - || food_is_rotten(you.inv[idx])) + || item.sub_type == CORPSE_SKELETON + || food_is_rotten(item)) { break; } // intentional fall-through for Vampires case OBJ_FOOD: - if (check_warning_inscriptions(you.inv[idx], OPER_EAT)) + if (check_warning_inscriptions(item, OPER_EAT)) eat_food(false, idx); return; case OBJ_BOOKS: - if (you.inv[idx].sub_type == BOOK_MANUAL - || you.inv[idx].sub_type == BOOK_DESTRUCTION) + if (item.sub_type == BOOK_MANUAL + || item.sub_type == BOOK_DESTRUCTION) { - if (check_warning_inscriptions(you.inv[idx], OPER_READ)) + if (check_warning_inscriptions(item, OPER_READ)) handle_read_book(idx); } // else it's a spellbook - else if (check_warning_inscriptions(you.inv[idx], OPER_MEMORISE)) + else if (check_warning_inscriptions(item, OPER_MEMORISE)) learn_spell(idx); return; - + case OBJ_SCROLLS: - if (check_warning_inscriptions(you.inv[idx], OPER_READ)) + if (check_warning_inscriptions(item, OPER_READ)) read_scroll(idx); return; case OBJ_JEWELLERY: if (equipped && !equipped_weapon) { - if (check_warning_inscriptions(you.inv[idx], OPER_REMOVE)) + if (check_warning_inscriptions(item, OPER_REMOVE)) remove_ring(idx); } - else if (check_warning_inscriptions(you.inv[idx], OPER_PUTON)) + else if (check_warning_inscriptions(item, OPER_PUTON)) puton_ring(idx, false); return; case OBJ_POTIONS: - if (check_warning_inscriptions(you.inv[idx], OPER_QUAFF)) + if (check_warning_inscriptions(item, OPER_QUAFF)) drink(idx); return; diff --git a/crawl-ref/source/libgui.cc b/crawl-ref/source/libgui.cc index 9547d64ccf..c65f754ed3 100644 --- a/crawl-ref/source/libgui.cc +++ b/crawl-ref/source/libgui.cc @@ -21,9 +21,11 @@ #include "describe.h" #include "direct.h" #include "files.h" +#include "food.h" #include "itemname.h" #include "itemprop.h" #include "items.h" +#include "it_use2.h" #include "externs.h" #include "guic.h" #include "message.h" @@ -368,15 +370,18 @@ void GmapUpdate(int x, int y, int what, bool upd_tile) if (c == Options.tile_monster_col && mgrd[x][y] != NON_MONSTER && upd_tile) { - if (mons_friendly(&menv[mgrd[x][y]])) + const int grid = mgrd[x][y]; + if (mons_friendly(&menv[grid])) c = Options.tile_friendly_col; // colour friendly monsters - else if (mons_neutral(&menv[mgrd[x][y]]) + else if (mons_neutral(&menv[grid]) && Options.tile_neutral_col != Options.tile_monster_col) { c = Options.tile_neutral_col; // colour neutral monsters } + else if (mons_class_flag( menv[grid].type, M_NO_EXP_GAIN )) + c = Options.tile_plant_col; } - + if (c == Options.tile_floor_col || c == Options.tile_item_col) { if (is_exclude_root( coord_def(x,y) )) @@ -1325,25 +1330,27 @@ static int _handle_mouse_motion(int mouse_x, int mouse_y, bool init) if (itemlist_iflag[cx] & TILEI_FLAG_FLOOR) { + const item_def item = mitm[ix]; + if (itemlist_key[cx]) { desc = itemlist_key[cx]; desc += " - "; } - desc += mitm[ix].name(DESC_NOCAP_A); + desc += item.name(DESC_NOCAP_A); if (display_actions) desc += EOL "[L-Click] Pick up (g)"; - if (mitm[ix].base_type == OBJ_CORPSES - && mitm[ix].sub_type != CORPSE_SKELETON - && !food_is_rotten(mitm[ix])) + if (item.base_type == OBJ_CORPSES + && item.sub_type != CORPSE_SKELETON + && !food_is_rotten(item)) { desc += EOL "[Shift-L-Click] Dissect (D)"; - + if (you.species == SP_VAMPIRE) desc += EOL "[Shift-R-Click] Drink blood (e)"; } - else if (mitm[ix].base_type == OBJ_FOOD + else if (item.base_type == OBJ_FOOD && you.species != SP_VAMPIRE && you.species != SP_MUMMY) { @@ -1352,26 +1359,26 @@ static int _handle_mouse_motion(int mouse_x, int mouse_y, bool init) } else // in inventory { - desc = you.inv[ix].name(DESC_INVENTORY_EQUIP); + const item_def item = you.inv[ix]; + + desc = item.name(DESC_INVENTORY_EQUIP); - // FIX ME: Might have to allow wielding as a secondary action - // for arrows (Sticks to Snakes), skeletons (Boneshards), - // chunks/potions of blood (Sublimation of Blood) if (display_actions) { - int type = you.inv[ix].base_type; + int type = item.base_type; const bool equipped = itemlist_iflag[cx] & TILEI_FLAG_EQUIP; + bool wielded = (you.equip[EQ_WEAPON] == ix); desc += EOL; - + if (_can_use_item(you.inv[ix], equipped)) { desc += "[L-Click] "; if (equipped) { - if (you.equip[EQ_WEAPON] == ix + if (wielded && type != OBJ_MISCELLANY - && !item_is_rod(you.inv[ix])) + && !item_is_rod(item)) { if (type == OBJ_JEWELLERY || type == OBJ_ARMOUR || type == OBJ_WEAPONS || type == OBJ_STAVES) @@ -1390,17 +1397,17 @@ static int _handle_mouse_motion(int mouse_x, int mouse_y, bool init) case OBJ_STAVES: case OBJ_MISCELLANY: desc += "Wield (w)"; - if (is_throwable(you.inv[ix], player_size(PSIZE_BODY))) + if (is_throwable(item, player_size(PSIZE_BODY))) desc += EOL "[Ctrl-L-Click] Fire (f)"; break; case OBJ_WEAPONS + 18: desc += "Unwield"; - if (is_throwable(you.inv[ix], player_size(PSIZE_BODY))) + if (is_throwable(item, player_size(PSIZE_BODY))) desc += EOL "[Ctrl-L-Click] Fire (f)"; break; case OBJ_MISCELLANY + 18: - if (you.inv[ix].sub_type >= MISC_DECK_OF_ESCAPE - && you.inv[ix].sub_type <= MISC_DECK_OF_DEFENCE) + if (item.sub_type >= MISC_DECK_OF_ESCAPE + && item.sub_type <= MISC_DECK_OF_DEFENCE) { desc += "Draw a card (E)"; desc += EOL "[Ctrl-L-Click] Unwield"; @@ -1425,37 +1432,94 @@ static int _handle_mouse_motion(int mouse_x, int mouse_y, bool init) break; case OBJ_MISSILES: desc += "Fire (f)"; + + if (wielded) + desc += EOL "[Ctrl-L-Click] Unwield"; + else if ( item.sub_type == MI_STONE + && player_knows_spell(SPELL_SANDBLAST) + || item.sub_type == MI_ARROW + && player_knows_spell( + SPELL_STICKS_TO_SNAKES) ) + { + // For Sandblast and Sticks to Snakes, respectively. + desc += EOL "[Ctrl-L-Click] Wield (w)"; + } break; case OBJ_WANDS: desc += "Zap (z)"; + if (wielded) + desc += EOL "[Ctrl-L-Click] Unwield"; break; case OBJ_BOOKS: - if (item_type_known(you.inv[ix]) - && you.inv[ix].sub_type != BOOK_MANUAL - && you.inv[ix].sub_type != BOOK_DESTRUCTION) + if (item_type_known(item) + && item.sub_type != BOOK_MANUAL + && item.sub_type != BOOK_DESTRUCTION) { desc += "Memorise (M)"; + if (wielded) + desc += EOL "[Ctrl-L-Click] Unwield"; break; } // else fall-through case OBJ_SCROLLS: desc += "Read (r)"; + if (wielded) + desc += EOL "[Ctrl-L-Click] Unwield"; break; case OBJ_POTIONS: desc += "Quaff (q)"; + // For Sublimation of Blood. + if (wielded) + desc += EOL "[Ctrl-L-Click] Unwield"; + else if ( item_type_known(item) + && (item.sub_type == POT_BLOOD + || item.sub_type + == POT_BLOOD_COAGULATED) + && player_knows_spell( + SPELL_SUBLIMATION_OF_BLOOD) ) + { + desc += EOL "[Ctrl-L-Click] Wield (w)"; + } break; case OBJ_FOOD: desc += "Eat (e)"; + // For Sublimation of Blood. + if (wielded) + desc += EOL "[Ctrl-L-Click] Unwield"; + else if (item.sub_type == FOOD_CHUNK + && player_knows_spell( + SPELL_SUBLIMATION_OF_BLOOD)) + { + desc += EOL "[Ctrl-L-Click] Wield (w)"; + } break; case OBJ_CORPSES: if (you.species == SP_VAMPIRE) desc += "Drink blood (e)"; + + if (wielded) + { + if (you.species == SP_VAMPIRE) + desc += EOL; + desc += "[Ctrl-L-Click] Unwield"; + } break; default: desc += "Use"; } } + // For Boneshards. + // special handling since skeletons have no primary action + if (item.base_type == OBJ_CORPSES + && item.sub_type == CORPSE_SKELETON) + { + if (wielded) + desc += EOL "[Ctrl-L-Click] Unwield"; + else if (player_knows_spell(SPELL_BONE_SHARDS)) + desc += EOL "[Ctrl-L-Click] Wield (w)"; + } + desc += EOL "[R-Click] Info"; // has to be non-equipped or non-cursed to drop if (!equipped || !_is_true_equipped_item(you.inv[ix]) diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index c4e9cf1ce7..54f4379754 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -1132,6 +1132,15 @@ int player_spell_levels(void) return (sl); } +bool player_knows_spell(int spell) +{ + for (int i = 0; i < 25; i++) + if (you.spells[i] == spell) + return true; + + return false; +} + int player_res_magic(void) { int rm = 0; diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h index 457db18132..2a31244d4e 100644 --- a/crawl-ref/source/player.h +++ b/crawl-ref/source/player.h @@ -228,6 +228,10 @@ int player_speed(void); * *********************************************************************** */ int player_spell_levels(void); +/* *********************************************************************** + * called from: libgui - item_use + * *********************************************************************** */ +bool player_knows_spell(int spell); // last updated 18may2000 {dlb} /* *********************************************************************** |