Jump to content

Recommended Posts

Hello, I need some help :)...

So, this's the code I need help with..

Spoiler

if damage > 100 then
		inst:DoTaskInTime(.25, function() inst.Physics:SetVel(math.cos(facing_angle)*25, 12, math.sin(facing_angle)*-25) end)
		Knockback_Stun_Large(inst) print("damage: "..tostring(damage))
	elseif damage > 90 then
		inst:DoTaskInTime(.25, function() inst.Physics:SetVel(math.cos(facing_angle)*21, 10, math.sin(facing_angle)*-21) end)
		Knockback_Stun_Great(inst) print("damage: "..tostring(damage))
	elseif damage > 80 then
		inst:DoTaskInTime(.25, function() inst.Physics:SetVel(math.cos(facing_angle)*19, 9, math.sin(facing_angle)*-19) end)
		Knockback_Stun_Great(inst) print("damage: "..tostring(damage))
	elseif damage > 70 then
		inst:DoTaskInTime(.25, function() inst.Physics:SetVel(math.cos(facing_angle)*17, 8, math.sin(facing_angle)*-17) end)
		Knockback_Stun_Med(inst) print("damage: "..tostring(damage))
	elseif damage > 60 then
		inst:DoTaskInTime(.25, function() inst.Physics:SetVel(math.cos(facing_angle)*15, 7, math.sin(facing_angle)*-15) end)
		Knockback_Stun_Med(inst) print("damage: "..tostring(damage))
	elseif damage > 50 then
		inst:DoTaskInTime(.25, function() inst.Physics:SetVel(math.cos(facing_angle)*13, 6, math.sin(facing_angle)*-13) end)
		Knockback_Stun_Small(inst) print("damage: "..tostring(damage))
	elseif damage > 40 then
		inst:DoTaskInTime(.25, function() inst.Physics:SetVel(math.cos(facing_angle)*11, 5, math.sin(facing_angle)*-11) end)
		Knockback_Stun_Small(inst) print("damage: "..tostring(damage))
	elseif damage > 30 then
		inst:DoTaskInTime(.25, function() inst.Physics:SetVel(math.cos(facing_angle)*9, 4, math.sin(facing_angle)*-9) end)
		Knockback_Stun_Mini(inst) print("damage: "..tostring(damage))
	elseif damage > 20 then
		inst:DoTaskInTime(.25, function() inst.Physics:SetVel(math.cos(facing_angle)*7, 3, math.sin(facing_angle)*-7) end)
		Knockback_Stun_Mini(inst) print("damage: "..tostring(damage))
	elseif damage > 10 then
		inst:DoTaskInTime(.25, function() inst.Physics:SetVel(math.cos(facing_angle)*3, 1, math.sin(facing_angle)*-3) end)
		Knockback_Stun_Tiny(inst) print("damage: "..tostring(damage))
	elseif damage < 10 then
		print("damage: "..tostring(damage))
	end

 

I was wondering if there is a way I can shorten this code or would that be impossible? Thanks for your time :)!

 

Edited by SuperDavid

I think so..

Like I would like that this code starts at 3, 1, -3 and-

inst.Physics:SetVel(math.cos(facing_angle)*25, 12, math.sin(facing_angle)*-25)

-gets the numbers increase by .5 for each 5 points of damage my character takes up to 100, but I don't even know if that's possible..

 

If I want to do that with elseif then I'd need 20 elseif which would be so annoying to go through..

 

Anyways, thanks for replying man :D!

 

EDIT: Also here's the knockback_stun things maybe they can be shortened or incorporated into the linear thing too?

Spoiler

local function Knockback_Stun_Tiny(inst)    
	if inst.components.playercontroller ~= nil then
		inst.components.playercontroller:Enable(false)
		inst:DoTaskInTime(.5, function() inst.components.playercontroller:Enable(true) inst.Physics:SetFriction(0) inst.Physics:SetDamping(5) end)
	end
end

local function Knockback_Stun_Mini(inst)    
	if inst.components.playercontroller ~= nil then
		inst.components.playercontroller:Enable(false)
		inst:DoTaskInTime(.6, function() inst.components.playercontroller:Enable(true) inst.Physics:SetFriction(0) inst.Physics:SetDamping(5) end)
	end
end

local function Knockback_Stun_Small(inst)    
	if inst.components.playercontroller ~= nil then
		inst.components.playercontroller:Enable(false)
		inst:DoTaskInTime(.7, function() inst.components.playercontroller:Enable(true) inst.Physics:SetFriction(0) inst.Physics:SetDamping(5) end)
	end
end

local function Knockback_Stun_Med(inst)    
	if inst.components.playercontroller ~= nil then
		inst.components.playercontroller:Enable(false)
		inst:DoTaskInTime(.8, function() inst.components.playercontroller:Enable(true) inst.Physics:SetFriction(0) inst.Physics:SetDamping(5) end)
	end
end

local function Knockback_Stun_Great(inst)    
	if inst.components.playercontroller ~= nil then
		inst.components.playercontroller:Enable(false)
		inst:DoTaskInTime(.9, function() inst.components.playercontroller:Enable(true) inst.Physics:SetFriction(0) inst.Physics:SetDamping(5) end)
	end
end

local function Knockback_Stun_Large(inst)    
	if inst.components.playercontroller ~= nil then
		inst.components.playercontroller:Enable(false)
		inst:DoTaskInTime(1, function() inst.components.playercontroller:Enable(true) inst.Physics:SetFriction(0) inst.Physics:SetDamping(5) end)
	end
end

 

 

Edited by SuperDavid

Alright I guess its time for me to lurk no more.

So using the numbers provided I got a linear knock back effect as below.

math.clamp(input,min,max) is a wonderful function for just this purpose.

Spoiler

local function doknockback(inst, damage)
    inst:DoTaskInTime(.25, function()
        inst.Physics:SetVel(
        math.cos(facing_angle)*math.clamp(damage/4,3,25), 
        math.clamp(damage/8, 1,12), 
        -math.sin(facing_angle)*math.clamp(damage/4,3,25))    
    end)
    --knockback stun doesn't need a seperate function now
    if inst.components.playercontroller ~= nil then
        inst.components.playercontroller:Enable(false)
        inst:DoTaskInTime(math.clamp(damage/100,0.5,1), function()
            inst.components.playercontroller:Enable(true)
            inst.Physics:SetFriction(0)
            inst.Physics:SetDamping(5)
        end)
    end    
end

I don't have time to test it out but I have been using a similar function already for a character mod of my own.

It is not perfectly as 1:1 as your if statements but it is more flexible to a degree as you could get damage values in between the ones you listed and have knock back appropriately. 

Too make it easier to read I spread out the lines of code, but you can condense it again to tidy things up.

EDIT: Suggestions

Spoiler

Also some tweaking to the division would be necessary right now the knock back stun is probably not perfect but the concept is there. You may want to consider taking less knock back stun from smaller damage 0.5 seconds is a lot. Especially if you get swarmed by bees or frogs.

Maybe just make it math.clamp(damage/100, 0.1, 1) this way small damage doesn't easily stun lock you.

Because right now even if you have it set so your character doesn't play the hit animation you are still disabled for 0.5 seconds unless that is what you want. =]

 

Edited by IronHunter
See amendment spoiler above

Okay so after some testing

Here is what I got, I forgot to include some code from your other post

Spoiler

    inst:ListenForEvent("attacked", function(inst, data)
        if data.attacker == nil then return end --safeguard
        local damage = data.attacker.components.combat.defaultdamage
        
        inst.components.locomotor:RunForward()
        inst.Physics:SetMotorVel(0,0,0)
        local facing_angle = data.attacker.Transform:GetRotation() * DEGREES
        inst.Physics:SetFriction(.3)
        inst.Physics:SetDamping(0)
        
        inst:DoTaskInTime(.25, function()
            inst.Physics:SetVel(
            math.cos(facing_angle)*math.clamp(damage/4,3,25), 
            math.clamp(damage/8, 1,12), 
            -math.sin(facing_angle)*math.clamp(damage/4,3,25))    
        end)
        --knockback stun doesn't need a seperate function now
        if inst.components.playercontroller ~= nil then
            inst.components.playercontroller:Enable(false)
            local stunlock = math.clamp(damage/100, 0.5,1)
            inst:DoTaskInTime(stunlock, function()
                inst.components.playercontroller:Enable(true)
                inst.Physics:SetFriction(0)
                inst.Physics:SetDamping(5)
            end)
        end    
    end)

 

Wow, thanks so much for your help man this's shorter & cooler now :D!!!

If I can just ask a few questions then I can understand how this stuff works!

 

My first question's what do the numbers in here stand for? Cause I don't really understand what it means now, hahaha..

