Sign in to follow this  
WhiteAutumn

Show the down arrow at health meter [Solved]

Recommended Posts

WhiteAutumn    2
Posted (edited)

Hi,
I'm making a thing that needs health to be drained constantly.
Copying how hunger.lua does it I did inst:DoPeriodicTask running every second that calls health:DoDelta which works,
however I don't get this down arrow that you get when you are starving?
LbF8n47.png

I don't see anything in hunger.lua which makes this arrow appear, how do you do it?
Thanks in advance!

Edited by WhiteAutumn
  • Like 1

Share this post


Link to post
Share on other sites
Ultroman    537

Actually, hunger.lua does trigger it, but it does not control it. The arrow is a client-side thing in the UI. It's part of the health-badge widget. You should not try to control it directly.

Please post the code you're using to manipulate health.

  • Like 1

Share this post


Link to post
Share on other sites
WhiteAutumn    2
23 hours ago, Ultroman said:

Actually, hunger.lua does trigger it, but it does not control it. The arrow is a client-side thing in the UI. It's part of the health-badge widget. You should not try to control it directly.

Please post the code you're using to manipulate health.

Here you go:

local function doHealthDelta(inst)
  if not inst.components.health:IsDead() and not inst:HasTag("playerghost") then
    inst.components.health:DoDelta(-0.1, true, "light")
  end
end

healthDeltaTask = inst:DoPeriodicTask(1, doHealthDelta, nil, inst)

 

Edited by WhiteAutumn

Share this post


Link to post
Share on other sites
WhiteAutumn    2
6 hours ago, thomas4845 said:

inst.components.health:DoDelta(-0,1, false, "light") can you try this

Tested and does not work :/

 


Looking at the declaration of DoDelta in health.lua

function Health:DoDelta(amount, overtime, cause, ignore_invincible, afflicter, ignore_absorb)

You'd think overtime true would make the arrow appear :/ 

Edited by WhiteAutumn

Share this post


Link to post
Share on other sites
Ultroman    537

What @WhiteAutumn posted is right, except one thing. We use periods as decimal separators, and the code snippet used a comma.

inst.components.health:DoDelta(-0.1, false, "light")

 

Share this post


Link to post
Share on other sites
WhiteAutumn    2
41 minutes ago, Ultroman said:

What @WhiteAutumn posted is right, except one thing. We use periods as decimal separators, and the code snippet used a comma.


inst.components.health:DoDelta(-0.1, false, "light")

 

Sorry that was a mistake from my trying to extract a more readable snippet from my mod, in code it's actually a dot.
One thing I forgot to mention is that my code snipped runs only server side since I components can't be modified on the client (iirc), maybe that's useful for diagnosing the problem.

Share this post


Link to post
Share on other sites
Ultroman    537
4 minutes ago, WhiteAutumn said:

Sorry that was a mistake from my trying to extract a more readable snippet from my mod, in code it's actually a dot.
One thing I forgot to mention is that my code snipped runs only server side since I components can't be modified on the client (iirc), maybe that's useful for diagnosing the problem.

Very understandable mistake, m8. And you're right. Clients don't have components (well, most of them, anyway). They only have replicas in order to communicate with the server.

Share this post


Link to post
Share on other sites
WhiteAutumn    2

Testing just to make sure, running it from client does indeed not work, kind of out of options :/

Edited by WhiteAutumn

Share this post


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

Why do you need to run the code on the client? That seems weird to me.

I don't, i just figured since the health arrow thing that appears is a client sided thing perhaps you would need to call it on client.

My problem is still that my health does decrease like intended however the arrow does not appear :/

Edited by WhiteAutumn

Share this post


Link to post
Share on other sites
Ultroman    537

It's most likely because the damage being received isn't large enough. There are tiers of arrow-size being shown, and the lowest doesn't show an arrow.

Share this post


Link to post
Share on other sites
WhiteAutumn    2
2 hours ago, Ultroman said:

It's most likely because the damage being received isn't large enough. There are tiers of arrow-size being shown, and the lowest doesn't show an arrow.

I tried with -5 health / second and it still does not trigger the arrow :/

Share this post


Link to post
Share on other sites
Ultroman    537

Well, looking at the way the health badge works, it's just not designed to show for all the changes to your health. It only shows arrows for specific purposes. It shows a down-arrow when freezing or overheating, or you're taking fire damage or you're starving or you have corrosives on you. It shows the up-arrow when the down-arrow is not active, and you are sleeping or have regen equipment equipped. That's it. It's not designed for what you want it to do. What it WILL do, however, is make the health-badge pulse red or green (depending on damage or healing) and make a sound.

Here's the code for it:

Spoiler

function HealthBadge:OnUpdate(dt)
    local down
    if (self.owner.IsFreezing ~= nil and self.owner:IsFreezing()) or
        (self.owner.replica.health ~= nil and self.owner.replica.health:IsTakingFireDamageFull()) or
        (self.owner.replica.hunger ~= nil and self.owner.replica.hunger:IsStarving()) or
        next(self.corrosives) ~= nil then
        down = "_most"
    elseif self.owner.IsOverheating ~= nil and self.owner:IsOverheating() then
        down = self.owner:HasTag("heatresistant") and "_more" or "_most"
    end

    -- Show the up-arrow when we're sleeping (but not in a straw roll: that doesn't heal us)
    local up = down == nil and
        (   (self.owner.player_classified ~= nil and self.owner.player_classified.issleephealing:value()) or
            next(self.hots) ~= nil or
            (self.owner.replica.inventory ~= nil and self.owner.replica.inventory:EquipHasTag("regen"))
        ) and
        self.owner.replica.health ~= nil and self.owner.replica.health:IsHurt()

    local anim =
        (down ~= nil and ("arrow_loop_decrease"..down)) or
        (not up and "neutral") or
        (next(self.hots) ~= nil and "arrow_loop_increase_most") or
        "arrow_loop_increase"

    if self.arrowdir ~= anim then
        self.arrowdir = anim
        self.sanityarrow:GetAnimState():PlayAnimation(anim, true)
    end
