Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

Frigfrid

Need help with Speed stat related to Wetness

Recommended Posts

Frigfrid    31

So, somehow I'm actually on college to learn programming but LUA's kicking my ass hard.

I need some help making a function (or anything, really) that makes him get a speed boost on two separate wetness levels, as in:

>29, speed is multiplied from 1 to 1.05

>59, speed is multiplied from 1 to 1.2

Everything else on the code is sorted out correctly, this is the only thing that's being a problem to me right now. An optional thing I'd like to add but, once again, is optional and not required, is making held weapons slip more easily than on a vanilla character since he's pretty clumsy.

I tried some codes I found on the forums, but none of them worked properly. One did manage to kiiiind of work, until I got the wetness above 59. Then the game crashed.

Current attempted code screenshots as follows:

BPv7SR2.png

(on local functions before master_postinit)

 

Tu3xFAR.png

inside master_postinit

I've tried other methods but this one was the least buggy one up to now.

 

Share this post


Link to post
Share on other sites
Ultroman    656

Note: Please read the last part of the post for an alternative approach, before using these code snippets.

This isn't the prettiest it can be, but it'll work. This is using an event listener, like in your code. What you were lacking, was actually setting the speed modifier on the player.

local function onmoisturedelta(inst)
	if inst.components.moisture:IsWet() then
		-- Remember to give it a default value at the end of such an inline conditional declaration.
		local speed = inst.wetness > 59 and 1.2 or inst.wetness > 29 and 1.05 or 1.0
		if speed == 1.0 then
			-- If speed multiplier is to be 1.0, remove it.
			inst.components.locomotor:RemoveExternalSpeedMultiplier(inst, "myuniquemodifierkey")
		else
			-- When using the same modifier key, it will just replace any existing modifier with the same key.
			inst.components.locomotor:SetExternalSpeedMultiplier(inst, "myuniquemodifierkey", speed)
		end
	else
		-- Remove modifier if the player is no longer wet.
		inst.components.locomotor:RemoveExternalSpeedMultiplier(inst, "myuniquemodifierkey")
	end
end

To save on CPU cycles, we can save the last result and only react when the result changes.

local function onmoisturedelta(inst)
	if inst.components.moisture:IsWet() then
		-- Remember to give it a default value at the end of such an inline conditional declaration.
		local speed = inst.wetness > 59 and 1.2 or inst.wetness > 29 and 1.05 or 1.0
		
		-- If we have a value in the variable inst.myModNameLastSpeedModifierResult, then
		-- we know what the last result was. If the new result is the same, exit early.
		if inst.myModNameLastSpeedModifierResult and speed == inst.myModNameLastSpeedModifierResult then
			return
		end
		
		-- Otherwise, save the new speed value to inst.myModNameLastSpeedModifierResult
		inst.myModNameLastSpeedModifierResult = speed
		
		-- Apply or remove the speed modifier as you see fit.
		if speed == 1.0 then
			-- If speed multiplier is to be 1.0, remove it.
			inst.components.locomotor:RemoveExternalSpeedMultiplier(inst, "myuniquemodifierkey")
		else
			-- When using the same modifier key, it will just replace any existing modifier with the same key.
			inst.components.locomotor:SetExternalSpeedMultiplier(inst, "myuniquemodifierkey", speed)
		end
	else
		-- Remove modifier if the player is no longer wet.
		inst.components.locomotor:RemoveExternalSpeedMultiplier(inst, "myuniquemodifierkey")
	end
end

 

To save even more on CPU cycles, you can use a periodic task instead of ListenForEvent. An event listener listening to changes in such things as temperature, health, sanity, hunger, moisture, etc., is potentially called several times per frame. We do not need buffs like this to be evaluated several times per frame. With a periodic task, we can make it check every 1 second or every 0.5 seconds. Granted, the periodic task then always runs during the summer while the player will never get wet, but the performance impact of such a simple check is negligible when it only happens once every 30 or 60 frames.

Look at this guide for how to make buffs using periodic tasks. There's even a movement speed example.

Share this post


Link to post
Share on other sites
Frigfrid    31
12 hours ago, Ultroman said:

Note: Please read the last part of the post for an alternative approach, before using these code snippets.

This isn't the prettiest it can be, but it'll work. This is using an event listener, like in your code. What you were lacking, was actually setting the speed modifier on the player.


local function onmoisturedelta(inst)
	if inst.components.moisture:IsWet() then
		-- Remember to give it a default value at the end of such an inline conditional declaration.
		local speed = inst.wetness > 59 and 1.2 or inst.wetness > 29 and 1.05 or 1.0
		if speed == 1.0 then
			-- If speed multiplier is to be 1.0, remove it.
			inst.components.locomotor:RemoveExternalSpeedMultiplier(inst, "myuniquemodifierkey")
		else
			-- When using the same modifier key, it will just replace any existing modifier with the same key.
			inst.components.locomotor:SetExternalSpeedMultiplier(inst, "myuniquemodifierkey", speed)
		end
	else
		-- Remove modifier if the player is no longer wet.
		inst.components.locomotor:RemoveExternalSpeedMultiplier(inst, "myuniquemodifierkey")
	end
end

To save on CPU cycles, we can save the last result and only react when the result changes.


local function onmoisturedelta(inst)
	if inst.components.moisture:IsWet() then
		-- Remember to give it a default value at the end of such an inline conditional declaration.
		local speed = inst.wetness > 59 and 1.2 or inst.wetness > 29 and 1.05 or 1.0
		
		-- If we have a value in the variable inst.myModNameLastSpeedModifierResult, then
		-- we know what the last result was. If the new result is the same, exit early.
		if inst.myModNameLastSpeedModifierResult and speed == inst.myModNameLastSpeedModifierResult then
			return
		end
		
		-- Otherwise, save the new speed value to inst.myModNameLastSpeedModifierResult
		inst.myModNameLastSpeedModifierResult = speed
		
		-- Apply or remove the speed modifier as you see fit.
		if speed == 1.0 then
			-- If speed multiplier is to be 1.0, remove it.
			inst.components.locomotor:RemoveExternalSpeedMultiplier(inst, "myuniquemodifierkey")
		else
			-- When using the same modifier key, it will just replace any existing modifier with the same key.
			inst.components.locomotor:SetExternalSpeedMultiplier(inst, "myuniquemodifierkey", speed)
		end
	else
		-- Remove modifier if the player is no longer wet.
		inst.components.locomotor:RemoveExternalSpeedMultiplier(inst, "myuniquemodifierkey")
	end
end

 

To save even more on CPU cycles, you can use a periodic task instead of ListenForEvent. An event listener listening to changes in such things as temperature, health, sanity, hunger, moisture, etc., is potentially called several times per frame. We do not need buffs like this to be evaluated several times per frame. With a periodic task, we can make it check every 1 second or every 0.5 seconds. Granted, the periodic task then always runs during the summer while the player will never get wet, but the performance impact of such a simple check is negligible when it only happens once every 30 or 60 frames.

Look at this guide for how to make buffs using periodic tasks. There's even a movement speed example.

Hey, thanks a lot for replying, this one actually managed to work fine! I'll try to do the other method later on if it's needed (ie, it lags on other computers) since I have a tester with a weaker CPU. This helped me a lot

Thanks once again :')

Share this post


Link to post
Share on other sites
Ultroman    656

It's not that it will make other computers lag by itself. It's more that if all modders try to minimize the CPU usage of their mods, the more mods every player can have running at the same time.

Share this post


Link to post
Share on other sites