mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/Spells: Implemented battle pet experience related spell effects and auras (#27488)
* Spell effect 286 (SPELL_EFFECT_GRANT_BATTLEPET_EXPERIENCE) * Aura type 420 (SPELL_AURA_MOD_BATTLE_PET_XP_PCT)
This commit is contained in:
@@ -541,6 +541,8 @@ void CriteriaHandler::UpdateCriteria(CriteriaType type, uint64 miscValue1 /*= 0*
|
||||
case CriteriaType::PVPKillInArea:
|
||||
case CriteriaType::WinArena: // This also behaves like CriteriaType::WinAnyRankedArena
|
||||
case CriteriaType::Login:
|
||||
case CriteriaType::BattlePetReachLevel:
|
||||
case CriteriaType::ActivelyEarnPetLevel:
|
||||
case CriteriaType::PlaceGarrisonBuilding:
|
||||
case CriteriaType::ActivateAnyGarrisonBuilding:
|
||||
case CriteriaType::HonorLevelIncrease:
|
||||
@@ -789,9 +791,7 @@ void CriteriaHandler::UpdateCriteria(CriteriaType type, uint64 miscValue1 /*= 0*
|
||||
case CriteriaType::CompleteScenario:
|
||||
case CriteriaType::AccountObtainPetThroughBattle:
|
||||
case CriteriaType::WinPetBattle:
|
||||
case CriteriaType::BattlePetReachLevel:
|
||||
case CriteriaType::PlayerObtainPetThroughBattle:
|
||||
case CriteriaType::ActivelyEarnPetLevel:
|
||||
case CriteriaType::EnterArea:
|
||||
case CriteriaType::LeaveArea:
|
||||
case CriteriaType::DefeatDungeonEncounter:
|
||||
@@ -1203,6 +1203,8 @@ bool CriteriaHandler::IsCompletedCriteria(Criteria const* criteria, uint64 requi
|
||||
case CriteriaType::CurrencyGained:
|
||||
case CriteriaType::PlaceGarrisonBuilding:
|
||||
case CriteriaType::UniquePetsOwned:
|
||||
case CriteriaType::BattlePetReachLevel:
|
||||
case CriteriaType::ActivelyEarnPetLevel:
|
||||
case CriteriaType::LearnAnyTransmogInSlot:
|
||||
case CriteriaType::ParagonLevelIncreaseWithFaction:
|
||||
case CriteriaType::PlayerHasEarnedHonor:
|
||||
@@ -1629,9 +1631,15 @@ bool CriteriaHandler::RequirementsSatisfied(Criteria const* criteria, uint64 mis
|
||||
if (miscValue1 != uint32(criteria->Entry->Asset.TransmogSetGroupID))
|
||||
return false;
|
||||
break;
|
||||
case CriteriaType::BattlePetReachLevel:
|
||||
case CriteriaType::ActivelyEarnPetLevel:
|
||||
if (!miscValue1 || !miscValue2 || miscValue2 != uint32(criteria->Entry->Asset.PetLevel))
|
||||
return false;
|
||||
break;
|
||||
case CriteriaType::ActivelyReachLevel:
|
||||
if (!miscValue1 || miscValue1 != uint32(criteria->Entry->Asset.PlayerLevel))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "Containers.h"
|
||||
#include "Creature.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "GameTables.h"
|
||||
#include "GameTime.h"
|
||||
#include "Item.h"
|
||||
#include "Log.h"
|
||||
@@ -677,6 +678,76 @@ void BattlePetMgr::ChangeBattlePetQuality(ObjectGuid guid, BattlePetBreedQuality
|
||||
// _owner->GetPlayer()->SetCurrentBattlePetBreedQuality(qualityValue);
|
||||
}
|
||||
|
||||
void BattlePetMgr::GrantBattlePetExperience(ObjectGuid guid, uint16 xp, BattlePetXpSource xpSource)
|
||||
{
|
||||
if (!HasJournalLock())
|
||||
return;
|
||||
|
||||
BattlePet* pet = GetPet(guid);
|
||||
if (!pet)
|
||||
return;
|
||||
|
||||
if (xp <= 0 || xpSource >= BattlePetXpSource::Count)
|
||||
return;
|
||||
|
||||
if (BattlePetSpeciesEntry const* battlePetSpecies = sBattlePetSpeciesStore.LookupEntry(pet->PacketInfo.Species))
|
||||
if (battlePetSpecies->GetFlags().HasFlag(BattlePetSpeciesFlags::CantBattle))
|
||||
return;
|
||||
|
||||
uint16 level = pet->PacketInfo.Level;
|
||||
if (level >= MAX_BATTLE_PET_LEVEL)
|
||||
return;
|
||||
|
||||
GtBattlePetXPEntry const* xpEntry = sBattlePetXPGameTable.GetRow(level);
|
||||
if (!xpEntry)
|
||||
return;
|
||||
|
||||
Player* player = _owner->GetPlayer();
|
||||
uint16 nextLevelXp = uint16(GetBattlePetXPPerLevel(xpEntry));
|
||||
|
||||
if (xpSource == BattlePetXpSource::PetBattle)
|
||||
xp *= player->GetTotalAuraMultiplier(SPELL_AURA_MOD_BATTLE_PET_XP_PCT);
|
||||
|
||||
xp += pet->PacketInfo.Exp;
|
||||
|
||||
while (xp >= nextLevelXp && level < MAX_BATTLE_PET_LEVEL)
|
||||
{
|
||||
xp -= nextLevelXp;
|
||||
|
||||
xpEntry = sBattlePetXPGameTable.GetRow(++level);
|
||||
if (!xpEntry)
|
||||
return;
|
||||
|
||||
nextLevelXp = uint16(GetBattlePetXPPerLevel(xpEntry));
|
||||
|
||||
player->UpdateCriteria(CriteriaType::BattlePetReachLevel, pet->PacketInfo.Species, level);
|
||||
if (xpSource == BattlePetXpSource::PetBattle)
|
||||
player->UpdateCriteria(CriteriaType::ActivelyEarnPetLevel, pet->PacketInfo.Species, level);
|
||||
}
|
||||
|
||||
pet->PacketInfo.Level = level;
|
||||
pet->PacketInfo.Exp = level < MAX_BATTLE_PET_LEVEL ? xp : 0;
|
||||
pet->CalculateStats();
|
||||
pet->PacketInfo.Health = pet->PacketInfo.MaxHealth;
|
||||
|
||||
if (pet->SaveInfo != BATTLE_PET_NEW)
|
||||
pet->SaveInfo = BATTLE_PET_CHANGED;
|
||||
|
||||
std::vector<std::reference_wrapper<BattlePet>> updates;
|
||||
updates.push_back(std::ref(*pet));
|
||||
SendUpdates(std::move(updates), false);
|
||||
|
||||
// Update battle pet related update fields
|
||||
if (Creature* summonedBattlePet = player->GetSummonedBattlePet())
|
||||
{
|
||||
if (summonedBattlePet->GetBattlePetCompanionGUID() == guid)
|
||||
{
|
||||
summonedBattlePet->SetWildBattlePetLevel(pet->PacketInfo.Level);
|
||||
player->SetBattlePetData(pet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattlePetMgr::HealBattlePetsPct(uint8 pct)
|
||||
{
|
||||
// TODO: After each Pet Battle, any injured companion will automatically
|
||||
|
||||
@@ -85,6 +85,14 @@ enum class BattlePetSlot : uint8
|
||||
Count
|
||||
};
|
||||
|
||||
enum class BattlePetXpSource : uint8
|
||||
{
|
||||
PetBattle = 0,
|
||||
SpellEffect = 1,
|
||||
|
||||
Count
|
||||
};
|
||||
|
||||
// 6.2.4
|
||||
enum FlagsControlType
|
||||
{
|
||||
@@ -172,6 +180,7 @@ public:
|
||||
|
||||
void CageBattlePet(ObjectGuid guid);
|
||||
void ChangeBattlePetQuality(ObjectGuid guid, BattlePetBreedQuality quality);
|
||||
void GrantBattlePetExperience(ObjectGuid guid, uint16 xp, BattlePetXpSource xpSource);
|
||||
void HealBattlePetsPct(uint8 pct);
|
||||
|
||||
void SummonPet(ObjectGuid guid);
|
||||
|
||||
@@ -487,9 +487,9 @@ enum class CriteriaType : uint8
|
||||
AccountObtainPetThroughBattle = 157, /*NYI*/ // (Account Only) Obtain a pet through battle
|
||||
WinPetBattle = 158, /*NYI*/ // Win a pet battle
|
||||
LosePetBattle = 159, /*NYI*/ // Lose a pet battle
|
||||
BattlePetReachLevel = 160, /*NYI*/ // (Account Only) Battle pet has reached level {#Level}
|
||||
BattlePetReachLevel = 160, // (Account Only) Battle pet has reached level {#Level}
|
||||
PlayerObtainPetThroughBattle = 161, /*NYI*/ // (Player) Obtain a pet through battle
|
||||
ActivelyEarnPetLevel = 162, /*NYI*/ // (Player) Actively earn level {#Level} with a pet by a player
|
||||
ActivelyEarnPetLevel = 162, // (Player) Actively earn level {#Level} with a pet by a player
|
||||
EnterArea = 163, /*NYI*/ // Enter Map Area "{AreaTable}"
|
||||
LeaveArea = 164, /*NYI*/ // Leave Map Area "{AreaTable}"
|
||||
DefeatDungeonEncounter = 165, /*NYI*/ // Defeat Encounter "{DungeonEncounter}"
|
||||
|
||||
@@ -28,6 +28,7 @@ GameTable<GtArtifactKnowledgeMultiplierEntry> sArtifactKnowledgeMultiplierGame
|
||||
GameTable<GtArtifactLevelXPEntry> sArtifactLevelXPGameTable;
|
||||
GameTable<GtBarberShopCostBaseEntry> sBarberShopCostBaseGameTable;
|
||||
GameTable<GtBaseMPEntry> sBaseMPGameTable;
|
||||
GameTable<GtBattlePetXPEntry> sBattlePetXPGameTable;
|
||||
GameTable<GtCombatRatingsEntry> sCombatRatingsGameTable;
|
||||
GameTable<GtCombatRatingsMultByILvl> sCombatRatingsMultByILvlGameTable;
|
||||
GameTable<GtHpPerStaEntry> sHpPerStaGameTable;
|
||||
@@ -113,6 +114,7 @@ void LoadGameTables(std::string const& dataPath)
|
||||
LOAD_GT(sArtifactLevelXPGameTable, "ArtifactLevelXP.txt");
|
||||
LOAD_GT(sBarberShopCostBaseGameTable, "BarberShopCostBase.txt");
|
||||
LOAD_GT(sBaseMPGameTable, "BaseMp.txt");
|
||||
LOAD_GT(sBattlePetXPGameTable, "BattlePetXP.txt");
|
||||
LOAD_GT(sCombatRatingsGameTable, "CombatRatings.txt");
|
||||
LOAD_GT(sCombatRatingsMultByILvlGameTable, "CombatRatingsMultByILvl.txt");
|
||||
LOAD_GT(sItemSocketCostPerLevelGameTable, "ItemSocketCostPerLevel.txt");
|
||||
|
||||
@@ -56,6 +56,12 @@ struct GtBaseMPEntry
|
||||
float DemonHunter = 0.0f;
|
||||
};
|
||||
|
||||
struct GtBattlePetXPEntry
|
||||
{
|
||||
float Wins = 0.0f;
|
||||
float Xp = 0.0f;
|
||||
};
|
||||
|
||||
struct GtCombatRatingsEntry
|
||||
{
|
||||
float Amplify = 0.0f;
|
||||
@@ -180,6 +186,7 @@ TC_GAME_API extern GameTable<GtArtifactKnowledgeMultiplierEntry> sArtifactKno
|
||||
TC_GAME_API extern GameTable<GtArtifactLevelXPEntry> sArtifactLevelXPGameTable;
|
||||
TC_GAME_API extern GameTable<GtBarberShopCostBaseEntry> sBarberShopCostBaseGameTable;
|
||||
TC_GAME_API extern GameTable<GtBaseMPEntry> sBaseMPGameTable;
|
||||
TC_GAME_API extern GameTable<GtBattlePetXPEntry> sBattlePetXPGameTable;
|
||||
TC_GAME_API extern GameTable<GtCombatRatingsEntry> sCombatRatingsGameTable;
|
||||
TC_GAME_API extern GameTable<GtCombatRatingsMultByILvl> sCombatRatingsMultByILvlGameTable;
|
||||
TC_GAME_API extern GameTable<GtHpPerStaEntry> sHpPerStaGameTable;
|
||||
@@ -279,6 +286,11 @@ inline float GetSpellScalingColumnForClass(GtSpellScalingEntry const* row, int32
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
inline float GetBattlePetXPPerLevel(GtBattlePetXPEntry const* row)
|
||||
{
|
||||
return row->Wins * row->Xp;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
float GetIlvlStatMultiplier(T const* row, InventoryType invType);
|
||||
|
||||
|
||||
@@ -511,7 +511,7 @@ enum AuraType : uint32
|
||||
SPELL_AURA_MOD_GLOBAL_COOLDOWN_BY_HASTE_REGEN = 417,
|
||||
SPELL_AURA_MOD_MAX_POWER = 418, // NYI
|
||||
SPELL_AURA_MOD_BASE_MANA_PCT = 419,
|
||||
SPELL_AURA_MOD_BATTLE_PET_XP_PCT = 420, // NYI
|
||||
SPELL_AURA_MOD_BATTLE_PET_XP_PCT = 420,
|
||||
SPELL_AURA_MOD_ABSORB_EFFECTS_DONE_PCT = 421, // NYI
|
||||
SPELL_AURA_MOD_ABSORB_EFFECTS_TAKEN_PCT = 422, // NYI
|
||||
SPELL_AURA_MOD_MANA_COST_PCT = 423,
|
||||
|
||||
@@ -488,7 +488,7 @@ NonDefaultConstructible<pAuraEffectHandler> AuraEffectHandler[TOTAL_AURAS]=
|
||||
&AuraEffect::HandleNoImmediateEffect, //417 SPELL_AURA_MOD_GLOBAL_COOLDOWN_BY_HASTE_REGEN implemented in Spell::TriggerGlobalCooldown
|
||||
&AuraEffect::HandleAuraModMaxPower, //418 SPELL_AURA_MOD_MAX_POWER
|
||||
&AuraEffect::HandleAuraModIncreaseBaseManaPercent, //419 SPELL_AURA_MOD_BASE_MANA_PCT
|
||||
&AuraEffect::HandleNULL, //420 SPELL_AURA_MOD_BATTLE_PET_XP_PCT
|
||||
&AuraEffect::HandleNoImmediateEffect, //420 SPELL_AURA_MOD_BATTLE_PET_XP_PCT - Implemented in BattlePetMgr::GrantBattlePetExperience
|
||||
&AuraEffect::HandleNULL, //421 SPELL_AURA_MOD_ABSORB_EFFECTS_DONE_PCT
|
||||
&AuraEffect::HandleNULL, //422 SPELL_AURA_MOD_ABSORB_EFFECTS_TAKEN_PCT
|
||||
&AuraEffect::HandleModManaCostPct, //423 SPELL_AURA_MOD_MANA_COST_PCT
|
||||
|
||||
@@ -399,6 +399,7 @@ class TC_GAME_API Spell
|
||||
void EffectLearnAzeriteEssencePower();
|
||||
void EffectCreatePrivateConversation();
|
||||
void EffectSendChatMessage();
|
||||
void EffectGrantBattlePetExperience();
|
||||
|
||||
typedef std::unordered_set<Aura*> UsedSpellMods;
|
||||
|
||||
|
||||
@@ -367,7 +367,7 @@ NonDefaultConstructible<SpellEffectHandlerFn> SpellEffectHandlers[TOTAL_SPELL_EF
|
||||
&Spell::EffectNULL, //283 SPELL_EFFECT_COMPLETE_CAMPAIGN
|
||||
&Spell::EffectSendChatMessage, //284 SPELL_EFFECT_SEND_CHAT_MESSAGE
|
||||
&Spell::EffectNULL, //285 SPELL_EFFECT_MODIFY_KEYSTONE_2
|
||||
&Spell::EffectNULL, //286 SPELL_EFFECT_GRANT_BATTLEPET_EXPERIENCE
|
||||
&Spell::EffectGrantBattlePetExperience, //286 SPELL_EFFECT_GRANT_BATTLEPET_EXPERIENCE
|
||||
&Spell::EffectNULL, //287 SPELL_EFFECT_SET_GARRISON_FOLLOWER_LEVEL
|
||||
};
|
||||
|
||||
@@ -5722,3 +5722,18 @@ void Spell::EffectSendChatMessage()
|
||||
ChatMsg chatType = ChatMsg(effectInfo->MiscValueB);
|
||||
unitCaster->Talk(broadcastTextId, chatType, CreatureTextMgr::GetRangeForChatType(chatType), unitTarget);
|
||||
}
|
||||
|
||||
void Spell::EffectGrantBattlePetExperience()
|
||||
{
|
||||
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
|
||||
return;
|
||||
|
||||
Player* playerCaster = m_caster->ToPlayer();
|
||||
if (!playerCaster)
|
||||
return;
|
||||
|
||||
if (!unitTarget || !unitTarget->IsCreature())
|
||||
return;
|
||||
|
||||
playerCaster->GetSession()->GetBattlePetMgr()->GrantBattlePetExperience(unitTarget->GetBattlePetCompanionGUID(), damage, BattlePets::BattlePetXpSource::SpellEffect);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user