-
Contributor
Has IBuff.TimeLeft() a bug?
Happy New Year 2018 
I noticed that IBuff.TimeLeft() reports zero (when it should not, like starting the skill) (at least) for DemonHunter Companion skill.
ISnoPower DemonHunter_Companion { get; } // 365311
As I investigated this I noticed that for this skill TimeLeftSeconds array behaves differently than other skills?
It seems that the correct value (10 s in this case) is later in the array and is preceded by zero values.
Maybe IBuff.TimeLeft() just grabs that value from first position and does not inspect other array values?
Could IconCounts array contain some data that helps to get correct TimeLeftSeconds value?
I "fixed" this for me with this:
Code:
static class IBuffExtensions
{
public static double TimeLeftFixed(this IBuff buf)
{
// Sometimes "time left" is not in first item but later?
// Here is first two zero items and then "time left" value and then zeroes again : ISnoPower DemonHunter_Companion { get; } // 365311
for (int i = 0; i < buf.TimeLeftSeconds.Length; ++i)
{
if (buf.TimeLeftSeconds[i] != 0) return buf.TimeLeftSeconds[i];
}
return 0;
}
}
Code to "reproduce" this in pastebin.
My test config:
Hud.RunOnPlugin<User.SelfCooldownPlugin>(plugin =>
{
var p = Hud.Sno.SnoPowers;
plugin.AddRule(p.DemonHunter_Vengeance);
plugin.AddRule(p.DemonHunter_Companion);
plugin.AddRule(p.Barbarian_IgnorePain);
plugin.AddRule(p.Barbarian_WrathOfTheBerserker);
plugin.AddRule(p.Barbarian_WarCry);
plugin.AddRule(p.Barbarian_BattleRage);
plugin.AddRule(p.Wizard_FrostNova);
plugin.AddRule(p.Wizard_Teleport);
plugin.AddRule(p.Crusader_Condemn);
plugin.AddRule(p.Crusader_LawsOfValor);
plugin.AddRule(p.Crusader_IronSkin);
plugin.AddRule(p.Crusader_AkaratsChampion);
});
-
Contributor
I noticed that Crusader "Laws of Valor" does not have a buf at all in corresponding skill and causes NRE :-(
TimeLeftFixed should not be called when NULL buf or TimeLeftFixed should check for NULL and return zero.
-
current implementation
public double TimeLeft()
{
if (!Active) return 0;
var skill = Player.Powers.GetUsedSkill(this.SnoPower);
var rune = skill != null ? skill.Rune : byte.MaxValue;
if (rune == byte.MaxValue) return TimeLeftSeconds[SnoPower.IconIndexes[0]];
else return TimeLeftSeconds[SnoPower.IconIndexes[rune + 1]];
}
Do not send me private messages unless it is absolutely necessary or the content is sensitive or when I ask you to do that...
-
Sadly ISnoPower.IconIndexes is a list I have to maintain, and it contains a runeIndex <> iconIndex mapping, so TimeLeft() can decide which iconIndex has to be used in TimeLeftSeconds[] for the currently used Rune.
Do not send me private messages unless it is absolutely necessary or the content is sensitive or when I ask you to do that...
-
so if you really need the time left for a specific skill and you know the rune itself, then you have to read the TimeLeftSeconds[x] where x depends on the rune.
I don't recommend your way to use the first non-zero number, because many buffs has multiple "icons" (slots...). Those icons (slots) can contain internal game mechanics not even visible on the game UI and you will need only ONE of those for a specific skill and rune.
Do not send me private messages unless it is absolutely necessary or the content is sensitive or when I ask you to do that...
-
Post Thanks / Like - 1 Thanks
JarJarD3 (1 members gave Thanks to KillerJohn for this useful post)
-
currently only those rune <> iconIndex mappings are "tought" to HUD (I stopped updating the list about 3 years ago...)
//sno rune index icon index power rune
108506 5 3 Witchdoctor_SpiritBarrage Manitou
134872 0 2 Wizard_Archon No Rune
134872 1 2 Wizard_Archon Improved Archon
134872 2 2 Wizard_Archon Slow Time
134872 3 2 Wizard_Archon Teleport
134872 4 2 Wizard_Archon Pure Power
134872 5 2 Wizard_Archon Combustion
86991 0 2 Wizard_EnergyArmor No Rune
86991 1 2 Wizard_EnergyArmor Prismatic Armor
86991 2 4 Wizard_EnergyArmor Energy Tap
86991 4 3 Wizard_EnergyArmor Absorption
86991 5 5 Wizard_EnergyArmor Pinpoint Barrier
99120 4 1 Wizard_Familiar Arcanot
99120 5 2 Wizard_Familiar Ancient Guardian
1769 0 3 Wizard_SlowTime No Rune
1769 1 3 Wizard_SlowTime Time Warp
1769 2 3 Wizard_SlowTime Point of No Return
1769 3 3 Wizard_SlowTime Time Shell
1769 4 3 Wizard_SlowTime Exhaustion
1769 5 3 Wizard_SlowTime Stretch Time
71548 1 4 Wizard_SpectralBlade Flame Blades
74499 4 3 Wizard_StormArmor Power of the Storm
Do not send me private messages unless it is absolutely necessary or the content is sensitive or when I ask you to do that...
-
Contributor
Thanks for the info.
I have to think this over if I can manage to live with current TimeLeft() impl or figure out how to "reliably" [hard code something
] handle DH Companion.
I'll test with other Companion runes to see how it changes/works...
-
do not overthink, because I realized I'll remove TimeLeft() from IBuff
Do not send me private messages unless it is absolutely necessary or the content is sensitive or when I ask you to do that...
-
Contributor
I made the fix as you proposed before reading your last comments.
Code:
public static double TimeLeftForced(this IBuff buf, uint index)
{
return buf.TimeLeftSeconds[index];
}
and in Paint(...)
Code:
if (skill.CurrentSnoPower.Sno == 365311 && skill.Rune == 2)
{
timeLeft = skill.Buff.TimeLeftForced(2); // SKILL Companion RUNE Wolf Companion!
}
So in next release IBuff.TimeLeft() will be removed or deprecated?
Then I have to dump all IBuff.TimeLeftSeconds arrays for those skills/runes I'm interested and maintain my on table for them.
Is there any way to find out if a skill/rune has a active period in addition to cooldown period?
Then it would be easy to calculate everything I need from IPlayerSkill CooldownStartTick and CooldownFinishTick...
Like "Wolf Companion" has increased damage for 10 seconds.
And "Spider Companion" has Slowing them by 80% for 5 seconds.
Boar has similar active duration, other DH skill runes are instant.
But as I dumped IBuff.TimeLeftSeconds arrays for Spider and Boar, I did not find active remaining time there as is Wolf. Too bad for me!
Sorry to be such a PITA all the time.
On the bright side if you can remove obsolete hard to maintain code as I am trying to use it the better.
-
Originally Posted by
JarJarD3
I made the fix as you proposed before reading your last comments.
Code:
public static double TimeLeftForced(this IBuff buf, uint index)
{
return buf.TimeLeftSeconds[index];
}
and in Paint(...)
Code:
if (skill.CurrentSnoPower.Sno == 365311 && skill.Rune == 2)
{
timeLeft = skill.Buff.TimeLeftForced(2); // SKILL Companion RUNE Wolf Companion!
}
So in next release
IBuff.TimeLeft() will be removed or deprecated?
Then I have to dump all
IBuff.TimeLeftSeconds arrays for those skills/runes I'm interested and maintain my on table for them.
Is there any way to find out if a skill/rune has a
active period in addition to cooldown period?
Then it would be easy to calculate everything I need from IPlayerSkill CooldownStartTick and CooldownFinishTick...
Like "Wolf Companion" has increased damage for 10 seconds.
And "Spider Companion" has Slowing them by 80% for 5 seconds.
Boar has similar active duration, other DH skill runes are instant.
But as I dumped
IBuff.TimeLeftSeconds arrays for Spider and Boar, I did not find
active remaining time there as is Wolf. Too bad for me!
Sorry to be such a PITA all the time.
On the bright side if you can remove obsolete hard to maintain code as I am trying to use it the better.
it supports only these, so you don't have to dump anything:
//sno rune index icon index power rune
108506 5 3 Witchdoctor_SpiritBarrage Manitou
134872 0 2 Wizard_Archon No Rune
134872 1 2 Wizard_Archon Improved Archon
134872 2 2 Wizard_Archon Slow Time
134872 3 2 Wizard_Archon Teleport
134872 4 2 Wizard_Archon Pure Power
134872 5 2 Wizard_Archon Combustion
86991 0 2 Wizard_EnergyArmor No Rune
86991 1 2 Wizard_EnergyArmor Prismatic Armor
86991 2 4 Wizard_EnergyArmor Energy Tap
86991 4 3 Wizard_EnergyArmor Absorption
86991 5 5 Wizard_EnergyArmor Pinpoint Barrier
99120 4 1 Wizard_Familiar Arcanot
99120 5 2 Wizard_Familiar Ancient Guardian
1769 0 3 Wizard_SlowTime No Rune
1769 1 3 Wizard_SlowTime Time Warp
1769 2 3 Wizard_SlowTime Point of No Return
1769 3 3 Wizard_SlowTime Time Shell
1769 4 3 Wizard_SlowTime Exhaustion
1769 5 3 Wizard_SlowTime Stretch Time
71548 1 4 Wizard_SpectralBlade Flame Blades
74499 4 3 Wizard_StormArmor Power of the Storm
I don't have the answers you are asking for, otherwise there would be already support for that in HUD
Do not send me private messages unless it is absolutely necessary or the content is sensitive or when I ask you to do that...