diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client.cpp | 41 | ||||
-rw-r--r-- | src/client.h | 9 | ||||
-rw-r--r-- | src/guiInventoryMenu.cpp | 114 | ||||
-rw-r--r-- | src/guiInventoryMenu.h | 62 | ||||
-rw-r--r-- | src/inventory.cpp | 103 | ||||
-rw-r--r-- | src/inventory.h | 59 | ||||
-rw-r--r-- | src/main.cpp | 81 | ||||
-rw-r--r-- | src/nodemetadata.cpp | 21 | ||||
-rw-r--r-- | src/nodemetadata.h | 8 | ||||
-rw-r--r-- | src/server.cpp | 158 | ||||
-rw-r--r-- | src/server.h | 10 |
11 files changed, 519 insertions, 147 deletions
diff --git a/src/client.cpp b/src/client.cpp index 2fb14cb68..ae0e027c2 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -106,6 +106,9 @@ Client::Client( player->updateName(playername); m_env.addPlayer(player); + + // Initialize player in the inventory context + m_inventory_context.current_player = player; } } @@ -1862,6 +1865,44 @@ void Client::getLocalInventory(Inventory &dst) dst = player->inventory; } +InventoryContext *Client::getInventoryContext() +{ + return &m_inventory_context; +} + +Inventory* Client::getInventory(InventoryContext *c, std::string id) +{ + if(id == "current_player") + { + assert(c->current_player); + return &(c->current_player->inventory); + } + + Strfnd fn(id); + std::string id0 = fn.next(":"); + + if(id0 == "nodemeta") + { + v3s16 p; + p.X = stoi(fn.next(",")); + p.Y = stoi(fn.next(",")); + p.Z = stoi(fn.next(",")); + NodeMetadata* meta = getNodeMetadata(p); + if(meta) + return meta->getInventory(); + dstream<<"nodemeta at ("<<p.X<<","<<p.Y<<","<<p.Z<<"): " + <<"no metadata found"<<std::endl; + return NULL; + } + + dstream<<__FUNCTION_NAME<<": unknown id "<<id<<std::endl; + return NULL; +} +void Client::inventoryAction(InventoryAction *a) +{ + sendInventoryAction(a); +} + MapBlockObject * Client::getSelectedObject( f32 max_d, v3f from_pos_f_on_map, diff --git a/src/client.h b/src/client.h index fdb98d28d..611116d45 100644 --- a/src/client.h +++ b/src/client.h @@ -224,7 +224,7 @@ struct IncomingPacket }; #endif -class Client : public con::PeerHandler +class Client : public con::PeerHandler, public InventoryManager { public: /* @@ -303,6 +303,11 @@ public: // Copies the inventory of the local player to parameter void getLocalInventory(Inventory &dst); + InventoryContext *getInventoryContext(); + + Inventory* getInventory(InventoryContext *c, std::string id); + void inventoryAction(InventoryAction *a); + // Gets closest object pointed by the shootline // Returns NULL if not found MapBlockObject * getSelectedObject( @@ -438,6 +443,8 @@ private: // The seed returned by the server in TOCLIENT_INIT is stored here u64 m_map_seed; + + InventoryContext m_inventory_context; }; #endif // !SERVER diff --git a/src/guiInventoryMenu.cpp b/src/guiInventoryMenu.cpp index ef795a5f4..2d20b24aa 100644 --- a/src/guiInventoryMenu.cpp +++ b/src/guiInventoryMenu.cpp @@ -78,18 +78,19 @@ void drawInventoryItem(video::IVideoDriver *driver, GUIInventoryMenu::GUIInventoryMenu(gui::IGUIEnvironment* env, gui::IGUIElement* parent, s32 id, - Inventory *inventory, - Queue<InventoryAction*> *actions, - IMenuManager *menumgr): - GUIModalMenu(env, parent, id, menumgr) + 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_inventory = inventory; m_selected_item = NULL; - m_actions = actions; - - /*m_selected_item = new ItemSpec; - m_selected_item->listname = "main"; - m_selected_item->i = 3;*/ } GUIInventoryMenu::~GUIInventoryMenu() @@ -102,6 +103,19 @@ GUIInventoryMenu::~GUIInventoryMenu() void GUIInventoryMenu::removeChildren() { + /*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++) + { + children_copy.push_back(*i); + } + for(core::list<gui::IGUIElement*>::Iterator + i = children_copy.begin(); + i != children_copy.end(); i++) + { + (*i)->remove(); + }*/ { gui::IGUIElement *e = getElementFromId(256); if(e != NULL) @@ -114,15 +128,19 @@ void GUIInventoryMenu::regenerateGui(v2u32 screensize) // Remove children removeChildren(); - padding = v2s32(24,24); + /*padding = v2s32(24,24); spacing = v2s32(60,56); - imgsize = v2s32(48,48); + imgsize = v2s32(48,48);*/ + + padding = v2s32(screensize.X/48, screensize.X/48); + spacing = v2s32(screensize.X/16, screensize.X/17); + imgsize = v2s32(screensize.X/20, screensize.X/20); s32 helptext_h = 15; v2s32 size( - padding.X*2+spacing.X*(8-1)+imgsize.X, - padding.Y*2+spacing.Y*(7-1)+imgsize.Y + helptext_h + padding.X*2+spacing.X*(m_menu_size.X-1)+imgsize.X, + padding.Y*2+spacing.Y*(m_menu_size.Y-1)+imgsize.Y + helptext_h ); core::rect<s32> rect( @@ -137,13 +155,27 @@ void GUIInventoryMenu::regenerateGui(v2u32 screensize) v2s32 basepos = getBasePos(); - m_draw_positions.clear(); - m_draw_positions.push_back(ListDrawSpec("main", + m_draw_spec.clear(); + for(u16 i=0; i<m_init_draw_spec.size(); i++) + { + DrawSpec &s = m_init_draw_spec[i]; + if(s.type == "list") + { + m_draw_spec.push_back(ListDrawSpec(s.name, s.subname, + basepos + v2s32(spacing.X*s.pos.X, spacing.Y*s.pos.Y), + s.geom)); + } + } + + /* + m_draw_spec.clear(); + m_draw_spec.push_back(ListDrawSpec("main", basepos + v2s32(spacing.X*0, spacing.Y*3), v2s32(8, 4))); - m_draw_positions.push_back(ListDrawSpec("craft", + m_draw_spec.push_back(ListDrawSpec("craft", basepos + v2s32(spacing.X*3, spacing.Y*0), v2s32(3, 3))); - m_draw_positions.push_back(ListDrawSpec("craftresult", + m_draw_spec.push_back(ListDrawSpec("craftresult", basepos + v2s32(spacing.X*7, spacing.Y*1), v2s32(1, 1))); + */ // Add children { @@ -160,9 +192,9 @@ GUIInventoryMenu::ItemSpec GUIInventoryMenu::getItemAtPos(v2s32 p) const { core::rect<s32> imgrect(0,0,imgsize.X,imgsize.Y); - for(u32 i=0; i<m_draw_positions.size(); i++) + for(u32 i=0; i<m_draw_spec.size(); i++) { - const ListDrawSpec &s = m_draw_positions[i]; + const ListDrawSpec &s = m_draw_spec[i]; for(s32 i=0; i<s.geom.X*s.geom.Y; i++) { @@ -172,15 +204,14 @@ GUIInventoryMenu::ItemSpec GUIInventoryMenu::getItemAtPos(v2s32 p) const core::rect<s32> rect = imgrect + s.pos + p0; if(rect.isPointInside(p)) { - return ItemSpec(s.listname, i); + return ItemSpec(s.inventoryname, s.listname, i); } } } - return ItemSpec("", -1); + return ItemSpec("", "", -1); } -//void GUIInventoryMenu::drawList(const std::string &name, v2s32 pos, v2s32 geom) void GUIInventoryMenu::drawList(const ListDrawSpec &s) { video::IVideoDriver* driver = Environment->getVideoDriver(); @@ -191,7 +222,9 @@ void GUIInventoryMenu::drawList(const ListDrawSpec &s) if (skin) font = skin->getFont(); - InventoryList *ilist = m_inventory->getList(s.listname); + Inventory *inv = m_invmgr->getInventory(m_c, s.inventoryname); + assert(inv); + InventoryList *ilist = inv->getList(s.listname); core::rect<s32> imgrect(0,0,imgsize.X,imgsize.Y); @@ -241,9 +274,9 @@ void GUIInventoryMenu::drawMenu() Draw items */ - for(u32 i=0; i<m_draw_positions.size(); i++) + for(u32 i=0; i<m_draw_spec.size(); i++) { - ListDrawSpec &s = m_draw_positions[i]; + ListDrawSpec &s = m_draw_spec[i]; drawList(s); } @@ -279,26 +312,36 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event) ItemSpec s = getItemAtPos(p); if(s.isValid()) { - //dstream<<"Mouse down on "<<s.listname<<" "<<s.i<<std::endl; + dstream<<"Mouse down on "<<s.inventoryname + <<"/"<<s.listname<<" "<<s.i<<std::endl; if(m_selected_item) { + Inventory *inv_from = m_invmgr->getInventory(m_c, + m_selected_item->inventoryname); + Inventory *inv_to = m_invmgr->getInventory(m_c, + s.inventoryname); + assert(inv_from); + assert(inv_to); InventoryList *list_from = - m_inventory->getList(m_selected_item->listname); + inv_from->getList(m_selected_item->listname); InventoryList *list_to = - m_inventory->getList(s.listname); + inv_to->getList(s.listname); // Indicates whether source slot completely empties bool source_empties = false; if(list_from && list_to && list_from->getItem(m_selected_item->i) != NULL) { - dstream<<"Queueing IACTION_MOVE"<<std::endl; + dstream<<"Handing IACTION_MOVE to manager"<<std::endl; IMoveAction *a = new IMoveAction(); a->count = right ? 1 : 0; - a->from_name = m_selected_item->listname; + a->from_inv = m_selected_item->inventoryname; + a->from_list = m_selected_item->listname; a->from_i = m_selected_item->i; - a->to_name = s.listname; + a->to_inv = s.inventoryname; + a->to_list = s.listname; a->to_i = s.i; - m_actions->push_back(a); + //ispec.actions->push_back(a); + m_invmgr->inventoryAction(a); if(list_from->getItem(m_selected_item->i)->getCount()==1) source_empties = true; @@ -316,7 +359,10 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event) /* Select if non-NULL */ - InventoryList *list = m_inventory->getList(s.listname); + Inventory *inv = m_invmgr->getInventory(m_c, + s.inventoryname); + assert(inv); + InventoryList *list = inv->getList(s.listname); if(list->getItem(s.i) != NULL) { m_selected_item = new ItemSpec(s); diff --git a/src/guiInventoryMenu.h b/src/guiInventoryMenu.h index 45a5e236a..acddb5c24 100644 --- a/src/guiInventoryMenu.h +++ b/src/guiInventoryMenu.h @@ -39,9 +39,12 @@ class GUIInventoryMenu : public GUIModalMenu { i = -1; } - ItemSpec(const std::string &a_name, s32 a_i) + ItemSpec(const std::string &a_inventoryname, + const std::string &a_listname, + s32 a_i) { - listname = a_name; + inventoryname = a_inventoryname; + listname = a_listname; i = a_i; } bool isValid() const @@ -49,6 +52,7 @@ class GUIInventoryMenu : public GUIModalMenu return i != -1; } + std::string inventoryname; std::string listname; s32 i; }; @@ -58,24 +62,55 @@ class GUIInventoryMenu : public GUIModalMenu ListDrawSpec() { } - ListDrawSpec(const std::string &a_name, v2s32 a_pos, v2s32 a_geom) + ListDrawSpec(const std::string &a_inventoryname, + const std::string &a_listname, + v2s32 a_pos, v2s32 a_geom) { - listname = a_name; + inventoryname = a_inventoryname; + listname = a_listname; pos = a_pos; geom = a_geom; } + std::string inventoryname; std::string listname; v2s32 pos; v2s32 geom; }; - public: + struct DrawSpec + { + DrawSpec() + { + } + DrawSpec(const std::string &a_type, + const std::string &a_name, + const std::string &a_subname, + v2s32 a_pos, + v2s32 a_geom) + { + type = a_type; + name = a_name; + subname = a_subname; + pos = a_pos; + geom = a_geom; + } + + std::string type; + std::string name; + std::string subname; + v2s32 pos; + v2s32 geom; + }; + GUIInventoryMenu(gui::IGUIEnvironment* env, gui::IGUIElement* parent, s32 id, - Inventory *inventory, - Queue<InventoryAction*> *actions, - IMenuManager *menumgr); + IMenuManager *menumgr, + v2s16 menu_size, + core::array<DrawSpec> &init_draw_spec, + InventoryContext *c, + InventoryManager *invmgr + ); ~GUIInventoryMenu(); void removeChildren(); @@ -96,16 +131,19 @@ private: return padding + AbsoluteRect.UpperLeftCorner; } + v2s16 m_menu_size; + v2s32 padding; v2s32 spacing; v2s32 imgsize; + + InventoryContext *m_c; + InventoryManager *m_invmgr; - core::array<ListDrawSpec> m_draw_positions; - - Inventory *m_inventory; + core::array<DrawSpec> m_init_draw_spec; + core::array<ListDrawSpec> m_draw_spec; ItemSpec *m_selected_item; - Queue<InventoryAction*> *m_actions; }; #endif diff --git a/src/inventory.cpp b/src/inventory.cpp index c29bb9470..a610a4617 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -96,17 +96,11 @@ InventoryItem* InventoryItem::deSerialize(std::istream &is) #ifndef SERVER video::ITexture * MapBlockObjectItem::getImage() { - //TODO - if(m_inventorystring.substr(0,3) == "Rat") - //return g_device->getVideoDriver()->getTexture(porting::getDataPath("rat.png").c_str()); - //return g_irrlicht->getTexture("rat.png"); - return NULL; + return g_texturesource->getTextureRaw("rat.png"); if(m_inventorystring.substr(0,4) == "Sign") - //return g_device->getVideoDriver()->getTexture(porting::getDataPath("sign.png").c_str()); - //return g_irrlicht->getTexture("sign.png"); - return NULL; + return g_texturesource->getTextureRaw("sign.png"); return NULL; } @@ -608,12 +602,27 @@ InventoryAction * InventoryAction::deSerialize(std::istream &is) return a; } -void IMoveAction::apply(Inventory *inventory) +void IMoveAction::apply(InventoryContext *c, InventoryManager *mgr) { - /*dstream<<"from_name="<<from_name<<" to_name="<<to_name<<std::endl; +#if 1 + + /*dstream<<"from_inv="<<from_inv<<" to_inv="<<to_inv<<std::endl; + dstream<<"from_list="<<from_list<<" to_list="<<to_list<<std::endl; dstream<<"from_i="<<from_i<<" to_i="<<to_i<<std::endl;*/ - InventoryList *list_from = inventory->getList(from_name); - InventoryList *list_to = inventory->getList(to_name); + + Inventory *inv_from = mgr->getInventory(c, from_inv); + Inventory *inv_to = mgr->getInventory(c, to_inv); + + if(!inv_from || !inv_to) + { + dstream<<__FUNCTION_NAME<<": Operation not allowed " + <<"(inventories not found)"<<std::endl; + return; + } + + InventoryList *list_from = inv_from->getList(from_list); + InventoryList *list_to = inv_to->getList(to_list); + /*dstream<<"list_from="<<list_from<<" list_to="<<list_to <<std::endl;*/ /*if(list_from) @@ -625,12 +634,28 @@ void IMoveAction::apply(Inventory *inventory) /* If a list doesn't exist or the source item doesn't exist - or the source and the destination slots are the same */ - if(!list_from || !list_to || list_from->getItem(from_i) == NULL - || (list_from == list_to && from_i == to_i)) + if(!list_from || !list_to) + { + dstream<<__FUNCTION_NAME<<": Operation not allowed " + <<"(a list doesn't exist)" + <<std::endl; + return; + } + if(list_from->getItem(from_i) == NULL) + { + dstream<<__FUNCTION_NAME<<": Operation not allowed " + <<"(the source item doesn't exist)" + <<std::endl; + return; + } + /* + If the source and the destination slots are the same + */ + if(inv_from == inv_to && list_from == list_to && from_i == to_i) { - dstream<<__FUNCTION_NAME<<": Operation not allowed"<<std::endl; + dstream<<__FUNCTION_NAME<<": Operation not allowed " + <<"(source and the destination slots are the same)"<<std::endl; return; } @@ -645,29 +670,33 @@ void IMoveAction::apply(Inventory *inventory) InventoryItem *olditem = item1; item1 = list_to->addItem(to_i, item1); - // If nothing is returned, the item was fully added - if(item1 == NULL) - return; - - // If olditem is returned, nothing was added. - bool nothing_added = (item1 == olditem); - - // If something else is returned, part of the item was left unadded. - // Add the other part back to the source item - list_from->addItem(from_i, item1); - - // If olditem is returned, nothing was added. - // Swap the items - if(nothing_added) + // If something is returned, the item was not fully added + if(item1 != NULL) { - // Take item from source list - item1 = list_from->changeItem(from_i, NULL); - // Adding was not possible, swap the items. - InventoryItem *item2 = list_to->changeItem(to_i, item1); - // Put item from destination list to the source list - list_from->changeItem(from_i, item2); - return; + // If olditem is returned, nothing was added. + bool nothing_added = (item1 == olditem); + + // If something else is returned, part of the item was left unadded. + // Add the other part back to the source item + list_from->addItem(from_i, item1); + + // If olditem is returned, nothing was added. + // Swap the items + if(nothing_added) + { + // Take item from source list + item1 = list_from->changeItem(from_i, NULL); + // Adding was not possible, swap the items. + InventoryItem *item2 = list_to->changeItem(to_i, item1); + // Put item from destination list to the source list + list_from->changeItem(from_i, item2); + } } + + mgr->inventoryModified(c, from_inv); + if(from_inv != to_inv) + mgr->inventoryModified(c, to_inv); +#endif } //END diff --git a/src/inventory.h b/src/inventory.h index 9155eb025..45bc488c5 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -495,6 +495,41 @@ private: core::array<InventoryList*> m_lists; }; +class Player; + +struct InventoryContext +{ + Player *current_player; + + InventoryContext(): + current_player(NULL) + {} +}; + +class InventoryAction; + +class InventoryManager +{ +public: + InventoryManager(){} + virtual ~InventoryManager(){} + + /* + Get a pointer to an inventory specified by id. + id can be: + - "current_player" + - "nodemeta:X,Y,Z" + */ + virtual Inventory* getInventory(InventoryContext *c, std::string id) + {return NULL;} + // Used on the server by InventoryAction::apply + virtual void inventoryModified(InventoryContext *c, std::string id) + {} + // Used on the client + virtual void inventoryAction(InventoryAction *a) + {} +}; + #define IACTION_MOVE 0 struct InventoryAction @@ -503,16 +538,18 @@ struct InventoryAction virtual u16 getType() const = 0; virtual void serialize(std::ostream &os) = 0; - virtual void apply(Inventory *inventory) = 0; + virtual void apply(InventoryContext *c, InventoryManager *mgr) = 0; }; struct IMoveAction : public InventoryAction { // count=0 means "everything" u16 count; - std::string from_name; + std::string from_inv; + std::string from_list; s16 from_i; - std::string to_name; + std::string to_inv; + std::string to_list; s16 to_i; IMoveAction() @@ -528,12 +565,16 @@ struct IMoveAction : public InventoryAction std::getline(is, ts, ' '); count = stoi(ts); - std::getline(is, from_name, ' '); + std::getline(is, from_inv, ' '); + + std::getline(is, from_list, ' '); std::getline(is, ts, ' '); from_i = stoi(ts); - std::getline(is, to_name, ' '); + std::getline(is, to_inv, ' '); + + std::getline(is, to_list, ' '); std::getline(is, ts, ' '); to_i = stoi(ts); @@ -548,13 +589,15 @@ struct IMoveAction : public InventoryAction { os<<"Move "; os<<count<<" "; - os<<from_name<<" "; + os<<from_inv<<" "; + os<<from_list<<" "; os<<from_i<<" "; - os<<to_name<<" "; + os<<to_inv<<" "; + os<<to_list<<" "; os<<to_i; } - void apply(Inventory *inventory); + void apply(InventoryContext *c, InventoryManager *mgr); }; #endif diff --git a/src/main.cpp b/src/main.cpp index 6bcd7f5ac..49246ec89 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -448,6 +448,7 @@ public: MainGameCallback g_gamecallback;
// Inventory actions from the menu are buffered here before sending
+// TODO: Get rid of this
Queue<InventoryAction*> inventory_action_queue;
// This is a copy of the inventory that the client's environment has
Inventory local_inventory;
@@ -621,9 +622,26 @@ public: {
dstream<<DTIME<<"MyEventReceiver: "
<<"Launching inventory"<<std::endl;
- (new GUIInventoryMenu(guienv, guiroot, -1,
- &local_inventory, &inventory_action_queue,
- &g_menumgr))->drop();
+
+ core::array<GUIInventoryMenu::DrawSpec> draw_spec;
+ draw_spec.push_back(GUIInventoryMenu::DrawSpec(
+ "list", "current_player", "main",
+ v2s32(0, 3), v2s32(8, 4)));
+ draw_spec.push_back(GUIInventoryMenu::DrawSpec(
+ "list", "current_player", "craft",
+ v2s32(3, 0), v2s32(3, 3)));
+ draw_spec.push_back(GUIInventoryMenu::DrawSpec(
+ "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->drop();
+
return true;
}
if(event.KeyInput.Key == irr::KEY_KEY_T)
@@ -2950,25 +2968,54 @@ int main(int argc, char *argv[]) {
std::cout<<DTIME<<"Ground right-clicked"<<std::endl;
- if(meta && meta->typeId() == CONTENT_SIGN_WALL)
+ if(meta && meta->typeId() == CONTENT_SIGN_WALL && !random_input)
{
dstream<<"Sign node right-clicked"<<std::endl;
- if(random_input == false)
- {
- // Get a new text for it
+ SignNodeMetadata *signmeta = (SignNodeMetadata*)meta;
+
+ // Get a new text for it
- TextDest *dest = new TextDestSignNode(nodepos, &client);
+ TextDest *dest = new TextDestSignNode(nodepos, &client);
- SignNodeMetadata *signmeta = (SignNodeMetadata*)meta;
-
- std::wstring wtext =
- narrow_to_wide(signmeta->getText());
+ 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;
+
+ core::array<GUIInventoryMenu::DrawSpec> draw_spec;
+
+ 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);
+
+ 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)));
+
+ GUIInventoryMenu *menu =
+ new GUIInventoryMenu(guienv, guiroot, -1,
+ &g_menumgr, v2s16(8,9), draw_spec,
+ g_client->getInventoryContext(),
+ g_client);
+
+ menu->drop();
- (new GUITextInputMenu(guienv, guiroot, -1,
- &g_menumgr, dest,
- wtext))->drop();
- }
}
else
{
@@ -3196,8 +3243,6 @@ int main(int argc, char *argv[]) old_selected_item = g_selected_item;
//std::cout<<"Updating local inventory"<<std::endl;
client.getLocalInventory(local_inventory);
- /*quick_inventory->setSelection(g_selected_item);
- quick_inventory->update();*/
}
/*
diff --git a/src/nodemetadata.cpp b/src/nodemetadata.cpp index fca4e5b84..294db178f 100644 --- a/src/nodemetadata.cpp +++ b/src/nodemetadata.cpp @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "utility.h" #include "mapnode.h" #include "exceptions.h" +#include "inventory.h" /* NodeMetadata @@ -111,6 +112,13 @@ std::string SignNodeMetadata::infoText() ChestNodeMetadata::ChestNodeMetadata() { NodeMetadata::registerType(typeId(), create); + + m_inventory = new Inventory(); + m_inventory->addList("0", 8*4); +} +ChestNodeMetadata::~ChestNodeMetadata() +{ + delete m_inventory; } u16 ChestNodeMetadata::typeId() const { @@ -118,19 +126,28 @@ u16 ChestNodeMetadata::typeId() const } NodeMetadata* ChestNodeMetadata::create(std::istream &is) { - return new ChestNodeMetadata(); + ChestNodeMetadata *d = new ChestNodeMetadata(); + d->m_inventory->deSerialize(is); + return d; } NodeMetadata* ChestNodeMetadata::clone() { - return new ChestNodeMetadata(); + 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"; } +/*Inventory* ChestNodeMetadata::getInventory() +{ + return m_inventory; +}*/ /* NodeMetadatalist diff --git a/src/nodemetadata.h b/src/nodemetadata.h index 21916677e..8877c2667 100644 --- a/src/nodemetadata.h +++ b/src/nodemetadata.h @@ -37,6 +37,8 @@ with this program; if not, write to the Free Software Foundation, Inc., - Text */ +class Inventory; + class NodeMetadata { public: @@ -52,7 +54,8 @@ public: virtual u16 typeId() const = 0; virtual NodeMetadata* clone() = 0; virtual void serializeBody(std::ostream &os) = 0; - virtual std::string infoText() { return "<todo: remove this text>"; } + virtual std::string infoText() {return "<todo: remove this text>";} + virtual Inventory* getInventory() {return NULL;} protected: static void registerType(u16 id, Factory f); @@ -83,14 +86,17 @@ class ChestNodeMetadata : public NodeMetadata { public: ChestNodeMetadata(); + ~ChestNodeMetadata(); virtual u16 typeId() const; static NodeMetadata* create(std::istream &is); virtual NodeMetadata* clone(); virtual void serializeBody(std::ostream &os); virtual std::string infoText(); + virtual Inventory* getInventory() {return m_inventory;} private: + Inventory *m_inventory; }; class NodeMetadataList diff --git a/src/server.cpp b/src/server.cpp index 4f3846cf8..a70c42a35 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2460,6 +2460,10 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) InventoryAction *a = InventoryAction::deSerialize(is); if(a != NULL) { + // Create context + InventoryContext c; + c.current_player = player; + /* Handle craftresult specially if not in creative mode */ @@ -2468,50 +2472,60 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) && g_settings.getBool("creative_mode") == false) { IMoveAction *ma = (IMoveAction*)a; - // Don't allow moving anything to craftresult - if(ma->to_name == "craftresult") - { - // Do nothing - disable_action = true; - } - // When something is removed from craftresult - if(ma->from_name == "craftresult") + if(ma->to_inv == "current_player" && + ma->from_inv == "current_player") { - disable_action = true; - // Remove stuff from craft - InventoryList *clist = player->inventory.getList("craft"); - if(clist) + // Don't allow moving anything to craftresult + if(ma->to_list == "craftresult") { - u16 count = ma->count; - if(count == 0) - count = 1; - clist->decrementMaterials(count); + // Do nothing + disable_action = true; } - // Do action - // Feed action to player inventory - a->apply(&player->inventory); - // Eat it - delete a; - // If something appeared in craftresult, throw it - // in the main list - InventoryList *rlist = player->inventory.getList("craftresult"); - InventoryList *mlist = player->inventory.getList("main"); - if(rlist && mlist && rlist->getUsedSlots() == 1) + // When something is removed from craftresult + if(ma->from_list == "craftresult") { - InventoryItem *item1 = rlist->changeItem(0, NULL); - mlist->addItem(item1); + disable_action = true; + // Remove stuff from craft + InventoryList *clist = player->inventory.getList("craft"); + if(clist) + { + u16 count = ma->count; + if(count == 0) + count = 1; + clist->decrementMaterials(count); + } + // Do action + // Feed action to player inventory + //a->apply(&player->inventory); + a->apply(&c, this); + // Eat it + delete a; + // If something appeared in craftresult, throw it + // in the main list + InventoryList *rlist = player->inventory.getList("craftresult"); + InventoryList *mlist = player->inventory.getList("main"); + if(rlist && mlist && rlist->getUsedSlots() == 1) + { + InventoryItem *item1 = rlist->changeItem(0, NULL); + mlist->addItem(item1); + } } } } + if(disable_action == false) { // Feed action to player inventory - a->apply(&player->inventory); - // Eat it + //a->apply(&player->inventory); + a->apply(&c, this); + // Eat the action delete a; } - // Send inventory - SendInventory(player->peer_id); + else + { + // Send inventory + SendInventory(player->peer_id); + } } else { @@ -2679,6 +2693,63 @@ void Server::onMapEditEvent(MapEditEvent *event) m_unsent_map_edit_queue.push_back(e); } +Inventory* Server::getInventory(InventoryContext *c, std::string id) +{ + if(id == "current_player") + { + assert(c->current_player); + return &(c->current_player->inventory); + } + + Strfnd fn(id); + std::string id0 = fn.next(":"); + + if(id0 == "nodemeta") + { + v3s16 p; + p.X = stoi(fn.next(",")); + p.Y = stoi(fn.next(",")); + p.Z = stoi(fn.next(",")); + NodeMetadata *meta = m_env.getMap().getNodeMetadata(p); + if(meta) + return meta->getInventory(); + dstream<<"nodemeta at ("<<p.X<<","<<p.Y<<","<<p.Z<<"): " + <<"no metadata found"<<std::endl; + return NULL; + } + + dstream<<__FUNCTION_NAME<<": unknown id "<<id<<std::endl; + return NULL; +} +void Server::inventoryModified(InventoryContext *c, std::string id) +{ + if(id == "current_player") + { + assert(c->current_player); + // Send inventory + SendInventory(c->current_player->peer_id); + return; + } + + Strfnd fn(id); + std::string id0 = fn.next(":"); + + if(id0 == "nodemeta") + { + v3s16 p; + p.X = stoi(fn.next(",")); + p.Y = stoi(fn.next(",")); + p.Z = stoi(fn.next(",")); + assert(c->current_player); + RemoteClient *client = getClient(c->current_player->peer_id); + v3s16 blockpos = getNodeBlockPos(p); + client->SetBlockNotSent(blockpos); + return; + } + + dstream<<__FUNCTION_NAME<<": unknown id "<<id<<std::endl; +} + core::list<PlayerInfo> Server::getPlayerInfo() { DSTACK(__FUNCTION_NAME); @@ -3027,7 +3098,8 @@ void Server::SendInventory(u16 peer_id) specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); if(checkItemCombination(items, specs)) { - rlist->addItem(new MapBlockObjectItem("Sign")); + //rlist->addItem(new MapBlockObjectItem("Sign")); + rlist->addItem(new MaterialItem(CONTENT_SIGN_WALL, 1)); found = true; } } @@ -3092,6 +3164,26 @@ void Server::SendInventory(u16 peer_id) found = true; } } + + // Chest1 + if(!found) + { + ItemSpec specs[9]; + specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[3] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[5] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[6] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[7] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[8] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + if(checkItemCombination(items, specs)) + { + rlist->addItem(new MaterialItem(CONTENT_CHEST, 1)); + found = true; + } + } + } } // if creative_mode == false diff --git a/src/server.h b/src/server.h index f997828b2..f1c7b6e01 100644 --- a/src/server.h +++ b/src/server.h @@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "utility.h" #include "porting.h" #include "map.h" +#include "inventory.h" struct QueuedBlockEmerge { @@ -342,7 +343,8 @@ private: u32 m_excess_gotblocks; }; -class Server : public con::PeerHandler, public MapEventReceiver +class Server : public con::PeerHandler, public MapEventReceiver, + public InventoryManager { public: /* @@ -382,6 +384,12 @@ public: */ void onMapEditEvent(MapEditEvent *event); + /* + Shall be called with the environment and the connection locked. + */ + Inventory* getInventory(InventoryContext *c, std::string id); + void inventoryModified(InventoryContext *c, std::string id); + private: // Virtual methods from con::PeerHandler. |