end

 

 

  • Like 1

Share this post


Link to post
Share on other sites
Serpens    516

as I wrote at the other thread:
Why dont you simply use the current game mechanic of overheating? As I understand, you want a vampire that is taking damage in the sun. So overheating fits, or not? For this ypu simply have to adjust the "IsOverheating" function saved in every player, so with AddPlayerPostInit and "inst.IsOverheating = ..." (while preserving the original function of course).  Or do AddPrefabPostInit("yourcharacter",.. (keep in mind that this function is called for server and client)

Edited by Serpens
  • Like 1

Share this post


Link to post
Share on other sites
WhiteAutumn    2
1 hour ago, Serpens said:

as I wrote at the other thread:
Why dont you simply use the current game mechanic of overheating? As I understand, you want a vampire that is taking damage in the sun. So overheating fits, or not? For this ypu simply have to adjust the "IsOverheating" function saved in every player, so with AddPlayerPostInit and "inst.IsOverheating = ..." (while preserving the original function of course).  Or do AddPrefabPostInit("yourcharacter",.. (keep in mind that this function is called for server and client)

I suppose, however I would like it more if I could thematically stay away from the overheating effect. Using the overheating mechanic would invoke the sort of orange-y overlay would it not? Also wouldn't stuff like eating ice or endothermic firepits stop the overheating effect? I wouldn't want that.

Share this post


Link to post
Share on other sites
Serpens    516
1 minute ago, WhiteAutumn said:

I suppose, however I would like it more if I could thematically stay away from the overheating effect. Using the overheating mechanic would invoke the sort of orange-y overlay would it not? Also wouldn't stuff like eating ice or endothermic firepits stop the overheating effect? I wouldn't want that.

if you make the "IsOverheating" function alwas return true if it is your char and in sun, then ice/endothermic wont do anything.
I dont know if it is easier to disable the orange overheating effect, than to enable the health loss effect :D
But of course it could conflict with regular overheating, so if you char is really overheated + in sun, the effect would be the same like normal overheating.

  • Like 2

Share this post


Link to post
Share on other sites
WhiteAutumn    2
9 hours ago, Ultroman said:

Well, looking at the way the health badge works, it's just not designed to show for all the changes to your health. It only shows arrows for specific purposes. It shows a down-arrow when freezing or overheating, or you're taking fire damage or you're starving or you have corrosives on you. It shows the up-arrow when the down-arrow is not active, and you are sleeping or have regen equipment equipped. That's it. It's not designed for what you want it to do. What it WILL do, however, is make the health-badge pulse red or green (depending on damage or healing) and make a sound.

 

Couldn't I override OnUpdate using AddClassPostConstruct then and change it to show changes in health caused by my mod? :D

3 minutes ago, Serpens said:

if you make the "IsOverheating" function alwas return true if it is your char and in sun, then ice/endothermic wont do anything.
I dont know if it is easier to disable the orange overheating effect, than to enable the health loss effect :D
But of course it could conflict with regular overheating, so if you char is really overheated + in sun, the effect would be the same like normal overheating.

I'll keep this in mind if I am not able to modify the health badge to show changes in health from my mod, thanks!

Share this post


Link to post
Share on other sites
Serpens    516
Just now, WhiteAutumn said:

Couldn't I override OnUpdate using AddClassPostConstruct then and change it to show changes in health caused by my mod? :D

yes, this was also just my thought, wonder why Ultroman did not wrote about it, his post sounded like it would be impossible. I currently dont have the time to look deeper into the files, if this would really solve the problem. You or ultroman can try it :)

Share this post


Link to post
Share on other sites
WhiteAutumn    2
27 minutes ago, Serpens said:

yes, this was also just my thought, wonder why Ultroman did not wrote about it, his post sounded like it would be impossible. I currently dont have the time to look deeper into the files, if this would really solve the problem. You or ultroman can try it :)

5154OiE.png

It works!
Think I have all my questions answered now finally, my inquisition of the DST modding forums is over haha.
A huge thanks to everyone who has helped me!

Share this post


Link to post
Share on other sites
Serpens    516
Just now, WhiteAutumn said:

5154OiE.png

It works!
Think I have all my questions answered now finally, my inquisition of the DST modding forums is over haha.
A huge thanks to everyone who has helped me!

great :) dont forget to only do this change for your character and return the default for everyone else or if your char is not in sun. So not only make your mod work, but also dont break the game :D

Share this post


Link to post
Share on other sites
WhiteAutumn    2
1 minute ago, Serpens said:

great :) dont forget to only do this change for your character and return the default for everyone else or if your char is not in sun. So not only make your mod work, but also dont break the game :D

Yep, I have a tag added at initialization which I check the owner of the widget to have before I do anything :)

Share this post


Link to post
Share on other sites
Ultroman    537
5 hours ago, Serpens said:

yes, this was also just my thought, wonder why Ultroman did not wrote about it, his post sounded like it would be impossible. I currently dont have the time to look deeper into the files, if this would really solve the problem. You or ultroman can try it :)

Time was a factor for me, as well. I simply missed the fact that OnUpdate() is public xD Sorry about that. Just be careful how you do it, though.

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