Spoiler

inst:DoTaskInTime(.25, function()
	inst.Physics:SetVel(
	math.cos(facing_angle)*math.clamp(damage/4,3,25), 
	math.clamp(damage/8, 1,12), 
	-math.sin(facing_angle)*math.clamp(damage/4,3,25))    
end)

 

My second question, well isn't really a question but more of a problem I need help with :)..

 

So, with this great code you gave me the "Knockback stun" isn't working very properly..  Like for example with this new code see how when I get knockbacked by Krampus 

Spoiler

bad.gif See in this picture at the end my character starts floating down

with this code


-- Knockback stun doesn't need a separate function now
		if inst.components.playercontroller ~= nil then
			inst.components.playercontroller:Enable(false)
			local stunlock = math.clamp(damage/100, 0.5,1.5)
			inst:DoTaskInTime(stunlock, function()
				inst.components.playercontroller:Enable(true)
				print("damage: "..tostring(damage))
				inst.Physics:SetFriction(0)
				inst.Physics:SetDamping(5)
			end)
		end

 

Spoiler

good.gifWhile see in this picture with old knockback he doesn't float down

with the old code


local function Knockback_Stun_Med(inst)    
	if inst.components.playercontroller ~= nil then
		inst.components.playercontroller:Enable(false)
		inst:DoTaskInTime(.8, function() inst.components.playercontroller:Enable(true) inst.Physics:SetFriction(0) inst.Physics:SetDamping(5) end)
	end
end

 

The problem with this new code I think is it's giving the character these code-

inst.Physics:SetFriction(0)
inst.Physics:SetDamping(5)

-too early compared to the old code.. Is there a way I can fix this or should I go back to the old knockback stun?

 

4 hours ago, IronHunter said:

It is not perfectly as 1:1 as your if statements but it is more flexible to a degree as you could get damage values in between the ones you listed and have knock back appropriately. 

I think maybe this would be better, right? Can you maybe do this for me too, unless you don't want to I understand :D!

Also, thanks so, so much for your help IronHunter :D!!

 

EDIT: This's all the code I have now incase you need to know :)!

Spoiler

local function Knockback(inst, data) -- TODO: Make when collide into object from great knockback take damage & collapse on ground
	if data.attacker == nil then return end -- Safeguard
		local damage = data.attacker.components.combat.defaultdamage
        
		inst.components.locomotor:RunForward()
		inst.Physics:SetMotorVel(0,0,0)
		local facing_angle = data.attacker.Transform:GetRotation() * DEGREES
		inst.Physics:SetFriction(1)
		inst.Physics:SetDamping(0)

		inst:DoTaskInTime(.25, function()
			inst.Physics:SetVel(
			math.cos(facing_angle)*math.clamp(damage/4,3,25), 
			math.clamp(damage/8, 1,12), 
			-math.sin(facing_angle)*math.clamp(damage/4,3,25))    
		end)
		
		-- Knockback stun doesn't need a separate function now
		if inst.components.playercontroller ~= nil then
			inst.components.playercontroller:Enable(false)
			local stunlock = math.clamp(damage/100, 0.5,1.5)
			inst:DoTaskInTime(stunlock, function()
				inst.components.playercontroller:Enable(true)
				print("damage: "..tostring(damage))
				inst.Physics:SetFriction(0)
				inst.Physics:SetDamping(5)
			end)
		end
end

 

 

Edited by SuperDavid

The numbers use math.clamp(input, minimum value, maximum value) to cap the velocity.

This caps the maximum horizontal velocity to 25 and the minimum to 3.

As well as the vertical velocity to 12 and 1 respectively.

The reason I divide the damage by 4 is to get a value e.g. krampus does 50 which gives you 12.5 or about middleground velocity for your damage caps.

 

The issue you stated seems to be the knockback stun activating in .25 seconds after the velocity launch. Maybe move the knockback stun if statement into the knockback task function above it after you setvelocity?

It seems to be that the krampus normally would have a hitstun of 0.7 so this would be a decent solution.

 

Like I said it won't be exactly the same but it is easier to tinker with the numbers until you get it the way you want.

I hope that clears things up.

Edit:

Also because gravity is a fixed value you'll always fall at the same speed in this game. So maybe have a damping value higher than 0 but less than 1?

I am fairly new to experimenting with don't starves physics but its worth testing at the very least.

One more thing if you do move the hitstun into the knockback task function. You may want to reduce the minimum stunlock to 0.25 so that damage lower than 50 will still do something around 0.5-0.6 seconds.

Edited by IronHunter
See above
26 minutes ago, IronHunter said:

The issue you stated seems to be the knockback stun activating in .25 seconds after the velocity launch. Maybe move the knockback stun if statement into the knockback task function above it after you setvelocity?

Okay, so I put the knockback stun code in the SetVel code area like & it works, at least I think :D!

Spoiler

local function Knockback(inst, data)
	if data.attacker == nil then return end -- Safeguard
		local damage = data.attacker.components.combat.defaultdamage
        
		inst.components.locomotor:RunForward()
		inst.Physics:SetMotorVel(0,0,0)
		local facing_angle = data.attacker.Transform:GetRotation() * DEGREES
		inst.Physics:SetFriction(1)
		inst.Physics:SetDamping(0)

		inst:DoTaskInTime(.25, function()
			inst.Physics:SetVel(
			math.cos(facing_angle)*math.clamp(damage/4,3,25), 
			math.clamp(damage/8, 1,12), 
			-math.sin(facing_angle)*math.clamp(damage/4,3,25))

			-- Knockback stun doesn't need a separate function now
			if inst.components.playercontroller ~= nil then
				inst.components.playercontroller:Enable(false)
				local stunlock = math.clamp(damage/100, 0.5,1.5)
				inst:DoTaskInTime(stunlock, function()
					inst.components.playercontroller:Enable(true)
					print("damage: "..tostring(damage))
					inst.Physics:SetFriction(0)
					inst.Physics:SetDamping(5)
				end)
			end
		end)
end

 

 

but, I have a new problem now (sorry)! If you can help that'd be great :)!

So, with this new code my character doesn't take knockback when moving around or going into many different states :(! Like look at this pic

Spoiler

wat.gif He takes knockback when idle, but when moving he doesn't!?

While with the old code

Spoiler

local function Knockback_Stun_Tiny(inst)    
	if inst.components.playercontroller ~= nil then
		inst.components.playercontroller:Enable(false)
		inst:DoTaskInTime(.5, function() inst.components.playercontroller:Enable(true) inst.Physics:SetFriction(0) inst.Physics:SetDamping(5) end)
	end
end

local function Knockback_Stun_Mini(inst)    
	if inst.components.playercontroller ~= nil then
		inst.components.playercontroller:Enable(false)
		inst:DoTaskInTime(.6, function() inst.components.playercontroller:Enable(true) inst.Physics:SetFriction(0) inst.Physics:SetDamping(5) end)
	end
end

local function Knockback_Stun_Small(inst)    
	if inst.components.playercontroller ~= nil then
		inst.components.playercontroller:Enable(false)
		inst:DoTaskInTime(.7, function() inst.components.playercontroller:Enable(true) inst.Physics:SetFriction(0) inst.Physics:SetDamping(5) end)
	end
end

local function Knockback_Stun_Med(inst)    
	if inst.components.playercontroller ~= nil then
		inst.components.playercontroller:Enable(false)
		inst:DoTaskInTime(.8, function() inst.components.playercontroller:Enable(true) inst.Physics:SetFriction(0) inst.Physics:SetDamping(5) end)
	end
end

local function Knockback_Stun_Great(inst)    
	if inst.components.playercontroller ~= nil then
		inst.components.playercontroller:Enable(false)
		inst:DoTaskInTime(.9, function() inst.components.playercontroller:Enable(true) inst.Physics:SetFriction(0) inst.Physics:SetDamping(5) end)
	end
end

local function Knockback_Stun_Large(inst)    
	if inst.components.playercontroller ~= nil then
		inst.components.playercontroller:Enable(false)
		inst:DoTaskInTime(1, function() inst.components.playercontroller:Enable(true) inst.Physics:SetFriction(0) inst.Physics:SetDamping(5) end)
	end
end

local function Old_Knockback(inst, data)
local damage = data.damage
local attacker = data.attacker
local facing_angle = attacker.Transform:GetRotation() * DEGREES

