View Single Post
07/07/15, 12:02 PM   #7
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Originally Posted by Capadillo View Post
EDIT2: Could it be the difference in latency?
Could what be? Do you mean the time interval difference on regen in & out of combat? No, since the real stat bar updates in large chunks the latency would have to be insane to have any effect & it would correct itself the first time the bar updated.

Originally Posted by Capadillo View Post
EDIT3: The main issue I have left over is when you're healed (i test by healing myself) the health bar sometimes jumps forward (like it should) then back again. Have a look and see what you think of the progress if you want!
I glanced at the code, and tried it out, it looks nice btw I like it....but I did not notice what you are describing. When I healed myself it jumped forward like it should and the only time it ever jumped back was if I got hit right after I healed.

However, I only tested it for a minute or two. If it is doing what you say its happening in this part of the code:
Lua Code:
  1. local currentValue = control.statusBar:GetValue();
  2. control.statusBar:SetMinMax(0, maxPower);
  3. -- Show damage taken or healing taken straight away!
  4. if( currentValue > currentPower )then
  5.     control.statusBar:SetValue(currentPower);
If the currentValue of the bar somehow gets higher than your actual current power, then it resets the bars value, which would make the bar jump back down. How far it would jump would depend on the difference between the currentValue & currentPower. That is the way I wrote the code in my example & it should do that to keep the bar in sync with your real power value. Although we can change "how" it keeps the bars value in check...later/below.
If the bar is getting out of sync somehow and the currentValue of the bar is getting to large ( > currentPower) then that is the problem. That code is just whats making it jump, but its not the problem.

Again I did not notice the problem, but my guess would be this:
Lua Code:
  1. -- If we have been healed?
  2. if( control.powerType == POWERTYPE_HEALTH and self.forceHealthUpdate ~= nil )then
  3.     currentValue = currentValue + self.forceHealthUpdate
  4.     self.forceHealthUpdate = 0;
  5. end
  6. -- If we had to heal...
  7. local POWERTYPE_REGEN = GetPlayerRegen(control.powerType);
  8. local COMBAT_MODIFIER = IsUnitInCombat(control.unitTag) and 1 or 1.75;
  9. control.statusBar:SetValue(currentValue + POWERTYPE_REGEN / (TICKS_PER_UPDATE / COMBAT_MODIFIER));
Remember the way its written, the bar is continuously filling in (as long as your missing health) to make it smooth and it starts filling in the bar BEFORE you actually gain the health....um this seems a little complicated & lengthy to explain, let me try an example.

You have 100 max health, you get hit for 20 dmg. Your code drops the bar to 80 and immediately starts filling in the bar. So as time goes on, you have 81 health, 82, 83, then you heal yourself for 10 health, this code sees that and saves it in self.forceHealthUpdate
Warning: Spoiler


Your update function is still ticking away and the next time it ticks it sees that self.forceHealthUpdate +10 value and adds it to your health bars currentValue:
Lua Code:
  1. -- If we have been healed?
  2. if( control.powerType == POWERTYPE_HEALTH and self.forceHealthUpdate ~= nil )then
  3.     currentValue = currentValue + self.forceHealthUpdate
  4.     self.forceHealthUpdate = 0;
  5. end
Now your health bars currentValue is at 94 health (+1 from the next regen tick & +10 from the heal)...BUT If the game hasn't actually registered a health regen tick yet (remember your health bar is filling in immediately and not waiting for a power Update Event to tell it that health was gained)....then as far as the game is concerned you only have 90 health: The original 80 (from after you took damage) + 10 from the heal.

Now, you caught the heal in your CombatEvent function...but when you gain health the power update event fires also which your PowerUpdate function is registered to:
Lua Code:
  1. EM:RegisterForEvent(self.name, EVENT_POWER_UPDATE, function(...) self:PowerUpdate(...); end);

