diff options
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/guiInventoryMenu.cpp | 16 | ||||
-rw-r--r-- | src/guiInventoryMenu.h | 8 | ||||
-rw-r--r-- | src/main.cpp | 44 | ||||
-rw-r--r-- | src/map.cpp | 8 | ||||
-rw-r--r-- | src/mapblock.cpp | 16 | ||||
-rw-r--r-- | src/mapnode.cpp | 2 | ||||
-rw-r--r-- | src/mapnode.h | 1 | ||||
-rw-r--r-- | src/modalMenu.h | 9 | ||||
-rw-r--r-- | src/nodemetadata.cpp | 103 | ||||
-rw-r--r-- | src/nodemetadata.h | 25 | ||||
-rw-r--r-- | 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<DrawSpec> &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<gui::IGUIElement*> &children = getChildren(); + const core::list<gui::IGUIElement*> &children = getChildren(); core::list<gui::IGUIElement*> children_copy; for(core::list<gui::IGUIElement*>::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"<<std::endl; + if(list_to == NULL) + dstream<<"to list doesn't exist"<<std::endl; // Indicates whether source slot completely empties bool source_empties = false; if(list_from && list_to diff --git a/src/guiInventoryMenu.h b/src/guiInventoryMenu.h index acddb5c24..10fb7a425 100644 --- a/src/guiInventoryMenu.h +++ b/src/guiInventoryMenu.h @@ -107,12 +107,16 @@ public: gui::IGUIElement* parent, s32 id, IMenuManager *menumgr, v2s16 menu_size, - core::array<DrawSpec> &init_draw_spec, InventoryContext *c, InventoryManager *invmgr ); ~GUIInventoryMenu(); + void setDrawSpec(core::array<DrawSpec> &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<<DTIME<<"MyEventReceiver: "
<<"Launching inventory"<<std::endl;
+ GUIInventoryMenu *menu =
+ new GUIInventoryMenu(guienv, guiroot, -1,
+ &g_menumgr, v2s16(8,7),
+ g_client->getInventoryContext(),
+ g_client);
+
core::array<GUIInventoryMenu::DrawSpec> 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<GUIInventoryMenu::DrawSpec> 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<GUIInventoryMenu::DrawSpec> 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"<<std::endl;
+
+ GUIFurnaceMenu *menu =
+ new GUIFurnaceMenu(guienv, guiroot, -1,
+ &g_menumgr, nodepos, g_client);
menu->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." <<std::endl; + + // TODO: Backup file; name is in fullpath. } } diff --git a/src/mapblock.cpp b/src/mapblock.cpp index efa760f0e..a4e13320e 100644 --- a/src/mapblock.cpp +++ b/src/mapblock.cpp @@ -1922,7 +1922,9 @@ void MapBlock::serialize(std::ostream &os, u8 version) */ if(version >= 14) { - m_node_metadata.serialize(os); + std::ostringstream oss(std::ios_base::binary); + m_node_metadata.serialize(oss); + os<<serializeString(oss.str()); } } } @@ -2043,7 +2045,17 @@ void MapBlock::deSerialize(std::istream &is, u8 version) */ if(version >= 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"<<std::endl; + } } } diff --git a/src/mapnode.cpp b/src/mapnode.cpp index f498d9e75..8e968c811 100644 --- a/src/mapnode.cpp +++ b/src/mapnode.cpp @@ -321,6 +321,8 @@ void init_mapnode() f->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<s32>(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 <sstream> /* 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<u16, Factory>::Node *n; n = m_types.find(id); if(n == NULL) { - dstream<<"NodeMetadata(): No factory for typeId="<<id<<std::endl; - throw SerializationError("Unknown metadata id"); + // If factory is not found, just return. + dstream<<"WARNING: NodeMetadata: No factory for typeId=" + <<id<<std::endl; + return NULL; } - Factory f = n->getValue(); - NodeMetadata *meta = (*f)(is); - return meta; + // Try to load the metadata. If it fails, just return. + try + { + std::istringstream iss(data, std::ios_base::binary); + + Factory f = n->getValue(); + NodeMetadata *meta = (*f)(iss); + return meta; + } + catch(SerializationError &e) + { + dstream<<"WARNING: NodeMetadata: ignoring SerializationError"<<std::endl; + return NULL; + } } void NodeMetadata::serialize(std::ostream &os) @@ -61,8 +80,10 @@ void NodeMetadata::serialize(std::ostream &os) u8 buf[2]; writeU16(buf, typeId()); os.write((char*)buf, 2); - - serializeBody(os); + + std::ostringstream oss(std::ios_base::binary); + serializeBody(oss); + os<<serializeString(oss.str()); } void NodeMetadata::registerType(u16 id, Factory f) @@ -144,10 +165,56 @@ std::string ChestNodeMetadata::infoText() { return "Chest"; } -/*Inventory* ChestNodeMetadata::getInventory() + +/* + FurnaceNodeMetadata +*/ + +FurnaceNodeMetadata::FurnaceNodeMetadata() { - return m_inventory; -}*/ + NodeMetadata::registerType(typeId(), create); + + m_inventory = new Inventory(); + m_inventory->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"<<std::endl; +} /* NodeMetadatalist @@ -197,17 +264,21 @@ void NodeMetadataList::deSerialize(std::istream &is) p16 -= p.Y * MAP_BLOCKSIZE; p.X += p16; + NodeMetadata *data = NodeMetadata::deSerialize(is); + + if(data == NULL) + continue; + if(m_data.find(p)) { - dstream<<"ERROR: NodeMetadataList::deSerialize(): " + dstream<<"WARNING: NodeMetadataList::deSerialize(): " <<"already set data at position" - <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")" + <<"("<<p.X<<","<<p.Y<<","<<p.Z<<"): Ignoring." <<std::endl; - throw SerializationError("NodeMetadataList::deSerialize()"); + delete data; + continue; } - NodeMetadata *data = NodeMetadata::deSerialize(is); - m_data.insert(p, data); } } diff --git a/src/nodemetadata.h b/src/nodemetadata.h index 8877c2667..e8aa57622 100644 --- a/src/nodemetadata.h +++ b/src/nodemetadata.h @@ -56,6 +56,9 @@ public: virtual void serializeBody(std::ostream &os) = 0; virtual std::string infoText() {return "<todo: remove this text>";} 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<u16, RemoteClient*>::Iterator i = m_clients.getIterator(); |