if not attacker then return end

	inst.Physics:SetFriction(1)
	inst.Physics:SetDamping(0)
	
	inst.components.locomotor:RunForward()
	inst.Physics:SetMotorVel(0,0,0)
	
	if not inst.Physics:IsActive() then
		inst.Physics:Start()
		inst.components.locomotor:Start()
	end

	if damage > 100 then
		inst:DoTaskInTime(.25, function() inst.Physics:SetVel(math.cos(facing_angle)*25, 12, math.sin(facing_angle)*-25) end)
		Knockback_Stun_Large(inst) print("damage: "..tostring(damage))
	elseif damage > 90 then
		inst:DoTaskInTime(.25, function() inst.Physics:SetVel(math.cos(facing_angle)*21, 10, math.sin(facing_angle)*-21) end)
		Knockback_Stun_Great(inst) print("damage: "..tostring(damage))
	elseif damage > 80 then
		inst:DoTaskInTime(.25, function() inst.Physics:SetVel(math.cos(facing_angle)*19, 9, math.sin(facing_angle)*-19) end)
		Knockback_Stun_Great(inst) print("damage: "..tostring(damage))
	elseif damage > 70 then
		inst:DoTaskInTime(.25, function() inst.Physics:SetVel(math.cos(facing_angle)*17, 8, math.sin(facing_angle)*-17) end)
		Knockback_Stun_Med(inst) print("damage: "..tostring(damage))
	elseif damage > 60 then
		inst:DoTaskInTime(.25, function() inst.Physics:SetVel(math.cos(facing_angle)*15, 7, math.sin(facing_angle)*-15) end)
		Knockback_Stun_Med(inst) print("damage: "..tostring(damage))
	elseif damage > 50 then
		inst:DoTaskInTime(.25, function() inst.Physics:SetVel(math.cos(facing_angle)*13, 6, math.sin(facing_angle)*-13) end)
		Knockback_Stun_Small(inst) print("damage: "..tostring(damage))
	elseif damage > 40 then
		inst:DoTaskInTime(.25, function() inst.Physics:SetVel(math.cos(facing_angle)*11, 5, math.sin(facing_angle)*-11) end)
		Knockback_Stun_Small(inst) print("damage: "..tostring(damage))
	elseif damage > 30 then
		inst:DoTaskInTime(.25, function() inst.Physics:SetVel(math.cos(facing_angle)*9, 4, math.sin(facing_angle)*-9) end)
		Knockback_Stun_Mini(inst) print("damage: "..tostring(damage))
	elseif damage > 20 then
		inst:DoTaskInTime(.25, function() inst.Physics:SetVel(math.cos(facing_angle)*7, 3, math.sin(facing_angle)*-7) end)
		Knockback_Stun_Mini(inst) print("damage: "..tostring(damage))
	elseif damage > 10 then
		inst:DoTaskInTime(.25, function() inst.Physics:SetVel(math.cos(facing_angle)*17, 8, math.sin(facing_angle)*-17) end)
		Knockback_Stun_Med(inst) print("damage: "..tostring(damage))
	elseif damage < 10 then
		inst:DoTaskInTime(.25, function() inst.Physics:SetVel(math.cos(facing_angle)*3, 1, math.sin(facing_angle)*-3) end)
		Knockback_Stun_Tiny(inst) print("damage: "..tostring(damage))
	end

end

 

Spoiler

gewd.gifHe takes knockback no matter what :)!

Do you maybe know why this is happening? I tried doing stuff but I couldn't figure it out & this is obviously a very important problem, I don't wanna have to use the old code even though you worked so hard for me :(..

 

If I can ask another question, if I wanted to increase the strength of the knockback with your code would I just increase the SetVel numbers?   And thanks very much again man :D!!

I don't have access to my computer atm, as I am out. But maybe from your other post. Ok I would say move back to the floatyness and just tinker with damping and the y velocity?

From my tests at home this morning I am not sure why this is happening other than the recent changes made moving the if statement into the task.

I'll tinker some more when I get home.

As for increasing the value you can change the numbers I added to your leisure. If you want more knockback just lower the number I am dividing damage by. e.g. right now its damage/4 so 50 damage is 12.5 knockback. If you change it to damage/3.5 you'll get 14.28 knockback instead. That is for horizontal values. Similarly increasing that number will make the knockback less.

Edit:

Derp..putting the if statement for the knockback stun into the other task delays the disabling of the player controller which is why it works when idle but doesn't work when moving.

Because I don't know how to adjust the falling speed of a character is to just make your character not get launched as high from attacks. The floatiness is because there doesn't seem to be any acceleration to the character's falling speed. I'll test this when I get home.

This thread was very enlightening:

 

Edited by IronHunter
See above

Hey David,

This should hopefully fix it for you

The stun lock curve is fixed, to match your original if statements, so overall this should function almost exactly like what you originally gave me.

Spoiler

	inst:ListenForEvent("attacked", function(inst, data)
		if data.attacker == nil or data.damage == nil then return end --safeguard
		local damage = data.damage
		
		inst.components.locomotor:RunForward()
		inst.Physics:SetMotorVel(0,0,0)
		local facing_angle = data.attacker.Transform:GetRotation() * DEGREES
		inst.Physics:SetFriction(0)
		inst.Physics:SetDamping(0)
		--knockback stun doesnt need a seperate function now
		if inst.components.playercontroller ~= nil then
			inst.components.playercontroller:Enable(false)
			--stun curve with the formula (damage/200)+0.5
			--10 = 0.5 == 0.55
			--20 = 0.6 == 0.60
			--30 = 0.6 == 0.65
			--40 = 0.7 == 0.70
			--50 = 0.7 == 0.75
			--60 = 0.8 == 0.80
			--70 = 0.8 == 0.85
			--80 = 0.9 == 0.90
			--90 = 0.9 == 0.95
			--100= 1.0 == 1.00
			local stunlock = math.clamp((damage/200)+0.5, 0.5,1.5)
			--to get a more accurate curve we desire we need to divide by 200 instead of 100 or just 1/2 of the previous value.
            		--and we need to add 0.5s this gives us an accurate stunlock curve almost identical to the original
			inst:DoTaskInTime(stunlock, function()
				inst.components.playercontroller:Enable(true)
				inst.Physics:SetFriction(0)
				inst.Physics:SetDamping(5)
                                inst:PutBackOnGround()
			end)
		end
		inst:DoTaskInTime(.25, function()
			inst.Physics:SetVel(
			math.cos(facing_angle)*math.clamp(damage/4,3,25), 
			math.clamp(damage/8, 1,12), 
			-math.sin(facing_angle)*math.clamp(damage/4,3,25))    
		end)
	end)

 

I don't have time to test much right now, maybe later.

Edit:

O you may find this useful: in the event you get knocked off the map because the knock back knocks you over the collision boundaries.

I put this inst:PutBackOnGround() in the task that resets your playercontroller.

It is the rescue command so it will automatically activate when the stun lock wears off.

Edit2: updated the safeguard

Edited by IronHunter
See above

Thank you so, so, so, so much man :D!! Now everything works very good, really thanks :D!!!!!

And I'm so sorry, but I just want to make sure with you what all the code does in case I want to edit values & stuff in future!

Spoiler

local function Knockback(inst, data)
if data.attacker == nil then return end -- Safeguard
		local damage = data.attacker.components.combat.defaultdamage
		local facing_angle = data.attacker.Transform:GetRotation() * DEGREES
		
		inst.components.locomotor:RunForward()
		inst.Physics:SetMotorVel(0,0,0)
		inst.Physics:SetFriction(1)
		inst.Physics:SetDamping(0)
		PlayFootstep(inst)
		if inst.components.playercontroller ~= nil then
			inst.components.playercontroller:Enable(false)
			--stun curve with the formula (damage/200)+0.5 -- Can I ask what is this stun curve? Is this the amount of time the player's stunned (can't control the player)?
			--10 = 0.5 == 0.55 -- What do all of these numbers mean (sorry) xD?
			--20 = 0.6 == 0.60
			--30 = 0.6 == 0.65
			--40 = 0.7 == 0.70
			--50 = 0.7 == 0.75
			--60 = 0.8 == 0.80
			--70 = 0.8 == 0.85
			--80 = 0.9 == 0.90
			--90 = 0.9 == 0.95
			--100= 1.0 == 1.00
			local stunlock = math.clamp((damage/200)+0.5, 0.5,1.5) -- If I change the values in here what would happen?

			inst:DoTaskInTime(stunlock, function()
				inst.components.playercontroller:Enable(true)
				inst.Physics:SetFriction(0)
				inst.Physics:SetDamping(5)
				print("damage: "..tostring(damage))
			end)
		end
		inst:DoTaskInTime(.25, function()
			inst.Physics:SetVel(
			math.cos(facing_angle)*math.clamp(damage/4,3,25), -- Lowering the "4" in here would make my character take more knockback, yes?
			math.clamp(damage/8, 1,12), -- Would lower the "8" in here make my character take more vertical knockback?
			-math.sin(facing_angle)*math.clamp(damage/4,3,25)) -- Lowering the "4" in here would make my character take more knockback, yes?
		end)
