Jump to content

Passive health regen


Ran

Recommended Posts

I swear I've been researching this for about 3 hours, and it sounds like it should be the simplest thing ever, but I can't for the life of me make it work.

 

I just want to add a passive health regen to the player. All the time, no if's, no nothing. There's multiple mods that add health regen but they are all needlessly complicated for what I want, and I couldn't really extract what I want from checking their codes.

 

I always get the dumbest errors which I'm sure can be solved really easily, but I just don't know how.

The most basic I could find around was:

inst.components.health:StartRegen( , ) --regen amount and period here, also looks like a butt when empty

but that gives me an error saying inst is a nil value. I tried solving that, but then it also said components was a nil value. I'm almost sure this is all really dumb to solve for someone who knows about it, but unfortunately I just don't.

Link to comment
Share on other sites

I swear I've been researching this for about 3 hours, and it sounds like it should be the simplest thing ever, but I can't for the life of me make it work.

 

I just want to add a passive health regen to the player. All the time, no if's, no nothing. There's multiple mods that add health regen but they are all needlessly complicated for what I want, and I couldn't really extract what I want from checking their codes.

 

I always get the dumbest errors which I'm sure can be solved really easily, but I just don't know how.

The most basic I could find around was:

inst.components.health:StartRegen( , ) --regen amount and period here, also looks like a butt when empty

but that gives me an error saying inst is a nil value. I tried solving that, but then it also said components was a nil value. I'm almost sure this is all really dumb to solve for someone who knows about it, but unfortunately I just don't.

 

It should work. Is your code located in modmain? If so, please post it.

Link to comment
Share on other sites

The whole modmain.lua is:

TUNING.WILSON_RUN_SPEED = 7inst.components.health:StartRegen(1, 3)

The first part works perfectly on its own. The numbers I'm just testing so don't mind em too much. The whole mod is that and the modinfo.lua.

When I enable it I get:

 

"...mon/dont_starve/data/../mods/Ran's Stats/modmain.lua:3: attempt to index global 'inst' (a nil value)"

 

Link to comment
Share on other sites

The whole modmain.lua is:

TUNING.WILSON_RUN_SPEED = 7inst.components.health:StartRegen(1, 3)

The first part works perfectly on its own. The numbers I'm just testing so don't mind em too much. The whole mod is that and the modinfo.lua.

When I enable it I get:

 

"...mon/dont_starve/data/../mods/Ran's Stats/modmain.lua:3: attempt to index global 'inst' (a nil value)"

 

In the game code, "inst" is used as a name for whatever instance(s) is (are) being treatened at the moment. You are not treating any instance. Generally you'd have to use a complicated chain of functions and methods to aquire the instances you want. But luckily there's a simple function to solve your problem, known as GetPlayer:

 

GetPlayer().components.health:StartRegen(1,3)

Link to comment
Share on other sites

If you want a modded health regen its best to do it WITHOUT using StartRegen()

 

Other mods that do stuff with regen will end up making your perm regen stop when what were doing finishes up.  Since the Health component only tracks one regen task, which is meant to be temporary, its a bad place to use for your needs.  Just use your own DoPeriodicTask() routine with a regen rate you are happy with applied in the callback.

Link to comment
Share on other sites

If you want a modded health regen its best to do it WITHOUT using StartRegen()

 

Other mods that do stuff with regen will end up making your perm regen stop when what were doing finishes up.  Since the Health component only tracks one regen task, which is meant to be temporary, its a bad place to use for your needs.  Just use your own DoPeriodicTask() routine with a regen rate you are happy with applied in the callback.

 

I doubt this person knows what DoPeriodicTask is XD

 

local function Regen(inst)

    inst.components.health:DoDelta(1) --how much to heal every turn

end

 

GetPlayer():DoPeriodicTask(2,Regen) --how long a turn takes

Link to comment
Share on other sites

Yeah, I did read about the whole instance thing, but still I couldn't find how to fix it. I tried the GetPlayer but I think I just used wrong syntax on that... (namely, I don't think I put the () after it, lol).

 

And indeed I had no idea what DoPeriodicTask was. I mean, I can understand the logic behind it, but not how to use it. I'll try that out.

 

Edit: Oh my god I'm just about ready to strangle kittens.

 

