From 389fe31ace38a8f53c210ff5ae823eae1780dfc8 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Tue, 5 Apr 2011 00:24:47 +0300 Subject: [PATCH] changed node metadata format to better accomodate future needs and problems --- src/CMakeLists.txt | 1 + src/guiInventoryMenu.cpp | 16 +++--- src/guiInventoryMenu.h | 8 ++- src/main.cpp | 44 ++++++++++++----- src/map.cpp | 8 +-- src/mapblock.cpp | 16 +++++- src/mapnode.cpp | 2 + src/mapnode.h | 1 + src/modalMenu.h | 9 +++- src/nodemetadata.cpp | 103 +++++++++++++++++++++++++++++++++------ src/nodemetadata.h | 25 ++++++++++ src/server.cpp | 5 +- 12 files changed, 192 insertions(+), 46 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e414df33a..17eabcb91 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -81,6 +81,7 @@ set(common_SRCS set(minetest_SRCS ${common_SRCS} clientobject.cpp + guiFurnaceMenu.cpp guiMainMenu.cpp guiMessageMenu.cpp guiTextInputMenu.cpp diff --git a/src/guiInventoryMenu.cpp b/src/guiInventoryMenu.cpp index 2d20b24aa..b83a84449 100644 --- a/src/guiInventoryMenu.cpp +++ b/src/guiInventoryMenu.cpp @@ -80,15 +80,13 @@ GUIInventoryMenu::GUIInventoryMenu(gui::IGUIEnvironment* env, gui::IGUIElement* parent, s32 id, IMenuManager *menumgr, v2s16 menu_size, - core::array &init_draw_spec, InventoryContext *c, InventoryManager *invmgr ): GUIModalMenu(env, parent, id, menumgr), m_menu_size(menu_size), m_c(c), - m_invmgr(invmgr), - m_init_draw_spec(init_draw_spec) + m_invmgr(invmgr) { m_selected_item = NULL; } @@ -103,7 +101,7 @@ GUIInventoryMenu::~GUIInventoryMenu() void GUIInventoryMenu::removeChildren() { - /*const core::list &children = getChildren(); + const core::list &children = getChildren(); core::list children_copy; for(core::list::ConstIterator i = children.begin(); i != children.end(); i++) @@ -115,12 +113,12 @@ void GUIInventoryMenu::removeChildren() i != children_copy.end(); i++) { (*i)->remove(); - }*/ - { + } + /*{ gui::IGUIElement *e = getElementFromId(256); if(e != NULL) e->remove(); - } + }*/ } void GUIInventoryMenu::regenerateGui(v2u32 screensize) @@ -326,6 +324,10 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event) inv_from->getList(m_selected_item->listname); InventoryList *list_to = inv_to->getList(s.listname); + if(list_from == NULL) + dstream<<"from list doesn't exist"< &init_draw_spec, InventoryContext *c, InventoryManager *invmgr ); ~GUIInventoryMenu(); + void setDrawSpec(core::array &init_draw_spec) + { + m_init_draw_spec = init_draw_spec; + } + void removeChildren(); /* Remove and re-add (or reposition) stuff @@ -125,7 +129,7 @@ public: bool OnEvent(const SEvent& event); -private: +protected: v2s32 getBasePos() const { return padding + AbsoluteRect.UpperLeftCorner; diff --git a/src/main.cpp b/src/main.cpp index df5bca21e..7ec542533 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -180,6 +180,10 @@ SUGG: Don't update all meshes always on single node changes, but TODO: Remove IrrlichtWrapper +SUGG: Add a "description" field to InventoryList and show it in + GUIInventoryMenu + - If separate menus are made for everything, this is not needed + Server: ------- @@ -332,6 +336,7 @@ Making it more portable: #include "mineral.h" #include "noise.h" #include "tile.h" +#include "guiFurnaceMenu.h" // TODO: Remove this IrrlichtWrapper *g_irrlicht = NULL; @@ -626,6 +631,12 @@ public: dstream<getInventoryContext(), + g_client); + core::array draw_spec; draw_spec.push_back(GUIInventoryMenu::DrawSpec( "list", "current_player", "main", @@ -637,11 +648,7 @@ public: "list", "current_player", "craftresult", v2s32(7, 1), v2s32(1, 1))); - GUIInventoryMenu *menu = - new GUIInventoryMenu(guienv, guiroot, -1, - &g_menumgr, v2s16(8,7), draw_spec, - g_client->getInventoryContext(), - g_client); + menu->setDrawSpec(draw_spec); menu->drop(); @@ -2994,8 +3001,6 @@ int main(int argc, char *argv[]) //ChestNodeMetadata *chestmeta = (ChestNodeMetadata*)meta; - core::array draw_spec; - std::string chest_inv_id; chest_inv_id += "nodemeta:"; chest_inv_id += itos(nodepos.X); @@ -3004,6 +3009,14 @@ int main(int argc, char *argv[]) chest_inv_id += ","; chest_inv_id += itos(nodepos.Z); + GUIInventoryMenu *menu = + new GUIInventoryMenu(guienv, guiroot, -1, + &g_menumgr, v2s16(8,9), + g_client->getInventoryContext(), + g_client); + + core::array draw_spec; + draw_spec.push_back(GUIInventoryMenu::DrawSpec( "list", chest_inv_id, "0", v2s32(0, 0), v2s32(8, 4))); @@ -3011,11 +3024,18 @@ int main(int argc, char *argv[]) "list", "current_player", "main", v2s32(0, 5), v2s32(8, 4))); - GUIInventoryMenu *menu = - new GUIInventoryMenu(guienv, guiroot, -1, - &g_menumgr, v2s16(8,9), draw_spec, - g_client->getInventoryContext(), - g_client); + menu->setDrawSpec(draw_spec); + + menu->drop(); + + } + else if(meta && meta->typeId() == CONTENT_FURNACE && !random_input) + { + dstream<<"Furnace node right-clicked"<drop(); diff --git a/src/map.cpp b/src/map.cpp index d644215be..f6115a62a 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -5192,14 +5192,14 @@ void ServerMap::loadBlock(std::string sectordir, std::string blockfile, MapSecto { DSTACK(__FUNCTION_NAME); + // Block file is map/sectors/xxxxxxxx/xxxx + std::string fullpath = m_savedir+"/sectors/"+sectordir+"/"+blockfile; try{ - // Block file is map/sectors/xxxxxxxx/xxxx - std::string fullpath = m_savedir+"/sectors/"+sectordir+"/"+blockfile; std::ifstream is(fullpath.c_str(), std::ios_base::binary); if(is.good() == false) throw FileNotGoodException("Cannot open block file"); - + v3s16 p3d = getBlockPos(sectordir, blockfile); v2s16 p2d(p3d.X, p3d.Z); @@ -5264,6 +5264,8 @@ void ServerMap::loadBlock(std::string sectordir, std::string blockfile, MapSecto "(SerializationError). Ignoring. " "A new one will be generated." <= 14) { - m_node_metadata.serialize(os); + std::ostringstream oss(std::ios_base::binary); + m_node_metadata.serialize(oss); + os<= 14) { - m_node_metadata.deSerialize(is); + // Ignore errors + try{ + std::string data = deSerializeString(is); + std::istringstream iss(data, std::ios_base::binary); + m_node_metadata.deSerialize(iss); + } + catch(SerializationError &e) + { + dstream<<"WARNING: MapBlock::deSerialize(): Ignoring an error" + <<" while deserializing node metadata"<setTexture(5, "furnace_front.png"); // Z- f->setInventoryTexture("furnace_front.png"); f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; + if(f->initial_metadata == NULL) + f->initial_metadata = new FurnaceNodeMetadata(); } diff --git a/src/mapnode.h b/src/mapnode.h index 2843208a9..ce233e8e3 100644 --- a/src/mapnode.h +++ b/src/mapnode.h @@ -98,6 +98,7 @@ void init_content_inventory_texture_paths(); #define CONTENT_SIGN_WALL 14 #define CONTENT_CHEST 15 #define CONTENT_FURNACE 16 +//#define CONTENT_WORKBENCH 17 /* Content feature list diff --git a/src/modalMenu.h b/src/modalMenu.h index ebbb06cfe..1f6d4d897 100644 --- a/src/modalMenu.h +++ b/src/modalMenu.h @@ -46,6 +46,8 @@ public: IGUIElement(gui::EGUIET_ELEMENT, env, parent, id, core::rect(0,0,100,100)) { + //m_force_regenerate_gui = false; + m_menumgr = menumgr; m_allow_focus_removal = false; m_screensize_old = v2u32(0,0); @@ -76,10 +78,11 @@ public: video::IVideoDriver* driver = Environment->getVideoDriver(); v2u32 screensize = driver->getScreenSize(); - if(screensize != m_screensize_old) + if(screensize != m_screensize_old /*|| m_force_regenerate_gui*/) { m_screensize_old = screensize; regenerateGui(screensize); + //m_force_regenerate_gui = false; } drawMenu(); @@ -119,7 +122,9 @@ public: virtual void regenerateGui(v2u32 screensize) = 0; virtual void drawMenu() = 0; virtual bool OnEvent(const SEvent& event) { return false; }; - + +protected: + //bool m_force_regenerate_gui; private: IMenuManager *m_menumgr; // This might be necessary to expose to the implementation if it diff --git a/src/nodemetadata.cpp b/src/nodemetadata.cpp index 294db178f..2405e7601 100644 --- a/src/nodemetadata.cpp +++ b/src/nodemetadata.cpp @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapnode.h" #include "exceptions.h" #include "inventory.h" +#include /* NodeMetadata @@ -39,21 +40,39 @@ NodeMetadata::~NodeMetadata() NodeMetadata* NodeMetadata::deSerialize(std::istream &is) { + // Read id u8 buf[2]; is.read((char*)buf, 2); s16 id = readS16(buf); - + + // Read data + std::string data = deSerializeString(is); + + // Find factory function core::map::Node *n; n = m_types.find(id); if(n == NULL) { - dstream<<"NodeMetadata(): No factory for typeId="<addList("fuel", 1); + m_inventory->addList("src", 1); + m_inventory->addList("dst", 1); +} +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); + /*std::string params; + std::getline(is, params, '\n');*/ + return d; +} +void FurnaceNodeMetadata::serializeBody(std::ostream &os) +{ + m_inventory->serialize(os); + // This line will contain the other parameters + //os<<"\n"; +} +std::string FurnaceNodeMetadata::infoText() +{ + return "Furnace"; +} +void FurnaceNodeMetadata::inventoryModified() +{ + dstream<<"Furnace inventory modification callback"<";} virtual Inventory* getInventory() {return NULL;} + // This is called always after the inventory is modified, before + // the changes are copied elsewhere + virtual void inventoryModified(){} protected: static void registerType(u16 id, Factory f); @@ -99,6 +102,28 @@ private: Inventory *m_inventory; }; +class FurnaceNodeMetadata : public NodeMetadata +{ +public: + FurnaceNodeMetadata(); + ~FurnaceNodeMetadata(); + + virtual u16 typeId() const; + virtual NodeMetadata* clone(); + static NodeMetadata* create(std::istream &is); + virtual void serializeBody(std::ostream &os); + virtual std::string infoText(); + virtual Inventory* getInventory() {return m_inventory;} + virtual void inventoryModified(); + +private: + Inventory *m_inventory; +}; + +/* + List of metadata of all the nodes of a block +*/ + class NodeMetadataList { public: diff --git a/src/server.cpp b/src/server.cpp index 7266a6ddf..df712e07f 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2743,8 +2743,9 @@ void Server::inventoryModified(InventoryContext *c, std::string id) assert(c->current_player); v3s16 blockpos = getNodeBlockPos(p); - /*RemoteClient *client = getClient(c->current_player->peer_id); - client->SetBlockNotSent(blockpos);*/ + NodeMetadata *meta = m_env.getMap().getNodeMetadata(p); + if(meta) + meta->inventoryModified(); for(core::map::Iterator i = m_clients.getIterator();