Sign in to follow this  
PuroPlays

Need help with custom perks

Recommended Posts

PuroPlays    0

Hello! If you are reading this and want to help, thank you!

Basically I have made a custom character with the DST extended character template, however i do not know how to code the perks i want.

The perks are gain higher damage, speed, and health the lower sanity you are.
And the other perk i need help with is that the character gains more stats from sleeping, but uses less hunger.

Thank you for helping!

Share this post


Link to post
Share on other sites
Ultroman    697

You have different options for some of these. Damage can be added to your character as a flat bonus damage for any damage you deal, or as a percentage modifier for any damage you deal. Either do:

inst.components.combat.bonus = 5 -- plus 5 damage to any damage you deal

or

inst.components.combat.externaldamagemultipliers:SetModifier("CHARACTERNAME", 1.05) -- 5% damage increase

For movement speed, the locomotor-component is what you want, and it has its own implementation of external modifiers, so you can do:

inst.components.locomotor:SetExternalSpeedMultiplier(inst, 1.05, "CHARACTERNAME") -- 5% speed increase

For health, I'm not sure what you want. Do you want to gain health or do you want to increase max health, or both? The first is the easiest.

EDIT: THIS APPROACH TO CHANGE THE SLEEPING VARIABLES DOESN'T WORK! Look at CarlZalph's reply in this other thread for an explanation and some working code!
For the increase in stats from sleeping, you're treading into some stinky waters. All the code for giving stats while sleeping, are done in local functions in the prefabs for the sleeping equipment, and they use TUNING variables. Since changing the TUNING variables would mean affecting everyone on the server, that's a bad choice. Fortunately, the sleepingbag-component (which is on the bedrolls, the tent and the siestahut) has a reference to these local functions, so you can extend the current functions, and add some code yourself.

Spoiler



AddComponentPostInit("sleepingbag", function(comp)
	-- Wait until next tick, so the prefab which added this component is done initializing.
	comp.inst:DoTaskInTime(0, function(comp)
		local old_onsleep = comp.onsleep
		comp.onsleep = function(inst, sleeper)
			old_onsleep(inst, sleeper) -- call the original function
			
			-- If the sleeper is your character, do some more stuff. onsleep is called many times while you sleep, so don't go overboard.
			-- Even 1 might be too much, so you can try 0.5 or 0.8, as well.
			if sleeper.prefab == "CHARACTERNAME" then
				sleeper.components.health:DoDelta(1, true) -- add 1 more health; "true" here means it won't show an extra blip on your health-meter
				sleeper.components.sanity:DoDelta(1, true) -- add 1 more sanity; ditto for the sanity-meter
				sleeper.components.hunger:DoDelta(1, true) -- add 1 more hunger; ditto for the hunger-meter
			end
		end
	end)
end)


 

Almost forgot about the first stuff being about how much sanity you have.

You can listen to the event "sanitydelta" on your character, which is called whenever your sanity is changed. Do like this:

-- Put this function above your character's fn().
local myfunction = function(inst, data)
	-- inst is your character. Data is data from the DoDelta(function) in the sanity component.
	local old_percent = data.old_percent -- percentage before the sanity change
	local new_percent = data.new_percent -- percentage after the sanity change
	-- Do something with it.
	-- inst.components.sanity.current will tell you the new value of sanity.
	-- inst.components.sanity.max will tell you the maximum sanity for your character.
	-- From this information, you should be able to calculate whatever you want for weighing your variables.
	-- This is where you would change your damage and speed modifiers, depending on how much sanity you have.
	-- Again, still not sure what you propose to do with health, but you will do that here, as well.
end

-- At the bottom of your character's fn(), do this...
inst:ListenForEvent("sanitydelta", myfunction)

 

Edited by Ultroman

Share this post


Link to post
Share on other sites
PuroPlays    0
On 2/5/2019 at 10:11 PM, Ultroman said:

You have different options for some of these. Damage can be added to your character as a flat bonus damage for any damage you deal, or as a percentage modifier for any damage you deal. Either do:


inst.components.combat.bonus = 5 -- plus 5 damage to any damage you deal

or


inst.components.combat.externaldamagemultipliers:SetModifier("CHARACTERNAME", 1.05) -- 5% damage increase

For movement speed, the locomotor-component is what you want, and it has its own implementation of external modifiers, so you can do:


inst.components.locomotor:SetExternalSpeedMultiplier(inst, 1.05, "CHARACTERNAME") -- 5% speed increase

For health, I'm not sure what you want. Do you want to gain health or do you want to increase max health, or both? The first is the easiest.