"...mon/dont_starve/data/../mods/Ran's Stats/modmain.lua:7: attempt to call global 'GetPlayer' (a nil value)"

 

Using:

local function Regen(inst)    inst.components.health:DoDelta(1)endGetPlayer():DoPeriodicTask(2,Regen)

Then I tried:

GLOBAL.GetPlayer():DoPeriodicTask(2,Regen)

(cause I don't understand much but sometimes that's what I needed to do) and simply got:

 

"...mon/dont_starve/data/../mods/Ran's Stats/modmain.lua:7: attempt to index a nil value"

Link to comment
Share on other sites

local function Regen()     GLOBAL.GetPlayer().components.health:DoDelta(1) end

Just so you understand whats wrong, the original regen function is never actually given an instance of the player so it has no clue who 'inst' was.   Either change the function to match what i just put above or change the call itself to back this line below.  Choose one or the other.  Not both.

GLOBAL.GetPlayer():DoPeriodicTask(2, function() Regen(GLOBAL.GetPlayer()) end)
Link to comment
Share on other sites

I'm... pretty confused right now, to be honest.

 

From what I understand I should change the inst for a GLOBAL.GetPlayer() (and get rid of the inst above), because there's nothing referencing to the player? I guess other regen mods I've done before always used an entity name in the function (like "glommer"), so then the inst refers to them, right? But do I even need a function if that's the case? Cause now it looks like the DoPeriodicTask part, which is just out there in the open.

 

And don't really understand the other method.

Link to comment
Share on other sites

I'm... pretty confused right now, to be honest.

 

From what I understand I should change the inst for a GLOBAL.GetPlayer() (and get rid of the inst above), because there's nothing referencing to the player? I guess other regen mods I've done before always used an entity name in the function (like "glommer"), so then the inst refers to them, right? But do I even need a function if that's the case? Cause now it looks like the DoPeriodicTask part, which is just out there in the open.

 

And don't really understand the other method.

with my single line of code that I put all characters will regen 1 health every 2 seconds very basic and very simple! nothing else needed at all

Link to comment
Share on other sites

Tried it, still giving an error x_x

 

"...mon/dont_starve/data/../mods/Ran's Stats/modmain.lua:9: attempt to index a nil value"

 

The whole code for reference:

TUNING.WILSON_RUN_SPEED = 7--[[local function Regen()    GLOBAL.GetPlayer().components.health:DoDelta(1)endGLOBAL.GetPlayer():DoPeriodicTask(2,Regen)]]GLOBAL.GetPlayer():DoPeriodicTask(2, function() GLOBAL.GetPlayer().components.health:DoDelta(1) end)

The commented out part is what I tried before, and gives the same error. I imagine both are the same thing just written differently.

Link to comment
Share on other sites

@Ran

 

More on instances.

 

Working tested code:

AddSimPostInit(function(player)	local time = 2 -- seconds	local amt = 1	player:DoPeriodicTask(time, function()		-- print("Healing")		player.components.health:DoDelta(amt)	end)end)

Edit: Yes, that can be shortened, but sometimes readability is more important than doing things in one line. The code won't run any faster because it's written more concisely, it still does all the steps as usual. It's especially helpful for beginners if they can understand the code by reading it.

Link to comment
Share on other sites

I agree, I rather something longer if I can understand it easier :razz: I'll give it a try.

 

Small question though, what are those commented "print" for? I've seen em all over the game files. I understand making a comment to explain what something is, but why the print? From what I gather print is to make some text show up somewhere on the screen, but if it's commented it wouldn't really do anything.

 

Edit: Alright, works perfectly. But there's one little thing that bugs me a bit... The sound it makes each time. I suppose it may be just normal, each time someone would normally get healed without mods it would trigger that sound, but other health regen mods I tried didn't actually do that. Is there any simple way to get rid of it? I don't wanna keep bothering people for something like this, so only if it's easy to do. I don't intend to actually make the regen happen every 2 seconds anyway, so it won't be that bad.

Link to comment
Share on other sites

