Jump to content

Preventing Equip Slip/Disarm


Recommended Posts

Alright, I've been working on this for a while now and can't figure it out. I'm creating a custom character and one of the perks is that his equipped hand items cannot be knocked out - neither by slipping when wet nor by disarming attacks like Bearger's. From what I can tell, there is no "clean" way to do this, I really hope I'm missing something entirely.

I can hackily make it work by immediately re-equipping the item when the "dropitem" event is fired and keeping track of what item it was so I don't go re-equipping just anything dropped, like so:

inst.lastKnownEquip = nil
inst:ListenForEvent("equip", function(inst, data)
    if data.eslot == EQUIPSLOTS.HANDS then
	inst.lastKnownEquip = data.item
    end
end)
inst:ListenForEvent("dropitem", function(inst, data) 
    if data.item == inst.lastKnownEquip then
    	inst.components.inventory:Equip(data.item)
    end
end)

This actually works, however it also means that any time the player actually wants to drop their hand item, it will continuously re-equip until they equip something different instead. In an effort to prevent that, I also listened in on the "unequip" event to remove the remembered item when it was unequipped by the player:

inst:ListenForEvent("unequip", function(inst, data)
    if data.eslot == EQUIPSLOTS.HANDS and data.item == inst.lastKnownEquip then
	inst.lastKnownEquip = nil
    end
end)

Unfortunately, for some reason, that brings the character back to default functionality. Despite the fact that Bearger's disarm code does not fire the "unequip" event ANYWHERE, he can still knock things out of my hands. It makes no sense to me, again I hope I am overlooking something very simple.

Any help is appreciated.

Link to comment
Share on other sites

This is the Bearger's function that makes you drop stuff

local function OnHitOther(inst, data)
	local other = data.target
	if other and other.components.inventory then
		local item = other.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
		if not item then return end
		other.components.inventory:DropItem(item)
		LaunchItem(inst, data.target, item)
	end
end

Tied to him via

inst:ListenForEvent("onhitother", OnHitOther)

So what I'm going to do is go to the table that holds functions that respond to that event and edit them.

OnHitOther is the only function that is there.

AddPrefabPostInit("bearger", function(inst)
	if not GLOBAL.TheWorld.ismastersim then
		return
	end
	local listeners = inst.event_listeners.onhitother
	local listener_fns = listeners[inst]
	local old = listener_fns[1]
	listener_fns[1] = function(inst, data)
		local other = data.target
		if other and other.prefab == "wathgrithr" then
			return
		end
		return old(inst, data)
	end
end)

Use this, change Wigfrid for your character.

 

 

Regarding dropping wet tools, that is spread across player_common.

We are going to use the same trick as above.

Put in master_postinit:

	-- Removing OnWork with DropWetTool
	local listeners1 = inst.event_listeners.working
	local listener_fns1 = listeners1[inst]
	local old1 = listener_fns1[1]
	inst:RemoveEventCallback("working", old1)

	-- Removing data.weapon, negating access to DropWetTool
	local listeners2 = inst.event_listeners.onattackother
	local listener_fns2 = listeners2[inst]
	local old2 = listener_fns2[1]
	listener_fns2[1] = function(inst, data)
		data.weapon = nil
		return old2(inst, data)
	end

 

Edited by DarkXero
Link to comment
Share on other sites

Thank you for the response. Overriding Bearger was going to be my last resort, because then I also need an override for Goose/Moose and would have to update for any monster that does this in the future as well. Since all of these disarm functions lead back to calling inventory:DropItem eventually, I was hoping there would be a way to prevent it there as a coverall - that's what I meant by "clean" way.

The thing I'm still confused about though, is how Bearger fires the "unequip" event. He only calls DropItem, which does not call the Unequip function anywhere, which is the only thing that fires the "unequip" event. So what am I missing here? Bearger should not fire this function when hitting me, yet he does:

	inst:ListenForEvent("unequip", function(inst, data)
		if data.eslot == EQUIPSLOTS.HANDS and data.item == inst.lastKnownEquip then
			inst.lastKnownEquip = nil
		end
	end)

 

Link to comment
Share on other sites

Interesting, so my way would work if this was just regular Don't Starve?

Alright then I suppose I'll have to go with overriding for now. I hope that they'll eventually split the disarm action into it's own preventable function in inventory, instead of using DropItem for it.

While I have you here, if you don't mind, how would you go about overriding Goose's disarm function? It's in the stategraph instead of the prefab so I imagine we'd have to handle it differently than Bearger, right?

Link to comment
Share on other sites

34 minutes ago, Squids said:

so my way would work if this was just regular Don't Starve?

The unequip event still gets pushed in single player.

I took a wrong lead when tracking the unequip event.

It's not the one in inventory_classified, that unequip event is only available for clients, to update their bar.

 

The real occurrence is

inventory:DropItem
inventoryitem:RemoveFromOwner
inventory:RemoveItem
inventory:Unequip
PushEvent("unequip"

following that track. You can jump down from DropItem to the PushEvent if you go following the code.

 

This also happens in single player.

 

48 minutes ago, Squids said:

how would you go about overriding Moose's disarm function?

AddStategraphPostInit("moose", function(sg)
	local disarm_state = sg.states.disarm
	local old = disarm_state.timeline[5].fn
	disarm_state.timeline[5].fn = function(inst)
		local target = inst.components.combat.target
		if target and target.prefab == "wathgrithr" then
			inst.CanDisarm = false
			return	
		end
		old(inst)
	end
end)

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...