end

 

And I only have like 2 last things if you really want you can help me with, they're not super important..but they'd make the knockback much more complete-ish :)!

 

My first question's if there's a way I can make when a player hits another player the knockback gets calculated based on their weapon damage (if they're holding one) instead of basedamage? Cause player's basedamage is their fist & they always do very little knockback even when hitting with a fresh hambat.

 

My last question is if there's a way to make it that when the player's wearing armor based on the armor's absorption value they take less knockback? If it can't be based on the armor's absorption value then can just be like when character's wearing body armor they take 25% less knockback & if wearing a helmet take another 25% less knockback?

 

I'm so, so, so sorry I keep asking new questions & new things, I would understand if you don't want to help anymore :). Though, if by any chance you still want to make this knockback greater than I'd really, really appreciate it sooo much & you don't even have to reply now, it can be whenever you have time within the week or even a month :D! I will keep trying to get achieve those stuff myself, but I will 99.99% fail, hahaha..

 

And I really, really thank you for all your super help!! Without you I'd have like 50+ elseif & 50+ knockback_stuns for every damage possibility :wilson_ecstatic:...

lol perfect timing I just edited the code so it gets the raw damage from the pushed event.

Fixed the safeguard vs grue, explosives, and if you get knocked into the ocean you get warped automatically back to land.

Spoiler

	inst:ListenForEvent("attacked", function(inst, data)
		if data.attacker == nil or data.damage == nil then return end --safeguard
		local damage = data.damage * (1-inst.components.health.absorb)
        	--innate armor because we clamped the values later, even if we take 0 damage or negative damage it will still have minimal knockback
		print("damage: " .. tostring(damage)) --pvp has a 50% damage penalty
		local facing_angle = data.attacker.Transform:GetRotation() * DEGREES
		
		inst.components.locomotor:RunForward()
		inst.Physics:SetMotorVel(0,0,0)
		inst.Physics:SetFriction(0)
		inst.Physics:SetDamping(0)
		if inst.components.playercontroller ~= nil then
			inst.components.playercontroller:Enable(false)
			local stunlock = math.clamp((damage/200)+0.5, 0.5,1.5)
			inst:DoTaskInTime(stunlock, function()
				inst.components.playercontroller:Enable(true)
				inst.Physics:SetFriction(0)
				inst.Physics:SetDamping(5)
				inst:PutBackOnGround()
			end)
		end
		inst:DoTaskInTime(.25, function()
			inst.Physics:SetVel(
			math.cos(facing_angle)*math.clamp(damage/4,3,25), 
			math.clamp(damage/8, 1,12), 
			-math.sin(facing_angle)*math.clamp(damage/4,3,25))    
		end)
	end)

 

Armor technically already applies as it modifies the damage taken before the pushed event.

Also I just did a quick addition which makes innate armor also reduce knock back. Enjoy

 

Edited by IronHunter
=] just making it more legible

Well, I think this knockback code works flawless now..!! Thank you very much IronHunter, this literally would've been impossible for me to do (since I suck at math & don't know nothing about DST physics lol) :D!!

 

I have two more things if you still feel up to helping & you have the time :D!

Spoiler

So, the first one I made when my character takes over 75 damage he drops his tool & here's the entire code.

Spoiler


local function Knockback(inst, data)
	if data.attacker == nil or data.damage == nil then return end -- Safeguard
		local damage = data.damage * (1-inst.components.health.absorb)
		local facing_angle = data.attacker.Transform:GetRotation() * DEGREES
		print("damage: " .. tostring(damage))
		
		if damage > 75 then
			local item = nil
			if inst and inst.components.inventory then
				item = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
				
				if item and item.Physics then
					inst.components.inventory:DropItem(item)
					local x, y, z = item:GetPosition():Get()
					y = .1
					item.Physics:Teleport(x,y,z)
					local hp = inst:GetPosition()
					local pt = data.attacker:GetPosition()
					local vel = (hp - pt):GetNormalized()
					local speed = 5 + (math.random() * 2)
					local angle = math.atan2(vel.z, vel.x) + (math.random() * 20 - 10) * DEGREES
					item.Physics:SetVel(math.cos(angle) * speed, 10, math.sin(angle) * speed)
				end
			end
		end
		
		inst.components.locomotor:RunForward()
		inst.Physics:SetMotorVel(0,0,0)
		inst.Physics:SetFriction(1)
		inst.Physics:SetDamping(0)
		PlayFootstep(inst)
		
		if inst.components.playercontroller ~= nil then
			inst.components.playercontroller:Enable(false)
			local stunlock = math.clamp((damage/200)+0.5, 0.5,1.5)
			inst:DoTaskInTime(stunlock, function()
				inst.components.playercontroller:Enable(true)
				inst.Physics:SetFriction(0)
				inst.Physics:SetDamping(5)
				inst:PutBackOnGround()
			end)
		end
		
		inst:DoTaskInTime(.25, function()
			inst.Physics:SetVel(
			math.cos(facing_angle)*math.clamp(damage/4,3,25),
			math.clamp(damage/8, 1,12),
			-math.sin(facing_angle)*math.clamp(damage/4,3,25))
			if damage > 75 then
				inst.sg:GoToState("collapse")
			end
		end)
end

 

So, the tool has a set value at the speed & distance it drops, I'm wondering if the tool can scale with the knockback my character took? If that would be possible that'd be awesome! (Though, it's not super necessary!)

EDIT: I'll put the other problem in a separate spoiler...getting too crowded in here, hahaha!

Spoiler

@IronHunter Hopefully, this's the last problem I annoy you with :)! Also, answer back whenever you have time, no rush :D(If you don't want to help me with this or it's too difficult then that's okay, I guess!)

So, when my character takes high damage he enters a state called "collapse" which's my way of making real "knockback stun", here's the code!

Spoiler


local Collapse = State {
	name = "collapse",
	tags = { "busy", "pausepredict", "nomorph", "collapsed" },

	onenter = function(inst)
		--inst.Physics:Stop()
		inst.AnimState:PlayAnimation("death")
	   
		if not inst:HasTag("mime") then
			inst.SoundEmitter:PlaySound((inst.talker_path_override or "dontstarve/characters/")..(inst.soundsname or inst.prefab).."/death_voice")
		end

		if inst.components.playercontroller ~= nil then
			inst.components.playercontroller:RemotePausePrediction()
		end
	end,
	
	timeline =
	{
		TimeEvent(45 * FRAMES, function(inst)
			local x, y, z = inst.Transform:GetWorldPosition()
			inst.AnimState:PlayAnimation("wakeup")
			--GLOBAL.TheCamera:CanControl(false)
			--GLOBAL.TheCamera:SetControllable(false)
			
			if inst.AnimState:GetCurrentFacing() == 0 then -- FACING_RIGHT = 0
				inst:ForceFacePoint(-2, y, z)
			elseif inst.AnimState:GetCurrentFacing() == 1 then -- FACING_UP = 1
				inst:ForceFacePoint(-2, y, z)
			elseif inst.AnimState:GetCurrentFacing() == 2 then -- FACING_LEFT = 2
				inst:ForceFacePoint(-2, y, z)
			elseif inst.AnimState:GetCurrentFacing() == 3 then -- FACING_DOWN = 3
				inst:ForceFacePoint(-2, y, z)
			elseif inst.AnimState:GetCurrentFacing() == 4 then -- FACING_UPRIGHT = 4
				inst:ForceFacePoint(-2, y, z)
			elseif inst.AnimState:GetCurrentFacing() == 5 then -- FACING_UPLEFT = 5
				inst:ForceFacePoint(-2, y, z)
			elseif inst.AnimState:GetCurrentFacing() == 6 then -- FACING_DOWNRIGHT = 6
				inst:ForceFacePoint(-2, y, z)
			elseif inst.AnimState:GetCurrentFacing() == 7 then -- FACING_DOWNLEFT = 7
				inst:ForceFacePoint(-2, y, z)
			elseif inst.AnimState:GetCurrentFacing() == 8 then -- FACING_NONE = 8
				inst:ForceFacePoint(-2, y, z)
			end
		end),
		
		TimeEvent(55 * FRAMES, function(inst)
			inst.sg:RemoveStateTag("busy")
			inst.sg:RemoveStateTag("collapsed")
		end),
	},

	events =
	{
		EventHandler("animover", function(inst)
			if inst.AnimState:AnimDone() then
				inst.sg:GoToState("idle")
			end
		end),
	},
}

 

Now, the problem's I want to make this look as nice as possible without creating a custom animation, since that's way too hard for me..

