From 7896dbd29bda379c2fb31feeb3b16bda57039c00 Mon Sep 17 00:00:00 2001 From: j-p-e-g Date: Fri, 11 Apr 2008 11:23:33 +0000 Subject: Fix 1937869: Have weapon swapping respect spells the character knows and allow wielding the appropriate items, e.g. arrows for Sticks to Snakes etc. Use the same rules for clicking on items in Tiles. Also add yet another minimap colour option, this time for plants (really zero xp monsters in general) since I became tired of plant-rich vaults showing up in bright red colours. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@4195 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/docs/options_guide.txt | 12 ++-- crawl-ref/init.txt | 1 + crawl-ref/source/direct.cc | 18 ++--- crawl-ref/source/externs.h | 1 + crawl-ref/source/initfile.cc | 6 ++ crawl-ref/source/item_use.cc | 141 +++++++++++++++++++++++++++------------ crawl-ref/source/libgui.cc | 112 ++++++++++++++++++++++++------- crawl-ref/source/player.cc | 9 +++ crawl-ref/source/player.h | 4 ++ 9 files changed, 226 insertions(+), 78 deletions(-) (limited to 'crawl-ref') 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} /* *********************************************************************** -- cgit v1.2.3-54-g00ecf