mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 09:15:29 +01:00 
			
		
		
		
	Add IDropAction and related stuff
This commit is contained in:
		@@ -35,6 +35,7 @@ void set_default_settings(Settings *settings)
 | 
			
		||||
	settings->setDefault("keymap_right", "KEY_KEY_D");
 | 
			
		||||
	settings->setDefault("keymap_jump", "KEY_SPACE");
 | 
			
		||||
	settings->setDefault("keymap_sneak", "KEY_LSHIFT");
 | 
			
		||||
	settings->setDefault("keymap_drop", "KEY_KEY_Q");
 | 
			
		||||
	settings->setDefault("keymap_inventory", "KEY_KEY_I");
 | 
			
		||||
	settings->setDefault("keymap_special1", "KEY_KEY_E");
 | 
			
		||||
	settings->setDefault("keymap_chat", "KEY_KEY_T");
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								src/game.cpp
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/game.cpp
									
									
									
									
									
								
							@@ -1215,9 +1215,19 @@ void the_game(
 | 
			
		||||
		input->step(dtime);
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
			Launch menus according to keys
 | 
			
		||||
			Launch menus and trigger stuff according to keys
 | 
			
		||||
		*/
 | 
			
		||||
		if(input->wasKeyDown(getKeySetting("keymap_inventory")))
 | 
			
		||||
		if(input->wasKeyDown(getKeySetting("keymap_drop")))
 | 
			
		||||
		{
 | 
			
		||||
			// drop selected item
 | 
			
		||||
			IDropAction *a = new IDropAction();
 | 
			
		||||
			a->count = 0;
 | 
			
		||||
			a->from_inv = "current_player";
 | 
			
		||||
			a->from_list = "main";
 | 
			
		||||
			a->from_i = g_selected_item;
 | 
			
		||||
			client.inventoryAction(a);
 | 
			
		||||
		}
 | 
			
		||||
		else if(input->wasKeyDown(getKeySetting("keymap_inventory")))
 | 
			
		||||
		{
 | 
			
		||||
			infostream<<"the_game: "
 | 
			
		||||
					<<"Launching inventory"<<std::endl;
 | 
			
		||||
 
 | 
			
		||||
@@ -202,6 +202,21 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
 | 
			
		||||
				wgettext(key_jump.name()));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	offset += v2s32(0, 25);
 | 
			
		||||
	{
 | 
			
		||||
		core::rect < s32 > rect(0, 0, 100, 20);
 | 
			
		||||
		rect += topleft + v2s32(offset.X, offset.Y);
 | 
			
		||||
		Environment->addStaticText(wgettext("Drop"), rect, false, true, this, -1);
 | 
			
		||||
		//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	{
 | 
			
		||||
		core::rect < s32 > rect(0, 0, 100, 30);
 | 
			
		||||
		rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
 | 
			
		||||
		this->dropbtn = Environment->addButton(rect, this, GUI_ID_KEY_DROP_BUTTON,
 | 
			
		||||
				wgettext(key_drop.name()));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	offset += v2s32(0, 25);
 | 
			
		||||
	{
 | 
			
		||||
		core::rect < s32 > rect(0, 0, 100, 20);
 | 
			
		||||
@@ -352,6 +367,7 @@ bool GUIKeyChangeMenu::acceptInput()
 | 
			
		||||
	g_settings->set("keymap_right", key_right.sym());
 | 
			
		||||
	g_settings->set("keymap_jump", key_jump.sym());
 | 
			
		||||
	g_settings->set("keymap_sneak", key_sneak.sym());
 | 
			
		||||
	g_settings->set("keymap_drop", key_drop.sym());
 | 
			
		||||
	g_settings->set("keymap_inventory", key_inventory.sym());
 | 
			
		||||
	g_settings->set("keymap_chat", key_chat.sym());
 | 
			
		||||
	g_settings->set("keymap_cmd", key_cmd.sym());
 | 
			
		||||
@@ -371,6 +387,7 @@ void GUIKeyChangeMenu::init_keys()
 | 
			
		||||
	key_right = getKeySetting("keymap_right");
 | 
			
		||||
	key_jump = getKeySetting("keymap_jump");
 | 
			
		||||
	key_sneak = getKeySetting("keymap_sneak");
 | 
			
		||||
	key_drop = getKeySetting("keymap_drop");
 | 
			
		||||
	key_inventory = getKeySetting("keymap_inventory");
 | 
			
		||||
	key_chat = getKeySetting("keymap_chat");
 | 
			
		||||
	key_cmd = getKeySetting("keymap_cmd");
 | 
			
		||||
@@ -407,6 +424,9 @@ bool GUIKeyChangeMenu::resetMenu()
 | 
			
		||||
		case GUI_ID_KEY_SNEAK_BUTTON:
 | 
			
		||||
			this->sneak->setText(wgettext(key_sneak.name()));
 | 
			
		||||
			break;
 | 
			
		||||
		case GUI_ID_KEY_DROP_BUTTON:
 | 
			
		||||
			this->dropbtn->setText(wgettext(key_drop.name()));
 | 
			
		||||
			break;
 | 
			
		||||
		case GUI_ID_KEY_INVENTORY_BUTTON:
 | 
			
		||||
			this->inventory->setText(
 | 
			
		||||
					wgettext(key_inventory.name()));
 | 
			
		||||
@@ -476,6 +496,11 @@ bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
 | 
			
		||||
			this->sneak->setText(wgettext(kp.name()));
 | 
			
		||||
			this->key_sneak = kp;
 | 
			
		||||
		}
 | 
			
		||||
		else if (activeKey == GUI_ID_KEY_DROP_BUTTON)
 | 
			
		||||
		{
 | 
			
		||||
			this->dropbtn->setText(wgettext(kp.name()));
 | 
			
		||||
			this->key_drop = kp;
 | 
			
		||||
		}
 | 
			
		||||
		else if (activeKey == GUI_ID_KEY_INVENTORY_BUTTON)
 | 
			
		||||
		{
 | 
			
		||||
			this->inventory->setText(wgettext(kp.name()));
 | 
			
		||||
@@ -590,6 +615,11 @@ bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
 | 
			
		||||
				activeKey = event.GUIEvent.Caller->getID();
 | 
			
		||||
				this->jump->setText(wgettext("press Key"));
 | 
			
		||||
				break;
 | 
			
		||||
			case GUI_ID_KEY_DROP_BUTTON:
 | 
			
		||||
				resetMenu();
 | 
			
		||||
				activeKey = event.GUIEvent.Caller->getID();
 | 
			
		||||
				this->dropbtn->setText(wgettext("press Key"));
 | 
			
		||||
				break;
 | 
			
		||||
			case GUI_ID_KEY_CHAT_BUTTON:
 | 
			
		||||
				resetMenu();
 | 
			
		||||
				activeKey = event.GUIEvent.Caller->getID();
 | 
			
		||||
 
 | 
			
		||||
@@ -45,6 +45,7 @@ enum
 | 
			
		||||
	GUI_ID_KEY_CHAT_BUTTON,
 | 
			
		||||
	GUI_ID_KEY_CMD_BUTTON,
 | 
			
		||||
	GUI_ID_KEY_SNEAK_BUTTON,
 | 
			
		||||
	GUI_ID_KEY_DROP_BUTTON,
 | 
			
		||||
	GUI_ID_KEY_INVENTORY_BUTTON,
 | 
			
		||||
	GUI_ID_KEY_DUMP_BUTTON,
 | 
			
		||||
	GUI_ID_KEY_RANGE_BUTTON
 | 
			
		||||
@@ -82,6 +83,7 @@ private:
 | 
			
		||||
	gui::IGUIButton *use;
 | 
			
		||||
	gui::IGUIButton *sneak;
 | 
			
		||||
	gui::IGUIButton *jump;
 | 
			
		||||
	gui::IGUIButton *dropbtn;
 | 
			
		||||
	gui::IGUIButton *inventory;
 | 
			
		||||
	gui::IGUIButton *fly;
 | 
			
		||||
	gui::IGUIButton *fast;
 | 
			
		||||
@@ -98,6 +100,7 @@ private:
 | 
			
		||||
	KeyPress key_use;
 | 
			
		||||
	KeyPress key_sneak;
 | 
			
		||||
	KeyPress key_jump;
 | 
			
		||||
	KeyPress key_drop;
 | 
			
		||||
	KeyPress key_inventory;
 | 
			
		||||
	KeyPress key_fly;
 | 
			
		||||
	KeyPress key_fast;
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
#include "content_mapnode.h"
 | 
			
		||||
#include "content_inventory.h"
 | 
			
		||||
#include "content_sao.h"
 | 
			
		||||
#include "environment.h"
 | 
			
		||||
#include "mapblock.h"
 | 
			
		||||
#include "player.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "nodedef.h"
 | 
			
		||||
@@ -173,7 +175,7 @@ std::string InventoryItem::getItemString() {
 | 
			
		||||
	return os.str();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ServerActiveObject* InventoryItem::createSAO(ServerEnvironment *env, u16 id, v3f pos)
 | 
			
		||||
ServerActiveObject* InventoryItem::createSAO(ServerEnvironment *env, v3f pos)
 | 
			
		||||
{
 | 
			
		||||
	/*
 | 
			
		||||
		Create an ItemSAO
 | 
			
		||||
@@ -307,14 +309,14 @@ video::ITexture * CraftItem::getImage() const
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
ServerActiveObject* CraftItem::createSAO(ServerEnvironment *env, u16 id, v3f pos)
 | 
			
		||||
ServerActiveObject* CraftItem::createSAO(ServerEnvironment *env, v3f pos)
 | 
			
		||||
{
 | 
			
		||||
	// Special cases
 | 
			
		||||
	ServerActiveObject *obj = item_craft_create_object(m_subname, env, pos);
 | 
			
		||||
	if(obj)
 | 
			
		||||
		return obj;
 | 
			
		||||
	// Default
 | 
			
		||||
	return InventoryItem::createSAO(env, id, pos);
 | 
			
		||||
	return InventoryItem::createSAO(env, pos);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u16 CraftItem::getDropCount() const
 | 
			
		||||
@@ -884,6 +886,10 @@ InventoryAction * InventoryAction::deSerialize(std::istream &is)
 | 
			
		||||
	{
 | 
			
		||||
		a = new IMoveAction(is);
 | 
			
		||||
	}
 | 
			
		||||
	else if(type == "Drop")
 | 
			
		||||
	{
 | 
			
		||||
		a = new IDropAction(is);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return a;
 | 
			
		||||
}
 | 
			
		||||
@@ -918,7 +924,8 @@ IMoveAction::IMoveAction(std::istream &is)
 | 
			
		||||
	to_i = stoi(ts);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IMoveAction::apply(InventoryContext *c, InventoryManager *mgr)
 | 
			
		||||
void IMoveAction::apply(InventoryContext *c, InventoryManager *mgr,
 | 
			
		||||
		ServerEnvironment *env)
 | 
			
		||||
{
 | 
			
		||||
	Inventory *inv_from = mgr->getInventory(c, from_inv);
 | 
			
		||||
	Inventory *inv_to = mgr->getInventory(c, to_inv);
 | 
			
		||||
@@ -1022,6 +1029,100 @@ void IMoveAction::apply(InventoryContext *c, InventoryManager *mgr)
 | 
			
		||||
			<<std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
IDropAction::IDropAction(std::istream &is)
 | 
			
		||||
{
 | 
			
		||||
	std::string ts;
 | 
			
		||||
 | 
			
		||||
	std::getline(is, ts, ' ');
 | 
			
		||||
	count = stoi(ts);
 | 
			
		||||
 | 
			
		||||
	std::getline(is, from_inv, ' ');
 | 
			
		||||
 | 
			
		||||
	std::getline(is, from_list, ' ');
 | 
			
		||||
 | 
			
		||||
	std::getline(is, ts, ' ');
 | 
			
		||||
	from_i = stoi(ts);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IDropAction::apply(InventoryContext *c, InventoryManager *mgr,
 | 
			
		||||
		ServerEnvironment *env)
 | 
			
		||||
{
 | 
			
		||||
	Inventory *inv_from = mgr->getInventory(c, from_inv);
 | 
			
		||||
	
 | 
			
		||||
	if(!inv_from){
 | 
			
		||||
		infostream<<"IDropAction::apply(): FAIL: source inventory not found: "
 | 
			
		||||
				<<"context=["<<describeC(c)<<"], from_inv=\""<<from_inv<<"\""<<std::endl;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	InventoryList *list_from = inv_from->getList(from_list);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
		If a list doesn't exist or the source item doesn't exist
 | 
			
		||||
	*/
 | 
			
		||||
	if(!list_from){
 | 
			
		||||
		infostream<<"IDropAction::apply(): FAIL: source list not found: "
 | 
			
		||||
				<<"context=["<<describeC(c)<<"], from_inv=\""<<from_inv<<"\""
 | 
			
		||||
				<<", from_list=\""<<from_list<<"\""<<std::endl;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if(list_from->getItem(from_i) == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		infostream<<"IDropAction::apply(): FAIL: source item not found: "
 | 
			
		||||
				<<"context=["<<describeC(c)<<"], from_inv=\""<<from_inv<<"\""
 | 
			
		||||
				<<", from_list=\""<<from_list<<"\""
 | 
			
		||||
				<<" from_i="<<from_i<<std::endl;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	v3f pos = c->current_player->getPosition();
 | 
			
		||||
	pos.Y += 0.5*BS;
 | 
			
		||||
	v3s16 blockpos = getNodeBlockPos(floatToInt(pos, BS));
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
		Ensure that the block is loaded so that the item
 | 
			
		||||
		can properly be added to the static list too
 | 
			
		||||
	*/
 | 
			
		||||
	MapBlock *block = env->getMap().emergeBlock(blockpos, false);
 | 
			
		||||
	if(block==NULL)
 | 
			
		||||
	{
 | 
			
		||||
		infostream<<"IDropAction::apply(): FAIL: block not found: "
 | 
			
		||||
				<<blockpos.X<<","<<blockpos.Y<<","<<blockpos.Z
 | 
			
		||||
				<<std::endl;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Take item from source list
 | 
			
		||||
	if(count == 0)
 | 
			
		||||
		count = list_from->getItem(from_i)->getDropCount();
 | 
			
		||||
	InventoryItem *item1 = list_from->takeItem(from_i, count);
 | 
			
		||||
 | 
			
		||||
	// Create an active object
 | 
			
		||||
	ServerActiveObject *obj = item1->createSAO(env, pos);
 | 
			
		||||
	if(obj == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		infostream<<"IDropAction::apply(): item resulted in NULL object, "
 | 
			
		||||
			<<"not placing onto map"
 | 
			
		||||
			<<std::endl;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		// Add the object to the environment
 | 
			
		||||
		env->addActiveObject(obj);
 | 
			
		||||
 | 
			
		||||
		infostream<<"Dropped object"<<std::endl;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mgr->inventoryModified(c, from_inv);
 | 
			
		||||
 | 
			
		||||
	infostream<<"IDropAction::apply(): dropped "
 | 
			
		||||
			<<"["<<describeC(c)<<"]"
 | 
			
		||||
			<<" from inv=\""<<from_inv<<"\""
 | 
			
		||||
			<<" list=\""<<from_list<<"\""
 | 
			
		||||
			<<" i="<<from_i
 | 
			
		||||
			<<std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	Craft checking system
 | 
			
		||||
*/
 | 
			
		||||
 
 | 
			
		||||
@@ -62,7 +62,7 @@ public:
 | 
			
		||||
	// Returns the string used for inventory
 | 
			
		||||
	virtual std::string getItemString();
 | 
			
		||||
	// Creates an object from the item, to be placed in the world.
 | 
			
		||||
	virtual ServerActiveObject* createSAO(ServerEnvironment *env, u16 id, v3f pos);
 | 
			
		||||
	virtual ServerActiveObject* createSAO(ServerEnvironment *env, v3f pos);
 | 
			
		||||
	// Gets amount of items that dropping one SAO will decrement
 | 
			
		||||
	virtual u16 getDropCount() const { return getCount(); }
 | 
			
		||||
 | 
			
		||||
@@ -252,7 +252,7 @@ public:
 | 
			
		||||
		return os.str();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ServerActiveObject* createSAO(ServerEnvironment *env, u16 id, v3f pos);
 | 
			
		||||
	ServerActiveObject* createSAO(ServerEnvironment *env, v3f pos);
 | 
			
		||||
	u16 getDropCount() const;
 | 
			
		||||
 | 
			
		||||
	virtual bool addableTo(const InventoryItem *other) const
 | 
			
		||||
@@ -535,6 +535,7 @@ public:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define IACTION_MOVE 0
 | 
			
		||||
#define IACTION_DROP 1
 | 
			
		||||
 | 
			
		||||
struct InventoryAction
 | 
			
		||||
{
 | 
			
		||||
@@ -542,7 +543,8 @@ struct InventoryAction
 | 
			
		||||
	
 | 
			
		||||
	virtual u16 getType() const = 0;
 | 
			
		||||
	virtual void serialize(std::ostream &os) const = 0;
 | 
			
		||||
	virtual void apply(InventoryContext *c, InventoryManager *mgr) = 0;
 | 
			
		||||
	virtual void apply(InventoryContext *c, InventoryManager *mgr,
 | 
			
		||||
			ServerEnvironment *env) = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct IMoveAction : public InventoryAction
 | 
			
		||||
@@ -582,7 +584,42 @@ struct IMoveAction : public InventoryAction
 | 
			
		||||
		os<<to_i;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void apply(InventoryContext *c, InventoryManager *mgr);
 | 
			
		||||
	void apply(InventoryContext *c, InventoryManager *mgr,
 | 
			
		||||
			ServerEnvironment *env);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct IDropAction : public InventoryAction
 | 
			
		||||
{
 | 
			
		||||
	// count=0 means "everything"
 | 
			
		||||
	u16 count;
 | 
			
		||||
	std::string from_inv;
 | 
			
		||||
	std::string from_list;
 | 
			
		||||
	s16 from_i;
 | 
			
		||||
	
 | 
			
		||||
	IDropAction()
 | 
			
		||||
	{
 | 
			
		||||
		count = 0;
 | 
			
		||||
		from_i = -1;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	IDropAction(std::istream &is);
 | 
			
		||||
 | 
			
		||||
	u16 getType() const
 | 
			
		||||
	{
 | 
			
		||||
		return IACTION_DROP;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void serialize(std::ostream &os) const
 | 
			
		||||
	{
 | 
			
		||||
		os<<"Drop ";
 | 
			
		||||
		os<<count<<" ";
 | 
			
		||||
		os<<from_inv<<" ";
 | 
			
		||||
		os<<from_list<<" ";
 | 
			
		||||
		os<<from_i;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void apply(InventoryContext *c, InventoryManager *mgr,
 | 
			
		||||
			ServerEnvironment *env);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 
 | 
			
		||||
@@ -3032,7 +3032,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
 | 
			
		||||
				/*
 | 
			
		||||
					Create the object
 | 
			
		||||
				*/
 | 
			
		||||
				ServerActiveObject *obj = item->createSAO(m_env, 0, pos);
 | 
			
		||||
				ServerActiveObject *obj = item->createSAO(m_env, pos);
 | 
			
		||||
 | 
			
		||||
				if(obj == NULL)
 | 
			
		||||
				{
 | 
			
		||||
@@ -3243,7 +3243,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
 | 
			
		||||
				// Disallow moving items if not allowed to build
 | 
			
		||||
				else if((getPlayerPrivs(player) & PRIV_BUILD) == 0)
 | 
			
		||||
				{
 | 
			
		||||
					return;
 | 
			
		||||
					disable_action = true;
 | 
			
		||||
				}
 | 
			
		||||
				// if it's a locking chest, only allow the owner or server admins to move items
 | 
			
		||||
				else if (ma->from_inv != "current_player" && (getPlayerPrivs(player) & PRIV_SERVER) == 0)
 | 
			
		||||
@@ -3260,7 +3260,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
 | 
			
		||||
						if(meta && meta->typeId() == LEGN(m_nodedef, "CONTENT_LOCKABLE_CHEST")) {
 | 
			
		||||
							LockingChestNodeMetadata *lcm = (LockingChestNodeMetadata*)meta;
 | 
			
		||||
							if (lcm->getOwner() != player->getName())
 | 
			
		||||
								return;
 | 
			
		||||
								disable_action = true;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
@@ -3278,7 +3278,36 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
 | 
			
		||||
						if(meta && meta->typeId() == LEGN(m_nodedef, "CONTENT_LOCKABLE_CHEST")) {
 | 
			
		||||
							LockingChestNodeMetadata *lcm = (LockingChestNodeMetadata*)meta;
 | 
			
		||||
							if (lcm->getOwner() != player->getName())
 | 
			
		||||
								return;
 | 
			
		||||
								disable_action = true;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(a->getType() == IACTION_DROP)
 | 
			
		||||
			{
 | 
			
		||||
				IDropAction *da = (IDropAction*)a;
 | 
			
		||||
				// Disallow dropping items if not allowed to build
 | 
			
		||||
				if((getPlayerPrivs(player) & PRIV_BUILD) == 0)
 | 
			
		||||
				{
 | 
			
		||||
					disable_action = true;
 | 
			
		||||
				}
 | 
			
		||||
				// if it's a locking chest, only allow the owner or server admins to drop items
 | 
			
		||||
				else if (da->from_inv != "current_player" && (getPlayerPrivs(player) & PRIV_SERVER) == 0)
 | 
			
		||||
				{
 | 
			
		||||
					Strfnd fn(da->from_inv);
 | 
			
		||||
					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 && meta->typeId() == LEGN(m_nodedef, "CONTENT_LOCKABLE_CHEST")) {
 | 
			
		||||
							LockingChestNodeMetadata *lcm = (LockingChestNodeMetadata*)meta;
 | 
			
		||||
							if (lcm->getOwner() != player->getName())
 | 
			
		||||
								disable_action = true;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
@@ -3287,9 +3316,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
 | 
			
		||||
			if(disable_action == false)
 | 
			
		||||
			{
 | 
			
		||||
				// Feed action to player inventory
 | 
			
		||||
				a->apply(&c, this);
 | 
			
		||||
				// Eat the action
 | 
			
		||||
				delete a;
 | 
			
		||||
				a->apply(&c, this, m_env);
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
@@ -3297,6 +3324,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
 | 
			
		||||
				UpdateCrafting(player->peer_id);
 | 
			
		||||
				SendInventory(player->peer_id);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Eat the action
 | 
			
		||||
			delete a;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user