So, the only anims I found out of the entire SGwilson that could fit a stun anim is "death" for the character falling to the ground & wakeup for getting off the ground.

Now the only problem is these anims seem to happen on completely different sides which would normally look like this...which looks very unnatural..

Spoiler

bad1.gif

Though, with adding this code-

Spoiler


if inst.AnimState:GetCurrentFacing() == 0 then -- FACING_RIGHT = 0
				inst:ForceFacePoint(-2, y, z)
			elseif inst.AnimState:GetCurrentFacing() == 1 then -- FACING_UP = 1
				inst:ForceFacePoint(-2, y, z)
			elseif inst.AnimState:GetCurrentFacing() == 2 then -- FACING_LEFT = 2
				inst:ForceFacePoint(-2, y, z)
			elseif inst.AnimState:GetCurrentFacing() == 3 then -- FACING_DOWN = 3
				inst:ForceFacePoint(-2, y, z)
			elseif inst.AnimState:GetCurrentFacing() == 4 then -- FACING_UPRIGHT = 4
				inst:ForceFacePoint(-2, y, z)
			elseif inst.AnimState:GetCurrentFacing() == 5 then -- FACING_UPLEFT = 5
				inst:ForceFacePoint(-2, y, z)
			elseif inst.AnimState:GetCurrentFacing() == 6 then -- FACING_DOWNRIGHT = 6
				inst:ForceFacePoint(-2, y, z)
			elseif inst.AnimState:GetCurrentFacing() == 7 then -- FACING_DOWNLEFT = 7
				inst:ForceFacePoint(-2, y, z)
			elseif inst.AnimState:GetCurrentFacing() == 8 then -- FACING_NONE = 8
				inst:ForceFacePoint(-2, y, z)
			end

 

I was able to get at some angles my character gets the way I want which would look like this

Spoiler

good1.gif

Which I think fits the best for a "stun" anim which isn't custom made! So, the only problem's all those "ForceFacePoint" I have no idea how to use them or what to do with them that'd make my character always fall on the good side (I don't know anything about x, y, z)!

As for why I don't just use the normal knockout anim it's because I think it doesn't feel natural for when the char gets hit by a super powerful attack & falls down like they're sleepy :lol:...

Spoiler

weird1.gif

 

I can't thank you enough man for helping me for so long! Without your help I couldn't get anywhere near to here..so really... Thank you!!!

Edited by SuperDavid

Certainly I am about to go to bed, got a test tomorrow.

Spoiler

inst.Physics:SetVel(
	math.cos(facing_angle)*math.clamp(damage/4,3,25),
	-- Lowering 4 increases horizontal knockback, yes?
	-- Yes lowering the 4 increases knockback
	-- e.g. if you take 50 damage it is divided by 4 and gives you 12.5 knockback, so making it 3.5 instead would result in 14.28 knockback
	math.clamp(damage/8, 1,12),
	-- Lowering 8 increases vertical knockback, yes?
	-- Yes again, same as the 4.
	-math.sin(facing_angle)*math.clamp(damage/4,3,25))
	-- Also, the last 2 numbers of each of these is the min & max knockback the character can take, yes?
	-- Yes min and max knockback clamped. So even if you take 0 damage thanks to your armor or something you'll still get knocked back 3 horizontally.

 

Spoiler

local stunlock = math.clamp((damage/200)+0.5, 0.5,1.5)
-- The numbers .5 & 1.5 is min/max stun the character can take, yes?
-- Yes, math.clamp(input, min, max) this is used in the DoTaskInTime so its in seconds.
-- Though, I don't know what "damage/200)+0.5" stands for..maybe can you tell me in way a idiot could understand xD?
-- In english/pseudocode it simply means the damage (e.g. 50) is divided by 200 so 0.25 + 0.5 = 0.75s the main reason I divided by 100 in the first place was to get a value for seconds of stun. However in order to get the curve you wanted I have to divide it again by 2. So 200 is the end result. Seeing as the minimum is 0.5 we have to add 0.5 to make the curve proper. I think in one of the previous posts I did it shows the new curve.

 

Spoiler

local damage = data.damage * (1-inst.components.health.absorb) 
-- Does this say the true damage my char took no matter his health.absorb value? Cause my char's health.absorb value changes a lot, going all the way to -2 to .5
-- It says the current health.absorb value upon getting attacked. So if your health absorb value is -2 at the time you'll take tripled damage and if it is 0.5 you'll take half damage appropriately. Which translates into tripled knockback and half knockback respectively.
-- All it is doing is reading the current value

 

Spoiler

local function Knockback(inst, data)
	if data.attacker == nil or data.damage == nil then return end -- Safeguard
		local damage = data.damage * (1-inst.components.health.absorb)
		-- Innate armor because we clamped the values later, even if we take 0 damage or negative damage it will still have minimal knockback.
		print("damage: " .. tostring(damage))
		local facing_angle = data.attacker.Transform:GetRotation() * DEGREES
		
		
		
		if damage > 50 then
			local item = nil
			if inst and inst.components.inventory then
				item = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
				
				if item and item.Physics then
					inst.components.inventory:DropItem(item)
					local x, y, z = item:GetPosition():Get()
					y = .1
					item.Physics:Teleport(x,y,z)
					local hp = inst:GetPosition()
					local pt = data.attacker:GetPosition()
					local vel = (hp - pt):GetNormalized()
					local speed = 5 + (math.random() * 2)
					local angle = math.atan2(vel.z, vel.x) + (math.random() * 20 - 10) * DEGREES
					item.Physics:SetVel(math.cos(angle) * speed, 10, math.sin(angle) * speed)
				end
			end
		end
		
		inst.components.locomotor:RunForward()
		inst.Physics:SetMotorVel(0,0,0)
		inst.Physics:SetFriction(1)
		inst.Physics:SetDamping(0)
		PlayFootstep(inst)
		
		if inst.components.playercontroller ~= nil then
			inst.components.playercontroller:Enable(false)
			local stunlock = math.clamp((damage/200)+0.5, 0.5,1.5)
			inst:DoTaskInTime(stunlock, function()
				inst.components.playercontroller:Enable(true)
				inst.Physics:SetFriction(0)
				inst.Physics:SetDamping(5)
				inst:PutBackOnGround()
				
			end)
		end
		
		inst:DoTaskInTime(.25, function()
			inst.Physics:SetVel(
			math.cos(facing_angle)*math.clamp(damage/4,3,25),
			math.clamp(damage/8, 1,12),
			-math.sin(facing_angle)*math.clamp(damage/4,3,25))
			if damage > 75 then
				inst.sg:GoToState("collapse")
			end
		end)
end

If you want to make the tool fly in correlation with your own knockback maybe base the speed on the damage you take?

Spoiler

wat.gif The problem's when char plays death anim then goes to wakeup anim they wake up on opposite side which looks weird, would it be possible to make it more like this?

  Hide contents

good.gifMaking the wakeup anim play the animation for the opposite side you were hit on, this is probably complicated so I understand if you don't know how!

This is the code for the collapse state

  Hide contents



local Collapse = State {
	name = "collapse",
	tags = { "busy", "pausepredict", "nomorph", "collapsed" },

	onenter = function(inst)
		--inst.Physics:Stop()
		inst.AnimState:PlayAnimation("death")
	   
		if not inst:HasTag("mime") then
			inst.SoundEmitter:PlaySound((inst.talker_path_override or "dontstarve/characters/")..(inst.soundsname or inst.prefab).."/death_voice")
		end

		if inst.components.playercontroller ~= nil then
			inst.components.playercontroller:RemotePausePrediction()
		end
	end,
	
	timeline =
	{
		TimeEvent(45 * FRAMES, function(inst)
			inst.AnimState:PlayAnimation("wakeup")
		end),
		
		TimeEvent(55 * FRAMES, function(inst)
			inst.sg:RemoveStateTag("busy")
			inst.sg:RemoveStateTag("collapsed")
		end),
	},

	events =
	{
		EventHandler("animover", function(inst)
			if inst.AnimState:AnimDone() then
				inst.sg:GoToState("idle")
			end
		end),
	},
}

 

 

How important is the death animation? Because there is an animation e.g. PushEvent("knockedout") used when getting knocked out from sleep effects. It was designed to be used with the wake up animation and is pretty much the same thing except you fall on your back instead of on your face.

That is all the time I have for today, I'll see if I can help out more tomorrow.

Knockback Code