For the increase in stats from sleeping, you're treading into some stinky waters. All the code for giving stats while sleeping, are done in local functions in the prefabs for the sleeping equipment, and they use TUNING variables. Since changing the TUNING variables would mean affecting everyone on the server, that's a bad choice. Fortunately, the sleepingbag-component (which is on the bedrolls, the tent and the siestahut) has a reference to these local functions, so you can extend the current functions, and add some code yourself.


AddComponentPostInit("sleepingbag", function(comp)
	local old_onsleep = comp.onsleep
	comp.onsleep = function(inst, sleeper)
		old_onsleep(inst, sleeper) -- call the original function
		
		-- If the sleeper is your character, do some more stuff. onsleep is called many times while you sleep, so don't go overboard.
		-- Even 1 might be too much, so you can try 0.5 or 0.8, as well.
		if sleeper.prefab == "CHARACTERNAME" then
			sleeper.components.health:DoDelta(1, true) -- add 1 more health; "true" here means it won't show an extra blip on your health-meter
			sleeper.components.sanity:DoDelta(1, true) -- add 1 more sanity; ditto for the sanity-meter
			sleeper.components.hunger:DoDelta(1, true) -- add 1 more hunger; ditto for the hunger-meter
		end
	end
end

 

Almost forgot about the first stuff being about how much sanity you have.

You can listen to the event "sanitydelta" on your character, which is called whenever your sanity is changed. Do like this:


-- Put this function above your character's fn().
local myfunction = function(inst, data)
	-- inst is your character. Data is data from the DoDelta(function) in the sanity component.
	local old_percent = data.old_percent -- percentage before the sanity change
	local new_percent = data.new_percent -- percentage after the sanity change
	-- Do something with it.
	-- inst.components.sanity.current will tell you the new value of sanity.
	-- inst.components.sanity.max will tell you the maximum sanity for your character.
	-- From this information, you should be able to calculate whatever you want for weighing your variables.
	-- This is where you would change your damage and speed modifiers, depending on how much sanity you have.
	-- Again, still not sure what you propose to do with health, but you will do that here, as well.
end

-- At the bottom of your character's fn(), do this...
inst:ListenForEvent("sanitydelta", myfunction)

 

Thank you for your reply! I was thinking of adding and healing max health but if that is hard i would rather just heal health, also i have a question does this go in the prefab (charactername.lua) and if so how would it look like if complete, thanks for your help!

Share this post


Link to post
Share on other sites
Ultroman    697

You're welcome :)

EDIT: THE AddComponentPostInit APPROACH TO CHANGE THE SLEEPING VARIABLES DOESN'T WORK! Look at CarlZalph's reply in this other thread for an explanation and some working code!

AddComponentPostInit goes in your modmain.lua

Listening to sanitydelta is to be done in the charactername.lua as I described in the code snippet.

It's not that it's hard per se, to change max health. It just seems like it'd be confusing to the player. I don't know. It's just that to regain it you have to craft items, and dying already decreases your max health.

The way max health penalty works, is that there's a penalty variable in the health-component. If it's 0, then there's 0% penalty (full max health); if it's 1, there's 100% penalty (0 max health); if it's 0.5, it's 50% max health (half max health). It's easy enough to manipulate. I just see annoyances having that kind of "perk". But you do whatever you want :)

You just need to somehow weigh the settings for these stats in myfunction, based on the current sanity.

Edited by Ultroman

Share this post


Link to post
Share on other sites
Ultroman    697

EDIT: THIS APPROACH TO CHANGE THE SLEEPING VARIABLES DOESN'T WORK! Look at CarlZalph's reply in this other thread for an explanation and some working code!

Just letting you know, that I've changed the code in my earlier post for the sleeping-stuff, since I forgot about a little caveat when using AddComponentPostInit. That function queues a function to be run after a component has been initialized, but since a component is always initialized first and has its functions changed later, what happens is this:

  1. a prefab has the sleepingbag-component added to it
  2. our function is called, and makes its changes
  3. the prefab makes changes its to the sleepingbag-component (overwriting our onsleep function)

There are two ways we can fix this:

  1. We move this code to four AddPrefabPostInit calls (one for each sleeping equipment) and refactor it slightly.
  2. We simply delay the changing of our code a tiny bit into the future using DoTaskInTime, because DoTaskInTime waits at least until next game-tick, even if you tell it to wait for 0 time.

Number 1 would be the obvious thing to do (and is also how I do it in my Sleepy Time mod, but if we do number 2, then we actually accommodate even the sleeping-equipment added by mods (or by Klei at a later date), since we go directly for the sleepingbag-component instead of individual prefabs.

I changed the code in my post above to use number 2 method.

Edited by Ultroman

Share this post


Link to post
Share on other sites

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
Sign in to follow this