diff options
-rw-r--r-- | src/content_nodemeta.cpp | 16 | ||||
-rw-r--r-- | src/content_nodemeta.h | 3 | ||||
-rw-r--r-- | src/game.cpp | 87 | ||||
-rw-r--r-- | src/guiInventoryMenu.cpp | 81 | ||||
-rw-r--r-- | src/guiInventoryMenu.h | 6 | ||||
-rw-r--r-- | src/main.cpp | 3 | ||||
-rw-r--r-- | src/nodemetadata.h | 3 |
7 files changed, 145 insertions, 54 deletions
diff --git a/src/content_nodemeta.cpp b/src/content_nodemeta.cpp index 8627e18d0..92b2cbada 100644 --- a/src/content_nodemeta.cpp +++ b/src/content_nodemeta.cpp @@ -109,6 +109,13 @@ bool ChestNodeMetadata::nodeRemovalDisabled() return false; return true; } +std::string ChestNodeMetadata::getInventoryDrawSpecString() +{ + return + "invsize[8,9;]" + "list[current_name;0;0,0;8,4;]" + "list[current_player;main;0,5;8,4;]"; +} /* FurnaceNodeMetadata @@ -301,5 +308,14 @@ bool FurnaceNodeMetadata::step(float dtime) } return changed; } +std::string FurnaceNodeMetadata::getInventoryDrawSpecString() +{ + return + "invsize[8,9;]" + "list[current_name;fuel;2,4;1,1;]" + "list[current_name;src;2,1;1,1;]" + "list[current_name;dst;5,1;2,2;]" + "list[current_player;main;0,5;8,4;]"; +} diff --git a/src/content_nodemeta.h b/src/content_nodemeta.h index ed5d5f24e..84c3aed9d 100644 --- a/src/content_nodemeta.h +++ b/src/content_nodemeta.h @@ -55,8 +55,8 @@ public: virtual void serializeBody(std::ostream &os); virtual std::string infoText(); virtual Inventory* getInventory() {return m_inventory;} - virtual bool nodeRemovalDisabled(); + virtual std::string getInventoryDrawSpecString(); private: Inventory *m_inventory; @@ -76,6 +76,7 @@ public: virtual Inventory* getInventory() {return m_inventory;} virtual void inventoryModified(); virtual bool step(float dtime); + virtual std::string getInventoryDrawSpecString(); private: Inventory *m_inventory; diff --git a/src/game.cpp b/src/game.cpp index b11547679..c36688d12 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1709,75 +1709,56 @@ void the_game( { std::cout<<DTIME<<"Ground right-clicked"<<std::endl; - if(meta && meta->typeId() == CONTENT_SIGN_WALL && !random_input) + // If metadata provides an inventory view, activate it + if(meta && meta->getInventoryDrawSpecString() != "" && !random_input) { - dstream<<"Sign node right-clicked"<<std::endl; - - SignNodeMetadata *signmeta = (SignNodeMetadata*)meta; - - // Get a new text for it - - TextDest *dest = new TextDestSignNode(nodepos, &client); - - std::wstring wtext = - narrow_to_wide(signmeta->getText()); - - (new GUITextInputMenu(guienv, guiroot, -1, - &g_menumgr, dest, - wtext))->drop(); - } - else if(meta && meta->typeId() == CONTENT_CHEST && !random_input) - { - dstream<<"Chest node right-clicked"<<std::endl; - - //ChestNodeMetadata *chestmeta = (ChestNodeMetadata*)meta; - + dstream<<DTIME<<"Launching custom inventory view"<<std::endl; /* - Construct the unique identification string of this - chest's inventory + Construct the unique identification string of the node */ - std::string chest_inv_id; - chest_inv_id += "nodemeta:"; - chest_inv_id += itos(nodepos.X); - chest_inv_id += ","; - chest_inv_id += itos(nodepos.Y); - chest_inv_id += ","; - chest_inv_id += itos(nodepos.Z); - + std::string current_name; + current_name += "nodemeta:"; + current_name += itos(nodepos.X); + current_name += ","; + current_name += itos(nodepos.Y); + current_name += ","; + current_name += itos(nodepos.Z); + /* - Create a menu with the player's inventory and the - chest's inventory + Create menu */ + + core::array<GUIInventoryMenu::DrawSpec> draw_spec; + v2s16 invsize = + GUIInventoryMenu::makeDrawSpecArrayFromString( + draw_spec, + meta->getInventoryDrawSpecString(), + current_name); + GUIInventoryMenu *menu = new GUIInventoryMenu(guienv, guiroot, -1, - &g_menumgr, v2s16(8,9), + &g_menumgr, invsize, client.getInventoryContext(), &client); - - core::array<GUIInventoryMenu::DrawSpec> draw_spec; - - draw_spec.push_back(GUIInventoryMenu::DrawSpec( - "list", chest_inv_id, "0", - v2s32(0, 0), v2s32(8, 4))); - draw_spec.push_back(GUIInventoryMenu::DrawSpec( - "list", "current_player", "main", - v2s32(0, 5), v2s32(8, 4))); - menu->setDrawSpec(draw_spec); - menu->drop(); - } - else if(meta && meta->typeId() == CONTENT_FURNACE && !random_input) + else if(meta && meta->typeId() == CONTENT_SIGN_WALL && !random_input) { - dstream<<"Furnace node right-clicked"<<std::endl; + dstream<<"Sign node right-clicked"<<std::endl; + + SignNodeMetadata *signmeta = (SignNodeMetadata*)meta; - GUIFurnaceMenu *menu = - new GUIFurnaceMenu(guienv, guiroot, -1, - &g_menumgr, nodepos, &client); + // Get a new text for it - menu->drop(); + TextDest *dest = new TextDestSignNode(nodepos, &client); + + std::wstring wtext = + narrow_to_wide(signmeta->getText()); + (new GUITextInputMenu(guienv, guiroot, -1, + &g_menumgr, dest, + wtext))->drop(); } else { diff --git a/src/guiInventoryMenu.cpp b/src/guiInventoryMenu.cpp index a4ba472f8..786a4dd22 100644 --- a/src/guiInventoryMenu.cpp +++ b/src/guiInventoryMenu.cpp @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "guiInventoryMenu.h" #include "constants.h" #include "keycode.h" +#include "strfnd.h" void drawInventoryItem(video::IVideoDriver *driver, gui::IGUIFont *font, @@ -412,5 +413,85 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event) return Parent ? Parent->OnEvent(event) : false; } +/* + Here is an example traditional set-up sequence for a DrawSpec list: + + std::string furnace_inv_id = "nodemetadata:0,1,2"; + core::array<GUIInventoryMenu::DrawSpec> draw_spec; + draw_spec.push_back(GUIInventoryMenu::DrawSpec( + "list", furnace_inv_id, "fuel", + v2s32(2, 3), v2s32(1, 1))); + draw_spec.push_back(GUIInventoryMenu::DrawSpec( + "list", furnace_inv_id, "src", + v2s32(2, 1), v2s32(1, 1))); + draw_spec.push_back(GUIInventoryMenu::DrawSpec( + "list", furnace_inv_id, "dst", + v2s32(5, 1), v2s32(2, 2))); + draw_spec.push_back(GUIInventoryMenu::DrawSpec( + "list", "current_player", "main", + v2s32(0, 5), v2s32(8, 4))); + setDrawSpec(draw_spec); + + Here is the string for creating the same DrawSpec list (a single line, + spread to multiple lines here): + + GUIInventoryMenu::makeDrawSpecArrayFromString( + draw_spec, + "nodemetadata:0,1,2", + "invsize[8,9;]" + "list[current_name;fuel;2,3;1,1;]" + "list[current_name;src;2,1;1,1;]" + "list[current_name;dst;5,1;2,2;]" + "list[current_player;main;0,5;8,4;]"); + + Returns inventory menu size defined by invsize[]. +*/ +v2s16 GUIInventoryMenu::makeDrawSpecArrayFromString( + core::array<GUIInventoryMenu::DrawSpec> &draw_spec, + const std::string &data, + const std::string ¤t_name) +{ + v2s16 invsize(8,9); + Strfnd f(data); + while(f.atend() == false) + { + std::string type = trim(f.next("[")); + //dstream<<"type="<<type<<std::endl; + if(type == "list") + { + std::string name = f.next(";"); + if(name == "current_name") + name = current_name; + std::string subname = f.next(";"); + s32 pos_x = stoi(f.next(",")); + s32 pos_y = stoi(f.next(";")); + s32 geom_x = stoi(f.next(",")); + s32 geom_y = stoi(f.next(";")); + dstream<<"list name="<<name<<", subname="<<subname + <<", pos=("<<pos_x<<","<<pos_y<<")" + <<", geom=("<<geom_x<<","<<geom_y<<")" + <<std::endl; + draw_spec.push_back(GUIInventoryMenu::DrawSpec( + type, name, subname, + v2s32(pos_x,pos_y),v2s32(geom_x,geom_y))); + f.next("]"); + } + else if(type == "invsize") + { + invsize.X = stoi(f.next(",")); + invsize.Y = stoi(f.next(";")); + dstream<<"invsize ("<<invsize.X<<","<<invsize.Y<<")"<<std::endl; + f.next("]"); + } + else + { + // Ignore others + std::string ts = f.next("]"); + dstream<<"Unknown DrawSpec: type="<<type<<", data=\""<<ts<<"\"" + <<std::endl; + } + } + return invsize; +} diff --git a/src/guiInventoryMenu.h b/src/guiInventoryMenu.h index 10fb7a425..5336cae82 100644 --- a/src/guiInventoryMenu.h +++ b/src/guiInventoryMenu.h @@ -102,6 +102,12 @@ public: v2s32 pos; v2s32 geom; }; + + // See .cpp for format + static v2s16 makeDrawSpecArrayFromString( + core::array<GUIInventoryMenu::DrawSpec> &draw_spec, + const std::string &data, + const std::string ¤t_name); GUIInventoryMenu(gui::IGUIEnvironment* env, gui::IGUIElement* parent, s32 id, diff --git a/src/main.cpp b/src/main.cpp index 455e0ac9b..71ab5d037 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -335,6 +335,9 @@ Misc. stuff: - Finish the ActiveBlockModifier stuff and use it for something
- Move mineral to param2, increment map serialization version, add conversion
+TODO: Create a common interface-whatever-thing to implement custom
+ special blocks with an inventory menu
+
Making it more portable:
------------------------
diff --git a/src/nodemetadata.h b/src/nodemetadata.h index 8471e1d97..de682f9b6 100644 --- a/src/nodemetadata.h +++ b/src/nodemetadata.h @@ -62,6 +62,9 @@ public: // A step in time. Returns true if metadata changed. virtual bool step(float dtime) {return false;} virtual bool nodeRemovalDisabled(){return false;} + // Used to make custom inventory menus. + // See format in guiInventoryMenu.cpp. + virtual std::string getInventoryDrawSpecString(){return "";} protected: static void registerType(u16 id, Factory f); |