Spoiler

	inst:ListenForEvent("attacked", function(inst, data)
		if data.attacker == nil or data.damage == nil then return end
		local damage = data.damage * (1-inst.components.health.absorb)
		print("damage: " .. tostring(damage))
		local facing_angle = data.attacker.Transform:GetRotation() * DEGREES
		
		if damage > 75 and inst.components.inventory then
			local item = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
			if item and item.Physics then
				inst.components.inventory:DropItem(item)
				local x, y, z = item:GetPosition():Get()
				y = .1
				item.Physics:Teleport(x,y,z)
				local hp = inst:GetPosition()
				local pt = data.attacker:GetPosition()
				local vel = (hp - pt):GetNormalized()
				local speed = math.clamp(damage/4, 3, 12.5)
				local angle = math.atan2(vel.z, vel.x) + math.random(-10,10) * DEGREES
				item.Physics:SetVel(math.cos(angle) * speed, 10, math.sin(angle) * speed)
			end
		end
		inst.components.locomotor:RunForward()
		inst.Physics:SetMotorVel(0,0,0)
		inst.Physics:SetFriction(0)
		inst.Physics:SetDamping(0)
		if inst.components.playercontroller ~= nil then
			inst.components.playercontroller:Enable(false)
			local stunlock = math.clamp((damage/200)+0.5, 0.5,1.5)
			inst:DoTaskInTime(stunlock, function()
				inst.components.playercontroller:Enable(true)
				inst.Physics:SetFriction(0)
				inst.Physics:SetDamping(5)
				inst:PutBackOnGround()
			end)
		end
		inst:DoTaskInTime(.25, function()
			inst.Physics:SetVel(
			math.cos(facing_angle)*math.clamp(damage/4,3,25), 
			math.clamp(damage/8, 1,12), 
			-math.sin(facing_angle)*math.clamp(damage/4,3,25))    
			if damage > 1 then
				inst.sg:GoToState("collapse")
			end
		end)
	end)

 

Stategraph

Spoiler

local pi = GLOBAL.PI
local degrees = GLOBAL.DEGREES
local collapse = State {
	name = "collapse",
	tags = { "busy", "pausepredict", "nomorph", "collapsed" },
	onenter = function(inst)
		inst.AnimState:PlayAnimation("death")   
		if not inst:HasTag("mime") then
			inst.SoundEmitter:PlaySound((inst.talker_path_override or "dontstarve/characters/")..(inst.soundsname or inst.prefab).."/death_voice")
		end
		if inst.components.playercontroller ~= nil then
			inst.components.playercontroller:RemotePausePrediction()
		end
	end,
	timeline =
	{
		TimeEvent(45 * FRAMES, function(inst)
			local player_angle = inst.Transform:GetRotation()*degrees + pi/4
			print("player_angle: " .. tostring(player_angle))
			if player_angle > pi*0.25 and player_angle <= pi*0.75 then
				inst.Transform:SetRotation(-pi/2)
				print("left")
			else
				inst.Transform:SetRotation(pi/2)
				print("right")
			end
			inst.AnimState:PlayAnimation("wakeup")
		end),		
		TimeEvent(55 * FRAMES, function(inst)
			inst.sg:RemoveStateTag("busy")
			inst.sg:RemoveStateTag("collapsed")
		end),
	},
	events =
	{
		EventHandler("animover", function(inst)
			if inst.AnimState:AnimDone() then
				inst.sg:GoToState("idle")
			end
		end),
	},
}

 

 

Edited by IronHunter
Typo Fix

Thank you soooooooooo much IronHunter everything's working so good now all thanks to you :D!!

There's just one little thing is that on lots of the angles the anim thingy still doesn't work?

Spoiler

E.g.

1..gif

1.png

There's probably no way to fix that, right?

Though, thanks so, so, so VERY much for everything, I couldn't have done any of this without you :wilson_smile:!!!!

Well too be fair I did do a amendment to the code, its working for me.

So maybe you copied the older version of it before I did the edit?

I am testing this on a dedicated server, and just letting a bunch of mobs hit me from various angles. While I move in different directions.

Spoiler

local pi = GLOBAL.PI
local degrees = GLOBAL.DEGREES
local collapse = State {
	name = "collapse",
	tags = { "busy", "pausepredict", "nomorph", "collapsed" },
	onenter = function(inst)
		--inst.Physics:Stop()
		inst.AnimState:PlayAnimation("death")   
		if not inst:HasTag("mime") then
			inst.SoundEmitter:PlaySound((inst.talker_path_override or "dontstarve/characters/")..(inst.soundsname or inst.prefab).."/death_voice")
		end
		if inst.components.playercontroller ~= nil then
			inst.components.playercontroller:RemotePausePrediction()
		end
	end,
	timeline =
	{
		TimeEvent(45 * FRAMES, function(inst)
			local player_angle = inst.Transform:GetRotation()*degrees + pi/4
			print("player_angle: " .. tostring(player_angle))
			if player_angle > pi*0.25 and player_angle <= pi*0.75 then
				inst.Transform:SetRotation(-pi/2)
				print("left")
			else
				inst.Transform:SetRotation(pi/2)
				print("right")
			end
			inst.AnimState:PlayAnimation("wakeup")
		end),		
		TimeEvent(55 * FRAMES, function(inst)
			inst.sg:RemoveStateTag("busy")
			inst.sg:RemoveStateTag("collapsed")
		end),
	},
	events =
	{
		EventHandler("animover", function(inst)
			if inst.AnimState:AnimDone() then
				inst.sg:GoToState("idle")
			end
		end),
	},
}
local function SGWilsonPostInit(sg)
    sg.states["collapse"] = collapse
end
AddStategraphState("SGwilson", collapse)
AddStategraphPostInit("wilson", SGWilsonPostInit) 

 

I'm not sure why its different for you? As it is this is kind of a hacky solution in the first place to make the two animations look nice.

Also I just tested it using this quick thing, it seems to work properly. I didn't have the patience to view it frame by frame, so I sped it up 5x but I watched the whole thing and the animation is in sync.

Spoiler

	inst.rotat = -PI
	inst.count = 0
	inst.check = inst:DoPeriodicTask(1.5, function()
		if inst.count <= 360 then
			inst.Transform:SetRotation(inst.rotat)
			print("Degrees: "..tostring(inst.rotat).." Count: "..tostring(inst.count).." GetRotation: "..tostring(inst.Transform:GetRotation()))
			inst.sg:GoToState("collapse")
			inst.rotat = inst.rotat + DEGREES*5
			inst.count = inst.count + 5
		else
			inst.check:Cancel()
		end
	end)

As well as some raw data

Spoiler