@Ran I used the print statement myself when testing the code, it wrote "Healing" to the console (press the grave accent key ` to open it). I commented it before posting the code here so it won't spam the console if you actually use that code. I didn't erase it completely so you can uncomment it during development to confirm that it is working.

 

Hmm. One moment, gotta check where the sound is coming from.

 

Edit: The sound is coming from the StatusDisplays widget

Copied here for reference:

self.inst:ListenForEvent("healthdelta", function(inst, data)  self:HealthDelta(data) end, self.owner)
function StatusDisplays:HealthDelta(data)	self.heart:SetPercent(data.newpercent, self.owner.components.health.maxhealth,self.owner.components.health:GetPenaltyPercent()) 		if data.oldpercent > .33 and data.newpercent <= .33 then		self.heart:StartWarning()	else		self.heart:StopWarning()	end		if not data.overtime then		if data.newpercent > data.oldpercent then			self.heart:PulseGreen()			TheFrontEnd:GetSound():PlaySound("dontstarve/HUD/health_up")		elseif data.newpercent < data.oldpercent then			TheFrontEnd:GetSound():PlaySound("dontstarve/HUD/health_down")			self.heart:PulseRed()		end	endend

 

You can modify that function to not make a sound depending on the cause.

local regen_cause = "custom_regen" -- Set this to whatever suits your modAddSimPostInit(function(player)	local time = 2 -- seconds	local amt = 1	player:DoPeriodicTask(time, function()		-- print("Healing")		-- Send a string in the cause parameter		player.components.health:DoDelta(amt, nil, regen_cause)	end)end)AddClassPostConstruct("widgets/statusdisplays", function(self)	local old_HealthDelta = self.HealthDelta	-- Copied from StatusDisplays	local HealthDelta_nosound = function(self, data)		self.heart:SetPercent(data.newpercent, self.owner.components.health.maxhealth,self.owner.components.health:GetPenaltyPercent())		if data.oldpercent > .33 and data.newpercent <= .33 then			self.heart:StartWarning()		else			self.heart:StopWarning()		end		if not data.overtime then			if data.newpercent > data.oldpercent then				self.heart:PulseGreen()				-- TheFrontEnd:GetSound():PlaySound("dontstarve/HUD/health_up")			elseif data.newpercent < data.oldpercent then				-- TheFrontEnd:GetSound():PlaySound("dontstarve/HUD/health_down")				self.heart:PulseRed()			end		end	end	-- The new health delta function	function self:HealthDelta(data)		if (data.cause == regen_cause) then			return HealthDelta_nosound(self, data)		else			return old_HealthDelta(self, data)		end	endend) 

Untested code.

 

Edit 2: Minor change to code above. Added return statement.

 

Edit 3: Fixed error from the posts below. (passing self)

 

Link to comment
Share on other sites

I see, so it's basically leftovers from testing. I remember laughing at some, like when attacking a Smallbird it would say "What did I ever do to you?", lol.

 

And damn, that's a lot of work you did, hope I'm not taking time away from something else. I'll test it in a bit, gotta do something else right now.

Link to comment
Share on other sites

I remember laughing at some, like when attacking a Smallbird it would say "What did I ever do to you?", lol.

Ahaha, yeahh. I remember that too xD Poor bird.

 

It's not really too much, only takes a couple minutes if you know what to look for, and another few because I like to make it organized.

Also, a large portion of the new code is copied directly from the game's code.

Link to comment
Share on other sites

Hm, well I think I didn't quite understand that last code. I'm getting an "attempt to index global 'StatusDisplays' (a nil value)" or the same but with "heart", but it might be my own fault, I'm not quite sure how I'm supposed to combine that new part with the old part, or if it should override it completely...

Link to comment
Share on other sites

@Ran The new one is the full code, the old one is included in there already.

Did you copy the first two portions? That was just a copy-paste of parts of statusdisplays.lua which makes a sound for reference.

 

Edit: I modified that post to make it clearer which part needs to be copied.

Link to comment
Share on other sites

Hm, yeah, that's what I tried first. I'm getting:

 

".../dont_starve/data/scripts/widgets/statusdisplays.lua:39: attempt to index field 'heart' (a nil value)"

 

when I try to load a save. It doesn't show an error then enabling the mod though, only when I try to load a save. Just in case I tried starting a new game, but it's the same thing after the world finishes generating.

Link to comment
Share on other sites

The magic of coding, where missing one seemingly insignificant tiny little thing can screw up absolutely everything. Lol.

 

Seems to work just right. Regen's fine, and no annoying sounds. Thanks a lot everyone :D

Link to comment
Share on other sites

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.

×
  • Create New...