Wonderlarr Posted May 20, 2021 Share Posted May 20, 2021 (edited) Hello Modders, here's a quick guide on how to make your character punch things really quickly. We'll be using AddStategraphPostInit here, so you'll want to throw these into your modmain.lua. Make sure to read the comments in the code, to adjust the things you'll need to adjust! I used Wilba from Hamlet to test here, but unless you're ripping off hamlet, you'll need to change it. AddStategraphPostInit("wilson", function(sg) -- This will add some code to the server side stategraph local _attack = sg.states["attack"] local _onenter = _attack.onenter _attack.onenter = function(inst,...) _onenter(inst,...) if inst.prefab == "wilba" then -- You'll want to change wilba to your own character's prefab local speed = 2 -- Change this to whatever yoy want your speed multiplier to go to, careful when going over 5 though, it gets buggy. inst.sg:SetTimeout(inst.sg.timeout/speed) inst.components.combat:SetAttackPeriod(TUNING.WILSON_ATTACK_PERIOD / speed) -- Attack period is essentially like an attack cooldown, so we divide it by the speed. inst.AnimState:SetDeltaTimeMultiplier(speed) -- This is the time multiplier for animations, we multiply it by our speed to make the character punch fast and not have animation desyncs. for k, v in pairs(_attack.timeline) do v.time = v.time/speed end end return end local _onexit = _attack.onexit _attack.onexit = function(inst,...) if inst.prefab == "wilba" then -- Make sure to change your prefab here too! inst.AnimState:SetDeltaTimeMultiplier(1) -- Here we'll only return out animation speed back to normal, since Attack Period being increased doesn't matter otherwise, and it might break things if we did return it after every attack. end return _onexit(inst,...) end end) AddStategraphPostInit("wilson_client", function(sg) -- This adds code to the client side stategraph, but it's only used if the client has Movement Prediction enabled. local _attack = sg.states["attack"] local _onenter = _attack.onenter _attack.onenter = function(inst,...) _onenter(inst,...) if inst.prefab == "wilba" then --Change it here again! local speed = 2 -- Make sure to set your speed here as well, so the client knows. inst.sg:SetTimeout(inst.sg.timeout/speed) inst.AnimState:SetDeltaTimeMultiplier(speed) for k, v in pairs(_attack.timeline) do v.time = v.time/speed end end return end local _onexit = _attack.onexit _attack.onexit = function(inst,...) if inst.prefab == "wilba" then -- Final change here, to your characters prefab again. inst.AnimState:SetDeltaTimeMultiplier(1) end return _onexit(inst,...) end end) Thing to keep in mind If you want your character to ALWAYS punch fast, you should probably comment out or remove the lines that mess with AttackPeriod, and instead put that in your characters master_postinit. Edited May 21, 2021 by TheSkylarr Changed title 2 1 Link to comment Share on other sites More sharing options...
Monti18 Posted May 21, 2021 Share Posted May 21, 2021 I'm not sure if this is entirely correct, as when I tried something like this for my mod to get a faster attack, my character started to attack faster and faster after each attack. To understand the cause, I added some print, like this: for k, v in pairs(_attack.timeline) do--"overide the timeline" print("v.time onenter before:"..tostring(v.time)) v.time = v.time/speed print("v.time onenter after:"..tostring(v.time)) end in the onenter and onexit function. The result can be seen in the first spoiler. Spoiler [00:07:04]: v.time onenter before:0.16666666666667 [00:07:04]: v.time onenter after:0.095238095238095 [00:07:04]: v.time onenter before:0.2 [00:07:04]: v.time onenter after:0.11428571428571 [00:07:04]: v.time onenter before:0.23333333333333 [00:07:04]: v.time onenter after:0.13333333333333 [00:07:04]: v.time onenter before:0.26666666666667 [00:07:04]: v.time onenter after:0.15238095238095 [00:07:04]: v.time onenter before:0.33333333333333 [00:07:04]: v.time onenter after:0.19047619047619 [00:07:05]: v.time onexit before:0.095238095238095 [00:07:05]: v.time onexit after:0.095238095238095 [00:07:05]: v.time onexit before:0.11428571428571 [00:07:05]: v.time onexit after:0.11428571428571 [00:07:05]: v.time onexit before:0.13333333333333 [00:07:05]: v.time onexit after:0.13333333333333 [00:07:05]: v.time onexit before:0.15238095238095 [00:07:05]: v.time onexit after:0.15238095238095 [00:07:05]: v.time onexit before:0.19047619047619 [00:07:05]: v.time onexit after:0.19047619047619 [00:07:05]: v.time onenter before:0.095238095238095 [00:07:05]: v.time onenter after:0.054421768707483 [00:07:05]: v.time onenter before:0.11428571428571 [00:07:05]: v.time onenter after:0.06530612244898 [00:07:05]: v.time onenter before:0.13333333333333 [00:07:05]: v.time onenter after:0.076190476190476 [00:07:05]: v.time onenter before:0.15238095238095 [00:07:05]: v.time onenter after:0.087074829931973 [00:07:05]: v.time onenter before:0.19047619047619 [00:07:05]: v.time onenter after:0.10884353741497 [00:07:05]: v.time onexit before:0.054421768707483 [00:07:05]: v.time onexit after:0.054421768707483 [00:07:05]: v.time onexit before:0.06530612244898 [00:07:05]: v.time onexit after:0.06530612244898 [00:07:05]: v.time onexit before:0.076190476190476 [00:07:05]: v.time onexit after:0.076190476190476 [00:07:05]: v.time onexit before:0.087074829931973 [00:07:05]: v.time onexit after:0.087074829931973 [00:07:05]: v.time onexit before:0.10884353741497 [00:07:05]: v.time onexit after:0.10884353741497 [00:07:05]: v.time onenter before:0.054421768707483 [00:07:05]: v.time onenter after:0.031098153547133 [00:07:05]: v.time onenter before:0.06530612244898 [00:07:05]: v.time onenter after:0.03731778425656 [00:07:05]: v.time onenter before:0.076190476190476 [00:07:05]: v.time onenter after:0.043537414965986 [00:07:05]: v.time onenter before:0.087074829931973 [00:07:05]: v.time onenter after:0.049757045675413 [00:07:05]: v.time onenter before:0.10884353741497 [00:07:05]: v.time onenter after:0.062196307094266 [00:07:05]: v.time onexit before:0.031098153547133 [00:07:05]: v.time onexit after:0.031098153547133 [00:07:05]: v.time onexit before:0.03731778425656 [00:07:05]: v.time onexit after:0.03731778425656 [00:07:05]: v.time onexit before:0.043537414965986 [00:07:05]: v.time onexit after:0.043537414965986 [00:07:05]: v.time onexit before:0.049757045675413 [00:07:05]: v.time onexit after:0.049757045675413 [00:07:05]: v.time onexit before:0.062196307094266 [00:07:05]: v.time onexit after:0.062196307094266 [00:07:05]: v.time onenter before:0.031098153547133 [00:07:05]: v.time onenter after:0.017770373455505 [00:07:05]: v.time onenter before:0.03731778425656 [00:07:05]: v.time onenter after:0.021324448146606 [00:07:05]: v.time onenter before:0.043537414965986 [00:07:05]: v.time onenter after:0.024878522837707 [00:07:05]: v.time onenter before:0.049757045675413 [00:07:05]: v.time onenter after:0.028432597528807 [00:07:05]: v.time onenter before:0.062196307094266 [00:07:05]: v.time onenter after:0.035540746911009 [00:07:06]: v.time onexit before:0.017770373455505 [00:07:06]: v.time onexit after:0.017770373455505 [00:07:06]: v.time onexit before:0.021324448146606 [00:07:06]: v.time onexit after:0.021324448146606 [00:07:06]: v.time onexit before:0.024878522837707 [00:07:06]: v.time onexit after:0.024878522837707 [00:07:06]: v.time onexit before:0.028432597528807 [00:07:06]: v.time onexit after:0.028432597528807 [00:07:06]: v.time onexit before:0.035540746911009 [00:07:06]: v.time onexit after:0.035540746911009 [00:07:06]: v.time onenter before:0.017770373455505 [00:07:06]: v.time onenter after:0.010154499117431 [00:07:06]: v.time onenter before:0.021324448146606 [00:07:06]: v.time onenter after:0.012185398940917 [00:07:06]: v.time onenter before:0.024878522837707 [00:07:06]: v.time onenter after:0.014216298764404 [00:07:06]: v.time onenter before:0.028432597528807 [00:07:06]: v.time onenter after:0.01624719858789 [00:07:06]: v.time onenter before:0.035540746911009 [00:07:06]: v.time onenter after:0.020308998234862 [00:07:06]: v.time onexit before:0.010154499117431 [00:07:06]: v.time onexit after:0.010154499117431 [00:07:06]: v.time onexit before:0.012185398940917 [00:07:06]: v.time onexit after:0.012185398940917 [00:07:06]: v.time onexit before:0.014216298764404 [00:07:06]: v.time onexit after:0.014216298764404 [00:07:06]: v.time onexit before:0.01624719858789 [00:07:06]: v.time onexit after:0.01624719858789 [00:07:06]: v.time onexit before:0.020308998234862 [00:07:06]: v.time onexit after:0.020308998234862 [00:07:06]: v.time onenter before:0.010154499117431 [00:07:06]: v.time onenter after:0.0058025709242464 [00:07:06]: v.time onenter before:0.012185398940917 [00:07:06]: v.time onenter after:0.0069630851090957 [00:07:06]: v.time onenter before:0.014216298764404 [00:07:06]: v.time onenter after:0.008123599293945 [00:07:06]: v.time onenter before:0.01624719858789 [00:07:06]: v.time onenter after:0.0092841134787943 [00:07:06]: v.time onenter before:0.020308998234862 [00:07:06]: v.time onenter after:0.011605141848493 [00:07:07]: v.time onexit before:0.0058025709242464 [00:07:07]: v.time onexit after:0.0058025709242464 [00:07:07]: v.time onexit before:0.0069630851090957 [00:07:07]: v.time onexit after:0.0069630851090957 [00:07:07]: v.time onexit before:0.008123599293945 [00:07:07]: v.time onexit after:0.008123599293945 [00:07:07]: v.time onexit before:0.0092841134787943 [00:07:07]: v.time onexit after:0.0092841134787943 [00:07:07]: v.time onexit before:0.011605141848493 [00:07:07]: v.time onexit after:0.011605141848493 [00:07:07]: v.time onenter before:0.0058025709242464 [00:07:07]: v.time onenter after:0.0033157548138551 [00:07:07]: v.time onenter before:0.0069630851090957 [00:07:07]: v.time onenter after:0.0039789057766261 [00:07:07]: v.time onenter before:0.008123599293945 [00:07:07]: v.time onenter after:0.0046420567393971 [00:07:07]: v.time onenter before:0.0092841134787943 [00:07:07]: v.time onenter after:0.0053052077021682 [00:07:07]: v.time onenter before:0.011605141848493 [00:07:07]: v.time onenter after:0.0066315096277102 [00:07:07]: v.time onexit before:0.0033157548138551 [00:07:07]: v.time onexit after:0.0033157548138551 [00:07:07]: v.time onexit before:0.0039789057766261 [00:07:07]: v.time onexit after:0.0039789057766261 [00:07:07]: v.time onexit before:0.0046420567393971 [00:07:07]: v.time onexit after:0.0046420567393971 [00:07:07]: v.time onexit before:0.0053052077021682 [00:07:07]: v.time onexit after:0.0053052077021682 [00:07:07]: v.time onexit before:0.0066315096277102 [00:07:07]: v.time onexit after:0.0066315096277102 [00:07:07]: v.time onenter before:0.0033157548138551 [00:07:07]: v.time onenter after:0.0018947170364886 [00:07:07]: v.time onenter before:0.0039789057766261 [00:07:07]: v.time onenter after:0.0022736604437864 [00:07:07]: v.time onenter before:0.0046420567393971 [00:07:07]: v.time onenter after:0.0026526038510841 [00:07:07]: v.time onenter before:0.0053052077021682 [00:07:07]: v.time onenter after:0.0030315472583818 [00:07:07]: v.time onenter before:0.0066315096277102 [00:07:07]: v.time onenter after:0.0037894340729773 [00:07:08]: v.time onexit before:0.0018947170364886 [00:07:08]: v.time onexit after:0.0018947170364886 [00:07:08]: v.time onexit before:0.0022736604437864 [00:07:08]: v.time onexit after:0.0022736604437864 [00:07:08]: v.time onexit before:0.0026526038510841 [00:07:08]: v.time onexit after:0.0026526038510841 [00:07:08]: v.time onexit before:0.0030315472583818 [00:07:08]: v.time onexit after:0.0030315472583818 [00:07:08]: v.time onexit before:0.0037894340729773 [00:07:08]: v.time onexit after:0.0037894340729773 [00:07:08]: v.time onenter before:0.0018947170364886 [00:07:08]: v.time onenter after:0.0010826954494221 [00:07:08]: v.time onenter before:0.0022736604437864 [00:07:08]: v.time onenter after:0.0012992345393065 [00:07:08]: v.time onenter before:0.0026526038510841 [00:07:08]: v.time onenter after:0.0015157736291909 [00:07:08]: v.time onenter before:0.0030315472583818 [00:07:08]: v.time onenter after:0.0017323127190753 [00:07:08]: v.time onenter before:0.0037894340729773 [00:07:08]: v.time onenter after:0.0021653908988441 As you can see, the timelines of the attacks are always getting smaller and smaller. That's why I thought of adding to the onexit function this: local _onexit = _attack.onexit _attack.onexit = function(inst,...) if inst.prefab == "wilba" then -- Final change here, to your characters prefab again. local speed = 2 inst.AnimState:SetDeltaTimeMultiplier(1) for k, v in pairs(_attack.timeline) do--"overide the timeline" v.time = v.time*speed end end return _onexit(inst,...) end After adding this to the onexit function, the prints can be seen in the second spoiler: Spoiler [00:02:29]: v.time onenter before:0.16666666666667 [00:02:29]: v.time onenter after:0.095238095238095 [00:02:29]: v.time onenter before:0.2 [00:02:29]: v.time onenter after:0.11428571428571 [00:02:29]: v.time onenter before:0.23333333333333 [00:02:29]: v.time onenter after:0.13333333333333 [00:02:29]: v.time onenter before:0.26666666666667 [00:02:29]: v.time onenter after:0.15238095238095 [00:02:29]: v.time onenter before:0.33333333333333 [00:02:29]: v.time onenter after:0.19047619047619 [00:02:29]: v.time onexit before:0.095238095238095 [00:02:29]: v.time onexit after:0.16666666666667 [00:02:29]: v.time onexit before:0.11428571428571 [00:02:29]: v.time onexit after:0.2 [00:02:29]: v.time onexit before:0.13333333333333 [00:02:29]: v.time onexit after:0.23333333333333 [00:02:29]: v.time onexit before:0.15238095238095 [00:02:29]: v.time onexit after:0.26666666666667 [00:02:29]: v.time onexit before:0.19047619047619 [00:02:29]: v.time onexit after:0.33333333333333 [00:02:29]: v.time onenter before:0.16666666666667 [00:02:29]: v.time onenter after:0.095238095238095 [00:02:29]: v.time onenter before:0.2 [00:02:29]: v.time onenter after:0.11428571428571 [00:02:29]: v.time onenter before:0.23333333333333 [00:02:29]: v.time onenter after:0.13333333333333 [00:02:29]: v.time onenter before:0.26666666666667 [00:02:29]: v.time onenter after:0.15238095238095 [00:02:29]: v.time onenter before:0.33333333333333 [00:02:29]: v.time onenter after:0.19047619047619 [00:02:30]: v.time onexit before:0.095238095238095 [00:02:30]: v.time onexit after:0.16666666666667 [00:02:30]: v.time onexit before:0.11428571428571 [00:02:30]: v.time onexit after:0.2 [00:02:30]: v.time onexit before:0.13333333333333 [00:02:30]: v.time onexit after:0.23333333333333 [00:02:30]: v.time onexit before:0.15238095238095 [00:02:30]: v.time onexit after:0.26666666666667 [00:02:30]: v.time onexit before:0.19047619047619 [00:02:30]: v.time onexit after:0.33333333333333 As you can see, the timelines stay at the same numbers. To be honest, I'm not sure sure if this is correct, as I only had a feeling that I was attacking faster than I should, but at least these numbers say so. 1 Link to comment Share on other sites More sharing options...
Wonderlarr Posted May 21, 2021 Author Share Posted May 21, 2021 @Monti18 Hmm, I just sat in my test world attacking a target dummy for about a minute and a half and didn't notice any change with my code, but the numbers do seem a little weird. I'll test it a bit later and add it to the guide if necessary Link to comment Share on other sites More sharing options...
Monti18 Posted May 22, 2021 Share Posted May 22, 2021 (edited) I made some tests (see in the spoiler) where you can see that the times between the attacks stays the same, so it doesn't seem to change the attackspeed after time, it was probably only my imagination Spoiler [00:24:48]: time attackenter:2.3000001199543 [00:24:48]: time since last attack:2.3000001199543 [00:24:48]: time attackexit:2.5666668005288 [00:24:48]: v.time onexit before:0.083333333333333 [00:24:48]: v.time onexit before:0.1 [00:24:48]: v.time onexit before:0.11666666666667 [00:24:48]: v.time onexit before:0.13333333333333 [00:24:48]: v.time onexit before:0.16666666666667 [00:24:48]: time attackenter:2.5666668005288 [00:24:48]: time since last attack:0.26666668057442 [00:24:48]: time attackexit:2.8333334811032 [00:24:48]: v.time onexit before:0.041666666666667 [00:24:48]: v.time onexit before:0.05 [00:24:48]: v.time onexit before:0.058333333333333 [00:24:48]: v.time onexit before:0.066666666666667 [00:24:48]: v.time onexit before:0.083333333333333 [00:24:48]: time attackenter:2.8333334811032 [00:24:48]: time since last attack:0.26666668057442 [00:24:49]: time attackexit:3.1000001616776 [00:24:49]: v.time onexit before:0.020833333333333 [00:24:49]: v.time onexit before:0.025 [00:24:49]: v.time onexit before:0.029166666666667 [00:24:49]: v.time onexit before:0.033333333333333 [00:24:49]: v.time onexit before:0.041666666666667 [00:24:49]: time attackenter:3.1000001616776 [00:24:49]: time since last attack:0.26666668057442 [00:24:49]: time attackexit:3.366666842252 [00:24:49]: v.time onexit before:0.010416666666667 [00:24:49]: v.time onexit before:0.0125 [00:24:49]: v.time onexit before:0.014583333333333 [00:24:49]: v.time onexit before:0.016666666666667 [00:24:49]: v.time onexit before:0.020833333333333 [00:24:49]: time attackenter:3.366666842252 [00:24:49]: time since last attack:0.26666668057442 [00:24:49]: time attackexit:3.6333335228264 [00:24:49]: v.time onexit before:0.0052083333333333 [00:24:49]: v.time onexit before:0.00625 [00:24:49]: v.time onexit before:0.0072916666666667 [00:24:49]: v.time onexit before:0.0083333333333333 [00:24:49]: v.time onexit before:0.010416666666667 [00:24:49]: time attackenter:3.6333335228264 [00:24:49]: time since last attack:0.26666668057442 [00:24:49]: time attackexit:3.9000002034009 [00:24:49]: v.time onexit before:0.0026041666666667 [00:24:49]: v.time onexit before:0.003125 [00:24:49]: v.time onexit before:0.0036458333333333 [00:24:49]: v.time onexit before:0.0041666666666667 [00:24:49]: v.time onexit before:0.0052083333333333 [00:24:49]: time attackenter:3.9000002034009 [00:24:49]: time since last attack:0.26666668057442 [00:24:50]: time attackexit:4.1666668839753 [00:24:50]: v.time onexit before:0.0013020833333333 [00:24:50]: v.time onexit before:0.0015625 [00:24:50]: v.time onexit before:0.0018229166666667 [00:24:50]: v.time onexit before:0.0020833333333333 [00:24:50]: v.time onexit before:0.0026041666666667 [00:24:50]: time attackenter:4.1666668839753 [00:24:50]: time since last attack:0.26666668057442 [00:24:50]: time attackexit:4.4333335645497 [00:24:50]: v.time onexit before:0.00065104166666667 [00:24:50]: v.time onexit before:0.00078125 [00:24:50]: v.time onexit before:0.00091145833333333 [00:24:50]: v.time onexit before:0.0010416666666667 [00:24:50]: v.time onexit before:0.0013020833333333 [00:24:50]: time attackenter:4.4333335645497 [00:24:50]: time since last attack:0.26666668057442 [00:24:50]: time attackexit:4.7000002451241 [00:24:50]: v.time onexit before:0.00032552083333333 [00:24:50]: v.time onexit before:0.000390625 [00:24:50]: v.time onexit before:0.00045572916666667 [00:24:50]: v.time onexit before:0.00052083333333333 [00:24:50]: v.time onexit before:0.00065104166666667 As for the timeline values that are changing, I'm not sure if this has implications for other things in the game, so perhaps it would be the best to get them back to their original values. Even without changing the timelines, you attack faster with this guide, just a frame slower than with the timeline change except for some frames where attack onenter and attack onexit overlap. Edit: This seems to only happen if you are not changing the timelines in the wilson stategraph and changing the timelines in the wilson_client stategraph. So its seems the timelines are probably mostly important for the clients. Edited May 22, 2021 by Monti18 1 Link to comment Share on other sites More sharing options...
Jusstice Posted October 24, 2021 Share Posted October 24, 2021 Hello, could you tell me how to make sure that only a blow from the fist is fast, and weapons and tools retain the same speed? 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