[00:00:50]: Degrees: -3.14159 Count: 0 GetRotation: -3.1415901184082	
[00:00:51]: player_angle: 0.7305664549995	
[00:00:51]: right	
[00:00:52]: Degrees: -3.0543236111111 Count: 5 GetRotation: -3.0543236732483	
[00:00:53]: player_angle: 0.73208954050755	
[00:00:53]: right	
[00:00:53]: Degrees: -2.9670572222222 Count: 10 GetRotation: -2.9670572280884	
[00:00:54]: player_angle: 0.73361262601561	
[00:00:54]: right	
[00:00:54]: Degrees: -2.8797908333333 Count: 15 GetRotation: -2.8797907829285	
[00:00:55]: player_angle: 0.73513571152367	
[00:00:55]: right	
[00:00:56]: Degrees: -2.7925244444444 Count: 20 GetRotation: -2.7925243377686	
[00:00:57]: player_angle: 0.73665879703172	
[00:00:57]: right	
[00:00:57]: Degrees: -2.7052580555556 Count: 25 GetRotation: -2.7052581310272	
[00:00:58]: player_angle: 0.73818187837859	
[00:00:58]: right	
[00:00:59]: Degrees: -2.6179916666667 Count: 30 GetRotation: -2.6179916858673	
[00:01:00]: player_angle: 0.73970496388665	
[00:01:00]: right	
[00:01:00]: Degrees: -2.5307252777778 Count: 35 GetRotation: -2.5307252407074	
[00:01:01]: player_angle: 0.7412280493947	
[00:01:01]: right	
[00:01:02]: Degrees: -2.4434588888889 Count: 40 GetRotation: -2.4434587955475	
[00:01:03]: player_angle: 0.74275113490276	
[00:01:03]: right	
[00:01:03]: Degrees: -2.3561925 Count: 45 GetRotation: -2.3561925888062	
[00:01:04]: player_angle: 0.74427421624962	
[00:01:04]: right	
[00:01:05]: Degrees: -2.2689261111111 Count: 50 GetRotation: -2.2689261436462	
[00:01:06]: player_angle: 0.74579730175768	
[00:01:06]: right	
[00:01:06]: Degrees: -2.1816597222222 Count: 55 GetRotation: -2.1816596984863	
[00:01:07]: player_angle: 0.74732038726574	
[00:01:07]: right	
[00:01:08]: Degrees: -2.0943933333333 Count: 60 GetRotation: -2.0943932533264	
[00:01:09]: player_angle: 0.74884347277379	
[00:01:09]: right	
[00:01:09]: Degrees: -2.0071269444444 Count: 65 GetRotation: -2.0071270465851	
[00:01:10]: player_angle: 0.75036655412066	
[00:01:10]: right	
[00:01:11]: Degrees: -1.9198605555556 Count: 70 GetRotation: -1.9198604822159	
[00:01:12]: player_angle: 0.75188964170931	
[00:01:12]: right	
[00:01:12]: Degrees: -1.8325941666667 Count: 75 GetRotation: -1.8325941562653	
[00:01:13]: player_angle: 0.75341272513677	
[00:01:13]: right	
[00:01:14]: Degrees: -1.7453277777778 Count: 80 GetRotation: -1.7453278303146	
[00:01:15]: player_angle: 0.75493580856423	
[00:01:15]: right	
[00:01:15]: Degrees: -1.6580613888889 Count: 85 GetRotation: -1.6580613851547	
[00:01:16]: player_angle: 0.75645889407229	
[00:01:16]: right	
[00:01:16]: Degrees: -1.570795 Count: 90 GetRotation: -1.5707950592041	
[00:01:17]: player_angle: 0.75798197749975	
[00:01:17]: right	
[00:01:18]: Degrees: -1.4835286111111 Count: 95 GetRotation: -1.4835286140442	
[00:01:19]: player_angle: 0.75950506300781	
[00:01:19]: right	
[00:01:19]: Degrees: -1.3962622222222 Count: 100 GetRotation: -1.3962621688843	
[00:01:20]: player_angle: 0.76102814851586	
[00:01:20]: right	
[00:01:21]: Degrees: -1.3089958333333 Count: 105 GetRotation: -1.3089958429337	
[00:01:22]: player_angle: 0.76255123194332	
[00:01:22]: right	
[00:01:22]: Degrees: -1.2217294444444 Count: 110 GetRotation: -1.2217293977737	
[00:01:23]: player_angle: 0.76407431745138	
[00:01:23]: right	
[00:01:24]: Degrees: -1.1344630555556 Count: 115 GetRotation: -1.1344630718231	
[00:01:25]: player_angle: 0.76559740087884	
[00:01:25]: right	
[00:01:25]: Degrees: -1.0471966666667 Count: 120 GetRotation: -1.0471966266632	
[00:01:26]: player_angle: 0.7671204863869	
[00:01:26]: right	
[00:01:27]: Degrees: -0.95993027777778 Count: 125 GetRotation: -0.95993024110794	
[00:01:28]: player_angle: 0.76864357085465	
[00:01:28]: right	
[00:01:28]: Degrees: -0.87266388888889 Count: 130 GetRotation: -0.87266391515732	
[00:01:29]: player_angle: 0.77016665428212	
[00:01:29]: right	
[00:01:30]: Degrees: -0.7853975 Count: 135 GetRotation: -0.78539752960205	
[00:01:31]: player_angle: 0.77168973874987	
[00:01:31]: right	
[00:01:31]: Degrees: -0.69813111111111 Count: 140 GetRotation: -0.69813108444214	
[00:01:32]: player_angle: 0.77321282425793	
[00:01:32]: right	
[00:01:33]: Degrees: -0.61086472222222 Count: 145 GetRotation: -0.61086469888687	
[00:01:34]: player_angle: 0.77473590872569	
[00:01:34]: right	
[00:01:34]: Degrees: -0.52359833333333 Count: 150 GetRotation: -0.5235983133316	
[00:01:35]: player_angle: 0.77625899319345	
[00:01:35]: right	
[00:01:36]: Degrees: -0.43633194444445 Count: 155 GetRotation: -0.43633195757866	
[00:01:37]: player_angle: 0.77778207714106	
[00:01:37]: right	
[00:01:37]: Degrees: -0.34906555555556 Count: 160 GetRotation: -0.34906554222107	
[00:01:38]: player_angle: 0.77930516212897	
[00:01:38]: right	
[00:01:38]: Degrees: -0.26179916666667 Count: 165 GetRotation: -0.2617991566658	
[00:01:39]: player_angle: 0.78082824659672	
[00:01:39]: right	
[00:01:40]: Degrees: -0.17453277777778 Count: 170 GetRotation: -0.17453277111053	
[00:01:41]: player_angle: 0.78235133106448	
[00:01:41]: right	
[00:01:41]: Degrees: -0.08726638888889 Count: 175 GetRotation: -0.087266385555267	
[00:01:42]: player_angle: 0.78387441553224	
[00:01:42]: right	
[00:01:43]: Degrees: -1.4432899320127e-015 Count: 180 GetRotation: -1.4432899320127e-015	
[00:01:44]: player_angle: 0.7853975	
[00:01:44]: right	
[00:01:44]: Degrees: 0.087266388888887 Count: 185 GetRotation: 0.087266385555267	
[00:01:45]: player_angle: 0.78692058446776	
[00:01:45]: left	
[00:01:46]: Degrees: 0.17453277777778 Count: 190 GetRotation: 0.17453277111053	
[00:01:47]: player_angle: 0.78844366893552	
[00:01:47]: left	
[00:01:47]: Degrees: 0.26179916666667 Count: 195 GetRotation: 0.2617991566658	
[00:01:48]: player_angle: 0.78996675340328	
[00:01:48]: left	
[00:01:49]: Degrees: 0.34906555555555 Count: 200 GetRotation: 0.34906554222107	
[00:01:50]: player_angle: 0.79148983787103	
[00:01:50]: left	
[00:01:50]: Degrees: 0.43633194444444 Count: 205 GetRotation: 0.43633195757866	
[00:01:51]: player_angle: 0.79301292285894	
[00:01:51]: left	
[00:01:52]: Degrees: 0.52359833333333 Count: 210 GetRotation: 0.5235983133316	
[00:01:53]: player_angle: 0.79453600680655	
[00:01:53]: left	
[00:01:53]: Degrees: 0.61086472222222 Count: 215 GetRotation: 0.61086469888687	
[00:01:54]: player_angle: 0.79605909127431	
[00:01:54]: left	
[00:01:55]: Degrees: 0.69813111111111 Count: 220 GetRotation: 0.69813108444214	
[00:01:56]: player_angle: 0.79758217574207	
[00:01:56]: left	
[00:01:56]: Degrees: 0.7853975 Count: 225 GetRotation: 0.78539752960205	
[00:01:57]: player_angle: 0.79910526125013	
[00:01:57]: left	
[00:01:58]: Degrees: 0.87266388888889 Count: 230 GetRotation: 0.87266391515732	
[00:01:59]: player_angle: 0.80062834571788	
[00:01:59]: left	
[00:01:59]: Degrees: 0.95993027777778 Count: 235 GetRotation: 0.95993024110794	
[00:02:00]: player_angle: 0.80215142914535	
[00:02:00]: left	
[00:02:00]: Degrees: 1.0471966666667 Count: 240 GetRotation: 1.0471966266632	
[00:02:01]: player_angle: 0.8036745136131	
[00:02:01]: left	
[00:02:02]: Degrees: 1.1344630555556 Count: 245 GetRotation: 1.1344630718231	
[00:02:03]: player_angle: 0.80519759912116	
[00:02:03]: left	
[00:02:03]: Degrees: 1.2217294444444 Count: 250 GetRotation: 1.2217293977737	
[00:02:04]: player_angle: 0.80672068254862	
[00:02:04]: left	
[00:02:05]: Degrees: 1.3089958333333 Count: 255 GetRotation: 1.3089958429337	
[00:02:06]: player_angle: 0.80824376805668	
[00:02:06]: left	
[00:02:06]: Degrees: 1.3962622222222 Count: 260 GetRotation: 1.3962621688843	
[00:02:07]: player_angle: 0.80976685148414	
[00:02:07]: left	
[00:02:08]: Degrees: 1.4835286111111 Count: 265 GetRotation: 1.4835286140442	
[00:02:09]: player_angle: 0.81128993699219	
[00:02:09]: left	
[00:02:09]: Degrees: 1.570795 Count: 270 GetRotation: 1.5707950592041	
[00:02:10]: player_angle: 0.81281302250025	
[00:02:10]: left	
[00:02:11]: Degrees: 1.6580613888889 Count: 275 GetRotation: 1.6580613851547	
[00:02:12]: player_angle: 0.81433610592771	
[00:02:12]: left	
[00:02:12]: Degrees: 1.7453277777778 Count: 280 GetRotation: 1.7453278303146	
[00:02:13]: player_angle: 0.81585919143577	
[00:02:13]: left	
[00:02:14]: Degrees: 1.8325941666667 Count: 285 GetRotation: 1.8325941562653	
[00:02:15]: player_angle: 0.81738227486323	
[00:02:15]: left	
[00:02:15]: Degrees: 1.9198605555556 Count: 290 GetRotation: 1.9198604822159	
[00:02:16]: player_angle: 0.81890535829069	
[00:02:16]: left	
[00:02:17]: Degrees: 2.0071269444444 Count: 295 GetRotation: 2.0071270465851	
[00:02:18]: player_angle: 0.82042844587934	
[00:02:18]: left	
[00:02:18]: Degrees: 2.0943933333333 Count: 300 GetRotation: 2.0943932533264	
[00:02:19]: player_angle: 0.82195152722621	
[00:02:19]: left	
[00:02:20]: Degrees: 2.1816597222222 Count: 305 GetRotation: 2.1816596984863	
[00:02:21]: player_angle: 0.82347461273426	
[00:02:21]: left	
[00:02:21]: Degrees: 2.2689261111111 Count: 310 GetRotation: 2.2689261436462	
[00:02:22]: player_angle: 0.82499769824232	
[00:02:22]: left	
[00:02:22]: Degrees: 2.3561925 Count: 315 GetRotation: 2.3561925888062	
[00:02:23]: player_angle: 0.82652078375038	
[00:02:23]: left	
[00:02:24]: Degrees: 2.4434588888889 Count: 320 GetRotation: 2.4434587955475	
[00:02:25]: player_angle: 0.82804386509724	
[00:02:25]: left	
[00:02:25]: Degrees: 2.5307252777778 Count: 325 GetRotation: 2.5307252407074	
[00:02:26]: player_angle: 0.8295669506053	
[00:02:26]: left	
[00:02:27]: Degrees: 2.6179916666667 Count: 330 GetRotation: 2.6179916858673	
[00:02:28]: player_angle: 0.83109003611335	
[00:02:28]: left	
[00:02:28]: Degrees: 2.7052580555556 Count: 335 GetRotation: 2.7052581310272	
[00:02:29]: player_angle: 0.83261312162141	
[00:02:29]: left	
[00:02:30]: Degrees: 2.7925244444444 Count: 340 GetRotation: 2.7925243377686	
[00:02:31]: player_angle: 0.83413620296828	
[00:02:31]: left	
[00:02:31]: Degrees: 2.8797908333333 Count: 345 GetRotation: 2.8797907829285	
[00:02:32]: player_angle: 0.83565928847633	
[00:02:32]: left	
[00:02:33]: Degrees: 2.9670572222222 Count: 350 GetRotation: 2.9670572280884	
[00:02:34]: player_angle: 0.83718237398439	
[00:02:34]: left	
[00:02:34]: Degrees: 3.0543236111111 Count: 355 GetRotation: 3.0543236732483	
[00:02:35]: player_angle: 0.83870545949245	
[00:02:35]: left	

