diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Achievements/CriteriaHandler.cpp | 12 | ||||
-rw-r--r-- | src/server/game/BattlePets/BattlePetMgr.cpp | 71 | ||||
-rw-r--r-- | src/server/game/BattlePets/BattlePetMgr.h | 9 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCEnums.h | 4 | ||||
-rw-r--r-- | src/server/game/DataStores/GameTables.cpp | 2 | ||||
-rw-r--r-- | src/server/game/DataStores/GameTables.h | 12 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraDefines.h | 2 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.h | 1 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 17 |
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); +} |