Is it possible to overwrite ObjectRef:punch?

Post Reply
User avatar
Piezo_
Member
Posts: 219
Joined: Fri Jul 20, 2018 21:36
GitHub: is proprietary I use NotABug
Location: (x,y,z)

Is it possible to overwrite ObjectRef:punch?

by Piezo_ » Post

As in, can the function itself be modified, similar to how one might overwrite minetest.is_protected?
while (true) { suffer(); }

User avatar
Krock
Developer
Posts: 4649
Joined: Thu Oct 03, 2013 07:48
GitHub: SmallJoker
Location: Switzerland
Contact:

Re: Is it possible to overwrite ObjectRef:punch?

by Krock » Post

If you want to modify one specific entity in your world:
This gets very hacky. You'd have to get the ID of the spawned entity and modify the contents of a non-documented table which contains the definitions.

If you want to modify an entity definition (same effect on all entities of the same kind):
1) Depend your mod on the other mod which defines the entity
2) Overwrite the basic definition like this: (untested)

Code: Select all

minetest.registered_entities["somemod:entityname"].on_punch = function(func, args, here)
	-- Do something
end
And in case you want to only extend the function:

Code: Select all

local old_punch = minetest.registered_entities["somemod:entityname"].on_punch
minetest.registered_entities["somemod:entityname"].on_punch = function(func, args, here)
	-- Do something (here maybe?)
	old_punch(func, args, here)
	-- Do something (or afterwards?)
end
Look, I programmed a bug for you. >> Mod Search Engine << - Mods by Krock - DuckDuckGo mod search bang: !mtmod <keyword here>

User avatar
texmex
Member
Posts: 1753
Joined: Mon Jul 11, 2016 21:08
GitHub: tacotexmex
In-game: tacotexmex

Re: Is it possible to overwrite ObjectRef:punch?

by texmex » Post


User avatar
Hybrid Dog
Member
Posts: 2828
Joined: Thu Nov 01, 2012 12:46
GitHub: HybridDog

Re: Is it possible to overwrite ObjectRef:punch?

by Hybrid Dog » Post

If you want to modify the ObjectRef.punch method, you first need to get the ObjectRef table, this can be done by using getmetatable on some object because ObjectRef is used as metatable for objects (note that players are objects, too).
Then you can overwrite it similarly to how one can overwrite minetest.is_protected.

You need an object to get ObjectRef, minetest.register_on_joinplayer takes a function which gives a player object and as long as punching does not happen without a player, the function should be executed early enough.

Here are two examples:
Disallowing teleportation under specific circumstances: https://github.com/HybridDog/nether-pac ... l.lua#L258
Temporarily disallow acceleration and velocity changes when executing an item entity's on_step: https://github.com/minetest-mods/item_d ... t.lua#L163 (I hope that the entity's on_step does not execute some function which indirectly performs object velocity or acceleration changes of some unrelated object, like making sand fall)

‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪

User avatar
Piezo_
Member
Posts: 219
Joined: Fri Jul 20, 2018 21:36
GitHub: is proprietary I use NotABug
Location: (x,y,z)

Re: Is it possible to overwrite ObjectRef:punch?

by Piezo_ » Post

Is the general "player" type present in registered_entities, and would overwriting it affect all players that joined after it had been overwritten?
while (true) { suffer(); }

User avatar
Krock
Developer
Posts: 4649
Joined: Thu Oct 03, 2013 07:48
GitHub: SmallJoker
Location: Switzerland
Contact:

Re: Is it possible to overwrite ObjectRef:punch?

by Krock » Post

Players are not Lua entities, so they are handled differently. To overwrite the "on_punch" function on players, register a callback using register_on_punchplayer.
Look, I programmed a bug for you. >> Mod Search Engine << - Mods by Krock - DuckDuckGo mod search bang: !mtmod <keyword here>

User avatar
Hybrid Dog
Member
Posts: 2828
Joined: Thu Nov 01, 2012 12:46
GitHub: HybridDog

Re: Is it possible to overwrite ObjectRef:punch?

by Hybrid Dog » Post

Every player and object is of type "userdata" and uses the same metatable: ObjectRef
registered_entities is a table of entity definitions, so it does not contain ObjectRef.
If you override the metatable, it affects every object and player, fortunately you can use the is_player method to test if an object or player is a player.

Code: Select all

local metatable_overridden
minetest.register_on_joinplayer(function(player)
	if metatable_overridden then
		return
	end
	metatable_overridden = true
	local mt = getmetatable(player)
	local old_punch = mt.punch
	mt.punch = function(obj, puncher, ...)
		if not obj:is_player() then
			return old_punch(obj, puncher, ...)
		end
		
		-- your code
		
		return old_punch(obj, puncher, ...)
	end
end)

‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪

User avatar
Piezo_
Member
Posts: 219
Joined: Fri Jul 20, 2018 21:36
GitHub: is proprietary I use NotABug
Location: (x,y,z)

Re: Is it possible to overwrite ObjectRef:punch?

by Piezo_ » Post

Well, I'll keep trying, but for some reason, when a player actually left-clicks another player, it seems :punch is not called.

I'll try overwriting :set_hp as well, and we'll see how that goes...

EDIT: It looks like register_on_punchplayer is capable of preventing player damage, I'll be using this for the player part, but I'll probably need to use the hacky overwriting mess for entities.
while (true) { suffer(); }

User avatar
Hybrid Dog
Member
Posts: 2828
Joined: Thu Nov 01, 2012 12:46
GitHub: HybridDog

Re: Is it possible to overwrite ObjectRef:punch?

by Hybrid Dog » Post

Maybe you can use on_punch in the entity definition to adjust damage: https://github.com/minetest/minetest/bl ... .txt#L3319

‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 7 guests