Squids Posted January 17, 2016 Share Posted January 17, 2016 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 More sharing options...
DarkXero Posted January 17, 2016 Share Posted January 17, 2016 (edited) 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 January 17, 2016 by DarkXero Link to comment Share on other sites More sharing options...
Squids Posted January 17, 2016 Author Share Posted January 17, 2016 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 More sharing options...
DarkXero Posted January 17, 2016 Share Posted January 17, 2016 (edited) -- Wrong info, see below. -- Edited January 17, 2016 by DarkXero Link to comment Share on other sites More sharing options...
Squids Posted January 17, 2016 Author Share Posted January 17, 2016 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 More sharing options...
DarkXero Posted January 17, 2016 Share Posted January 17, 2016 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 More sharing options...
Squids Posted January 17, 2016 Author Share Posted January 17, 2016 I see. Knew I must've been overlooking something somewhere. Thank you for all your help, really appreciate it. I suppose this can be locked as resolved, or however this forum handles that. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now