So now PowerUpdate fires because the EVENT_POWER_UPDATE also fired and this code runs:
Lua Code:
  1. function TAB:PowerUpdate(_, unitTag, _, powerType, currentPower, maxPower)
  2.     -- Do we watch for this unitTag & powerType?
  3.     if( not POWER_INFO[unitTag] or not POWER_INFO[unitTag][powerType] ) then return false; end
  4.     -- Look for any controls that match this pattern.
  5.     local control = _G['TAB'..ucfirst(unitTag)..ucfirst(POWER_INFO[unitTag][powerType])];
  6.     -- If it exists.
  7.     if( control )then
  8.         local currentValue = control.statusBar:GetValue();
  9.         control.statusBar:SetMinMax(0, maxPower);
  10.         -- Show damage taken or healing taken straight away!
  11.         if( currentValue > currentPower )then
  12.             control.statusBar:SetValue(currentPower);
  13. ...
  14. end

and the key piece of this, finally....is that remember your bar registers you as having 94 health, while the game says you only have 90 health (because the game hasn't run an update for a health "regen")
Lua Code:
  1. if( currentValue > currentPower )then
  2.             control.statusBar:SetValue(currentPower);
and that code would force the bars value to jump back down because the currentValue is greater than the currentPower.
Also, if your bar is updating to fast and getting to far ahead of your actual health from when you altered those interval values and you heal yourself this code could also cause the bar to jump back down.



The best thing I can think of atm:

If your bar is getting to far ahead of the actual values, you could do something like this to limit how far ahead the bar can go. This would prevent it from getting more than 1 regen tick worth of stat ahead of the actual power value, regardless of what your intervals are set at:
Lua Code:
  1. -- If we had to heal...
  2. local POWERTYPE_REGEN = GetPlayerRegen(control.powerType);
  3. local COMBAT_MODIFIER = IsUnitInCombat(control.unitTag) and 1 or 1.75;
  4.  
  5. -- Since we want to allow the bar to fill in "up to" an amount of
  6. -- POWERTYPE_REGEN ahead of the actual power, we make this the actual power + POWERTYPE_REGEN
  7. local actualPower = GetUnitPower("player", control.powerType) + POWERTYPE_REGEN
  8. currentValue = currentValue + POWERTYPE_REGEN / (TICKS_PER_UPDATE / COMBAT_MODIFIER)
  9.  
  10. -- Take the minimum of the two, this will make sure our bars value never jumps ahead
  11. -- more than POWERTYPE_REGEN of the players actual power value.
  12. local newValue = zo_min(currentValue, actualPower)
  13. control.statusBar:SetValue(newValue);

But if its being caused by the heals problem/example I gave then it could still be forced to jump back down...so you could also do something like this:
Lua Code:
  1. if( control )then
  2.     local currentValue = control.statusBar:GetValue();
  3.     control.statusBar:SetMinMax(0, maxPower);
  4.     if powerType == POWERTYPE_HEALTH then
  5.         if oldHealth > currentPower then
  6.             control.statusBar:SetValue(currentPower);
  7.             control.label:SetText(zo_round(currentValue/maxPower*100)..'%');
  8.         end
  9.         oldHealth = currentPower
  10.        
  11.     elseif currentValue > currentPower then
  12.         control.statusBar:SetValue(currentPower);
  13.         control.label:SetText(zo_round(currentValue/maxPower*100)..'%');
  14.     end
  15. ...
Each time you have a power update event, check to see if its for health & save that health amount in some variable. Then do your "if" check against the saved "oldHealth" value, instead of the stat bars current value. This would prevent the status bar from jumping back down because its ticking ahead of the games regen ticks. Don't forget to initialize oldHealth in your OnLoad.

But if you do this fix, you probably need to do both of the fixes I mentioned because this code here would no longer prevent the bar from ticking to far ahead of your stats actual value!! so we need both fixes. But then this may also require you to readjust your interval regen values.

Changes on my dropbox: TinyAttributeBar

I did also notice one strange thing, If I run...at first the bar updates immediately as I'm running. If you keep sprinting though eventually the bar stops updating until you stop running & the first stamina regen power update event fires. Apparently it appears that (for stamina at least) GetPlayerStat(..) returns 0 if you sprint for to long (it doesn't take long). I don't know if this is a game bug or if its intentional, like you get tired and stop regaining stamina until you stop sprinting.
  Reply With Quote