Sign in to follow this  
sinideas

[SOLVED] how to access healthbadge?

Recommended Posts

sinideas    2

I would like to access the "healthbadge" widget via the player inst.
Is this possible?

I found this old post

but:

inst.HUD.controls

returns nil 

:(

Edited by sinideas

Share this post


Link to post
Share on other sites
sinideas    2

Thanks for the help guys and sorry for my clumsiness :)

9 hours ago, Ultroman said:

Take a look at another mod that does it. Combined Status comes to mind.

Couldn't find anything that help me out :(

6 hours ago, YakumoYukari said:

inst.HUD only exist in the client

So it should be accessed in client-side.

I'am on the clien-side(I think >.<) and inst.HUD does exist but inst.HUD.controls doesn't

I can do it with components, for example to access to the health component:

inst.components.health...

I just want to do the same thing but for a widget instead (healthbadge one, in this case)

Edited by sinideas

Share this post


Link to post
Share on other sites
Ultroman    742

What exactly do you want to achieve? Knowing that might make it easier for us to help you find a way to do it. What is your mod? What do you want it to do concerning the health or the health badge?

Share this post


Link to post
Share on other sites
sinideas    2
1 hour ago, Ultroman said:

What exactly do you want to achieve? Knowing that might make it easier for us to help you find a way to do it. What is your mod? What do you want it to do concerning the health or the health badge?

The mod is working fine ( I think xD), I found one alternative that is using Events
modmain.lua (Line 14):

self.inst:PushEvent("AddHpToRegen", amount)

modmain.lua (Line 29) inside healthbadge using AddClassPostConstruct:

...ListenForEvent("AddHpToRegen"...

But I still want to learn how to access without events, "directly", if it is even posible >.<

Something like:

modmain.lua (Line 14):

-- self.inst:PushEvent("AddHpToRegen", amount)
self.inst.HUD.controls.healthbadge.HpReg.FunctionToDoTheThings()

 

Edited by sinideas

Share this post


Link to post
Share on other sites
Ultroman    742

Seems like you're doing an unnecessary switch of responsibility here. Why not keep the healing functionality in the health-component, and simply intercept them (like you do) and accumulate them all in a new variable on the health component, and have a script right there similar to what you're doing to heal the owner in the widget? Seems weird to relay the responsibility of the health-component to a widget. The widget could still do what it's supposed to do e.g. show the regen-numbers when it receives the event. Perhaps it could even be made to also show damage numbers, so you are aware whenever your health changes. That's sort of a mod in itself, showing the damage numbers.

Anyway, it looks like it's working fine. Pushing an event is a preferred method. It decouples the HUD from the actual components on the player. That's why DoDelta does it originally.

Edited by Ultroman

Share this post


Link to post
Share on other sites
sinideas    2

Kinda noob on the modding thing sry.

2 hours ago, Ultroman said:

Why not keep the healing functionality in the health-component, and simply intercept them (like you do) and accumulate them all in a new variable on the health component, and have a script right there similar to what you're doing to heal the owner in the widget?

I dont know how to do that :D

At the start of making this mod I added a component who keep track of the healing process, but since the widget need to keep track of the healing process to update the heal animation, it make me feel like the code was redundant, so i removed the component and here we are x)

Edited by sinideas

Share this post


Link to post
Share on other sites
Ultroman    742

The health-component's DoDelta does not handle healing over time. The "amount" it receives is directly added to the player instantly. The "overtime" parameter isn't really used by it, only by the self.redirect function (don't know what that uses it for) and it is sent with the event to the status display (badge), and if "overtime" is set to 'true', then it does not pulse. That's it. The badge does nothing more.

The code handling healing over time is the health-component with its DoRegen function, which internally calls DoDelta each time it applies the incremental amount of healing over time. Sad thing, though, the regen only supports having one regen task running at a time, and the task takes an amount AND a period, so you'd have to do some gymnastics every time you wanted to add another regen.

So, you'd have to roll your own regen, which you have already done, only you've put it half in the UI and half in the health-component. Your initial plan of having your own regen in your own component sounds much better.

Also, right now you're using AddComponentPostInit. Your code extends ALL DoDelta functions in ANYTHING with a health-component, but then internally checks every time DoDelta is called, whether the owner of the component has the tag "player". It would be MUCH better to do AddPlayerPostInit and change only their health components. Even walls have health-components! That's a lot of extra prefabs you're making changes to, and your code doesn't check BEFORE it extends the DoDelta function.

This does the same as your code currently does, but the postinit function is only called on players, instead of on ANY prefab with a health-component.

AddPlayerPostInit(function(inst)
	if inst.components.health then
		local old_DoDelta = inst.components.health.DoDelta
		function inst.components.health:DoDelta(amount, overtime, cause, ignore_invincible, afflicter, ignore_absorb)
			if amount > 0 and cause~="HealthRegen" and cause~="tent" and cause~="siestahut" and cause~="bedroll" then
				--- We call our event
				-- You can catch this in any component of the player, even in your own component.
				self.inst:PushEvent("AddHpToRegen", amount)
				return 0
			else
				--- We call the default "DoDelta"
				return old_DoDelta(self, amount, overtime, cause, ignore_invincible, afflicter, ignore_absorb)
			end
		end
	end
end)

It's totally up to you about how you code the regen etc. Obviously :) But if I were you, I'd go back to having your own component doing the regen, using DoDelta and putting the cause as "HealthRegen". Then in your widget you can just listen for the "healthdelta" event originally called by DoDelta and if the cause is your "HealthRegen" then you push an event with the applied healing to your widget.

Your choice entirely. I'm only advocating for this because of my background in system design where separation of concerns is a huge deal xD

Edited by Ultroman

Share this post


Link to post
Share on other sites
sinideas    2

Thanks a lot for your time and help @Ultroman

On 4/10/2019 at 5:01 AM, Ultroman said:

Also, right now you're using AddComponentPostInit. Your code extends ALL DoDelta functions in ANYTHING with a health-component, but then internally checks every time DoDelta is called, whether the owner of the component has the tag "player". It would be MUCH better to do AddPlayerPostInit and change only their health components. Even walls have health-components! That's a lot of extra prefabs you're making changes to, and your code doesn't check BEFORE it extends the DoDelta function.

:o that make +9999 of sense, didn't thought in that one. You are so right, thanksss

and same for the ("cause~="siestahut" and cause~="bedroll"") thing =) *cheers*

------

I still have curiosity if someone knows about that:

On 4/9/2019 at 5:39 AM, sinideas said:

I would like to access the "healthbadge" widget via the player inst.
Is this possible?

something like: self.inst.HUD.controls.healthbadge (but a working one xD)

 

SOLVED!!!

I was checking if I could access inside a AddClassPostConstruct function, so self.inst.HUD.controls returns nil.

But then I tried in a function that would run after a time since the game started. And now self.inst.HUD.controls EXIST! so now i can access to the healthbadge widget via the player inst with self.inst.HUD.controls.status.heart

\(^.^)/

 

Edited by sinideas

Share this post


Link to post
Share on other sites
zarklord_klei    4016

just fyi, putting any game mechanic inside the HUD, will ensure that it will never work on any mp server, or any server with caves enabled.
IE the only situation it will work properly on is a server without caves launched from the client.

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