From da692355e84f8d1e5210c3c89daf775cf23ec38b Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sat, 18 Jun 2011 00:46:50 +0300 Subject: Created and moved stuff to content_nodemeta.{h,cpp} --- src/content_nodemeta.cpp | 305 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 src/content_nodemeta.cpp (limited to 'src/content_nodemeta.cpp') diff --git a/src/content_nodemeta.cpp b/src/content_nodemeta.cpp new file mode 100644 index 000000000..8627e18d0 --- /dev/null +++ b/src/content_nodemeta.cpp @@ -0,0 +1,305 @@ +/* +Minetest-c55 +Copyright (C) 2010-2011 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "content_nodemeta.h" +#include "inventory.h" +#include "content_mapnode.h" + +/* + SignNodeMetadata +*/ + +// Prototype +SignNodeMetadata proto_SignNodeMetadata(""); + +SignNodeMetadata::SignNodeMetadata(std::string text): + m_text(text) +{ + NodeMetadata::registerType(typeId(), create); +} +u16 SignNodeMetadata::typeId() const +{ + return CONTENT_SIGN_WALL; +} +NodeMetadata* SignNodeMetadata::create(std::istream &is) +{ + std::string text = deSerializeString(is); + return new SignNodeMetadata(text); +} +NodeMetadata* SignNodeMetadata::clone() +{ + return new SignNodeMetadata(m_text); +} +void SignNodeMetadata::serializeBody(std::ostream &os) +{ + os<addList("0", 8*4); +} +ChestNodeMetadata::~ChestNodeMetadata() +{ + delete m_inventory; +} +u16 ChestNodeMetadata::typeId() const +{ + return CONTENT_CHEST; +} +NodeMetadata* ChestNodeMetadata::create(std::istream &is) +{ + ChestNodeMetadata *d = new ChestNodeMetadata(); + d->m_inventory->deSerialize(is); + return d; +} +NodeMetadata* ChestNodeMetadata::clone() +{ + ChestNodeMetadata *d = new ChestNodeMetadata(); + *d->m_inventory = *m_inventory; + return d; +} +void ChestNodeMetadata::serializeBody(std::ostream &os) +{ + m_inventory->serialize(os); +} +std::string ChestNodeMetadata::infoText() +{ + return "Chest"; +} +bool ChestNodeMetadata::nodeRemovalDisabled() +{ + /* + Disable removal if chest contains something + */ + InventoryList *list = m_inventory->getList("0"); + if(list == NULL) + return false; + if(list->getUsedSlots() == 0) + return false; + return true; +} + +/* + FurnaceNodeMetadata +*/ + +// Prototype +FurnaceNodeMetadata proto_FurnaceNodeMetadata; + +FurnaceNodeMetadata::FurnaceNodeMetadata() +{ + NodeMetadata::registerType(typeId(), create); + + m_inventory = new Inventory(); + m_inventory->addList("fuel", 1); + m_inventory->addList("src", 1); + m_inventory->addList("dst", 4); + + m_step_accumulator = 0; + m_fuel_totaltime = 0; + m_fuel_time = 0; + m_src_totaltime = 0; + m_src_time = 0; +} +FurnaceNodeMetadata::~FurnaceNodeMetadata() +{ + delete m_inventory; +} +u16 FurnaceNodeMetadata::typeId() const +{ + return CONTENT_FURNACE; +} +NodeMetadata* FurnaceNodeMetadata::clone() +{ + FurnaceNodeMetadata *d = new FurnaceNodeMetadata(); + *d->m_inventory = *m_inventory; + return d; +} +NodeMetadata* FurnaceNodeMetadata::create(std::istream &is) +{ + FurnaceNodeMetadata *d = new FurnaceNodeMetadata(); + + d->m_inventory->deSerialize(is); + + int temp; + is>>temp; + d->m_fuel_totaltime = (float)temp/10; + is>>temp; + d->m_fuel_time = (float)temp/10; + + return d; +} +void FurnaceNodeMetadata::serializeBody(std::ostream &os) +{ + m_inventory->serialize(os); + os<= m_fuel_totaltime) + { + InventoryList *src_list = m_inventory->getList("src"); + assert(src_list); + InventoryItem *src_item = src_list->getItem(0); + + if(src_item) + return "Furnace is out of fuel"; + else + return "Furnace is inactive"; + } + else + { + std::string s = "Furnace is active ("; + s += itos(m_fuel_time/m_fuel_totaltime*100); + s += "%)"; + return s; + } +} +void FurnaceNodeMetadata::inventoryModified() +{ + dstream<<"Furnace inventory modification callback"< 60.0) + dstream<<"Furnace stepping a long time ("< interval) + { + m_step_accumulator -= interval; + dtime = interval; + + //dstream<<"Furnace step dtime="<getList("dst"); + assert(dst_list); + + InventoryList *src_list = m_inventory->getList("src"); + assert(src_list); + InventoryItem *src_item = src_list->getItem(0); + + // Start only if there are free slots in dst, so that it can + // accomodate any result item + if(dst_list->getFreeSlots() > 0 && src_item && src_item->isCookable()) + { + m_src_totaltime = 3; + } + else + { + m_src_time = 0; + m_src_totaltime = 0; + } + + /* + If fuel is burning, increment the burn counters. + If item finishes cooking, move it to result. + */ + if(m_fuel_time < m_fuel_totaltime) + { + //dstream<<"Furnace is active"<= m_src_totaltime && m_src_totaltime > 0.001 + && src_item) + { + InventoryItem *cookresult = src_item->createCookResult(); + dst_list->addItem(cookresult); + src_list->decrementMaterials(1); + m_src_time = 0; + m_src_totaltime = 0; + } + changed = true; + continue; + } + + /* + If there is no source item or source item is not cookable, stop loop. + */ + if(src_item == NULL || m_src_totaltime < 0.001) + { + m_step_accumulator = 0; + break; + } + + //dstream<<"Furnace is out of fuel"<getList("fuel"); + assert(fuel_list); + InventoryItem *fuel_item = fuel_list->getItem(0); + + if(ItemSpec(ITEM_MATERIAL, CONTENT_TREE).checkItem(fuel_item)) + { + m_fuel_totaltime = 30; + m_fuel_time = 0; + fuel_list->decrementMaterials(1); + changed = true; + } + else if(ItemSpec(ITEM_MATERIAL, CONTENT_WOOD).checkItem(fuel_item)) + { + m_fuel_totaltime = 30/4; + m_fuel_time = 0; + fuel_list->decrementMaterials(1); + changed = true; + } + else if(ItemSpec(ITEM_CRAFT, "Stick").checkItem(fuel_item)) + { + m_fuel_totaltime = 30/4/4; + m_fuel_time = 0; + fuel_list->decrementMaterials(1); + changed = true; + } + else if(ItemSpec(ITEM_CRAFT, "lump_of_coal").checkItem(fuel_item)) + { + m_fuel_totaltime = 40; + m_fuel_time = 0; + fuel_list->decrementMaterials(1); + changed = true; + } + else + { + //dstream<<"No fuel found"< Date: Sat, 18 Jun 2011 02:00:01 +0300 Subject: moved inventory menu definition of chest and furnace to content_nodemeta.{h,cpp} --- src/content_nodemeta.cpp | 16 +++++++++ src/content_nodemeta.h | 3 +- src/game.cpp | 87 +++++++++++++++++++----------------------------- src/guiInventoryMenu.cpp | 81 ++++++++++++++++++++++++++++++++++++++++++++ src/guiInventoryMenu.h | 6 ++++ src/main.cpp | 3 ++ src/nodemetadata.h | 3 ++ 7 files changed, 145 insertions(+), 54 deletions(-) (limited to 'src/content_nodemeta.cpp') 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<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"<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"< 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 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"<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 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 &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="< &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); -- cgit v1.2.3 From a4cceb93ec3f2e092d513896e4beeac3bafe3502 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sat, 18 Jun 2011 08:50:05 +0300 Subject: fixed wrong furnace menu layout --- src/content_nodemeta.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/content_nodemeta.cpp') diff --git a/src/content_nodemeta.cpp b/src/content_nodemeta.cpp index 92b2cbada..681e2b925 100644 --- a/src/content_nodemeta.cpp +++ b/src/content_nodemeta.cpp @@ -312,7 +312,7 @@ std::string FurnaceNodeMetadata::getInventoryDrawSpecString() { return "invsize[8,9;]" - "list[current_name;fuel;2,4;1,1;]" + "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;]"; -- cgit v1.2.3