28 uint32 const PetBattlePvpProposalTimeout = 60;
29 uint32 const PetBattlePvpChallengeTimeout = 60;
32 bool ValidatePetBattleQueueRequest(
Player& player);
33 bool ValidatePetBattlePvpDuelTarget(
Player& challenger,
Player* target);
35 void SendPetBattleDuelPopup(
Player& challenger,
Player& target)
41 data.WriteGuidMask(arbiterGuid, 5);
42 data.WriteGuidMask(casterGuid, 4, 2, 7);
43 data.WriteGuidMask(arbiterGuid, 0);
44 data.WriteGuidMask(casterGuid, 5);
45 data.WriteGuidMask(arbiterGuid, 4, 6);
46 data.WriteGuidMask(casterGuid, 1, 3, 6);
47 data.WriteGuidMask(arbiterGuid, 7, 3, 2, 1);
48 data.WriteGuidMask(casterGuid, 0);
50 data.WriteGuidBytes(arbiterGuid, 5, 3);
51 data.WriteGuidBytes(casterGuid, 7, 4);
52 data.WriteGuidBytes(arbiterGuid, 7);
53 data.WriteGuidBytes(casterGuid, 3, 6, 0);
54 data.WriteGuidBytes(arbiterGuid, 4);
55 data.WriteGuidBytes(casterGuid, 2, 1);
56 data.WriteGuidBytes(arbiterGuid, 0, 2, 6, 1);
57 data.WriteGuidBytes(casterGuid, 5);
69 wildPetBreed =
sObjectMgr->BattlePetGetRandomBreed(speciesId);
72 sObjectMgr->BattlePetGetRandomQuality(speciesId), wildPetBreed);
104 if (!activeBattle.
IsPvP())
119 return GetActiveBattlePet(*opponentBattlePetMgr);
124 if (!battlePet || !abilityId)
146 void SendBattlePetFinished(
Player& player)
152 void ClearActivePetBattleAndSave(
Player& player)
170 void FinishActivePvpPetBattleForOpponent(
Player& player,
uint64 opponentGuid,
uint8 opponentWinner,
bool abandoned)
192 SendBattlePetFinalRound(*opponent, opponentFinalRound);
194 ClearActivePetBattleAndSave(*opponent);
197 void FinishActivePvpPetBattle(
Player& player,
uint64 opponentGuid,
199 uint8 opponentWinner,
bool opponentAbandoned)
201 SendBattlePetFinalRound(player, playerFinalRound);
202 FinishActivePvpPetBattleForOpponent(player, opponentGuid, opponentWinner, opponentAbandoned);
203 ClearActivePetBattleAndSave(player);
206 void FinishActivePvpPetBattleAfterForfeit(
Player& loser,
uint64 opponentGuid,
235 void BuildPetBattleQueueSlotResults(
Player& player,
239 slotResults[slot] = PetBattleQueueSlotResult(player, slot);
245 BuildPetBattleQueueSlotResults(player, slotResults);
251 void SendPetBattleQueueStatus(
Player& player,
uint32 status)
254 SendPetBattleQueueStatus(*session, player, status);
257 void SendPetBattleQueueProposeMatch(
Player& player)
266 void SendPetBattlePvpChallengeFailed(
uint64 playerGuid)
274 return challenge.
CreatedAt && time(NULL) - challenge.
CreatedAt >= PetBattlePvpChallengeTimeout;
277 void ClearPetBattlePvpChallengeForTarget(
uint64 targetGuid,
bool notifyPlayers =
false,
280 PetBattlePvpStateStore::ChallengeMap::iterator challengeItr =
295 SendPetBattlePvpChallengeFailed(challenge.
TargetGuid);
298 void ClearPetBattlePvpChallengesFor(
uint64 playerGuid,
bool notifyPlayers =
false,
301 ClearPetBattlePvpChallengeForTarget(playerGuid, notifyPlayers, exceptGuid);
303 PetBattlePvpStateStore::ChallengeTargetMap::iterator targetItr =
308 ClearPetBattlePvpChallengeForTarget(targetItr->second, notifyPlayers, exceptGuid);
311 PetBattlePvpStateStore::ChallengeMap::iterator FindPetBattlePvpChallengeForPlayer(
uint64 playerGuid)
316 bool ExpirePetBattlePvpChallenge(
Player& player)
318 PetBattlePvpStateStore::ChallengeMap::iterator challengeItr =
319 FindPetBattlePvpChallengeForPlayer(player.
GetGUID());
321 || !IsPetBattlePvpChallengeExpired(challengeItr->second))
324 ClearPetBattlePvpChallengeForTarget(challengeItr->first,
true);
334 if (!activeBattlePet)
341 if (!loadoutBattlePet)
348 if (loadoutBattlePet == activeBattlePet)
363 for (
uint8 petIndex = 0; petIndex < team.
PetCount; petIndex++)
368 G3D::Vector3 CalculatePetBattlePlayerPosition(
Player const& player,
369 G3D::Vector3
const& ownPetPosition, G3D::Vector3
const& opponentPetPosition)
371 float dx = opponentPetPosition.x - ownPetPosition.x;
372 float dy = opponentPetPosition.y - ownPetPosition.y;
373 float length = std::sqrt(dx * dx + dy * dy);
384 constexpr float playerPetBackstep = 2.5f;
385 return G3D::Vector3(ownPetPosition.x - dx * playerPetBackstep,
386 ownPetPosition.y - dy * playerPetBackstep, ownPetPosition.z);
389 void PlacePlayerForPetBattle(
Player& player, G3D::Vector3
const& ownPetPosition,
390 G3D::Vector3
const& opponentPetPosition)
392 G3D::Vector3
const playerPosition =
393 CalculatePetBattlePlayerPosition(player, ownPetPosition, opponentPetPosition);
395 std::atan2(opponentPetPosition.y - playerPosition.y,
396 opponentPetPosition.x - playerPosition.x));
398 player.
NearTeleportTo(playerPosition.x, playerPosition.y, playerPosition.z, orientation);
400 opponentPetPosition.x, opponentPetPosition.y);
403 bool StartPetBattlePvpForPlayer(
Player& player,
Player& opponent,
406 G3D::Vector3
const& origin, G3D::Vector3
const* positions,
407 float orientation,
bool hasLocationResult,
uint32 locationResult,
420 PlacePlayerForPetBattle(player, positions[0], positions[1]);
423 origin, positions,
true, orientation, hasLocationResult, locationResult);
430 playerTeam.
FrontPet, enemyFrontPet, battleSource);
432 SetActivePetBattleTeam(*battlePetMgr, playerTeam);
436 teams[0] = playerTeam;
437 teams[1] = opponentTeam;
447 bool StartPetBattlePvp(
Player& player,
Player& opponent, G3D::Vector3
const& origin,
448 G3D::Vector3
const* positions,
float orientation,
bool hasLocationResult,
uint32 locationResult,
451 if (!ValidatePetBattleQueueRequest(player) || !ValidatePetBattlePvpDuelTarget(player, &opponent))
456 if (!BuildPlayerPetBattleTeam(player, playerTeam) || !BuildPlayerPetBattleTeam(opponent, opponentTeam))
463 G3D::Vector3 opponentPositions[2] = { positions[1], positions[0] };
466 bool const playerStarted = StartPetBattlePvpForPlayer(player, opponent, playerTeam, opponentTeam,
467 origin, positions, orientation, hasLocationResult, locationResult, battleSource);
468 bool const opponentStarted = StartPetBattlePvpForPlayer(opponent, player, opponentTeam, playerTeam,
469 origin, opponentPositions, opponentOrientation, hasLocationResult, locationResult, battleSource);
471 if (!playerStarted || !opponentStarted)
481 void BuildPetBattleQueueLocation(
Player const& player,
Player const& opponent,
482 G3D::Vector3& origin, G3D::Vector3* positions,
float& orientation)
488 float length = std::sqrt(dx * dx + dy * dy);
503 positions[0] = G3D::Vector3(centerX - dx * 1.5f, centerY - dy * 1.5f, centerZ);
504 positions[1] = G3D::Vector3(centerX + dx * 1.5f, centerY + dy * 1.5f, centerZ);
508 bool IsPetBattlePvpQueueCandidate(
Player* player)
520 void RemovePetBattlePvpQueueEntry(
uint64 playerGuid)
525 void ClearPetBattlePvpProposal(
uint64 playerGuid)
532 return proposal.
CreatedAt && time(NULL) - proposal.
CreatedAt >= PetBattlePvpProposalTimeout;
535 void LeavePetBattlePvpQueue(
Player& player,
bool sendStatus,
538 bool sendOpponentStatus =
true)
541 RemovePetBattlePvpQueueEntry(playerGuid);
543 PetBattlePvpStateStore::ProposalMap::iterator proposalItr = PetBattlePvpState.
Proposals().find(playerGuid);
544 uint64 const opponentGuid = proposalItr != PetBattlePvpState.
Proposals().end() ? proposalItr->second.OpponentGuid : 0;
545 ClearPetBattlePvpProposal(playerGuid);
549 SendPetBattleQueueStatus(player, playerStatus);
557 if (sendOpponentStatus)
558 SendPetBattleQueueStatus(*opponent, opponentStatus);
562 bool ExpirePetBattlePvpProposal(
Player& player)
564 PetBattlePvpStateStore::ProposalMap::iterator proposalItr =
566 if (proposalItr == PetBattlePvpState.
Proposals().end() || !IsPetBattlePvpProposalExpired(proposalItr->second))
569 LeavePetBattlePvpQueue(player,
true,
578 RemovePetBattlePvpQueueEntry(playerGuid);
580 for (PetBattlePvpStateStore::QueueContainer::iterator itr = PetBattlePvpState.
Queue().begin();
581 itr != PetBattlePvpState.
Queue().end();)
584 if (!IsPetBattlePvpQueueCandidate(opponent))
589 itr = PetBattlePvpState.
Queue().erase(itr);
593 uint64 const opponentGuid = *itr;
594 PetBattlePvpState.
Queue().erase(itr);
601 void ProposePetBattlePvpMatch(
Player& player,
Player& opponent)
605 time_t
const createdAt = time(NULL);
607 PetBattlePvpState.
AddProposalPair(playerGuid, opponentGuid, createdAt);
609 SendPetBattleQueueProposeMatch(player);
610 SendPetBattleQueueProposeMatch(opponent);
624 ClearPetBattlePvpChallengesFor(playerGuid);
625 ClearPetBattlePvpProposal(playerGuid);
626 RemovePetBattlePvpQueueEntry(playerGuid);
630 uint64 const opponentGuid = TakePetBattlePvpQueueOpponent(player);
634 ProposePetBattlePvpMatch(player, *opponent);
641 void FailAcceptedPetBattlePvpQueueMatch(
Player& player,
Player* opponent)
643 LeavePetBattlePvpQueue(player,
true,
646 opponent !=
nullptr);
651 SendPetBattleQueueStatus(*opponent,
656 bool ReadPetBattleQueueProposeAccepted(
WorldPacket& recvData)
658 if (recvData.
rpos() >= recvData.
size())
666 recvData >> petBattleRequest.
Origin.z;
668 for (
uint8 i = 0; i < 2; i++)
670 recvData >> petBattleRequest.
Positions[i].x;
671 recvData >> petBattleRequest.
Positions[i].z;
672 recvData >> petBattleRequest.
Positions[i].y;
675 recvData >> petBattleRequest.
Origin.y;
676 recvData >> petBattleRequest.
Origin.x;
685 | (
uint32(tail[3]) << 24);
689 bool ValidatePetBattleQueueRequest(
Player& player)
719 bool ValidatePetBattlePvpDuelTarget(
Player& challenger,
Player* target)
723 if (!target || target == &challenger || !targetBattlePetMgr || targetBattlePetMgr->
HasActivePetBattle()
751 bool HandlePendingPetBattlePvpChallengeResponse(
Player& target,
755 PetBattlePvpStateStore::ChallengeMap::iterator challengeItr =
760 if (IsPetBattlePvpChallengeExpired(challengeItr->second))
762 ClearPetBattlePvpChallengeForTarget(targetGuid,
true);
770 ClearPetBattlePvpChallengeForTarget(targetGuid);
777 ClearPetBattlePvpChallengeForTarget(targetGuid);
782 if (!challengeItr->second.PromptAcknowledged)
784 challengeItr->second.PromptAcknowledged =
true;
788 challenge = challengeItr->second;
789 ClearPetBattlePvpChallengeForTarget(targetGuid);
791 LeavePetBattlePvpQueue(*challenger,
false);
792 LeavePetBattlePvpQueue(target,
false);
794 if (!StartPetBattlePvp(*challenger, target, challenge.
Origin, challenge.
Positions,
804 bool CompletePendingPetBattlePvpChallenge(
Player& target,
bool accepted)
807 PetBattlePvpStateStore::ChallengeMap::iterator challengeItr =
812 if (IsPetBattlePvpChallengeExpired(challengeItr->second))
814 ClearPetBattlePvpChallengeForTarget(targetGuid,
true);
820 ClearPetBattlePvpChallengeForTarget(targetGuid);
834 LeavePetBattlePvpQueue(*challenger,
false);
835 LeavePetBattlePvpQueue(target,
false);
837 if (!StartPetBattlePvp(*challenger, target, challenge.
Origin, challenge.
Positions,
854 ExpirePetBattlePvpChallenge(*player);
855 ExpirePetBattlePvpProposal(*player);
864 ClearPetBattlePvpChallengesFor(player->
GetGUID(),
true, player->
GetGUID());
865 LeavePetBattlePvpQueue(*player,
false,
872 SF_LOG_DEBUG(
"network",
"WORLD: Received CMSG_PET_BATTLE_START_PVP_MATCHMAKING");
875 if (!player || !ValidatePetBattleQueueRequest(*player))
878 JoinPetBattlePvpQueue(*
this, *player);
883 SF_LOG_DEBUG(
"network",
"WORLD: Received CMSG_PET_BATTLE_STOP_PVP_MATCHMAKING");
886 LeavePetBattlePvpQueue(*player,
true);
891 SF_LOG_DEBUG(
"network",
"WORLD: Received CMSG_PET_BATTLE_QUEUE_PROPOSE_MATCH_RESULT");
897 if (ExpirePetBattlePvpProposal(*player))
901 PetBattlePvpStateStore::ProposalMap::iterator proposalItr = PetBattlePvpState.
Proposals().find(playerGuid);
902 if (proposalItr == PetBattlePvpState.
Proposals().end())
908 if (!ReadPetBattleQueueProposeAccepted(recvData))
910 LeavePetBattlePvpQueue(*player,
true,
916 proposalItr->second.Accepted =
true;
918 uint64 const opponentGuid = proposalItr->second.OpponentGuid;
919 PetBattlePvpStateStore::ProposalMap::iterator opponentProposalItr =
920 PetBattlePvpState.
Proposals().find(opponentGuid);
921 if (opponentProposalItr == PetBattlePvpState.
Proposals().end())
923 LeavePetBattlePvpQueue(*player,
true);
927 if (!opponentProposalItr->second.Accepted)
933 FailAcceptedPetBattlePvpQueueMatch(*player,
nullptr);
937 if (!ValidatePetBattleQueueRequest(*player) || !ValidatePetBattlePvpDuelTarget(*player, opponent))
939 FailAcceptedPetBattlePvpQueueMatch(*player, opponent);
943 ClearPetBattlePvpProposal(playerGuid);
944 RemovePetBattlePvpQueueEntry(playerGuid);
945 RemovePetBattlePvpQueueEntry(opponentGuid);
954 G3D::Vector3 positions[2];
955 float orientation = 0.0f;
956 BuildPetBattleQueueLocation(*player, *opponent, origin, positions, orientation);
957 if (!StartPetBattlePvp(*player, *opponent, origin, positions, orientation,
false, 0,
960 SendPetBattleQueueStatus(*
this, *player,
962 SendPetBattleQueueStatus(*opponent,
969 SF_LOG_DEBUG(
"network",
"WORLD: Received CMSG_PET_BATTLE_REQUEST_PVP");
972 ReadPetBattlePvpDuelRequestLocation(recvData, petBattleRequest);
978 if (!ValidatePetBattleQueueRequest(*player))
982 if (!ValidatePetBattlePvpDuelTarget(*player, target))
985 LeavePetBattlePvpQueue(*player,
false);
986 LeavePetBattlePvpQueue(*target,
false);
990 ClearPetBattlePvpChallengesFor(playerGuid,
true, playerGuid);
991 ClearPetBattlePvpChallengesFor(targetGuid,
true, targetGuid);
1012 SendPetBattleDuelPopup(*player, *target);
1021 return CompletePendingPetBattlePvpChallenge(*player, accepted);
1026 SF_LOG_DEBUG(
"network",
"WORLD: Received CMSG_BATTLE_PET_DELETE");
1030 recvData.
ReadGuidMask(petEntry, 3, 5, 6, 2, 4, 0, 7, 1);
1038 SF_LOG_DEBUG(
"network",
"CMSG_BATTLE_PET_DELETE - Player %u tryed to release Battle Pet %lu which it doesn't own!",
1045 SF_LOG_DEBUG(
"network",
"CMSG_BATTLE_PET_DELETE - Player %u tryed to release Battle Pet %lu which isn't releasable!",
1052 SF_LOG_DEBUG(
"network",
"CMSG_BATTLE_PET_DELETE - Player %u tryed to release slotted Battle Pet %lu!",
1057 battlePetMgr->
Delete(battlePet);
1061#define BATTLE_PET_MAX_DECLINED_NAMES 5
1066 SF_LOG_DEBUG(
"network",
"WORLD: Received CMSG_BATTLE_PET_MODIFY_NAME");
1070 std::string nickname;
1071 bool hasDeclinedNames;
1074 petEntry[5] = recvData.
ReadBit();
1075 petEntry[7] = recvData.
ReadBit();
1076 petEntry[3] = recvData.
ReadBit();
1077 petEntry[0] = recvData.
ReadBit();
1078 petEntry[6] = recvData.
ReadBit();
1079 nicknameLen = recvData.
ReadBits(7);
1080 petEntry[2] = recvData.
ReadBit();
1081 petEntry[1] = recvData.
ReadBit();
1082 hasDeclinedNames = recvData.
ReadBit();
1083 petEntry[4] = recvData.
ReadBit();
1085 if (hasDeclinedNames)
1087 declinedNameLen[i] = recvData.
ReadBits(7);
1099 if (hasDeclinedNames)
1103 declinedNames[i] = recvData.
ReadString(declinedNameLen[i]);
1111 SF_LOG_DEBUG(
"network",
"CMSG_BATTLE_PET_MODIFY_NAME - Player %u tryed to set the name for Battle Pet %lu which it doesn't own!",
1118 SF_LOG_DEBUG(
"network",
"CMSG_BATTLE_PET_MODIFY_NAME - Player %u tryed to set the name for Battle Pet %lu with an invalid length!",
1136 SF_LOG_DEBUG(
"network",
"WORLD: Received CMSG_BATTLE_PET_QUERY_NAME");
1140 petguid[2] = recvData.
ReadBit();
1141 petEntry[6] = recvData.
ReadBit();
1142 petEntry[3] = recvData.
ReadBit();
1143 petguid[3] = recvData.
ReadBit();
1144 petEntry[7] = recvData.
ReadBit();
1145 petguid[4] = recvData.
ReadBit();
1146 petguid[1] = recvData.
ReadBit();
1147 petguid[0] = recvData.
ReadBit();
1148 petEntry[0] = recvData.
ReadBit();
1149 petguid[7] = recvData.
ReadBit();
1150 petguid[5] = recvData.
ReadBit();
1151 petguid[6] = recvData.
ReadBit();
1152 petEntry[1] = recvData.
ReadBit();
1153 petEntry[2] = recvData.
ReadBit();
1154 petEntry[5] = recvData.
ReadBit();
1155 petEntry[4] = recvData.
ReadBit();
1177 SF_LOG_DEBUG(
"network",
"CMSG_BATTLE_PET_QUERY_NAME - Player %u queried the name of Battle Pet %lu which doesnt't exist in world!",
1197 data <<
uint64(petEntry);
1217 SF_LOG_DEBUG(
"network",
"WORLD: Received CMSG_BATTLE_PET_REQUEST_JOURNAL");
1225 SF_LOG_DEBUG(
"network",
"WORLD: Received CMSG_BATTLE_PET_LEARN");
1228 recvData.
ReadGuidMask(itemGuid, 7, 1, 0, 5, 4, 2, 3, 6);
1235 SF_LOG_DEBUG(
"network",
"CMSG_BATTLE_PET_LEARN - Player %u tried to learn a battle pet from missing item " UI64FMTD,
1243 SF_LOG_DEBUG(
"network",
"CMSG_BATTLE_PET_LEARN - Player %u tried to learn a battle pet from non-pet item %u",
1249 if (!battlePetMgr->
Create(speciesItr->second))
1258 SF_LOG_DEBUG(
"network",
"WORLD: Received CMSG_BATTLE_PET_SET_BATTLE_SLOT");
1265 recvData.
ReadGuidMask(petEntry, 4, 6, 5, 7, 3, 1, 0, 2);
1273 SF_LOG_DEBUG(
"network",
"CMSG_BATTLE_PET_SET_BATTLE_SLOT - Player %u tryed to add Battle Pet %lu to loadout which it doesn't own!",
1280 SF_LOG_DEBUG(
"network",
"CMSG_BATTLE_PET_SET_BATTLE_SLOT - Player %u tryed to add Battle Pet %lu into slot %u which is locked!",
1288 SF_LOG_DEBUG(
"network",
"CMSG_BATTLE_PET_SET_BATTLE_SLOT - Player %u tryed to add a compainion Battle Pet %lu into slot %u!",
1315 SF_LOG_DEBUG(
"network",
"WORLD: Received CMSG_BATTLE_PET_SET_FLAGS");
1332 SF_LOG_DEBUG(
"network",
"CMSG_BATTLE_PET_SET_FLAGS - Player %u tryed to set the flags for Battle Pet %lu which it doesn't own!",
1343 SF_LOG_DEBUG(
"network",
"CMSG_BATTLE_PET_SET_FLAGS - Player %u tryed to set an invalid Battle Pet flag %u!",
1350 SF_LOG_DEBUG(
"network",
"CMSG_BATTLE_PET_SET_FLAGS - Player %u tryed to set Battle Pet flag %u with invalid mode %u!",
1361 SF_LOG_DEBUG(
"network",
"CMSG_BATTLE_PET_SET_FLAGS - Player %u tryed to select unavailable Battle Pet ability flag %u for pet %lu!",
1378 if (oldFlags != battlePet->
GetFlags())
1387 SF_LOG_DEBUG(
"network",
"WORLD: Received CMSG_BATTLE_PET_SUMMON_COMPANION");
1391 recvData.
ReadGuidMask(petEntry, 3, 2, 5, 0, 7, 1, 6, 4);
1400 SF_LOG_DEBUG(
"network",
"CMSG_SUMMON_BATTLE_PET_COMPANION - Player %u tryed to summon battle pet companion %lu which it doesn't own!",
1407 SF_LOG_DEBUG(
"network",
"CMSG_SUMMON_BATTLE_PET_COMPANION - Player %u tryed to summon battle pet companion %lu which is dead!",
1419 player->
CastSpell(player, summonSpell,
true);
1426 SF_LOG_DEBUG(
"network",
"WORLD: Received CMSG_PET_BATTLE_INPUT");
1439 bool handled =
false;
1440 bool sendRound =
false;
1441 bool sendFinal =
false;
1442 uint64 pvpForfeitOpponentGuid = 0;
1443 uint64 pvpFinalOpponentGuid = 0;
1455 BattlePet const* allyBattlePet = GetActiveBattlePet(*battlePetMgr);
1456 BattlePet const* enemyBattlePet = GetPvpOpponentActiveBattlePet(*player, activeBattle);
1457 uint32 const enemyDamage = enemyBattlePet
1459 : BattlePetInputDamageForEnemyAbility(enemyAbilityId, activeBattle);
1460 uint8 const allyAbilitySlot = BattlePetActiveAbilitySlot(allyBattlePet, command.
AbilityID);
1464 if (activeBattle.
IsPvP())
1465 pvpFinalOpponentGuid = activeBattle.
EnemyGUID;
1477 : BattlePetInputIncomingDamageReductionForEnemyAbility(enemyAbilityId, activeBattle),
1479 round, &finalRound);
1480 sendRound = handled;
1481 sendFinal = !finalRound.
Pets.empty();
1490 sendRound = handled;
1495 if (activeBattle.
IsPvP())
1496 pvpForfeitOpponentGuid = activeBattle.
EnemyGUID;
1499 sendFinal = handled;
1507 BattlePet const* enemyBattlePet = GetPvpOpponentActiveBattlePet(*player, activeBattle);
1508 uint32 const enemyDamage = enemyBattlePet
1510 : BattlePetInputDamageForEnemyAbility(enemyAbilityId, activeBattle);
1515 sendRound = handled;
1516 sendFinal = handled && !finalRound.
Pets.empty();
1527 SendBattlePetRoundResult(*player, round);
1531 if (pvpForfeitOpponentGuid)
1532 FinishActivePvpPetBattleAfterForfeit(*player, pvpForfeitOpponentGuid, finalRound);
1533 else if (pvpFinalOpponentGuid)
1534 FinishActivePvpPetBattle(*player, pvpFinalOpponentGuid, finalRound,
1535 OpponentWinnerForFinalRound(finalRound),
false);
1538 SendBattlePetFinalRound(*player, finalRound);
1539 ClearActivePetBattleAndSave(*player);
1546 SF_LOG_DEBUG(
"network",
"WORLD: Received CMSG_PET_BATTLE_SET_FRONT_PET");
1563 SendBattlePetRoundResult(*player, round);
1579 SF_LOG_DEBUG(
"network",
"WORLD: Received CMSG_PET_BATTLE_FINAL_NOTIFY");
1585 SendBattlePetFinished(*player);
1589 ClearActivePetBattleAndSave(*player);
1594 SF_LOG_DEBUG(
"network",
"WORLD: Received CMSG_PET_BATTLE_QUIT_NOTIFY");
1606 if (pvpOpponentGuid)
1608 FinishActivePvpPetBattleAfterForfeit(*player, pvpOpponentGuid, finalRound);
1612 SendBattlePetFinalRound(*player, finalRound);
1615 ClearActivePetBattleAndSave(*player);
1620 SF_LOG_DEBUG(
"network",
"WORLD: Received CMSG_PET_BATTLE_REQUEST_UPDATE");
1632 if (HandlePendingPetBattlePvpChallengeResponse(*player, request))
1635 if (ExpirePetBattlePvpProposal(*player))
1653 if (pvpOpponentGuid)
1654 FinishActivePvpPetBattleAfterForfeit(*player, pvpOpponentGuid, finalRound);
1657 SendBattlePetFinalRound(*player, finalRound);
1658 ClearActivePetBattleAndSave(*player);
1664 SF_LOG_DEBUG(
"network",
"WORLD: Received CMSG_BATTLE_PET_WILD_REQUEST");
1666 bool missingOrientation;
1671 for (
uint8 i = 0; i < 2; i++)
1673 recvData >> petBattleRequest.
Positions[i].x;
1674 recvData >> petBattleRequest.
Positions[i].z;
1675 recvData >> petBattleRequest.
Positions[i].y;
1679 recvData >> petBattleRequest.
Origin.z;
1680 recvData >> petBattleRequest.
Origin.y;
1681 recvData >> petBattleRequest.
Origin.x;
1684 missingOrientation = recvData.
ReadBit();
1686 missingResult = recvData.
ReadBit();
1690 if (!missingOrientation)
1727 if (!activeBattlePet)
1734 uint8 activeBattlePetIndex = 0;
1739 if (!loadoutBattlePet)
1746 if (loadoutBattlePet == activeBattlePet)
1747 activeBattlePetIndex = petIndex;
1750 teams[0].
FrontPet = activeBattlePetIndex;
1756 uint8 wildPetBreed = 0;
1757 if (!BuildWildInitialUpdatePetData(*wildBattlePet, teams[1].Pets[0], wildPetBreed))
1766 petBattleRequest.
Enemy = wildBattlePet;
1767 bool const hasClientOrientation = !missingOrientation;
1781 uint16(teams[1].Pets[0].Species),
uint8(teams[1].Pets[0].Level),
uint8(teams[1].Pets[0].Quality),
1782 wildPetBreed, activeBattlePetIndex);
1784 for (
uint8 petIndex = 0; petIndex < teams[0].
PetCount; petIndex++)
uint32 BattlePetInputEffectForAbility(uint32 abilityId)
uint8 BattlePetNormalizeWildLevel(uint8 level)
uint16 BattlePetSpeciesIdByNpcId(uint32 npcId)
uint32 BattlePetDamageFromStats(uint32 abilityId, uint16 power, uint8 level)
uint8 BattlePetIncomingDamageReductionRounds(uint32 abilityId)
uint32 BattlePetInputIncomingDamageReductionForAbility(uint32 abilityId, BattlePet const *caster)
uint16 BattlePetAbilityCooldown(uint32 abilityId)
uint16 BattlePetPowerFromBattleState(uint16 species, uint8 level, uint8 quality, uint8 breed)
uint32 BattlePetInputDamageForAbility(uint32 abilityId, BattlePet const *caster)
uint32 BattlePetIncomingDamageReductionFromStats(uint32 abilityId, uint16 power, uint8 level)
#define BATTLE_PET_MAX_NAME_LENGTH
BattlePetAchievementSource
@ BATTLE_PET_ACHIEVEMENT_SOURCE_PVP_DUEL
@ BATTLE_PET_ACHIEVEMENT_SOURCE_PVP_MATCHMAKING
constexpr uint8 BATTLE_PET_ABILITY_SLOT_INVALID
uint8 BattlePetAbilitySlotForJournalFlag(uint32 flag)
constexpr uint8 BATTLE_PET_ABILITY_SLOT_COUNT
@ BATTLE_PET_JOURNAL_FLAG_ABILITY_2
@ BATTLE_PET_JOURNAL_FLAG_ABILITY_3
@ BATTLE_PET_JOURNAL_FLAG_FAVORITES
@ BATTLE_PET_JOURNAL_FLAG_ABILITY_1
@ PET_BATTLE_TRAP_STATUS_UNAVAILABLE
@ PET_BATTLE_WINNER_ENEMY
@ BATTLE_PET_FLAG_MODE_UNSET
@ BATTLE_PET_FLAG_MODE_SET
#define BATTLE_PET_MAX_DECLINED_NAMES
@ PET_BATTLE_REQUEST_FAILED_INVALID_TARGET
@ PET_BATTLE_REQUEST_FAILED_NO_PETS
@ PET_BATTLE_REQUEST_FAILED_ALL_PETS_DEAD
#define BATTLE_PET_MAX_LOADOUT_SLOTS
@ BATTLE_PET_LOADOUT_SLOT_NONE
PetBattlePvpStateStore & GetPetBattlePvpStateStore()
@ BATTLE_PET_FLAG_RELEASABLE
@ BATTLE_PET_FLAG_COMPANION
uint32 BattlePetGetSpeciesAbility(uint16 speciesId, uint8 abilitySlot, uint16 flags, uint8 level)
bool BattlePetSpeciesHasFlag(uint16 speciesId, uint16 flag)
BattlePetItemXSpeciesStore sBattlePetItemXSpeciesStore
bool BattlePetHasSpeciesAbility(uint16 speciesId, uint8 abilitySlot, bool alternateAbility, uint8 level)
DB2Storage< BattlePetSpeciesEntry > sBattlePetSpeciesStore(BattlePetSpeciesfmt)
uint32 BattlePetGetSummonSpell(uint16 speciesId)
#define SF_LOG_DEBUG(filterType__,...)
@ UNIT_NPC_FLAG_WILDPET_CAPTURABLE
@ UNIT_FIELD_BATTLE_PET_COMPANION_NAME_TIMESTAMP
void SetFlag(uint16 flag)
void SetNickname(std::string const &nickname)
void UnSetFlag(uint16 flag)
uint16 GetCurrentHealth() const
uint16 GetSpecies() const
uint16 GetMaxHealth() const
std::string GetNickname() const
void SetTimestamp(uint32 timestamp)
uint32 GetTimestamp() const
bool SetActivePetBattleAllyPet(uint8 petIndex, uint64 petId, uint32 maxHealth, uint32 health)
bool IsPetBattlePvpQueued() const
TempSummon * GetCurrentSummon() const
void StartPvpPetBattle(uint64 opponentGuid, uint64 allyPetId, uint32 allyMaxHealth, uint32 allyHealth, uint64 enemyPetId, uint32 enemyMaxHealth, uint32 enemyHealth, uint16 enemySpecies=0, uint8 enemyLevel=0, uint8 enemyQuality=0, uint8 allyFrontPet=0, uint8 enemyFrontPet=3, BattlePetAchievementSource source=BATTLE_PET_ACHIEVEMENT_SOURCE_PVP_DUEL)
uint8 GetActivePetBattleTrapStatus() const
uint32 GetTrapAbility() const
void HideActivePetBattleWorldObject(Creature *creature)
void SendBattlePetJournal()
void Delete(BattlePet *battlePet)
ActivePetBattle const & GetActivePetBattle() const
void ClearActivePetBattle()
BattlePet * GetFirstAliveLoadoutBattlePet() const
bool ApplyBattlePetAbilityExchangeInput(uint32 roundId, uint32 allyDamage, uint32 allyAbilityEffectId, uint8 allyAbilitySlot, uint32 allyAbilityId, uint16 allyAbilityCooldown, uint32 enemyDamage, uint32 enemyAbilityEffectId, uint32 allyIncomingDamageReduction, uint8 allyIncomingDamageReductionRounds, uint32 enemyIncomingDamageReduction, uint8 enemyIncomingDamageReductionRounds, Skyfire::BattlePetPackets::BattlePetRoundResult &round, Skyfire::BattlePetPackets::BattlePetFinalRound *finalRound=NULL)
void SendBattlePetSlotUpdate(uint8 slot, bool notification, uint64 id=0)
void FinishActivePetBattle(uint8 winner)
bool ApplyBattlePetTrapInput(uint32 roundId, uint32 trapAbilityEffectId, uint32 enemyDamage, uint32 enemyAbilityEffectId, Skyfire::BattlePetPackets::BattlePetRoundResult &round, Skyfire::BattlePetPackets::BattlePetFinalRound &finalRound)
BattlePet * Create(uint16 speciesId)
void SetCurrentSummonId(uint64 summonId)
bool ApplyBattlePetSwapInput(uint32 roundId, uint8 newFrontPet, Skyfire::BattlePetPackets::BattlePetRoundResult &round)
void SendBattlePetJournalLock()
uint64 GetLoadoutSlot(uint8 slot) const
uint64 GetCurrentSummonId() const
uint8 GetLoadoutSlotForBattlePet(uint64 id) const
bool HasLoadoutSlot(uint8 slot) const
void StartWildPetBattle(uint64 enemyGuid, uint64 allyPetId, uint32 allyMaxHealth, uint32 allyHealth, uint64 enemyPetId, uint32 enemyMaxHealth, uint32 enemyHealth, uint16 enemySpecies=0, uint8 enemyLevel=0, uint8 enemyQuality=0, uint8 enemyBreed=0, uint8 allyFrontPet=0)
void SetPetBattlePvpQueued(bool queued)
bool ApplyBattlePetForfeitInput(uint32 roundId, Skyfire::BattlePetPackets::BattlePetFinalRound &finalRound)
BattlePet * GetBattlePet(uint64 id) const
void SetLoadoutSlot(uint8 slot, uint64 id, bool save=false)
void SendBattlePetUpdate(BattlePet *battlePet, bool notification)
bool BuildActivePetBattleFinalRound(bool abandoned, Skyfire::BattlePetPackets::BattlePetFinalRound &finalRound, bool captured=false)
void UnSummonCurrentBattlePet(bool temporary)
void ApplyActivePetBattlePlayerState(float faceX, float faceY)
void SendPetBattleRequestFailed(uint8 reason)
bool HasActivePetBattle() const
bool HasLoadoutBattlePet() const
bool SelectActivePetBattleFrontPet(uint8 frontPet)
bool WriteBit(uint32 bit)
void WriteString(std::string const &str)
uint32 ReadBits(size_t bits)
void ReadGuidBytes(ObjectGuid &guid, Offsets... offsets)
void ReadByteSeq(uint8 &b)
std::string ReadString(size_t length)
void ReadGuidMask(ObjectGuid &guid, Offsets... offsets)
void WriteBits(T value, size_t bits)
static Creature * GetCreatureOrPetOrVehicle(WorldObject const &, uint64)
static Player * FindPlayer(uint64)
uint32 GetGUIDLow() const
bool HasFlag(uint16 index, uint32 flag) const
void SetUInt32Value(uint16 index, uint32 value)
ProposalMap & Proposals()
void ClearProposal(uint64 playerGuid)
ChallengeMap::iterator FindChallengeForPlayer(uint64 playerGuid)
void EraseChallengeForTarget(uint64 targetGuid)
void AddQueueEntry(uint64 playerGuid)
void AddProposalPair(uint64 playerGuid, uint64 opponentGuid, time_t createdAt)
void AddChallenge(PetBattlePvpChallenge const &challenge)
ChallengeTargetMap & ChallengeTargetByChallenger()
void RemoveQueueEntry(uint64 playerGuid)
ChallengeMap & ChallengesByTarget()
BattlePetMgr * GetBattlePetMgr()
void SendDirectMessage(WorldPacket *data)
WorldSession * GetSession() const
Item * GetItemByGuid(uint64 guid) const
void DestroyItem(uint8 bag, uint8 slot, bool update)
Player * GetSelectedPlayer() const
Unit * GetSummoner() const
void CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
void NearTeleportTo(float x, float y, float z, float orientation, bool casting=false)
TempSummon * ToTempSummon()
Player session in the World.
void HandleBattlePetInputFirstPet(WorldPacket &recvData)
void HandleBattlePetInput(WorldPacket &recvData)
void HandleBattlePetDelete(WorldPacket &recvData)
void HandleBattlePetModifyName(WorldPacket &recvData)
void HandleBattlePetRequestJournal(WorldPacket &recvData)
void HandleBattlePetFinalNotify(WorldPacket &recvData)
void HandleBattlePetCage(WorldPacket &recvData)
void HandlePetBattleRequestPvp(WorldPacket &recvData)
Player * GetPlayer() const
void HandleBattlePetQuitNotify(WorldPacket &recvData)
void ClearPetBattlePvpQueueState()
void UpdatePetBattlePvpQueueState()
void HandlePetBattleStopPvpMatchmaking(WorldPacket &recvData)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
void HandleBattlePetRequestUpdate(WorldPacket &recvData)
void HandleBattlePetQueryName(WorldPacket &recvData)
void HandleBattlePetSummonCompanion(WorldPacket &recvData)
void HandlePetBattleQueueProposeMatchResult(WorldPacket &recvData)
void HandleBattlePetLearn(WorldPacket &recvData)
void HandleBattlePetWildRequest(WorldPacket &recvData)
void HandleBattlePetSetBattleSlot(WorldPacket &recvData)
void HandleBattlePetSetFlags(WorldPacket &recvData)
void HandlePetBattleStartPvpMatchmaking(WorldPacket &recvData)
bool HandlePendingPetBattlePvpDuelResponse(bool accepted)
@ SMSG_BATTLE_PET_QUERY_NAME_RESPONSE
WorldPacket BuildQueueStatusPacket(ObjectGuid requesterGuid, uint32 status, uint32 const *slotResults)
BattlePetInput ReadBattlePetInput(WorldPacket &data)
uint8 const PET_BATTLE_QUEUE_SLOT_COUNT
InitialUpdatePetData BuildInitialUpdatePetData(BattlePet const &battlePet)
BattlePetFirstPetSelection ReadBattlePetFirstPetSelection(WorldPacket &data)
BattlePetInputCommand BuildBattlePetInputCommand(BattlePetInput const &input)
WorldPacket BuildFinalizeLocationPacket(G3D::Vector3 const &origin, G3D::Vector3 const *positions, bool hasOrientation, float orientation, bool hasLocationResult, uint32 locationResult)
BattlePetRequestUpdate ReadBattlePetRequestUpdate(WorldPacket &data)
WorldPacket BuildInitialUpdatePacket(ObjectGuid wildBattlePetGuid, InitialUpdateTeamData const *teams, uint8 teamCount, bool isPvP)
WorldPacket BuildFinalRoundPacket(BattlePetFinalRound const &finalRound)
WorldPacket BuildPvpChallengePacket(ObjectGuid challengerGuid, G3D::Vector3 const &origin, G3D::Vector3 const *positions, bool hasOrientation, float orientation, bool hasLocationResult, uint32 locationResult)
WorldPacket BuildFirstRoundPacket(uint32 roundId, uint8 allyFrontPet, uint8 enemyFrontPet, uint8 allyTrapStatus, uint8 enemyTrapStatus)
@ PET_BATTLE_QUEUE_STATUS_SLOT_DEAD
@ PET_BATTLE_QUEUE_STATUS_ALREADY_QUEUED
@ PET_BATTLE_QUEUE_STATUS_JOIN_FAILED
@ PET_BATTLE_QUEUE_STATUS_REMOVED
@ PET_BATTLE_QUEUE_STATUS_QUEUED
@ PET_BATTLE_QUEUE_STATUS_PROPOSAL_TIMEOUT
@ PET_BATTLE_QUEUE_STATUS_OPPONENT_DECLINED
@ PET_BATTLE_QUEUE_STATUS_SLOT_NO_SPECIES
@ PET_BATTLE_QUEUE_STATUS_SLOT_NO_PET
@ PET_BATTLE_QUEUE_STATUS_PROPOSAL_DECLINED
@ PET_BATTLE_QUEUE_STATUS_NONE
@ BATTLE_PET_INPUT_ACTION_ABILITY
@ BATTLE_PET_INPUT_ACTION_SWAP
@ BATTLE_PET_INPUT_ACTION_FORFEIT
@ BATTLE_PET_INPUT_ACTION_TRAP
@ BATTLE_PET_INPUT_ACTION_NONE
InitialUpdatePetData BuildWildInitialUpdatePetData(uint64 id, uint16 speciesId, uint8 level, uint8 quality, uint8 breed)
WorldPacket BuildRoundResultPacket(BattlePetRoundResult const &round)
float CalculateBattlePetFacing(G3D::Vector3 const &origin, G3D::Vector3 const *positions)
uint8 const INITIAL_UPDATE_MAX_TEAM_PETS
WorldPacket BuildQueueProposeMatchPacket()
WorldPacket BuildFinishedPacket()
float ResolveBattlePetFacing(bool hasClientOrientation, float clientOrientation, G3D::Vector3 const &origin, G3D::Vector3 const *positions)
bool WaitingForAllyFrontPet
G3D::Vector3 Positions[2]
G3D::Vector3 Positions[2]
static float NormalizeOrientation(float o)
float GetPositionZ() const
float GetOrientation() const
float GetPositionX() const
float GetPositionY() const
std::vector< BattlePetFinalRoundPet > Pets
InitialUpdatePetData Pets[INITIAL_UPDATE_MAX_TEAM_PETS]