Fixed DK runes and runic power

This commit is contained in:
hondacrx
2017-11-13 14:12:42 -05:00
parent a5f7add4d6
commit 02535a0d47
9 changed files with 80 additions and 130 deletions
+28 -21
View File
@@ -329,7 +329,7 @@ namespace Game.Entities
bool ThisIsYou = flags.HasAnyFlag(UpdateFlag.Self); bool ThisIsYou = flags.HasAnyFlag(UpdateFlag.Self);
bool SmoothPhasing = false; bool SmoothPhasing = false;
bool SceneObjCreate = false; bool SceneObjCreate = false;
bool PlayerCreateData = false; bool PlayerCreateData = GetTypeId() == TypeId.Player && ToUnit().GetPowerIndex(PowerType.Runes) != (int)PowerType.Max;
int PauseTimesCount = 0; int PauseTimesCount = 0;
GameObject go = ToGameObject(); GameObject go = ToGameObject();
@@ -787,26 +787,33 @@ namespace Game.Entities
// } // }
//} //}
//if (PlayerCreateData) if (PlayerCreateData)
//{ {
// data.WriteBit(HasSceneInstanceIDs); bool HasSceneInstanceIDs = false;
// data.WriteBit(HasRuneState); bool HasRuneState = ToUnit().GetPowerIndex(PowerType.Runes) != (int)PowerType.Max;
// data.FlushBits();
// if (HasSceneInstanceIDs) data.WriteBit(HasSceneInstanceIDs);
// { data.WriteBit(HasRuneState);
// *data << uint32(SceneInstanceIDs.size()); data.FlushBits();
// for (std::size_t i = 0; i < SceneInstanceIDs.size(); ++i) //if (HasSceneInstanceIDs)
// *data << uint32(SceneInstanceIDs[i]); //{
// } // *data << uint32(SceneInstanceIDs.size());
// if (HasRuneState) // for (std::size_t i = 0; i < SceneInstanceIDs.size(); ++i)
// { // *data << uint32(SceneInstanceIDs[i]);
// *data << uint8(RechargingRuneMask); //}
// *data << uint8(UsableRuneMask); if (HasRuneState)
// *data << uint32(ToUnit().GetMaxPower(POWER_RUNES)); {
// for (uint32 i = 0; i < ToUnit().GetMaxPower(POWER_RUNES); ++i) Player player = ToPlayer();
// *data << uint8(255 - (ToUnit().ToPlayer().GetRuneCooldown(i) * 51)); float baseCd = player.GetRuneBaseCooldown();
// } uint maxRunes = (uint)player.GetMaxPower(PowerType.Runes);
//}
data.WriteUInt8((1 << (int)maxRunes) - 1u);
data.WriteUInt8(player.GetRunesState());
data.WriteUInt32(maxRunes);
for (byte i = 0; i < maxRunes; ++i)
data.WriteUInt8((baseCd - (float)player.GetRuneCooldown(i)) / baseCd * 255);
}
}
} }
public virtual void BuildValuesUpdate(UpdateType updatetype, ByteBuffer data, Player target) public virtual void BuildValuesUpdate(UpdateType updatetype, ByteBuffer data, Player target)
+12
View File
@@ -2942,6 +2942,18 @@ namespace Game.Entities
SetUInt32Value(UnitFields.Power + loadedPowers, 0); SetUInt32Value(UnitFields.Power + loadedPowers, 0);
SetPower(PowerType.LunarPower, 0); SetPower(PowerType.LunarPower, 0);
// Init rune recharge
if (GetPowerIndex(PowerType.Runes) != (int)PowerType.Max)
{
int runes = GetPower(PowerType.Runes);
int maxRunes = GetMaxPower(PowerType.Runes);
uint runeCooldown = GetRuneBaseCooldown();
while (runes < maxRunes)
{
SetRuneCooldown((byte)runes, runeCooldown, false);
++runes;
}
}
Log.outDebug(LogFilter.Player, "The value of player {0} after load item and aura is: ", GetName()); Log.outDebug(LogFilter.Player, "The value of player {0} after load item and aura is: ", GetName());
+4 -7
View File
@@ -117,9 +117,6 @@ namespace Game.Entities
MultiMap<uint, uint> m_overrideSpells = new MultiMap<uint, uint>(); MultiMap<uint, uint> m_overrideSpells = new MultiMap<uint, uint>();
public Spell m_spellModTakingSpell; public Spell m_spellModTakingSpell;
uint m_oldpetspell; uint m_oldpetspell;
// Rune type / Rune timer
uint[] m_runeGraceCooldown = new uint[PlayerConst.MaxRunes];
uint[] m_lastRuneGraceTimers = new uint[PlayerConst.MaxRunes];
//Mail //Mail
List<Mail> m_mail = new List<Mail>(); List<Mail> m_mail = new List<Mail>();
@@ -347,14 +344,14 @@ namespace Game.Entities
if (set) if (set)
{ {
RuneState |= (byte)(1 << index); // usable RuneState |= (byte)(1 << index); // usable
if (id == 0) if (id != 0)
CooldownOrder.Add(index); CooldownOrder.RemoveAt(index);
} }
else else
{ {
RuneState &= (byte)~(1 << index); // on cooldown RuneState &= (byte)~(1 << index); // on cooldown
if (id != 0) if (id == 0)
CooldownOrder.Remove(id); CooldownOrder.Add(index);
} }
} }
+21 -48
View File
@@ -2852,22 +2852,16 @@ namespace Game.Entities
/**********************************/ /**********************************/
public void SetRuneCooldown(byte index, uint cooldown, bool casted = false) public void SetRuneCooldown(byte index, uint cooldown, bool casted = false)
{ {
uint gracePeriod = GetRuneTimer(index);
if (casted && IsInCombat())
{
if (gracePeriod < 0xFFFFFFFF && cooldown > 0)
{
uint lessCd = Math.Min(2500, gracePeriod);
cooldown = (cooldown > lessCd) ? (cooldown - lessCd) : 0;
SetLastRuneGraceTimer(index, lessCd);
}
SetRuneTimer(index, 0);
}
m_runes.Cooldown[index] = cooldown; m_runes.Cooldown[index] = cooldown;
m_runes.SetRuneState(index, (cooldown == 0) ? true : false); m_runes.SetRuneState(index, (cooldown == 0) ? true : false);
uint activeRunes = m_runes.Cooldown[Math.Min(GetMaxPower(PowerType.Runes), (int)PowerType.Max)];
if (activeRunes != GetPower(PowerType.Runes))
SetPower(PowerType.Runes, (int)activeRunes);
}
public byte GetRunesState()
{
return (byte)(m_runes.RuneState & ((1 << GetMaxPower(PowerType.Runes)) - 1));
} }
public uint GetRuneBaseCooldown() public uint GetRuneBaseCooldown()
@@ -2894,28 +2888,15 @@ namespace Game.Entities
public void ResyncRunes() public void ResyncRunes()
{ {
ResyncRunes data = new ResyncRunes(); int maxRunes = GetMaxPower(PowerType.Runes);
data.Runes.Start = 0;
ResyncRunes data = new ResyncRunes(maxRunes);
data.Runes.Start = (byte)((1 << maxRunes) - 1);
data.Runes.Count = GetRunesState(); data.Runes.Count = GetRunesState();
for (byte i = 0; i < PlayerConst.MaxRunes; ++i) float baseCd = GetRuneBaseCooldown();
data.Runes.Cooldowns.Add((byte)(255 - (GetRuneCooldown(i) * 51))); for (byte i = 0; i < maxRunes; ++i)
data.Runes.Cooldowns.Add((byte)((baseCd - GetRuneCooldown(i)) / baseCd * 255));
// calculate mask of recharging runes
uint regeneratedRunes = 0;
int regenIndex = 0;
while (regeneratedRunes < PlayerConst.MaxRechargingRunes && !m_runes.CooldownOrder.Empty())
{
byte runeToRegen = m_runes.CooldownOrder[regenIndex++];
uint runeCooldown = GetRuneCooldown(runeToRegen);
if (runeCooldown > m_regenTimer)
{
data.Runes.Start |= (byte)(1 << runeToRegen);
++regenIndex;
}
++regeneratedRunes;
}
SendPacket(data); SendPacket(data);
} }
@@ -2940,15 +2921,11 @@ namespace Game.Entities
m_runes.RuneState = 0; m_runes.RuneState = 0;
for (byte i = 0; i < PlayerConst.MaxRunes; ++i) for (byte i = 0; i < PlayerConst.MaxRunes; ++i)
{
SetRuneCooldown(i, 0); // reset cooldowns SetRuneCooldown(i, 0); // reset cooldowns
SetRuneTimer(i, 0xFFFFFFFF); // Reset rune flags
SetLastRuneGraceTimer(i, 0);
}
// set a base regen timer equal to 10 sec // set a base regen timer equal to 10 sec
SetStatFloatValue(UnitFields.PowerRegenFlatModifier + runeIndex, 0.1f); SetStatFloatValue(UnitFields.PowerRegenFlatModifier + runeIndex, 0.0f);
SetStatFloatValue(UnitFields.PowerRegenInterruptedFlatModifier + runeIndex, 0.1f); SetStatFloatValue(UnitFields.PowerRegenInterruptedFlatModifier + runeIndex, 0.0f);
} }
public void UpdateAllRunesRegen() public void UpdateAllRunesRegen()
@@ -2960,19 +2937,15 @@ namespace Game.Entities
if (runeIndex == (int)PowerType.Max) if (runeIndex == (int)PowerType.Max)
return; return;
PowerTypeRecord runeEntry = Global.DB2Mgr.GetPowerTypeEntry(PowerType.Runes);
uint cooldown = GetRuneBaseCooldown(); uint cooldown = GetRuneBaseCooldown();
SetStatFloatValue(UnitFields.PowerRegenFlatModifier + runeIndex, (float)(1 * Time.InMilliseconds) / cooldown); SetStatFloatValue(UnitFields.PowerRegenFlatModifier + runeIndex, (float)(1 * Time.InMilliseconds) / (float)cooldown - runeEntry.RegenerationPeace);
SetStatFloatValue(UnitFields.PowerRegenInterruptedFlatModifier + runeIndex, (float)(1 * Time.InMilliseconds) / cooldown); SetStatFloatValue(UnitFields.PowerRegenInterruptedFlatModifier + runeIndex, (float)(1 * Time.InMilliseconds) / (float)cooldown - runeEntry.RegenerationCombat);
} }
public byte GetRunesState() { return m_runes.RuneState; }
public uint GetRuneCooldown(byte index) { return m_runes.Cooldown[index]; } public uint GetRuneCooldown(byte index) { return m_runes.Cooldown[index]; }
public uint GetRuneTimer(byte index) { return m_runeGraceCooldown[index]; }
public void SetRuneTimer(byte index, uint timer) { m_runeGraceCooldown[index] = timer; }
public uint GetLastRuneGraceTimer(byte index) { return m_lastRuneGraceTimers[index]; }
public void SetLastRuneGraceTimer(byte index, uint timer) { m_lastRuneGraceTimers[index] = timer; }
public bool CanNoReagentCast(SpellInfo spellInfo) public bool CanNoReagentCast(SpellInfo spellInfo)
{ {
// don't take reagents for spells with SPELL_ATTR5_NO_REAGENT_WHILE_PREP // don't take reagents for spells with SPELL_ATTR5_NO_REAGENT_WHILE_PREP
+3 -30
View File
@@ -66,13 +66,6 @@ namespace Game.Entities
PlayerTalkClass = new PlayerMenu(session); PlayerTalkClass = new PlayerMenu(session);
m_currentBuybackSlot = InventorySlots.BuyBackStart; m_currentBuybackSlot = InventorySlots.BuyBackStart;
// Init rune flags
for (byte i = 0; i < PlayerConst.MaxRunes; ++i)
{
SetRuneTimer(i, 0xFFFFFFFF);
SetLastRuneGraceTimer(i, 0);
}
for (byte i = 0; i < (int)MirrorTimerType.Max; i++) for (byte i = 0; i < (int)MirrorTimerType.Max; i++)
m_MirrorTimer[i] = -1; m_MirrorTimer[i] = -1;
@@ -744,26 +737,6 @@ namespace Game.Entities
} }
} }
if (GetClass() == Class.Deathknight)
{
// Update rune timers
for (byte i = 0; i < PlayerConst.MaxRunes; ++i)
{
uint timer = GetRuneTimer(i);
// Don't update timer if rune is disabled
if (GetRuneCooldown(i) != 0)
continue;
// Timer has began
if (timer < 0xFFFFFFFF)
{
timer += diff;
SetRuneTimer(i, Math.Min(2500, timer));
}
}
}
// group update // group update
SendUpdateToOutOfRangeGroupMembers(); SendUpdateToOutOfRangeGroupMembers();
@@ -3745,9 +3718,9 @@ namespace Game.Entities
{ {
uint regeneratedRunes = 0; uint regeneratedRunes = 0;
int regenIndex = 0; int regenIndex = 0;
while (regeneratedRunes < PlayerConst.MaxRechargingRunes && !m_runes.CooldownOrder.Empty()) while (regeneratedRunes < PlayerConst.MaxRechargingRunes && m_runes.CooldownOrder.Count > regenIndex)
{ {
byte runeToRegen = m_runes.CooldownOrder[regenIndex++]; byte runeToRegen = m_runes.CooldownOrder[regenIndex];
uint runeCooldown = GetRuneCooldown(runeToRegen); uint runeCooldown = GetRuneCooldown(runeToRegen);
if (runeCooldown > m_regenTimer) if (runeCooldown > m_regenTimer)
{ {
@@ -3755,7 +3728,7 @@ namespace Game.Entities
++regenIndex; ++regenIndex;
} }
else else
SetRuneCooldown((byte)runeCooldown, 0); SetRuneCooldown(runeToRegen, 0);
++regeneratedRunes; ++regeneratedRunes;
} }
-10
View File
@@ -251,16 +251,6 @@ namespace Game.Entities
m_CombatTimer = 0; m_CombatTimer = 0;
RemoveFlag(UnitFields.Flags, UnitFlags.InCombat); RemoveFlag(UnitFields.Flags, UnitFlags.InCombat);
// Reset rune flags after combat
if (IsTypeId(TypeId.Player) && GetClass() == Class.Deathknight)
{
for (byte i = 0; i < PlayerConst.MaxRunes; ++i)
{
ToPlayer().SetRuneTimer(i, 0xFFFFFFFF);
ToPlayer().SetLastRuneGraceTimer(i, 0);
}
}
// Player's state will be cleared in Player.UpdateContestedPvP // Player's state will be cleared in Player.UpdateContestedPvP
Creature creature = ToCreature(); Creature creature = ToCreature();
if (creature != null) if (creature != null)
+8 -9
View File
@@ -3543,7 +3543,7 @@ namespace Game.Spells
{ {
runeData.Start = m_runesState; // runes state before runeData.Start = m_runesState; // runes state before
runeData.Count = player.GetRunesState(); // runes state after runeData.Count = player.GetRunesState(); // runes state after
for (byte i = 0; i < PlayerConst.MaxRunes; ++i) for (byte i = 0; i < player.GetMaxPower(PowerType.Runes); ++i)
{ {
// float casts ensure the division is performed on floats as we need float result // float casts ensure the division is performed on floats as we need float result
float baseCd = player.GetRuneBaseCooldown(); float baseCd = player.GetRuneBaseCooldown();
@@ -3554,7 +3554,7 @@ namespace Game.Spells
{ {
runeData.Start = 0; runeData.Start = 0;
runeData.Count = 0; runeData.Count = 0;
for (byte i = 0; i < PlayerConst.MaxRunes; ++i) for (byte i = 0; i < player.GetMaxPower(PowerType.Runes); ++i)
runeData.Cooldowns.Add(0); runeData.Cooldowns.Add(0);
} }
} }
@@ -3659,7 +3659,7 @@ namespace Game.Spells
{ {
runeData.Start = m_runesState; // runes state before runeData.Start = m_runesState; // runes state before
runeData.Count = player.GetRunesState(); // runes state after runeData.Count = player.GetRunesState(); // runes state after
for (byte i = 0; i < PlayerConst.MaxRunes; ++i) for (byte i = 0; i < player.GetMaxPower(PowerType.Runes); ++i)
{ {
// float casts ensure the division is performed on floats as we need float result // float casts ensure the division is performed on floats as we need float result
float baseCd = player.GetRuneBaseCooldown(); float baseCd = player.GetRuneBaseCooldown();
@@ -3670,7 +3670,7 @@ namespace Game.Spells
{ {
runeData.Start = 0; runeData.Start = 0;
runeData.Count = 0; runeData.Count = 0;
for (byte i = 0; i < PlayerConst.MaxRunes; ++i) for (byte i = 0; i < player.GetMaxPower(PowerType.Runes); ++i)
runeData.Cooldowns.Add(0); runeData.Cooldowns.Add(0);
} }
} }
@@ -4148,8 +4148,8 @@ namespace Game.Spells
SpellCastResult CheckRuneCost() SpellCastResult CheckRuneCost()
{ {
var runeCost = m_powerCost.Find(cost => cost.Power == PowerType.Runes); int runeCost = m_powerCost.Sum(cost => cost.Power == PowerType.Runes ? cost.Amount : 0);
if (runeCost == null) if (runeCost == 0)
return SpellCastResult.SpellCastOk; return SpellCastResult.SpellCastOk;
Player player = m_caster.ToPlayer(); Player player = m_caster.ToPlayer();
@@ -4164,7 +4164,7 @@ namespace Game.Spells
if (player.GetRuneCooldown(i) == 0) if (player.GetRuneCooldown(i) == 0)
++readyRunes; ++readyRunes;
if (readyRunes < runeCost.Amount) if (readyRunes < runeCost)
return SpellCastResult.NoPower; // not sure if result code is correct return SpellCastResult.NoPower; // not sure if result code is correct
return SpellCastResult.SpellCastOk; return SpellCastResult.SpellCastOk;
@@ -4178,8 +4178,7 @@ namespace Game.Spells
Player player = m_caster.ToPlayer(); Player player = m_caster.ToPlayer();
m_runesState = player.GetRunesState(); // store previous state m_runesState = player.GetRunesState(); // store previous state
int runeCost = m_powerCost.Find(cost => cost.Power == PowerType.Runes).Amount; int runeCost = m_powerCost.Sum(cost => cost.Power == PowerType.Runes ? cost.Amount : 0);
for (byte i = 0; i < player.GetMaxPower(PowerType.Runes); ++i) for (byte i = 0; i < player.GetMaxPower(PowerType.Runes); ++i)
{ {
if (player.GetRuneCooldown(i) == 0 && runeCost > 0) if (player.GetRuneCooldown(i) == 0 && runeCost > 0)
-2
View File
@@ -2308,8 +2308,6 @@ namespace Game.Spells
else else
collector(Global.DB2Mgr.GetSpellPowers(Id, caster.GetMap().GetDifficultyID())); collector(Global.DB2Mgr.GetSpellPowers(Id, caster.GetMap().GetDifficultyID()));
// POWER_RUNES is handled by SpellRuneCost.db2, and cost.Amount is always 0 (see Spell.TakeRunePower)
costs.RemoveAll(cost => cost.Power != PowerType.Runes && cost.Amount <= 0);
return costs; return costs;
} }
+4 -3
View File
@@ -88,11 +88,12 @@ namespace Scripts.Spells.DeathKnight
Unit caster = eventInfo.GetActor(); Unit caster = eventInfo.GetActor();
if (caster) if (caster)
{ {
if (!caster.IsTypeId(TypeId.Player) || caster.GetClass() != Class.Deathknight) Player player = caster.ToPlayer();
if (!player || caster.GetClass() != Class.Deathknight)
return false; return false;
for (byte i = 0; i < PlayerConst.MaxRunes; ++i) for (byte i = 0; i < player.GetMaxPower(PowerType.Runes); ++i)
if (caster.ToPlayer().GetRuneCooldown(i) == 0) if (player.GetRuneCooldown(i) == 0)
return false; return false;
return true; return true;