From b067976678a5ea0111c8328d99198d737717de5c Mon Sep 17 00:00:00 2001 From: hondacrx Date: Sun, 4 Mar 2018 23:40:51 -0500 Subject: [PATCH] Core/Creatures: Updated power type handling --- Source/Game/Entities/Creature/Creature.cs | 14 ++--- Source/Game/Entities/Pet.cs | 2 - Source/Game/Entities/Player/Player.cs | 11 +--- Source/Game/Entities/StatSystem.cs | 71 ++++++++++++---------- Source/Game/Entities/TemporarySummon.cs | 74 +++++++++++++++-------- Source/Game/Entities/Unit/Unit.Pets.cs | 4 -- Source/Game/Entities/Unit/Unit.cs | 25 +++++++- 7 files changed, 119 insertions(+), 82 deletions(-) diff --git a/Source/Game/Entities/Creature/Creature.cs b/Source/Game/Entities/Creature/Creature.cs index dab257568..d6a9de2d6 100644 --- a/Source/Game/Entities/Creature/Creature.cs +++ b/Source/Game/Entities/Creature/Creature.cs @@ -1159,28 +1159,22 @@ namespace Game.Entities switch (GetClass()) { - case Class.Warrior: - SetPowerType(PowerType.Rage); - break; - case Class.Rogue: - SetPowerType(PowerType.Energy); - break; - default: + case Class.Paladin: + case Class.Mage: SetMaxPower(PowerType.Mana, (int)mana); SetPower(PowerType.Mana, (int)mana); break; + default: // We don't set max power here, 0 makes power bar hidden + break; } SetModifierValue(UnitMods.Health, UnitModifierType.BaseValue, health); - SetModifierValue(UnitMods.Mana, UnitModifierType.BaseValue, mana); //Damage float basedamage = stats.GenerateBaseDamage(cInfo); - float weaponBaseMinDamage = basedamage; float weaponBaseMaxDamage = basedamage * 1.5f; - SetBaseWeaponDamage(WeaponAttackType.BaseAttack, WeaponDamageRange.MinDamage, weaponBaseMinDamage); SetBaseWeaponDamage(WeaponAttackType.BaseAttack, WeaponDamageRange.MaxDamage, weaponBaseMaxDamage); diff --git a/Source/Game/Entities/Pet.cs b/Source/Game/Entities/Pet.cs index 6e8df143a..bc56988b7 100644 --- a/Source/Game/Entities/Pet.cs +++ b/Source/Game/Entities/Pet.cs @@ -218,7 +218,6 @@ namespace Game.Entities SetByteFlag(UnitFields.Bytes2, UnitBytes2Offsets.PetFlags, (result.Read(9) ? UnitPetFlags.CanBeAbandoned : UnitPetFlags.CanBeRenamed | UnitPetFlags.CanBeAbandoned)); SetUInt32Value(UnitFields.Flags, (uint)UnitFlags.PvpAttackable); // this enables popup window (pet abandon, cancel) - SetPowerType(PowerType.Focus); break; default: if (!IsPetGhoul()) @@ -714,7 +713,6 @@ namespace Game.Entities if (!Create(map.GenerateLowGuid(HighGuid.Pet), map, cinfo.Entry)) return false; - SetPowerType(PowerType.Focus); SetUInt32Value(UnitFields.PetNameTimestamp, 0); SetUInt32Value(UnitFields.PetExperience, 0); SetUInt32Value(UnitFields.PetNextLevelExp, (uint)(Global.ObjectMgr.GetXPForLevel(getLevel() + 1) * PetXPFactor)); diff --git a/Source/Game/Entities/Player/Player.cs b/Source/Game/Entities/Player/Player.cs index 5c4ab030d..c30da806f 100644 --- a/Source/Game/Entities/Player/Player.cs +++ b/Source/Game/Entities/Player/Player.cs @@ -346,8 +346,7 @@ namespace Game.Entities // apply original stats mods before spell loading or item equipment that call before equip _RemoveStatsMods() UpdateMaxHealth(); // Update max Health (for add bonus from stamina) SetFullHealth(); - if (GetPowerType() == PowerType.Mana) - SetFullPower(PowerType.Mana); + SetFullPower(PowerType.Mana); // original spells LearnDefaultSkills(); @@ -4826,8 +4825,6 @@ namespace Game.Entities pet.SetCreatorGUID(GetGUID()); pet.SetUInt32Value(UnitFields.FactionTemplate, getFaction()); - - pet.SetPowerType(PowerType.Mana); pet.SetUInt64Value(UnitFields.NpcFlags, (uint)NPCFlags.None); pet.SetUInt32Value(UnitFields.Bytes1, 0); pet.InitStatsForLevel(getLevel()); @@ -5317,13 +5314,9 @@ namespace Game.Entities _ApplyAllLevelScaleItemMods(true); // Moved to above SetFullHealth so player will have full health from Heirlooms - // set current level health and mana/energy to maximum after applying all mods. + // Only health and mana are set to maximum. SetFullHealth(); SetFullPower(PowerType.Mana); - SetFullPower(PowerType.Energy); - if (GetPower(PowerType.Rage) > GetMaxPower(PowerType.Rage)) - SetFullPower(PowerType.Rage); - SetPower(PowerType.Focus, 0); // update level to hunter/summon pet Pet pet = GetPet(); diff --git a/Source/Game/Entities/StatSystem.cs b/Source/Game/Entities/StatSystem.cs index dc46f9ddd..b443b0c06 100644 --- a/Source/Game/Entities/StatSystem.cs +++ b/Source/Game/Entities/StatSystem.cs @@ -436,29 +436,22 @@ namespace Game.Entities pet.SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_POWER_TYPE); }*/ - float powerMultiplier = 1.0f; - if (!IsPet()) - { - Creature creature = ToCreature(); - if (creature) - powerMultiplier = creature.GetCreatureTemplate().ModMana; - } + // Update max power + UpdateMaxPower(powerType); + // Update current power switch (powerType) { - default: - case PowerType.Mana: + case PowerType.Mana: // Keep the same (druid form switching...) + case PowerType.Energy: break; - case PowerType.Rage: - SetMaxPower(PowerType.Rage, (int)Math.Ceiling(GetCreatePowers(PowerType.Rage) * powerMultiplier)); + case PowerType.Rage: // Reset to zero SetPower(PowerType.Rage, 0); break; - case PowerType.Focus: - SetMaxPower(PowerType.Focus, (int)Math.Ceiling(GetCreatePowers(PowerType.Focus) * powerMultiplier)); - SetPower(PowerType.Focus, (int)Math.Ceiling(GetCreatePowers(PowerType.Focus) * powerMultiplier)); + case PowerType.Focus: // Make it full + SetFullPower(powerType); break; - case PowerType.Energy: - SetMaxPower(PowerType.Energy, (int)Math.Ceiling(GetCreatePowers(PowerType.Energy) * powerMultiplier)); + default: break; } } @@ -549,18 +542,7 @@ namespace Game.Entities return 0; } - public uint GetPowerIndex(PowerType powerType) - { - // This is here because hunter pets are of the warrior class. - // With the current implementation, the core only gives them - // POWER_RAGE, so we enforce the class to hunter so that they - // effectively get focus power. - Class _class = GetClass(); - if (IsPet() && ToPet().getPetType() == PetType.Hunter) - _class = Class.Hunter; - - return Global.DB2Mgr.GetPowerIndexByClass(powerType, _class); - } + public virtual uint GetPowerIndex(PowerType powerType) { return 0; } public float GetPowerPct(PowerType powerType) { return GetMaxPower(powerType) != 0 ? 100.0f* GetPower(powerType) / GetMaxPower(powerType) : 0.0f; } public void ApplyResilience(Unit victim, ref uint damage) @@ -1651,8 +1633,16 @@ namespace Game.Entities return stamina * ratio; } + public override uint GetPowerIndex(PowerType powerType) + { + return Global.DB2Mgr.GetPowerIndexByClass(powerType, GetClass()); + } public override void UpdateMaxPower(PowerType power) { + uint powerIndex = GetPowerIndex(power); + if (powerIndex == (uint)PowerType.Max || powerIndex >= (uint)PowerType.MaxPerClass) + return; + UnitMods unitMod = UnitMods.PowerStart + (int)power; float value = GetModifierValue(unitMod, UnitModifierType.BaseValue) + GetCreatePowers(power); @@ -1660,7 +1650,7 @@ namespace Game.Entities value += GetModifierValue(unitMod, UnitModifierType.TotalValue); value *= GetModifierValue(unitMod, UnitModifierType.TotalPCT); - SetMaxPower(power, (int)value); + SetMaxPower(power, (int)Math.Round(value)); } public void ApplySpellPenetrationBonus(int amount, bool apply) @@ -1782,12 +1772,31 @@ namespace Game.Entities SetMaxHealth((uint)value); } + public override uint GetPowerIndex(PowerType powerType) + { + if (powerType == GetPowerType()) + return 0; + if (powerType == PowerType.AlternatePower) + return 1; + if (powerType == PowerType.ComboPoints) + return 2; + + return (uint)PowerType.Max; + } + public override void UpdateMaxPower(PowerType power) { + if (GetPowerIndex(power) == (uint)PowerType.Max) + return; + UnitMods unitMod = UnitMods.PowerStart + (int)power; - float value = GetTotalAuraModValue(unitMod); - SetMaxPower(power, (int)value); + float value = GetModifierValue(unitMod, UnitModifierType.BaseValue) + GetCreatePowers(power); + value *= GetModifierValue(unitMod, UnitModifierType.BasePCT); + value += GetModifierValue(unitMod, UnitModifierType.TotalValue); + value *= GetModifierValue(unitMod, UnitModifierType.TotalPCT); + + SetMaxPower(power, (int)Math.Round(value)); } public override void UpdateAttackPowerAndDamage(bool ranged = false) diff --git a/Source/Game/Entities/TemporarySummon.cs b/Source/Game/Entities/TemporarySummon.cs index 7a0f6553c..82b14766f 100644 --- a/Source/Game/Entities/TemporarySummon.cs +++ b/Source/Game/Entities/TemporarySummon.cs @@ -346,10 +346,20 @@ namespace Game.Entities public void SetFollowAngle(float angle) { m_followAngle = angle; } - public bool IsPetGhoul() { return GetEntry() == 26125; } // Ghoul may be guardian or pet + // Warlock pets + public bool IsPetImp() { return GetEntry() == (uint)PetEntry.Imp; } + public bool IsPetFelhunter() { return GetEntry() == (uint)PetEntry.FelHunter; } + public bool IsPetVoidwalker() { return GetEntry() == (uint)PetEntry.VoidWalker; } + public bool IsPetSuccubus() { return GetEntry() == (uint)PetEntry.Succubus; } + public bool IsPetDoomguard() { return GetEntry() == (uint)PetEntry.Doomguard; } + public bool IsPetFelguard() { return GetEntry() == (uint)PetEntry.Felguard; } - public bool IsSpiritWolf() { return GetEntry() == 29264; } // Spirit wolf from feral spirits + // Death Knight pets + public bool IsPetGhoul() { return GetEntry() == (uint)PetEntry.Ghoul; } // Ghoul may be guardian or pet + public bool IsPetAbomination() { return GetEntry() == (uint)PetEntry.Abomination; } // Sludge Belcher dk talent + // Shaman pet + public bool IsSpiritWolf() { return GetEntry() == (uint)PetEntry.SpiritWolf; } // Spirit wolf from feral spirits Unit m_owner; float m_followAngle; @@ -454,13 +464,12 @@ namespace Game.Entities for (int i = (int)SpellSchools.Holy; i < (int)SpellSchools.Max; ++i) SetModifierValue(UnitMods.ResistanceStart + i, UnitModifierType.BaseValue, cinfo.Resistance[i]); - //health, mana, armor and resistance + // Health, Mana or Power, Armor PetLevelInfo pInfo = Global.ObjectMgr.GetPetLevelInfo(creature_ID, petlevel); if (pInfo != null) // exist in DB { SetCreateHealth(pInfo.health); - if (petType != PetType.Hunter) //hunter pet use focus - SetCreateMana(pInfo.mana); + SetCreateMana(pInfo.mana); if (pInfo.armor > 0) SetModifierValue(UnitMods.Armor, UnitModifierType.BaseValue, pInfo.armor); @@ -481,6 +490,17 @@ namespace Game.Entities SetCreateStat(Stats.Intellect, 28); } + // Power + if (petType == PetType.Hunter) // Hunter pets have focus + SetPowerType(PowerType.Focus); + else if (IsPetGhoul() || IsPetAbomination()) // DK pets have energy + SetPowerType(PowerType.Energy); + else if (IsPetImp() || IsPetFelhunter() || IsPetVoidwalker() || IsPetSuccubus() || IsPetDoomguard() || IsPetFelguard()) // Warlock pets have energy (since 5.x) + SetPowerType(PowerType.Energy); + else + SetPowerType(PowerType.Mana); + + // Damage SetBonusDamage(0); switch (petType) { @@ -711,6 +731,8 @@ namespace Game.Entities public override bool UpdateAllStats() { + UpdateMaxHealth(); + for (var i = Stats.Strength; i < Stats.Max; ++i) UpdateStats(i); @@ -799,30 +821,14 @@ namespace Game.Entities public override void UpdateMaxPower(PowerType power) { + if (GetPowerIndex(power) == (uint)PowerType.Max) + return; + UnitMods unitMod = UnitMods.PowerStart + (int)power; - float addValue = (power == PowerType.Mana) ? GetStat(Stats.Intellect) - GetCreateStat(Stats.Intellect) : 0.0f; - float multiplicator = 15.0f; - - switch (GetEntry()) - { - case ENTRY_IMP: - multiplicator = 4.95f; - break; - case ENTRY_VOIDWALKER: - case ENTRY_SUCCUBUS: - case ENTRY_FELHUNTER: - case ENTRY_FELGUARD: - multiplicator = 11.5f; - break; - default: - multiplicator = 15.0f; - break; - } - float value = GetModifierValue(unitMod, UnitModifierType.BaseValue) + GetCreatePowers(power); value *= GetModifierValue(unitMod, UnitModifierType.BasePCT); - value += GetModifierValue(unitMod, UnitModifierType.TotalValue) + addValue * multiplicator; + value += GetModifierValue(unitMod, UnitModifierType.TotalValue); value *= GetModifierValue(unitMod, UnitModifierType.TotalPCT); SetMaxPower(power, (int)value); @@ -1024,4 +1030,22 @@ namespace Game.Entities public TempSummonType type; // Summon type, see TempSummonType for available types public uint time; // Despawn time, usable only with certain temp summon types } + + enum PetEntry + { + // Warlock pets + Imp = 416, + FelHunter = 691, + VoidWalker = 1860, + Succubus = 1863, + Doomguard = 18540, + Felguard = 30146, + + // Death Knight pets + Ghoul = 26125, + Abomination = 106848, + + // Shaman pet + SpiritWolf = 29264 + } } diff --git a/Source/Game/Entities/Unit/Unit.Pets.cs b/Source/Game/Entities/Unit/Unit.Pets.cs index 47deaa566..d3f9475ad 100644 --- a/Source/Game/Entities/Unit/Unit.Pets.cs +++ b/Source/Game/Entities/Unit/Unit.Pets.cs @@ -213,10 +213,6 @@ namespace Game.Entities for (UnitMoveType i = 0; i < UnitMoveType.Max; ++i) minion.SetSpeedRate(i, m_speed_rate[(int)i]); - // Ghoul pets have energy instead of mana (is anywhere better place for this code?) - if (minion.IsPetGhoul()) - minion.SetPowerType(PowerType.Energy); - // Send infinity cooldown - client does that automatically but after relog cooldown needs to be set again SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(minion.GetUInt32Value(UnitFields.CreatedBySpell)); if (spellInfo != null && spellInfo.IsCooldownStartedOnEvent()) diff --git a/Source/Game/Entities/Unit/Unit.cs b/Source/Game/Entities/Unit/Unit.cs index 7facc2e5d..c99d60911 100644 --- a/Source/Game/Entities/Unit/Unit.cs +++ b/Source/Game/Entities/Unit/Unit.cs @@ -1941,12 +1941,35 @@ namespace Game.Entities AuraEffect powerTypeAura = powerTypeAuras.First(); displayPower = (PowerType)powerTypeAura.GetMiscValue(); } - else + else if (GetTypeId() == TypeId.Player) { ChrClassesRecord cEntry = CliDB.ChrClassesStorage.LookupByKey(GetClass()); if (cEntry != null && cEntry.PowerType < PowerType.Max) displayPower = cEntry.PowerType; } + else if (GetTypeId() == TypeId.Unit) + { + Vehicle vehicle = GetVehicle(); + if (vehicle) + { + PowerDisplayRecord powerDisplay = CliDB.PowerDisplayStorage.LookupByKey(vehicle.GetVehicleInfo().PowerDisplayID[0]); + if (powerDisplay != null) + displayPower = (PowerType)powerDisplay.PowerType; + else if (GetClass() == Class.Rogue) + displayPower = PowerType.Energy; + } + else + { + Pet pet = ToPet(); + if (pet) + { + if (pet.getPetType() == PetType.Hunter) // Hunter pets have focus + displayPower = PowerType.Focus; + else if (pet.IsPetGhoul() || pet.IsPetAbomination()) // DK pets have energy + displayPower = PowerType.Energy; + } + } + } break; } }