InventoryList* InvRef::getlist(lua_State *L, InvRef *ref, const char *listname) { NO_MAP_LOCK_REQUIRED; Inventory *inv = getinv(L, ref); if(!inv) return NULL; return inv->getList(listname); }
bool FurnaceNodeMetadata::nodeRemovalDisabled() { /* Disable removal if furnace is not empty */ InventoryList *list[3] = {m_inventory->getList("src"), m_inventory->getList("dst"), m_inventory->getList("fuel")}; for(int i = 0; i < 3; i++) { if(list[i] == NULL) continue; if(list[i]->getUsedSlots() == 0) continue; return true; } return false; }
void GUIInventoryMenu::drawList(const ListDrawSpec &s) { video::IVideoDriver* driver = Environment->getVideoDriver(); // Get font gui::IGUIFont *font = NULL; gui::IGUISkin* skin = Environment->getSkin(); if (skin) font = skin->getFont(); 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); for(s32 i=0; i<s.geom.X*s.geom.Y; i++) { s32 x = (i%s.geom.X) * spacing.X; s32 y = (i/s.geom.X) * spacing.Y; v2s32 p(x,y); core::rect<s32> rect = imgrect + s.pos + p; InventoryItem *item = NULL; if(ilist) item = ilist->getItem(i); if(m_selected_item != NULL && m_selected_item->listname == s.listname && m_selected_item->i == i) { /*s32 border = imgsize.X/12; driver->draw2DRectangle(video::SColor(255,192,192,192), core::rect<s32>(rect.UpperLeftCorner - v2s32(1,1)*border, rect.LowerRightCorner + v2s32(1,1)*border), NULL); driver->draw2DRectangle(video::SColor(255,0,0,0), core::rect<s32>(rect.UpperLeftCorner - v2s32(1,1)*((border+1)/2), rect.LowerRightCorner + v2s32(1,1)*((border+1)/2)), NULL);*/ s32 border = 2; driver->draw2DRectangle(video::SColor(255,255,0,0), core::rect<s32>(rect.UpperLeftCorner - v2s32(1,1)*border, rect.LowerRightCorner + v2s32(1,1)*border), &AbsoluteClippingRect); } video::SColor bgcolor(255,128,128,128); driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect); if(item) { drawInventoryItem(driver, font, item, rect, &AbsoluteClippingRect); } } }
bool PlayerSAO::setWieldedItem(const ItemStack &item) { Inventory *inv = getInventory(); if (inv) { InventoryList *mlist = inv->getList(getWieldList()); if (mlist) { ItemStack olditem = mlist->getItem(getWieldIndex()); if (olditem.name.empty()) { InventoryList *hlist = inv->getList("hand"); if (hlist) { hlist->changeItem(0, item); return true; } } mlist->changeItem(getWieldIndex(), item); return true; } } return false; }
bool PlayerSAO::setWieldedItem(const ItemStack &item) { Inventory *inv = getInventory(); if (inv) { InventoryList *mlist = inv->getList(getWieldList()); if (mlist) { mlist->changeItem(getWieldIndex(), item); return true; } } return false; }
bool LockingChestNodeMetadata::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; }
bool ServerActiveObject::setWieldedItem(const ItemStack &item) { Inventory *inv = getInventory(); if(inv) { InventoryList *list = inv->getList(getWieldList()); if (list) { list->changeItem(getWieldIndex(), item); setInventoryModified(); return true; } } return false; }
bool FurnaceNodeMetadata::getBurnResult(bool remove, float &burntime) { std::vector<ItemStack> items; InventoryList *fuel_list = m_inventory->getList("fuel"); assert(fuel_list); items.push_back(fuel_list->getItem(0)); CraftInput ci(CRAFT_METHOD_FUEL, 1, items); CraftOutput co; bool found = m_gamedef->getCraftDefManager()->getCraftResult( ci, co, remove, m_gamedef); if(remove) fuel_list->changeItem(0, ci.items[0]); burntime = co.time; return found; }
// set_list(self, listname, list) int InvRef::l_set_list(lua_State *L) { NO_MAP_LOCK_REQUIRED; InvRef *ref = checkobject(L, 1); const char *listname = luaL_checkstring(L, 2); Inventory *inv = getinv(L, ref); if(inv == NULL){ return 0; } InventoryList *list = inv->getList(listname); if(list) read_inventory_list(L, 3, inv, listname, getServer(L), list->getSize()); else read_inventory_list(L, 3, inv, listname, getServer(L)); reportInventoryChange(L, ref); return 0; }
// set_width(self, listname, size) int InvRef::l_set_width(lua_State *L) { NO_MAP_LOCK_REQUIRED; InvRef *ref = checkobject(L, 1); const char *listname = luaL_checkstring(L, 2); int newwidth = luaL_checknumber(L, 3); Inventory *inv = getinv(L, ref); if(inv == NULL){ return 0; } InventoryList *list = inv->getList(listname); if(list){ list->setWidth(newwidth); } else { return 0; } reportInventoryChange(L, ref); return 0; }
bool FurnaceNodeMetadata::getCookResult(bool remove, std::string &cookresult, float &cooktime) { std::vector<ItemStack> items; InventoryList *src_list = m_inventory->getList("src"); assert(src_list); items.push_back(src_list->getItem(0)); CraftInput ci(CRAFT_METHOD_COOKING, 1, items); CraftOutput co; bool found = m_gamedef->getCraftDefManager()->getCraftResult( ci, co, remove, m_gamedef); if(remove) src_list->changeItem(0, ci.items[0]); cookresult = co.item; cooktime = co.time; return found; }
// set_size(self, listname, size) int InvRef::l_set_size(lua_State *L) { NO_MAP_LOCK_REQUIRED; InvRef *ref = checkobject(L, 1); const char *listname = luaL_checkstring(L, 2); int newsize = luaL_checknumber(L, 3); if (newsize < 0) { lua_pushboolean(L, false); return 1; } Inventory *inv = getinv(L, ref); if(inv == NULL){ lua_pushboolean(L, false); return 1; } if(newsize == 0){ inv->deleteList(listname); reportInventoryChange(L, ref); lua_pushboolean(L, true); return 1; } InventoryList *list = inv->getList(listname); if(list){ list->setSize(newsize); } else { list = inv->addList(listname, newsize); if (!list) { lua_pushboolean(L, false); return 1; } } reportInventoryChange(L, ref); lua_pushboolean(L, true); return 1; }
// set_lists(self, lists) int InvRef::l_set_lists(lua_State *L) { NO_MAP_LOCK_REQUIRED; InvRef *ref = checkobject(L, 1); Inventory *inv = getinv(L, ref); if (!inv) { return 0; } lua_pushnil(L); while (lua_next(L, 2)) { const char* listname = lua_tostring(L, -2); InventoryList *list = inv->getList(listname); if (list) { read_inventory_list(L, -1, inv, listname, getServer(L), list->getSize()); } else { read_inventory_list(L, -1, inv, listname, getServer(L)); } lua_pop(L, 1); } return 0; }
void GUIFormSpecMenu::drawSelectedItem() { if(!m_selected_item) return; video::IVideoDriver* driver = Environment->getVideoDriver(); // Get font gui::IGUIFont *font = NULL; gui::IGUISkin* skin = Environment->getSkin(); if (skin) font = skin->getFont(); Inventory *inv = m_invmgr->getInventory(m_selected_item->inventoryloc); assert(inv); InventoryList *list = inv->getList(m_selected_item->listname); assert(list); ItemStack stack = list->getItem(m_selected_item->i); stack.count = m_selected_amount; core::rect<s32> imgrect(0,0,imgsize.X,imgsize.Y); core::rect<s32> rect = imgrect + (m_pointer - imgrect.getCenter()); drawItemStack(driver, font, stack, rect, NULL, m_gamedef); }
bool RollbackAction::applyRevert(Map *map, InventoryManager *imgr, IGameDef *gamedef) const { try { switch (type) { case TYPE_NOTHING: return true; case TYPE_SET_NODE: { INodeDefManager *ndef = gamedef->ndef(); // Make sure position is loaded from disk map->emergeBlock(getContainerPos(p, MAP_BLOCKSIZE), false); // Check current node MapNode current_node = map->getNodeNoEx(p); std::string current_name = ndef->get(current_node).name; // If current node not the new node, it's bad if (current_name != n_new.name) { return false; } // Create rollback node MapNode n(ndef, n_old.name, n_old.param1, n_old.param2); // Set rollback node try { if (!map->addNodeWithEvent(p, n)) { infostream << "RollbackAction::applyRevert(): " << "AddNodeWithEvent failed at " << PP(p) << " for " << n_old.name << std::endl; return false; } if (n_old.meta.empty()) { map->removeNodeMetadata(p); } else { NodeMetadata *meta = map->getNodeMetadata(p); if (!meta) { meta = new NodeMetadata(gamedef); if (!map->setNodeMetadata(p, meta)) { delete meta; infostream << "RollbackAction::applyRevert(): " << "setNodeMetadata failed at " << PP(p) << " for " << n_old.name << std::endl; return false; } } std::istringstream is(n_old.meta, std::ios::binary); meta->deSerialize(is); } // Inform other things that the meta data has changed v3s16 blockpos = getContainerPos(p, MAP_BLOCKSIZE); MapEditEvent event; event.type = MEET_BLOCK_NODE_METADATA_CHANGED; event.p = blockpos; map->dispatchEvent(&event); // Set the block to be saved MapBlock *block = map->getBlockNoCreateNoEx(blockpos); if (block) { block->raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_REPORT_META_CHANGE); } } catch (InvalidPositionException &e) { infostream << "RollbackAction::applyRevert(): " << "InvalidPositionException: " << e.what() << std::endl; return false; } // Success return true; } case TYPE_MODIFY_INVENTORY_STACK: { InventoryLocation loc; loc.deSerialize(inventory_location); std::string real_name = gamedef->idef()->getAlias(inventory_stack.name); Inventory *inv = imgr->getInventory(loc); if (!inv) { infostream << "RollbackAction::applyRevert(): Could not get " "inventory at " << inventory_location << std::endl; return false; } InventoryList *list = inv->getList(inventory_list); if (!list) { infostream << "RollbackAction::applyRevert(): Could not get " "inventory list \"" << inventory_list << "\" in " << inventory_location << std::endl; return false; } if (list->getSize() <= inventory_index) { infostream << "RollbackAction::applyRevert(): List index " << inventory_index << " too large in " << "inventory list \"" << inventory_list << "\" in " << inventory_location << std::endl; } // If item was added, take away item, otherwise add removed item if (inventory_add) { // Silently ignore different current item if (list->getItem(inventory_index).name != real_name) return false; list->takeItem(inventory_index, inventory_stack.count); } else { list->addItem(inventory_index, inventory_stack); } // Inventory was modified; send to clients imgr->setInventoryModified(loc); return true; } default: errorstream << "RollbackAction::applyRevert(): type not handled" << std::endl; return false; } } catch(SerializationError &e) { errorstream << "RollbackAction::applyRevert(): n_old.name=" << n_old.name << ", SerializationError: " << e.what() << std::endl; } return false; }
bool GUIInventoryMenu::OnEvent(const SEvent& event) { if(event.EventType==EET_KEY_INPUT_EVENT) { KeyPress kp(event.KeyInput); if (event.KeyInput.PressedDown && (kp == EscapeKey || kp == getKeySetting("keymap_inventory"))) { quitMenu(); return true; } } if(event.EventType==EET_MOUSE_INPUT_EVENT) { char amount = -1; if(event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) amount = 0; else if(event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN) amount = 1; else if(event.MouseInput.Event == EMIE_MMOUSE_PRESSED_DOWN) amount = 10; if(amount >= 0) { v2s32 p(event.MouseInput.X, event.MouseInput.Y); //infostream<<"Mouse down at p=("<<p.X<<","<<p.Y<<")"<<std::endl; ItemSpec s = getItemAtPos(p); if(s.isValid()) { infostream<<"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 = inv_from->getList(m_selected_item->listname); InventoryList *list_to = inv_to->getList(s.listname); if(list_from == NULL) infostream<<"from list doesn't exist"<<std::endl; if(list_to == NULL) infostream<<"to list doesn't exist"<<std::endl; // Indicates whether source slot completely empties bool source_empties = false; if(list_from && list_to && list_from->getItem(m_selected_item->i) != NULL) { infostream<<"Handing IACTION_MOVE to manager"<<std::endl; IMoveAction *a = new IMoveAction(); a->count = amount; a->from_inv = m_selected_item->inventoryname; a->from_list = m_selected_item->listname; a->from_i = m_selected_item->i; a->to_inv = s.inventoryname; a->to_list = s.listname; a->to_i = s.i; //ispec.actions->push_back(a); m_invmgr->inventoryAction(a); if(list_from->getItem(m_selected_item->i)->getCount()==1) source_empties = true; } // Remove selection if target was left-clicked or source // slot was emptied if(amount == 0 || source_empties) { delete m_selected_item; m_selected_item = NULL; } } else { /* Select if non-NULL */ 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); } } } else { if(m_selected_item) { delete m_selected_item; m_selected_item = NULL; } } } } if(event.EventType==EET_GUI_EVENT) { if(event.GUIEvent.EventType==gui::EGET_ELEMENT_FOCUS_LOST && isVisible()) { if(!canTakeFocus(event.GUIEvent.Element)) { infostream<<"GUIInventoryMenu: Not allowing focus change." <<std::endl; // Returning true disables focus change return true; } } if(event.GUIEvent.EventType==gui::EGET_BUTTON_CLICKED) { /*switch(event.GUIEvent.Caller->getID()) { case 256: // continue setVisible(false); break; case 257: // exit dev->closeDevice(); break; }*/ } } return Parent ? Parent->OnEvent(event) : false; }
bool FurnaceNodeMetadata::step(float dtime) { if(dtime > 60.0) infostream<<"Furnace stepping a long time ("<<dtime<<")"<<std::endl; InventoryList *dst_list = m_inventory->getList("dst"); assert(dst_list); // Update at a fixed frequency const float interval = 2.0; m_step_accumulator += dtime; bool changed = false; while(m_step_accumulator > interval) { m_step_accumulator -= interval; dtime = interval; //infostream<<"Furnace step dtime="<<dtime<<std::endl; bool changed_this_loop = false; // Check // 1. if the source item is cookable // 2. if there is room for the cooked item std::string cookresult; float cooktime; bool cookable = getCookResult(false, cookresult, cooktime); ItemStack cookresult_item; bool room_available = false; if(cookable) { cookresult_item.deSerialize(cookresult, m_gamedef->idef()); room_available = dst_list->roomForItem(cookresult_item); } // Step fuel time bool burning = (m_fuel_time < m_fuel_totaltime); if(burning) { changed_this_loop = true; m_fuel_time += dtime; } std::string infotext; if(room_available) { float burntime; if(burning) { changed_this_loop = true; m_src_time += dtime; m_src_totaltime = cooktime; infotext = "Furnace is cooking"; } else if(getBurnResult(true, burntime)) { // Fuel inserted changed_this_loop = true; m_fuel_time = 0; m_fuel_totaltime = burntime; //m_src_time += dtime; //m_src_totaltime = cooktime; infotext = "Furnace is cooking"; } else { m_src_time = 0; m_src_totaltime = 0; infotext = "Furnace is out of fuel"; } if(m_src_totaltime > 0.001 && m_src_time >= m_src_totaltime) { // One item fully cooked changed_this_loop = true; dst_list->addItem(cookresult_item); getCookResult(true, cookresult, cooktime); // decrement source m_src_totaltime = 0; m_src_time = 0; } } else { // Not cookable or no room available m_src_totaltime = 0; m_src_time = 0; if(cookable) infotext = "Furnace is overloaded"; else if(burning) infotext = "Furnace is active"; else { infotext = "Furnace is inactive"; m_fuel_totaltime = 0; m_fuel_time = 0; } } // Do this so it doesn't always show (0%) for weak fuel if(m_fuel_totaltime > 3) { infotext += " ("; infotext += itos(m_fuel_time/m_fuel_totaltime*100); infotext += "%)"; } if(infotext != m_infotext) { m_infotext = infotext; changed_this_loop = true; } if(burning && m_fuel_time >= m_fuel_totaltime) { m_fuel_time = 0; m_fuel_totaltime = 0; } if(changed_this_loop) { changed = true; } else { m_step_accumulator = 0; break; } } return changed; }
void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase) { video::IVideoDriver* driver = Environment->getVideoDriver(); // Get font gui::IGUIFont *font = NULL; gui::IGUISkin* skin = Environment->getSkin(); if (skin) font = skin->getFont(); Inventory *inv = m_invmgr->getInventory(s.inventoryloc); if(!inv){ infostream<<"GUIFormSpecMenu::drawList(): WARNING: " <<"The inventory location " <<"\""<<s.inventoryloc.dump()<<"\" doesn't exist" <<std::endl; return; } InventoryList *ilist = inv->getList(s.listname); if(!ilist){ infostream<<"GUIFormSpecMenu::drawList(): WARNING: " <<"The inventory list \""<<s.listname<<"\" @ \"" <<s.inventoryloc.dump()<<"\" doesn't exist" <<std::endl; return; } core::rect<s32> imgrect(0,0,imgsize.X,imgsize.Y); for(s32 i=0; i<s.geom.X*s.geom.Y; i++) { u32 item_i = i + s.start_item_i; if(item_i >= ilist->getSize()) break; s32 x = (i%s.geom.X) * spacing.X; s32 y = (i/s.geom.X) * spacing.Y; v2s32 p(x,y); core::rect<s32> rect = imgrect + s.pos + p; ItemStack item; if(ilist) item = ilist->getItem(item_i); bool selected = m_selected_item && m_invmgr->getInventory(m_selected_item->inventoryloc) == inv && m_selected_item->listname == s.listname && m_selected_item->i == i; bool hovering = rect.isPointInside(m_pointer); if(phase == 0) { if(hovering && m_selected_item) { video::SColor bgcolor(255,192,192,192); driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect); } else { video::SColor bgcolor(255,128,128,128); driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect); } } if(phase == 1) { // Draw item stack if(selected) { item.takeItem(m_selected_amount); } if(!item.empty()) { drawItemStack(driver, font, item, rect, &AbsoluteClippingRect, m_gamedef); } // Draw tooltip std::string tooltip_text = ""; if(hovering && !m_selected_item) tooltip_text = item.getDefinition(m_gamedef->idef()).description; if(tooltip_text != "") { m_tooltip_element->setVisible(true); this->bringToFront(m_tooltip_element); m_tooltip_element->setText(narrow_to_wide(tooltip_text).c_str()); s32 tooltip_x = m_pointer.X + 15; s32 tooltip_y = m_pointer.Y + 15; s32 tooltip_width = m_tooltip_element->getTextWidth() + 15; s32 tooltip_height = m_tooltip_element->getTextHeight() + 5; m_tooltip_element->setRelativePosition(core::rect<s32>( core::position2d<s32>(tooltip_x, tooltip_y), core::dimension2d<s32>(tooltip_width, tooltip_height))); } } } }
void GUIFormSpecMenu::updateSelectedItem() { // WARNING: BLACK MAGIC // See if there is a stack suited for our current guess. // If such stack does not exist, clear the guess. if(m_selected_content_guess.name != "") { bool found = false; for(u32 i=0; i<m_inventorylists.size() && !found; i++){ const ListDrawSpec &s = m_inventorylists[i]; Inventory *inv = m_invmgr->getInventory(s.inventoryloc); if(!inv) continue; InventoryList *list = inv->getList(s.listname); if(!list) continue; for(s32 i=0; i<s.geom.X*s.geom.Y && !found; i++){ u32 item_i = i + s.start_item_i; if(item_i >= list->getSize()) continue; ItemStack stack = list->getItem(item_i); if(stack.name == m_selected_content_guess.name && stack.count == m_selected_content_guess.count){ found = true; if(m_selected_item){ // If guessed stack is already selected, all is fine if(m_selected_item->inventoryloc == s.inventoryloc && m_selected_item->listname == s.listname && m_selected_item->i == (s32)item_i && m_selected_amount == stack.count){ break; } delete m_selected_item; m_selected_item = NULL; } infostream<<"Client: Changing selected content guess to " <<s.inventoryloc.dump()<<" "<<s.listname <<" "<<item_i<<std::endl; m_selected_item = new ItemSpec(s.inventoryloc, s.listname, item_i); m_selected_amount = stack.count; break; } } } if(!found){ infostream<<"Client: Discarding selected content guess: " <<m_selected_content_guess.getItemString()<<std::endl; m_selected_content_guess.name = ""; } } // If the selected stack has become empty for some reason, deselect it. // If the selected stack has become smaller, adjust m_selected_amount. if(m_selected_item) { bool selection_valid = false; if(m_selected_item->isValid()) { Inventory *inv = m_invmgr->getInventory(m_selected_item->inventoryloc); if(inv) { InventoryList *list = inv->getList(m_selected_item->listname); if(list && (u32) m_selected_item->i < list->getSize()) { ItemStack stack = list->getItem(m_selected_item->i); if(m_selected_amount > stack.count) m_selected_amount = stack.count; if(!stack.empty()) selection_valid = true; } } } if(!selection_valid) { delete m_selected_item; m_selected_item = NULL; m_selected_amount = 0; m_selected_dragging = false; } } // If craftresult is nonempty and nothing else is selected, select it now. if(!m_selected_item) { for(u32 i=0; i<m_inventorylists.size(); i++) { const ListDrawSpec &s = m_inventorylists[i]; if(s.listname == "craftpreview") { Inventory *inv = m_invmgr->getInventory(s.inventoryloc); InventoryList *list = inv->getList("craftresult"); if(list && list->getSize() >= 1 && !list->getItem(0).empty()) { m_selected_item = new ItemSpec; m_selected_item->inventoryloc = s.inventoryloc; m_selected_item->listname = "craftresult"; m_selected_item->i = 0; m_selected_amount = 0; m_selected_dragging = false; break; } } } } // If craftresult is selected, keep the whole stack selected if(m_selected_item && m_selected_item->listname == "craftresult") { Inventory *inv = m_invmgr->getInventory(m_selected_item->inventoryloc); assert(inv); InventoryList *list = inv->getList(m_selected_item->listname); assert(list); m_selected_amount = list->getItem(m_selected_item->i).count; } }
// Returns true if node timer must be set static bool content_nodemeta_deserialize_legacy_body( std::istream &is, s16 id, NodeMetadata *meta) { meta->clear(); if(id == NODEMETA_GENERIC) // GenericNodeMetadata (0.4-dev) { meta->getInventory()->deSerialize(is); deSerializeLongString(is); // m_text deSerializeString(is); // m_owner meta->setString("infotext",deSerializeString(is)); meta->setString("formspec",deSerializeString(is)); readU8(is); // m_allow_text_input readU8(is); // m_allow_removal readU8(is); // m_enforce_owner int num_vars = readU32(is); for(int i=0; i<num_vars; i++){ std::string name = deSerializeString(is); std::string var = deSerializeLongString(is); meta->setString(name, var); } return false; } else if(id == NODEMETA_SIGN) // SignNodeMetadata { meta->setString("text", deSerializeString(is)); //meta->setString("infotext","\"${text}\""); meta->setString("infotext", std::string("\"") + meta->getString("text") + "\""); meta->setString("formspec","field[text;;${text}]"); return false; } else if(id == NODEMETA_CHEST) // ChestNodeMetadata { meta->getInventory()->deSerialize(is); // Rename inventory list "0" to "main" Inventory *inv = meta->getInventory(); if(!inv->getList("main") && inv->getList("0")){ inv->getList("0")->setName("main"); } assert(inv->getList("main") && !inv->getList("0")); meta->setString("formspec","size[8,9]" "list[current_name;main;0,0;8,4;]" "list[current_player;main;0,5;8,4;]"); return false; } else if(id == NODEMETA_LOCKABLE_CHEST) // LockingChestNodeMetadata { meta->setString("owner", deSerializeString(is)); meta->getInventory()->deSerialize(is); // Rename inventory list "0" to "main" Inventory *inv = meta->getInventory(); if(!inv->getList("main") && inv->getList("0")){ inv->getList("0")->setName("main"); } assert(inv->getList("main") && !inv->getList("0")); meta->setString("formspec","size[8,9]" "list[current_name;main;0,0;8,4;]" "list[current_player;main;0,5;8,4;]"); return false; } else if(id == NODEMETA_FURNACE) // FurnaceNodeMetadata { meta->getInventory()->deSerialize(is); int temp = 0; is>>temp; meta->setString("fuel_totaltime", ftos((float)temp/10)); temp = 0; is>>temp; meta->setString("fuel_time", ftos((float)temp/10)); temp = 0; is>>temp; //meta->setString("src_totaltime", ftos((float)temp/10)); temp = 0; is>>temp; meta->setString("src_time", ftos((float)temp/10)); meta->setString("formspec","size[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;]"); return true; }