aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMeji <alvaromegias_46@hotmail.com>2021-12-30 20:38:29 +0100
committerGitHub <noreply@github.com>2021-12-30 20:38:29 +0100
commit9354b4ac8ec63f0b2ee5ceb3c8b6a3c6a75bd99f (patch)
tree0370cd85197397f79210d5e6b0897b8b3ff4889c /src
parent9cc3cd128cf931141f6b806a33e1a715274b84e7 (diff)
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)
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Achievements/CriteriaHandler.cpp12
-rw-r--r--src/server/game/BattlePets/BattlePetMgr.cpp71
-rw-r--r--src/server/game/BattlePets/BattlePetMgr.h9
-rw-r--r--src/server/game/DataStores/DBCEnums.h4
-rw-r--r--src/server/game/DataStores/GameTables.cpp2
-rw-r--r--src/server/game/DataStores/GameTables.h12
-rw-r--r--src/server/game/Spells/Auras/SpellAuraDefines.h2
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp2
-rw-r--r--src/server/game/Spells/Spell.h1
-rw-r--r--src/server/game/Spells/SpellEffects.cpp17
10 files changed, 125 insertions, 7 deletions
diff --git a/src/server/game/Achievements/CriteriaHandler.cpp b/src/server/game/Achievements/CriteriaHandler.cpp
index 948e9b9cfe2..7b25f151ee7 100644
--- a/src/server/game/Achievements/CriteriaHandler.cpp
+++ b/src/server/game/Achievements/CriteriaHandler.cpp
@@ -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;
}
diff --git a/src/server/game/BattlePets/BattlePetMgr.cpp b/src/server/game/BattlePets/BattlePetMgr.cpp
index 85ab36ef132..3243f5d621b 100644
--- a/src/server/game/BattlePets/BattlePetMgr.cpp
+++ b/src/server/game/BattlePets/BattlePetMgr.cpp
@@ -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
diff --git a/src/server/game/BattlePets/BattlePetMgr.h b/src/server/game/BattlePets/BattlePetMgr.h
index 3c2542eb596..f0cf284f896 100644
--- a/src/server/game/BattlePets/BattlePetMgr.h
+++ b/src/server/game/BattlePets/BattlePetMgr.h
@@ -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);
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index e7d58467943..21073d00bd9 100644
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -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}"
diff --git a/src/server/game/DataStores/GameTables.cpp b/src/server/game/DataStores/GameTables.cpp
index a8f83354675..d77b805d404 100644
--- a/src/server/game/DataStores/GameTables.cpp
+++ b/src/server/game/DataStores/GameTables.cpp
@@ -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");
diff --git a/src/server/game/DataStores/GameTables.h b/src/server/game/DataStores/GameTables.h
index ea14c64c56b..f0aef35b810 100644
--- a/src/server/game/DataStores/GameTables.h
+++ b/src/server/game/DataStores/GameTables.h
@@ -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);
diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h
index d31ec35ef12..9fb3018a08a 100644
--- a/src/server/game/Spells/Auras/SpellAuraDefines.h
+++ b/src/server/game/Spells/Auras/SpellAuraDefines.h
@@ -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,
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 183a738f7b7..1db54def277 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -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
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 9d314fe62aa..69fd9d2026d 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -399,6 +399,7 @@ class TC_GAME_API Spell
void EffectLearnAzeriteEssencePower();
void EffectCreatePrivateConversation();
void EffectSendChatMessage();
+ void EffectGrantBattlePetExperience();
typedef std::unordered_set<Aura*> UsedSpellMods;
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 04aed7b0e08..2785194768d 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -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);
+}