-
Member
Spell Cooldowns
Hello everyone!
I'm trying to implement spell cooldown info for my bot, and I've got stuck. My code below returns values for ~50% of my spells only. It happens because for some spells duration is 0. For example, for shaman, this code returns valid numbers for Earthbind Totem, but for Spirit Link Totem it returns nothing because duration in WoW memory is 0. Any help please?
Code:
// WoW build 32028
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool QueryPerformanceFrequency(out long frequency);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
[StructLayout(LayoutKind.Explicit)]
internal struct SpellCooldownInfo
{
[FieldOffset(0x8)]
internal IntPtr NextAddress;
[FieldOffset(0x10)]
internal int SpellID;
[FieldOffset(0x1C)]
internal int StartTime;
[FieldOffset(0x20)]
internal int Duration;
}
private long GetCurrentTime()
{
QueryPerformanceFrequency(out long frequency);
QueryPerformanceCounter(out long counter);
long currentTime = (counter * 1000) / frequency;
return currentTime;
}
private long GetSpellCooldown(int spellID)
{
textBox1.AppendText($"NEW CALL: {spellID}\r\n");
long currentTime = GetCurrentTime();
IntPtr spellObj = game.Memory.Read<IntPtr>(game.Memory.ImageBase + 0x2824F60 + 0x10);
int startTime = 0;
long cooldown = 0;
while (((ulong)spellObj & 1) == 0 && spellObj != IntPtr.Zero)
{
SpellCooldownInfo spellCooldownInfo = game.Memory.Read<SpellCooldownInfo>(spellObj);
if (spellCooldownInfo.SpellID == spellID && spellCooldownInfo.Duration > 0)
{
if (spellCooldownInfo.StartTime > startTime)
{
startTime = spellCooldownInfo.StartTime;
cooldown = spellCooldownInfo.Duration - (currentTime - spellCooldownInfo.StartTime);
}
}
spellObj = spellCooldownInfo.NextAddress;
}
return cooldown < 0 ? 0 : cooldown;
}
Last edited by provirus; 10-12-2019 at 09:50 AM.
-
Contributor
Look further down in the SpellHistoryEntry struct, there's another duration length offset that some spells trigger.
-
Member
Originally Posted by
ChrisIsMe
Look further down in the SpellHistoryEntry struct, there's another duration length offset that some spells trigger.
How far is it? I've checked every byte until spellEntry + 0x100, there are not any duration value.
-
You need to reverse SpellHistory:GetCooldown. There are three cool downs in the spell entry struct. CD1, CD2, and Global Cooldown. CD1 is generally the individual cool down, CD2 is genearlly the common cool down, and Global Cooldown is well the global cooldown. The common cool down is for things like trinkets, so if you have two on use trinkets and you use trinket A, trinket B CD2 will start at 30 secs and count down. You have to wait at least 30 sec in between trinkets.
You can find SpellHistory:GetCooldown by looking at the Script_GetSpellCooldown sub_1161F90 in the 32028 binary. From that sub the sub_B42F40 has all of the offsets you need for the complete spellentry struct.
Last edited by counted; 10-13-2019 at 10:00 AM.
-
Post Thanks / Like - 2 Thanks
-
Member
Originally Posted by
counted
You need to reverse SpellHistory:GetCooldown. There are three cool downs in the spell entry struct. CD1, CD2, and Global Cooldown. CD1 is generally the individual cool down, CD2 is genearlly the common cool down, and Global Cooldown is well the global cooldown. The common cool down is for things like trinkets, so if you have two on use trinkets and you use trinket A, trinket B CD2 will start at 30 secs and count down. You have to wait at least 30 sec in between trinkets.
You can find SpellHistory:GetCooldown by looking at the Script_GetSpellCooldown sub_1161F90 in the 32028 binary. From that sub the sub_B42F40 has all of the offsets you need for the complete spellentry struct.
Sorry for late reply.
Maybe I've explained myself wrong. I've found this function when I was searching for offsets; that was quite obvious. But 'CD1' offset returns 0 for certain spells on cooldown. 'GetCooldown' function is big, and I'm not good in reversing, so I cannot fully understand it. Can you please point me more precisely? Should I look at the start or end, or specific 'if' statement...
-
Established Member
There is also a fourth type of cooldown, spell charges, stored in a separate list in spellhistory global - there are spells that don't have multiple charges but still use that system and Spirit Link is such a spell, their entry in regular cooldown struct is for GCD only
Last edited by shauren; 10-24-2019 at 08:57 AM.