From 4f02417442109656263366ffcefd68231a0da7e9 Mon Sep 17 00:00:00 2001 From: ennewalker Date: Tue, 31 Mar 2009 03:08:39 +0000 Subject: [2722438] Fixing crash when viewing shop contents. shop_item* was being blindly casted to monsters*, which didn't play well with a non-existent virtual function table. Fixed by creating a ShopItemEntry and a MonstersMenuEntry class to differentiate the meaning of MenuEntry::data and to avoid crashes in the future by having MenuEntry::get_tiles() be a no-op. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@9572 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/directn.cc | 4 +--- crawl-ref/source/invent.cc | 7 ++++++- crawl-ref/source/menu.cc | 13 ++++++++++++- crawl-ref/source/menu.h | 10 ++++++++++ crawl-ref/source/stash.cc | 20 +++++++++++++++----- crawl-ref/source/stash.h | 13 +++++++------ 6 files changed, 51 insertions(+), 16 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc index b3a31e0f36..605192bf47 100644 --- a/crawl-ref/source/directn.cc +++ b/crawl-ref/source/directn.cc @@ -586,9 +586,7 @@ void full_describe_view() { if (j == 0) { - me = new MenuEntry(prefix + str, MEL_ITEM, 1, hotkey); - me->data = (void*) list_mons[i]; - me->quantity = 1; // Hack to make monsters selectable. + me = new MonsterMenuEntry(prefix+str, list_mons[i], hotkey); } #ifndef USE_TILE else diff --git a/crawl-ref/source/invent.cc b/crawl-ref/source/invent.cc index 73be3dd37f..7486dc4667 100644 --- a/crawl-ref/source/invent.cc +++ b/crawl-ref/source/invent.cc @@ -513,7 +513,12 @@ bool InvEntry::get_tiles(std::vector& tileset) const // Do we want to display the floor type or is that too distracting? const coord_def c = item->pos; int ch = -1; - if (c != coord_def()) + if (c.x == 0) + { + // Store items. + tileset.push_back(tile_def(TILE_ITEM_SLOT, TEX_DUNGEON)); + } + else if (c != coord_def()) { ch = tileidx_feature(grd(c), c.x, c.y); if (ch == TILE_FLOOR_NORMAL) diff --git a/crawl-ref/source/menu.cc b/crawl-ref/source/menu.cc index c452cf7973..67af41fd61 100644 --- a/crawl-ref/source/menu.cc +++ b/crawl-ref/source/menu.cc @@ -685,10 +685,21 @@ void Menu::select_items(int key, int qty) cgotoxy( x, y ); } +MonsterMenuEntry::MonsterMenuEntry(const std::string &str, const monsters* mon, int hotkey) : + MenuEntry(str, MEL_ITEM, 1, hotkey) +{ + data = (void*)mon; + quantity = 1; +} + #ifdef USE_TILE bool MenuEntry::get_tiles(std::vector& tileset) const { - // Is this a monster? + return false; +} + +bool MonsterMenuEntry::get_tiles(std::vector& tileset) const +{ monsters *m = (monsters*)(data); if (!m) return (false); diff --git a/crawl-ref/source/menu.h b/crawl-ref/source/menu.h index 7f8b4c6372..12517ec097 100644 --- a/crawl-ref/source/menu.h +++ b/crawl-ref/source/menu.h @@ -162,6 +162,16 @@ public: void toggle() { text.swap(alt_text); } }; +class MonsterMenuEntry : public MenuEntry +{ +public: + MonsterMenuEntry(const std::string &str, const monsters* mon, int hotkey); + +#ifdef USE_TILE + virtual bool get_tiles(std::vector& tileset) const; +#endif +}; + class MenuHighlighter { public: diff --git a/crawl-ref/source/stash.cc b/crawl-ref/source/stash.cc index cecf818d5c..caa4eed7d5 100644 --- a/crawl-ref/source/stash.cc +++ b/crawl-ref/source/stash.cc @@ -912,6 +912,18 @@ void ShopInfo::describe_shop_item(const shop_item &si) const const_cast(si).item.flags = oldflags; } +class ShopItemEntry : public InvEntry +{ +public: + ShopItemEntry(const ShopInfo::shop_item &it, + const std::string &item_name, + menu_letter hotkey) : InvEntry(it.item) + { + text = item_name; + add_hotkey(hotkey); + } +}; + bool ShopInfo::show_menu(const std::string &place, bool can_travel) const { @@ -937,11 +949,9 @@ bool ShopInfo::show_menu(const std::string &place, { for (int i = 0, count = items.size(); i < count; ++i) { - MenuEntry *me = new MenuEntry(shop_item_name(items[i]), - MEL_ITEM, - 1, - hotkey++); - me->data = const_cast( &items[i] ); + MenuEntry *me = new ShopItemEntry(items[i], + shop_item_name(items[i]), + hotkey++); menu.add_entry(me); } } diff --git a/crawl-ref/source/stash.h b/crawl-ref/source/stash.h index 4b3811ec05..d14b67173e 100644 --- a/crawl-ref/source/stash.h +++ b/crawl-ref/source/stash.h @@ -145,6 +145,13 @@ public: bool isAt(int xp, int yp) const { return x == xp && y == yp; } + // Messy! + struct shop_item + { + item_def item; + unsigned price; + }; + private: int x, y; std::string name; @@ -154,12 +161,6 @@ private: // Set true if the player has visited this shop bool visited; - // Messy! - struct shop_item - { - item_def item; - unsigned price; - }; std::vector items; std::string shop_item_name(const shop_item &si) const; -- cgit v1.2.3-54-g00ecf