Esempio n. 1
0
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);
}
Esempio n. 2
0
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);
		}

	}
}
Esempio n. 4
0
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
// 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;
}
Esempio n. 10
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;
}
Esempio n. 11
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;
}
Esempio n. 12
0
// 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;
}
Esempio n. 13
0
// 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);
}
Esempio n. 15
0
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;
}
Esempio n. 17
0
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;
	}
}
Esempio n. 20
0
// 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;
	}