Rune cooldowns, still bugged for some unknown reason :(

This commit is contained in:
tomrus88 2008-12-01 19:31:47 +03:00
parent 518d7f6297
commit b37ccbd08b
5 changed files with 107 additions and 31 deletions

View file

@ -241,8 +241,6 @@ class MANGOS_DLL_SPEC Object
{ {
ASSERT( index < m_valuesCount || PrintIndexError( index , false ) ); ASSERT( index < m_valuesCount || PrintIndexError( index , false ) );
ASSERT( offset < 4 ); ASSERT( offset < 4 );
//return *(((uint16*)&m_uint32Values[ index ])+offset);
//return (((uint8*)m_uint32Values[index])[offset] & flag) != 0;
return (((uint8*)&m_uint32Values[index])[offset] & flag) != 0; return (((uint8*)&m_uint32Values[index])[offset] & flag) != 0;
} }

View file

@ -18899,7 +18899,29 @@ void Player::SetTitle(CharTitlesEntry const* title)
void Player::ConvertRune(uint8 index, uint8 newType) void Player::ConvertRune(uint8 index, uint8 newType)
{ {
SetCurrentRune(index, newType); SetCurrentRune(index, newType);
// SMSG_CONVERT_RUNE
WorldPacket data(SMSG_CONVERT_RUNE, 2);
data << uint8(index);
data << uint8(newType);
GetSession()->SendPacket(&data);
}
void Player::ResyncRunes(uint8 count)
{
WorldPacket data(SMSG_RESYNC_RUNES, count * 2);
for(uint32 i = 0; i < count; ++i)
{
data << uint8(GetCurrentRune(i)); // rune type
data << uint8(255 - (GetRuneCooldown(i) * 51)); // passed cooldown time (0-255)
}
GetSession()->SendPacket(&data);
}
void Player::AddRunePower(uint8 index)
{
WorldPacket data(SMSG_ADD_RUNE_POWER, 4);
data << uint32(1 << index); // mask (0x00-0x3F probably)
GetSession()->SendPacket(&data);
} }
void Player::InitRunes() void Player::InitRunes()
@ -18909,11 +18931,14 @@ void Player::InitRunes()
m_runes = new Runes; m_runes = new Runes;
m_runes->runeState = 0;
for(uint32 i = 0; i < MAX_RUNES; ++i) for(uint32 i = 0; i < MAX_RUNES; ++i)
{ {
SetBaseRune(i, i / 2); // init base types SetBaseRune(i, i / 2); // init base types
SetCurrentRune(i, i / 2); // init current types SetCurrentRune(i, i / 2); // init current types
SetRuneCooldown(i, 0); // reset cooldowns SetRuneCooldown(i, 0); // reset cooldowns
m_runes->SetRuneState(i);
} }
for(uint32 i = 0; i < NUM_RUNE_TYPES; ++i) for(uint32 i = 0; i < NUM_RUNE_TYPES; ++i)

View file

@ -230,8 +230,8 @@ struct Areas
enum RuneType enum RuneType
{ {
RUNE_BLOOD = 0, RUNE_BLOOD = 0,
RUNE_FROST = 1, RUNE_UNHOLY = 1,
RUNE_UNHOLY = 2, RUNE_FROST = 2,
RUNE_DEATH = 3, RUNE_DEATH = 3,
NUM_RUNE_TYPES = 4 NUM_RUNE_TYPES = 4
}; };
@ -246,6 +246,15 @@ struct RuneInfo
struct Runes struct Runes
{ {
RuneInfo runes[6]; RuneInfo runes[6];
uint8 runeState; // mask of available runes
void SetRuneState(uint8 index, bool set = true)
{
if(set)
runeState |= (1 << index); // usable
else
runeState &= ~(1 << index); // on cooldown
}
}; };
enum FactionFlags enum FactionFlags
@ -2092,13 +2101,16 @@ class MANGOS_DLL_SPEC Player : public Unit
WorldLocation& GetTeleportDest() { return m_teleport_dest; } WorldLocation& GetTeleportDest() { return m_teleport_dest; }
DeclinedName const* GetDeclinedNames() const { return m_declinedname; } DeclinedName const* GetDeclinedNames() const { return m_declinedname; }
uint8 GetRunesState() const { return m_runes->runeState; }
uint8 GetBaseRune(uint8 index) const { return m_runes->runes[index].BaseRune; } uint8 GetBaseRune(uint8 index) const { return m_runes->runes[index].BaseRune; }
uint8 GetCurrentRune(uint8 index) const { return m_runes->runes[index].CurrentRune; } uint8 GetCurrentRune(uint8 index) const { return m_runes->runes[index].CurrentRune; }
uint8 GetRuneCooldown(uint8 index) const { return m_runes->runes[index].Cooldown; } uint8 GetRuneCooldown(uint8 index) const { return m_runes->runes[index].Cooldown; }
void SetBaseRune(uint8 index, uint8 baseRune) { m_runes->runes[index].BaseRune = baseRune; } void SetBaseRune(uint8 index, uint8 baseRune) { m_runes->runes[index].BaseRune = baseRune; }
void SetCurrentRune(uint8 index, uint8 currentRune) { m_runes->runes[index].CurrentRune = currentRune; } void SetCurrentRune(uint8 index, uint8 currentRune) { m_runes->runes[index].CurrentRune = currentRune; }
void SetRuneCooldown(uint8 index, uint8 cooldown) { m_runes->runes[index].Cooldown = cooldown; } void SetRuneCooldown(uint8 index, uint8 cooldown) { m_runes->runes[index].Cooldown = cooldown; m_runes->SetRuneState(index, (cooldown == 0) ? true : false); }
void ConvertRune(uint8 index, uint8 newType); void ConvertRune(uint8 index, uint8 newType);
void ResyncRunes(uint8 count);
void AddRunePower(uint8 index);
void InitRunes(); void InitRunes();
AchievementMgr& GetAchievementMgr() { return m_achievementMgr; } AchievementMgr& GetAchievementMgr() { return m_achievementMgr; }
bool HasTitle(uint32 bitIndex); bool HasTitle(uint32 bitIndex);

View file

@ -346,6 +346,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
else else
m_autoRepeat = false; m_autoRepeat = false;
m_runesState = 0;
m_powerCost = 0; // setup to correct value in Spell::prepare, don't must be used before. m_powerCost = 0; // setup to correct value in Spell::prepare, don't must be used before.
m_casttime = 0; // setup to correct value in Spell::prepare, don't must be used before. m_casttime = 0; // setup to correct value in Spell::prepare, don't must be used before.
m_timer = 0; // will set to castime in prepare m_timer = 0; // will set to castime in prepare
@ -2652,6 +2653,9 @@ void Spell::SendSpellStart()
if(IsRangedSpell()) if(IsRangedSpell())
castFlags |= CAST_FLAG_AMMO; castFlags |= CAST_FLAG_AMMO;
if(m_runesState)
castFlags |= CAST_FLAG_UNKNOWN10;
Unit *target; Unit *target;
if(!m_targets.getUnitTarget()) if(!m_targets.getUnitTarget())
target = m_caster; target = m_caster;
@ -2672,19 +2676,26 @@ void Spell::SendSpellStart()
m_targets.write(&data); m_targets.write(&data);
if ( castFlags & CAST_FLAG_UNKNOWN6 ) if ( castFlags & CAST_FLAG_UNKNOWN6 ) // predicted power?
data << uint32(0); data << uint32(0);
if ( castFlags & CAST_FLAG_UNKNOWN7 ) if ( castFlags & CAST_FLAG_UNKNOWN7 ) // rune cooldowns
{ {
uint8 v1 = 0; uint8 v1 = 0;//m_runesState;
uint8 v2 = 0; uint8 v2 = 0;//((Player*)m_caster)->GetRunesState();
data << v1; // v1 data << uint8(v1); // runes state before
data << v2; // v2 data << uint8(v2); // runes state after
for(uint8 i = 0; i < 6; ++i) for(uint8 i = 0; i < MAX_RUNES; ++i)
if((1 << i) & v1) {
if(!(1 << i) & v2) uint8 m = (1 << i);
data << uint8(0); if(m & v1) // usable before...
{
if(!(m & v2)) // ...but on cooldown now...
{
data << uint8(0); // some unknown byte (time?)
}
}
}
} }
if ( castFlags & CAST_FLAG_AMMO ) if ( castFlags & CAST_FLAG_AMMO )
@ -2709,7 +2720,14 @@ void Spell::SendSpellGo()
uint32 castFlags = CAST_FLAG_UNKNOWN3; uint32 castFlags = CAST_FLAG_UNKNOWN3;
if(IsRangedSpell()) if(IsRangedSpell())
castFlags |= CAST_FLAG_AMMO; castFlags |= CAST_FLAG_AMMO; // arrows/bullets visual
if(m_runesState)
{
castFlags |= CAST_FLAG_UNKNOWN10; // same as in SMSG_SPELL_START
castFlags |= CAST_FLAG_UNKNOWN6; // makes cooldowns visible
castFlags |= CAST_FLAG_UNKNOWN7; // rune cooldowns
}
WorldPacket data(SMSG_SPELL_GO, 50); // guess size WorldPacket data(SMSG_SPELL_GO, 50); // guess size
if(m_CastItem) if(m_CastItem)
@ -2727,19 +2745,26 @@ void Spell::SendSpellGo()
m_targets.write(&data); m_targets.write(&data);
if ( castFlags & CAST_FLAG_UNKNOWN6 ) // unknown wotlk if ( castFlags & CAST_FLAG_UNKNOWN6 ) // unknown wotlk, predicted power?
data << uint32(0); data << uint32(0);
if ( castFlags & CAST_FLAG_UNKNOWN7 ) if ( castFlags & CAST_FLAG_UNKNOWN7 ) // rune cooldowns?
{ {
uint8 v1 = 0; uint8 v1 = m_runesState;
uint8 v2 = 0; uint8 v2 = ((Player*)m_caster)->GetRunesState();
data << v1; // v1 data << uint8(v1); // runes state before
data << v2; // v2 data << uint8(v2); // runes state after
for(uint8 i = 0; i < 6; ++i) for(uint8 i = 0; i < MAX_RUNES; ++i)
if((1 << i) & v1) {
if(!(1 << i) & v2) uint8 m = (1 << i);
data << uint8(0); if(m & v1) // usable before...
{
if(!(m & v2)) // ...but on cooldown now...
{
data << uint8(0); // some unknown byte (time?)
}
}
}
} }
if ( castFlags & CAST_FLAG_UNKNOWN4 ) // unknown wotlk if ( castFlags & CAST_FLAG_UNKNOWN4 ) // unknown wotlk
@ -3204,6 +3229,8 @@ void Spell::TakeRunePower()
if(!src || (src->NoRuneCost() && src->NoRunicPowerGain())) if(!src || (src->NoRuneCost() && src->NoRunicPowerGain()))
return; return;
m_runesState = plr->GetRunesState(); // store previous state
int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
for(uint32 i = 0; i < RUNE_DEATH; ++i) for(uint32 i = 0; i < RUNE_DEATH; ++i)
@ -3223,7 +3250,7 @@ void Spell::TakeRunePower()
} }
} }
runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_FROST] + runeCost[RUNE_UNHOLY]; runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
if(runeCost[RUNE_DEATH] > 0) if(runeCost[RUNE_DEATH] > 0)
{ {

View file

@ -67,16 +67,29 @@ enum SpellCastTargetFlags
enum SpellCastFlags enum SpellCastFlags
{ {
CAST_FLAG_NONE = 0x00000000,
CAST_FLAG_UNKNOWN0 = 0x00000001, // may be pending spell cast
CAST_FLAG_UNKNOWN1 = 0x00000002, CAST_FLAG_UNKNOWN1 = 0x00000002,
CAST_FLAG_UNKNOWN11 = 0x00000004,
CAST_FLAG_UNKNOWN12 = 0x00000008,
CAST_FLAG_UNKNOWN2 = 0x00000010, CAST_FLAG_UNKNOWN2 = 0x00000010,
CAST_FLAG_AMMO = 0x00000020, CAST_FLAG_AMMO = 0x00000020, // Projectiles visual
CAST_FLAG_UNKNOWN8 = 0x00000040, CAST_FLAG_UNKNOWN8 = 0x00000040,
CAST_FLAG_UNKNOWN9 = 0x00000080, CAST_FLAG_UNKNOWN9 = 0x00000080,
CAST_FLAG_UNKNOWN3 = 0x00000100, CAST_FLAG_UNKNOWN3 = 0x00000100,
CAST_FLAG_UNKNOWN6 = 0x00000800, // wotlk CAST_FLAG_UNKNOWN13 = 0x00000200,
CAST_FLAG_UNKNOWN14 = 0x00000400,
CAST_FLAG_UNKNOWN6 = 0x00000800, // wotlk, trigger rune cooldown
CAST_FLAG_UNKNOWN15 = 0x00001000,
CAST_FLAG_UNKNOWN16 = 0x00002000,
CAST_FLAG_UNKNOWN17 = 0x00004000,
CAST_FLAG_UNKNOWN18 = 0x00008000,
CAST_FLAG_UNKNOWN19 = 0x00010000,
CAST_FLAG_UNKNOWN4 = 0x00020000, // wotlk CAST_FLAG_UNKNOWN4 = 0x00020000, // wotlk
CAST_FLAG_UNKNOWN10 = 0x00040000,
CAST_FLAG_UNKNOWN5 = 0x00080000, // wotlk CAST_FLAG_UNKNOWN5 = 0x00080000, // wotlk
CAST_FLAG_UNKNOWN7 = 0x00200000 // wotlk CAST_FLAG_UNKNOWN20 = 0x00100000,
CAST_FLAG_UNKNOWN7 = 0x00200000 // wotlk, rune cooldown list
}; };
enum SpellNotifyPushType enum SpellNotifyPushType
@ -436,6 +449,7 @@ class Spell
int32 m_casttime; // Calculated spell cast time initialized only in Spell::prepare int32 m_casttime; // Calculated spell cast time initialized only in Spell::prepare
bool m_canReflect; // can reflect this spell? bool m_canReflect; // can reflect this spell?
bool m_autoRepeat; bool m_autoRepeat;
uint8 m_runesState;
uint8 m_delayAtDamageCount; uint8 m_delayAtDamageCount;
int32 GetNextDelayAtDamageMsTime() { return m_delayAtDamageCount < 5 ? 1000 - (m_delayAtDamageCount++)* 200 : 200; } int32 GetNextDelayAtDamageMsTime() { return m_delayAtDamageCount < 5 ? 1000 - (m_delayAtDamageCount++)* 200 : 200; }