If its still not working for you, you could probably use this data to change the if statements to something like this

Spoiler

if inst.Transform:GetRotation() > 0 then
	--left
	inst.Transform:SetRotation(-pi/2)
else
	--right
	inst.Transform:SetRotation(pi/2)
end

 

Edit:

Updated State-graph to demonstrate:

Spoiler

local pi = GLOBAL.PI
local degrees = GLOBAL.DEGREES
local collapse = State {
	name = "collapse",
	tags = { "busy", "pausepredict", "nomorph", "collapsed" },
	onenter = function(inst)
		--inst.Physics:Stop()
		inst.AnimState:PlayAnimation("death")   
		if not inst:HasTag("mime") then
			inst.SoundEmitter:PlaySound((inst.talker_path_override or "dontstarve/characters/")..(inst.soundsname or inst.prefab).."/death_voice")
		end
		if inst.components.playercontroller ~= nil then
			inst.components.playercontroller:RemotePausePrediction()
		end
	end,
	timeline =
	{
		TimeEvent(30 * FRAMES, function(inst)
			local rotat = inst.Transform:GetRotation() + pi
			if rotat > pi and rotat <= pi*2 then
				print(tostring(rotat).." left")
				inst.Transform:SetRotation(-pi/2)
			else
				print(tostring(rotat).." right")
				inst.Transform:SetRotation(pi/2)
			end
			inst.AnimState:PlayAnimation("wakeup")
		end),		
		TimeEvent(55 * FRAMES, function(inst)
			inst.sg:RemoveStateTag("busy")
			inst.sg:RemoveStateTag("collapsed")
		end),
	},
	events =
	{
		EventHandler("animover", function(inst)
			if inst.AnimState:AnimDone() then
				inst.sg:GoToState("idle")
			end
		end),
	},
}
local function SGWilsonPostInit(sg)
    sg.states["collapse"] = collapse
end
AddStategraphState("SGwilson", collapse)
AddStategraphPostInit("wilson", SGWilsonPostInit) 

 

Edited by IronHunter
See above

After exhaustive testing,

This seems to work 100% of the time, as I've tested 360 degrees of rotation and the animation is synced on my computer.

Spoiler

local pi = GLOBAL.PI
local degrees = GLOBAL.DEGREES
local collapse = State {
	name = "collapse",
	tags = { "busy", "pausepredict", "nomorph", "collapsed" },
	onenter = function(inst)
		--inst.Physics:Stop()
		inst.AnimState:PlayAnimation("death")   
		if not inst:HasTag("mime") then
			inst.SoundEmitter:PlaySound((inst.talker_path_override or "dontstarve/characters/")..(inst.soundsname or inst.prefab).."/death_voice")
		end
		if inst.components.playercontroller ~= nil then
			inst.components.playercontroller:RemotePausePrediction()
		end
	end,
	timeline =
	{
		TimeEvent(30 * FRAMES, function(inst)
			local rotat = inst.Transform:GetRotation() + pi
			if rotat > pi and rotat <= pi*2 then
				print(tostring(rotat).." left")
				inst.Transform:SetRotation(-pi/2)
			else
				print(tostring(rotat).." right")
				inst.Transform:SetRotation(pi/2)
			end
			inst.AnimState:PlayAnimation("wakeup")
		end),		
		TimeEvent(55 * FRAMES, function(inst)
			inst.sg:RemoveStateTag("busy")
			inst.sg:RemoveStateTag("collapsed")
		end),
	},
	events =
	{
		EventHandler("animover", function(inst)
			if inst.AnimState:AnimDone() then
				inst.sg:GoToState("idle")
			end
		end),
	},
}
local function SGWilsonPostInit(sg)
    sg.states["collapse"] = collapse
end
AddStategraphState("SGwilson", collapse)
AddStategraphPostInit("wilson", SGWilsonPostInit) 

 

lol

After exhaustive testing,

This seems to work 100% of the time, as I've tested 360 degrees of rotation and the animation is synced on my computer.

Spoiler

local pi = GLOBAL.PI
local degrees = GLOBAL.DEGREES
local collapse = State {
	name = "collapse",
	tags = { "busy", "pausepredict", "nomorph", "collapsed" },
	onenter = function(inst)
		--inst.Physics:Stop()
		inst.AnimState:PlayAnimation("death")   
		if not inst:HasTag("mime") then
			inst.SoundEmitter:PlaySound((inst.talker_path_override or "dontstarve/characters/")..(inst.soundsname or inst.prefab).."/death_voice")
		end
		if inst.components.playercontroller ~= nil then
			inst.components.playercontroller:RemotePausePrediction()
		end
	end,
	timeline =
	{
		TimeEvent(45 * FRAMES, function(inst)
			local rotat = inst.Transform:GetRotation() + pi
			if rotat > pi and rotat <= pi*2 then
				print(tostring(rotat).." left")
				inst.Transform:SetRotation(-pi/2)
			else
				print(tostring(rotat).." right")
				inst.Transform:SetRotation(pi/2)
			end
			inst.AnimState:PlayAnimation("wakeup")
		end),		
		TimeEvent(55 * FRAMES, function(inst)
			inst.sg:RemoveStateTag("busy")
			inst.sg:RemoveStateTag("collapsed")
		end),
	},
	events =
	{
		EventHandler("animover", function(inst)
			if inst.AnimState:AnimDone() then
				inst.sg:GoToState("idle")
			end
		end),
	},
}
local function SGWilsonPostInit(sg)
    sg.states["collapse"] = collapse
end
AddStategraphState("SGwilson", collapse)
AddStategraphPostInit("wilson", SGWilsonPostInit) 

 

lol

Edited by IronHunter

WOW!!! Amazing, truly amazing :D:D:D!!!! Thanks so much!!!! Now everything's so great, thank you!! (Though, with movement prediction off it looks a little choppy, but who cares!!) 

Everything's great man, thank you SO much for all your time, thank you, thank you :wilson_goodjob:!!!!!!

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
×
  • Create New...