you need to break it down to simplest form, and use events(including ticks) to drive and update it.
Since your case involve using a variable to control player status, and player status also affect the amount of variable, you will need to break these 2 parts clean(to avoid events call update status, and then call update variable, circular triggering.)
It’s not “simple” if you want to also expand it later on(ie food poison, buff state[regeneration for -5 tire every 1 second, and last 10 seconds], permanent state like injured[always tired, set tireMin to like 80+ ] before you get healed.).
So what can get you most flexibility? It lies in never update status and variable in the same execution line, and use functions and events to drive one at a time.
Say for update the variable, in the tick event, you call function to update it in a stream,(-> means white execution line) tick->MovementCause( check for walk/run/idle)->ItemCause(check if buff/poison)->PermaCause(check injury)
In each function you update respectively to add/reduce value. That’s the tick update part.
On the status change, you always drive with non-tick based events.
For movement input events, you query tire value to preset condition(bCanWalk(0~90)/bCanRun(0~60)), and then update your speed, and then decide your current status base on speed(idle/exhausted/walking/running through another function).
Since the moving status are mutually exclusive, you can use a enum.(need to check if is falling)
gotta go, will be back.