Trenix Posted May 27, 2020 Share Posted May 27, 2020 I have tried the entire day to figure out the coding and how to make the possible. I honestly have no idea where to start. I read through the game's coding and found "stunlock" under every character and "STUNLOCK_TIMES" under Tuning. I'm not sure if this is what I'm looking for. In the Tuning part of the script, it gives Often, Sometimes, and Rarely. I figured if I set StunLock_Times to 0 it would maybe remove the stunlocked from attacks entirely. Also there is a data.stimuli named "stun", maybe that has something to do with it? I donno, I'm lost and out of all of the languages I've dealt with, LUA seems very difficult. I honestly can't figure out how to start my functions. Please help so I have an idea of what I'm supposed to do so I can learn more moving forward. I also cannot find another MOD that actually does this. Searching the forums, everyone just provided broken scripts that didn't work, or stopped working with newer updates. What's worse is that there isn't an actual API. So finding what I'm looking to change requires me to look deep in the game's files. Link to comment https://forums.kleientertainment.com/forums/topic/118530-no-stun-when-attacked/ Share on other sites More sharing options...
Trenix Posted May 27, 2020 Author Share Posted May 27, 2020 (edited) So what I think I'm actually looking for is trying to make all characters not stop moving when hit. I noticed that in State "hit" there is inst.components.locomotor:Stop() and inst:ClearBufferedAction(). I'm not sure if these are what is preventing the character from moving and basically doing anything after being hit. Reading all over the forums, I'm just finding old code that doesn't work and very rarely does anything involve changing original code but rather just adds. Yet how do I override existing code? If I liked the way DST was, I wouldn't be modding it in the first place. Here is a bunch of stuff I was messing around with. I used mods, I used forum posts, I used even API... which isn't really an API because it appears outdated and some functions don't even work. local State = GLOBAL.State local TimeEvent = GLOBAL.TimeEvent local EventHandler = GLOBAL.EventHandler local FRAMES = GLOBAL.FRAMES --local hitstate = State({ -- name = "hit", -- tags = {"busy", "pausepredict"}, -- -- onenter = function(inst, forzen) -- inst.AnimState:PlayAnimation("hit") -- if frozen == "noimpactsound" then -- frozen = nil -- else -- inst.SoundEmitter:PlaySound("dontstarve/wilson/hit") -- end -- DoHurtSound(inst) -- -- local stun_frames = math.min(math.floor(inst.AnimState:GetCurrentAnimationLength() / FRAMES + .5), frozen and 10 or 6) -- if inst.components.playercontroller ~= nil then -- inst.components.playercontroller:RemotePausePrediction(stun_frames <= 7 and stun_frames or nil) -- end -- inst.sg:SetTimeout(stun_frames * FRAMES) -- end, -- -- ontimeout = function(inst) -- inst.sg:GoToState("idle", true) -- end, -- events = -- { -- EventHandler("animover", function(inst) -- if inst.AnimState:AnimDone() then -- inst.sg:GoToState("idle") -- end -- end), -- }, --}) local newOnenter = function(inst) inst.AnimState:PlayAnimation("hit") if frozen == "noimpactsound" then frozen = nil else inst.SoundEmitter:PlaySound("dontstarve/wilson/hit") end DoHurtSound(inst) local stun_frames = math.min(math.floor(inst.AnimState:GetCurrentAnimationLength() / FRAMES + .5), frozen and 10 or 6) if inst.components.playercontroller ~= nil then inst.components.playercontroller:RemotePausePrediction(stun_frames <= 7 and stun_frames or nil) end inst.sg:SetTimeout(stun_frames * FRAMES) end, local function SGWilsonPostInit(sg) sg.states["hit"].onenter = newOnenter end --AddStategraphState("wilson", hitstate) AddStategraphPostInit("wilson", SGWilsonPostInit) At this point I'm just frustrated and about to give up. Edited May 27, 2020 by Trenix Link to comment https://forums.kleientertainment.com/forums/topic/118530-no-stun-when-attacked/#findComment-1336667 Share on other sites More sharing options...
Well-met Posted May 27, 2020 Share Posted May 27, 2020 rule of thumb, when I can't figure out how to do a thing I try to find a workshop mod that does it. Then I just dissect their code and learn how they did it. Link to comment https://forums.kleientertainment.com/forums/topic/118530-no-stun-when-attacked/#findComment-1336673 Share on other sites More sharing options...
Trenix Posted May 27, 2020 Author Share Posted May 27, 2020 Yeah I know, I looked and couldn't find anything. Link to comment https://forums.kleientertainment.com/forums/topic/118530-no-stun-when-attacked/#findComment-1336676 Share on other sites More sharing options...
Trenix Posted May 27, 2020 Author Share Posted May 27, 2020 -- Prevent Stunlock -- local require = GLOBAL.require local State = GLOBAL.State local Action = GLOBAL.Action local ActionHandler = GLOBAL.ActionHandler local TimeEvent = GLOBAL.TimeEvent local EventHandler = GLOBAL.EventHandler local ACTIONS = GLOBAL.ACTIONS local FRAMES = GLOBAL.FRAMES local new_hitstate = State { name = "hit", tags = { "busy", "pausepredict" }, onenter = function(inst, frozen) ForceStopHeavyLifting(inst) inst.components.locomotor:Stop() inst:ClearBufferedAction() inst.AnimState:PlayAnimation("hit") print("MyFunction was called") if frozen == "noimpactsound" then frozen = nil else inst.SoundEmitter:PlaySound("dontstarve/wilson/hit") end DoHurtSound(inst) --V2C: some of the woodie's were-transforms have shorter hit anims local stun_frames = math.min(math.floor(inst.AnimState:GetCurrentAnimationLength() / FRAMES + .5), frozen and 10 or 6) if inst.components.playercontroller ~= nil then --Specify min frames of pause since "busy" tag may be --removed too fast for our network update interval. inst.components.playercontroller:RemotePausePrediction(stun_frames <= 7 and stun_frames or nil) end inst.sg:SetTimeout(stun_frames * FRAMES) end, ontimeout = function(inst) inst.sg:GoToState("idle", true) end, events = { EventHandler("animover", function(inst) if inst.AnimState:AnimDone() then inst.sg:GoToState("idle") end end), }, } AddStategraphState("wilson", new_hitstate) This is the last thing I could come up with. Results in a crash. Essentially I wanted to override being hit and tweaking a few things to see how they work. I'm just surprised why it's so complicated to do so and why we're not only required to learn LUA but also learn the codes that the developers put forth without any updated API given to us. I can now see why development in mods is low and often abandoned. If someone can explain what I'm doing wrong and maybe some operations that I've somehow missed, please let me know. I wasted an entire day trying to figure this out and I'mma go crazy if I'll continue with this. Link to comment https://forums.kleientertainment.com/forums/topic/118530-no-stun-when-attacked/#findComment-1336784 Share on other sites More sharing options...
. . . Posted May 27, 2020 Share Posted May 27, 2020 (edited) hi this code maybe work i found it in some amazing mod Spoiler AddStategraphPostInit("wilson", function(sg) local _attacked = sg.events.attacked.fn sg.events.attacked.fn = function(inst, data) local a = data.attacker and data.attacker.components.combat or nil local b = a and a.playerstunlock or nil if inst.puturvaluefornotgettinghithere and a then a.playerstunlock = GLOBAL.PLAYERSTUNLOCK.NEVER inst.sg.timeinstate = 0 end _attacked(inst, data) if inst.puturvaluefornotgettinghithere and a then a.playerstunlock = b end end end) for to work put the "puturvaluefornotgettinghithere" to true and nil when no want work and you can name whatever you want, peace bro. and ya your right it sucks lots of these stuff are not simpler to do and no proper API or anything Edited May 27, 2020 by --- -.- Link to comment https://forums.kleientertainment.com/forums/topic/118530-no-stun-when-attacked/#findComment-1336794 Share on other sites More sharing options...
Trenix Posted May 28, 2020 Author Share Posted May 28, 2020 Thanks for your response but it didn't seem to work. local puturvaluefornotgettinghithere = true AddStategraphPostInit("wilson", function(sg) local _attacked = sg.events.attacked.fn sg.events.attacked.fn = function(inst, data) local a = data.attacker and data.attacker.components.combat or nil local b = a and a.playerstunlock or nil if inst.puturvaluefornotgettinghithere and a then a.playerstunlock = GLOBAL.PLAYERSTUNLOCK.NEVER inst.sg.timeinstate = 0 end _attacked(inst, data) if inst.puturvaluefornotgettinghithere and a then a.playerstunlock = b end end end) Is what I tried, maybe I'm doing it wrong? I was digging deeper into SGwilson.lua and am almost certain this has something to do with it. EventHandler("attacked", function(inst, data) if not inst.components.health:IsDead() and not inst.sg:HasStateTag("drowning") then if data.weapon ~= nil and data.weapon:HasTag("tranquilizer") and (inst.sg:HasStateTag("bedroll") or inst.sg:HasStateTag("knockout")) then return --Do nothing elseif inst.sg:HasStateTag("transform") or inst.sg:HasStateTag("dismounting") then -- don't interrupt transform or when bucked in the air inst.SoundEmitter:PlaySound("dontstarve/wilson/hit") DoHurtSound(inst) elseif inst.sg:HasStateTag("sleeping") then inst.SoundEmitter:PlaySound("dontstarve/wilson/hit") DoHurtSound(inst) if inst.sleepingbag ~= nil then inst.sleepingbag.components.sleepingbag:DoWakeUp() inst.sleepingbag = nil else inst.sg.statemem.iswaking = true inst.sg:GoToState("wakeup") end elseif inst.sg:HasStateTag("parrying") and data.redirected then if not inst.sg:HasStateTag("parryhit") then inst.sg.statemem.parrying = true inst.sg:GoToState("parry_hit", { timeleft = inst.sg.statemem.task ~= nil and GetTaskRemaining(inst.sg.statemem.task) or inst.sg.statemem.parrytime, pushing = data.attacker ~= nil and data.attacker.sg ~= nil and data.attacker.sg:HasStateTag("pushing"), }) end elseif data.attacker ~= nil and data.attacker:HasTag("groundspike") and not inst.components.rider:IsRiding() and not inst:HasTag("wereplayer") then inst.sg:GoToState("hit_spike", data.attacker) elseif data.attacker ~= nil and data.attacker.sg ~= nil and data.attacker.sg:HasStateTag("pushing") then inst.sg:GoToState("hit_push") elseif inst.sg:HasStateTag("shell") then inst.sg:GoToState("shell_hit") elseif inst.components.pinnable ~= nil and inst.components.pinnable:IsStuck() then inst.sg:GoToState("pinned_hit") elseif data.stimuli == "darkness" then inst.sg:GoToState("hit_darkness") elseif data.stimuli == "electric" and not inst.components.inventory:IsInsulated() then inst.sg:GoToState("electrocute") elseif inst.sg:HasStateTag("nointerrupt") then inst.SoundEmitter:PlaySound("dontstarve/wilson/hit") DoHurtSound(inst) else local t = GetTime() local stunlock = data.stimuli ~= "stun" and data.attacker ~= nil and --V2C: skip stunlock protection when idle -- gjans: we transition to idle for 1 frame after being hit, hence the timeinstate check not (inst.sg:HasStateTag("idle") and inst.sg.timeinstate > 0) and data.attacker.components.combat ~= nil and data.attacker.components.combat.playerstunlock or nil if stunlock ~= nil and t - (inst.sg.mem.laststuntime or 0) < ( (stunlock == PLAYERSTUNLOCK.NEVER and math.huge) or (stunlock == PLAYERSTUNLOCK.RARELY and TUNING.STUNLOCK_TIMES.RARELY) or (stunlock == PLAYERSTUNLOCK.SOMETIMES and TUNING.STUNLOCK_TIMES.SOMETIMES) or (stunlock == PLAYERSTUNLOCK.OFTEN and TUNING.STUNLOCK_TIMES.OFTEN) or 0 --unsupported case ) then -- don't go to full hit state, just play sounds inst.SoundEmitter:PlaySound("dontstarve/wilson/hit") DoHurtSound(inst) else inst.sg.mem.laststuntime = t inst.sg:GoToState("hit", data.noimpactsound and "noimpactsound" or nil) end end end end), I now need to figure how to override it with this... --EventHandler("attacked", function(inst, data) -- if not inst.components.health:IsDead() and not inst.sg:HasStateTag("drowning") then -- if data.weapon ~= nil and data.weapon:HasTag("tranquilizer") and (inst.sg:HasStateTag("bedroll") or inst.sg:HasStateTag("knockout")) then -- return --Do nothing -- elseif inst.sg:HasStateTag("transform") or inst.sg:HasStateTag("dismounting") then -- -- don't interrupt transform or when bucked in the air -- inst.SoundEmitter:PlaySound("dontstarve/wilson/hit") -- DoHurtSound(inst) -- elseif inst.sg:HasStateTag("sleeping") then -- inst.SoundEmitter:PlaySound("dontstarve/wilson/hit") -- DoHurtSound(inst) -- if inst.sleepingbag ~= nil then -- inst.sleepingbag.components.sleepingbag:DoWakeUp() -- inst.sleepingbag = nil -- else -- inst.sg.statemem.iswaking = true -- inst.sg:GoToState("wakeup") -- end -- elseif inst.sg:HasStateTag("parrying") and data.redirected then -- if not inst.sg:HasStateTag("parryhit") then -- inst.sg.statemem.parrying = true -- inst.sg:GoToState("parry_hit", { -- timeleft = inst.sg.statemem.task ~= nil and GetTaskRemaining(inst.sg.statemem.task) or inst.sg.statemem.parrytime, -- pushing = data.attacker ~= nil and data.attacker.sg ~= nil and data.attacker.sg:HasStateTag("pushing"), -- }) -- end -- elseif data.attacker ~= nil -- and data.attacker:HasTag("groundspike") -- and not inst.components.rider:IsRiding() -- and not inst:HasTag("wereplayer") then -- inst.sg:GoToState("hit_spike", data.attacker) -- elseif data.attacker ~= nil -- and data.attacker.sg ~= nil -- and data.attacker.sg:HasStateTag("pushing") then -- inst.sg:GoToState("hit_push") -- elseif inst.sg:HasStateTag("shell") then -- inst.sg:GoToState("shell_hit") -- elseif inst.components.pinnable ~= nil and inst.components.pinnable:IsStuck() then -- inst.sg:GoToState("pinned_hit") -- elseif data.stimuli == "darkness" then -- inst.sg:GoToState("hit_darkness") -- elseif data.stimuli == "electric" and not inst.components.inventory:IsInsulated() then -- inst.sg:GoToState("electrocute") -- else -- inst.SoundEmitter:PlaySound("dontstarve/wilson/hit") -- DoHurtSound(inst) It seems like the game intentionally adds a stun and prevents players also from being stun locked. It's exceptionally noticeable when you idle and get hit. I either have no idea of what I'm talking about, or I'm finally onto it. Stunlock times were also part of tuning.lua, but seems that they ended up turning it off and getting rid of it. I'll try a bit harder, but if I can't figure it out, I'll probably move onto modding a different game. Maybe lua isn't for me. So much time wasted and I've gotten no where. Link to comment https://forums.kleientertainment.com/forums/topic/118530-no-stun-when-attacked/#findComment-1336846 Share on other sites More sharing options...
Trenix Posted May 28, 2020 Author Share Posted May 28, 2020 local MYACT = Action(3) MYACT.str = "Prevent Stun" MYACT.id = "attacked" MYACT.fn = function(inst, data) if not inst.components.health:IsDead() and not inst.sg:HasStateTag("drowning") then if data.weapon ~= nil and data.weapon:HasTag("tranquilizer") and (inst.sg:HasStateTag("bedroll") or inst.sg:HasStateTag("knockout")) then return --Do nothing elseif inst.sg:HasStateTag("transform") or inst.sg:HasStateTag("dismounting") then -- don't interrupt transform or when bucked in the air inst.SoundEmitter:PlaySound("dontstarve/wilson/hit") DoHurtSound(inst) elseif inst.sg:HasStateTag("sleeping") then inst.SoundEmitter:PlaySound("dontstarve/wilson/hit") DoHurtSound(inst) if inst.sleepingbag ~= nil then inst.sleepingbag.components.sleepingbag:DoWakeUp() inst.sleepingbag = nil else inst.sg.statemem.iswaking = true inst.sg:GoToState("wakeup") end elseif inst.sg:HasStateTag("parrying") and data.redirected then if not inst.sg:HasStateTag("parryhit") then inst.sg.statemem.parrying = true inst.sg:GoToState("parry_hit", { timeleft = inst.sg.statemem.task ~= nil and GetTaskRemaining(inst.sg.statemem.task) or inst.sg.statemem.parrytime, pushing = data.attacker ~= nil and data.attacker.sg ~= nil and data.attacker.sg:HasStateTag("pushing"), }) end elseif data.attacker ~= nil and data.attacker:HasTag("groundspike") and not inst.components.rider:IsRiding() and not inst:HasTag("wereplayer") then inst.sg:GoToState("hit_spike", data.attacker) elseif data.attacker ~= nil and data.attacker.sg ~= nil and data.attacker.sg:HasStateTag("pushing") then inst.sg:GoToState("hit_push") elseif inst.sg:HasStateTag("shell") then inst.sg:GoToState("shell_hit") elseif inst.components.pinnable ~= nil and inst.components.pinnable:IsStuck() then inst.sg:GoToState("pinned_hit") elseif data.stimuli == "darkness" then inst.sg:GoToState("hit_darkness") elseif data.stimuli == "electric" and not inst.components.inventory:IsInsulated() then inst.sg:GoToState("electrocute") else inst.SoundEmitter:PlaySound("dontstarve/wilson/hit") DoHurtSound(inst) end end end AddAction(MYACT) AddStategraphActionHandler("willow",ActionHandler(MYACT, "newattack")) Yeah this is all I got following the API the provided us which clearly doesn't work... nor does it effectively explain anything. If you can help, great. But otherwise if I don't figure this out which took me two days of reading through code and using useless API, then I much rather mod another game. I'm not sure if LUA is supposed to be this difficult, or if the developers just made it hell to work with. Link to comment https://forums.kleientertainment.com/forums/topic/118530-no-stun-when-attacked/#findComment-1336855 Share on other sites More sharing options...
. . . Posted May 28, 2020 Share Posted May 28, 2020 (edited) 4 hours ago, Trenix said: I'm doing it wrong? yes. you put this value on the character when you want to have no hit stun then make nil when you not want it lol inst.puturvaluefornotgettinghithere = true Edited May 28, 2020 by --- -.- 1 Link to comment https://forums.kleientertainment.com/forums/topic/118530-no-stun-when-attacked/#findComment-1336880 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