19 uint8 constexpr PetBattleEffectTargetStatChange = 0;
20 uint8 constexpr PetBattleEffectTargetState = 1;
21 uint8 constexpr PetBattleEffectTargetAbilityChange = 2;
22 uint8 constexpr PetBattleEffectTargetPet = 3;
23 uint8 constexpr PetBattleEffectTargetNone = 4;
24 uint8 constexpr PetBattleEffectTargetTriggerAbility = 5;
25 uint8 constexpr PetBattleEffectTargetNpcEmote = 6;
26 uint8 constexpr PetBattleEffectTargetAura = 7;
27 uint8 constexpr PetBattleEffectActivePet = 4;
28 uint8 constexpr PetBattleEffectCatch = 5;
29 uint16 constexpr PetBattleEffectFlagMiss = 0x0002;
30 uint8 constexpr PetBattleRoundResultNormal = 2;
31 uint8 constexpr PetBattleRoundResultCatchOrKill = 3;
35 data.
WriteBit(!effect.AbilityEffectID);
36 data.
WriteBit(!effect.PetBattleEffectType);
37 data.
WriteBits(effect.Targets.size(), 25);
44 if (target.Type == PetBattleEffectTargetStatChange)
47 if (target.Type == PetBattleEffectTargetAura)
55 if (target.Type == PetBattleEffectTargetNpcEmote)
58 if (target.Type == PetBattleEffectTargetAbilityChange)
65 if (target.Type == PetBattleEffectTargetTriggerAbility)
68 if (target.Type == PetBattleEffectTargetState)
70 data.
WriteBit(!target.HasStateValue);
76 if (target.Type == PetBattleEffectTargetPet)
77 data.
WriteBit(!target.HasRemainingHealth);
80 data.
WriteBit(effect.CasterPBOID == -1);
81 data.
WriteBit(!effect.TurnInstanceID);
89 data <<
uint16(effect.Flags);
91 if (effect.AbilityEffectID)
92 data <<
uint32(effect.AbilityEffectID);
96 if (target.PetX != -1)
97 data <<
uint8(target.PetX);
99 if (target.Type == PetBattleEffectTargetStatChange && target.HasStatus)
100 data <<
uint32(target.Status);
102 if (target.Type == PetBattleEffectTargetState)
104 if (target.HasStateID)
105 data <<
uint32(target.StateID);
107 if (target.HasStateValue)
108 data <<
uint32(target.StateValue);
111 if (target.Type == PetBattleEffectTargetAbilityChange)
118 if (target.Type == PetBattleEffectTargetPet && target.HasRemainingHealth)
119 data <<
int32(target.RemainingHealth);
121 if (target.Type == PetBattleEffectTargetTriggerAbility)
124 if (target.Type == PetBattleEffectTargetNpcEmote)
128 if (effect.PetBattleEffectType)
129 data <<
uint8(effect.PetBattleEffectType);
131 if (effect.TurnInstanceID)
132 data <<
uint16(effect.TurnInstanceID);
134 if (effect.CasterPBOID != -1)
135 data <<
uint8(effect.CasterPBOID);
137 if (effect.StackDepth)
138 data <<
uint8(effect.StackDepth);
157 for (
uint8 i = 0; i < 3; ++i)
165 BattlePet battlePet(
id, speciesId, level, quality, breed);
252 data >> selection.
PetID;
267 uint8 guidByteCount = 0;
268 for (
uint8 i = 0; i < 8; ++i)
272 if (data.
rpos() + guidByteCount > data.
size())
283 target.
PetX = targetPet;
284 target.
Type = PetBattleEffectTargetNone;
289 effect.
Targets.push_back(target);
298 target.
PetX = targetPet;
299 target.
Type = PetBattleEffectTargetPet;
308 effect.
Targets.push_back(target);
314 bool captured,
uint16 turnInstanceId)
317 target.
PetX = targetPet;
318 target.
Type = PetBattleEffectTargetStatChange;
320 target.
Status = captured ? 1 : 0;
325 effect.
Flags = captured ? PetBattleEffectFlagMiss : 0;
329 effect.
Targets.push_back(target);
335 int32 remainingHealth,
uint32 abilityEffectId,
bool targetDied)
340 round.
DeadPets.push_back(targetPet);
344 int32 remainingHealth,
uint32 abilityEffectId,
bool targetDied)
403 std::vector<BattlePetFinalRoundPet>
const& pets)
406 finalRound.
Winners[0] = allyWon;
407 finalRound.
Winners[1] = !allyWon;
409 finalRound.
Pets = pets;
417 std::vector<BattlePetFinalRoundPet> pets;
418 pets.push_back(allyPet);
419 pets.push_back(enemyPet);
424 uint8 teamCount,
bool isPvP)
428 bool const hasWaitingForFrontPetsMaxSecs =
true;
429 bool const hasPvPMaxRoundTime =
true;
430 bool const hasForfeitPenalty =
true;
431 bool const hasCreatureId =
false;
432 bool const hasDisplayId =
false;
435 for (
uint8 i = 0; i < 3; i++)
441 for (
uint8 i = 0; i < 2; i++)
444 uint8 const battlePetCount = team
447 bool const hasRoundTimeSec =
false;
448 bool const hasFrontPet = battlePetCount != 0;
449 bool const trapStatus = team && team->
TrapStatus != 0;
457 for (
uint8 j = 0; j < battlePetCount; j++)
466 uint8 abilityCount = 0;
467 for (
uint8 k = 0; k < 3; k++)
480 for (
uint8 l = 0; l < 3; l++)
499 data.
WriteBit(!hasWaitingForFrontPetsMaxSecs);
509 for (
uint8 i = 0; i < 2; i++)
515 bool const hasRoundTimeSec =
false;
516 bool const hasFrontPet = battlePetCount != 0;
517 bool const trapStatus = team && team->
TrapStatus != 0;
519 uint8 battlePetTeamIndex = 0;
520 for (
uint8 j = 0; j < battlePetCount; j++)
522 data << battlePetTeamIndex;
523 battlePetTeamIndex++;
527 uint8 const petBattleObjectId = i == 0 ? j :
uint8(3 + j);
529 for (
uint8 k = 0; k < 3; k++)
536 data <<
uint8(petBattleObjectId);
583 if (hasForfeitPenalty)
593 if (hasPvPMaxRoundTime)
598 if (hasWaitingForFrontPetsMaxSecs)
608 uint8 teamPetCount,
bool isPvP)
611 for (
uint8 i = 0; teamPets && i < 2 && i < teamPetCount; i++)
613 teams[i].
Pets[0] = teamPets[i];
630 uint8 const frontPets[2] = { allyFrontPet, enemyFrontPet };
631 uint8 const trapStatuses[2] = { allyTrapStatus, enemyTrapStatus };
634 for (
uint8 i = 0; i < 2; ++i)
637 data <<
uint8(trapStatuses[i]);
648 for (
uint8 i = 0; i < 2; ++i)
657 data.
WriteBits(PetBattleEffectTargetNone, 3);
664 for (
uint8 i = 0; i < 2; ++i)
666 data <<
uint8(frontPets[i]);
667 data <<
uint8(frontPets[i]);
668 data <<
uint8(PetBattleEffectActivePet);
671 data <<
uint8(PetBattleRoundResultNormal);
682 float const centerX = (positions[0].x + positions[1].x) * 0.5f;
683 float const centerY = (positions[0].y + positions[1].y) * 0.5f;
684 float facing = std::atan2(centerY - origin.y, centerX - origin.x);
686 facing += 6.28318530717958647692f;
692 G3D::Vector3
const& origin, G3D::Vector3
const* positions)
694 if (hasClientOrientation)
695 return clientOrientation;
704 for (
uint8 i = 0; i < 2; ++i)
715 WriteRoundEffectBits(data, effect);
738 WriteRoundEffectBytes(data, effect);
778 for (
uint8 i = 0; i < 2; ++i)
785 bool hasOrientation,
float orientation,
bool hasLocationResult,
uint32 locationResult)
791 for (
uint8 i = 0; i < 2; i++)
793 data << positions[i].y;
794 data << positions[i].x;
795 data << positions[i].z;
803 if (hasLocationResult)
804 data <<
uint32(locationResult);
807 data << float(orientation);
813 bool hasOrientation,
float orientation,
bool hasLocationResult,
uint32 locationResult)
824 data << float(orientation);
831 if (hasLocationResult)
832 data <<
uint32(locationResult);
836 for (
uint8 i = 0; i < 2; ++i)
838 data << positions[i].y;
839 data << positions[i].x;
840 data << positions[i].z;
889 data <<
uint8(reason);
@ ACTIVE_PET_BATTLE_TURN_EFFECT_DAMAGE
@ ACTIVE_PET_BATTLE_TURN_EFFECT_SWAP
uint32 BattlePetGetSpeciesAbility(uint16 speciesId, uint8 abilitySlot, uint16 flags, uint8 level)
uint16 GetCurrentHealth() const
uint16 GetSpecies() const
uint16 GetMaxHealth() const
std::string GetNickname() const
void WriteGuidBytes(const ObjectGuid &guid, Offsets... offsets)
bool WriteBit(uint32 bit)
void WriteGuidMask(const ObjectGuid &guid, Offsets... offsets)
void WriteString(std::string const &str)
void ReadGuidBytes(ObjectGuid &guid, Offsets... offsets)
void ReadGuidMask(ObjectGuid &guid, Offsets... offsets)
void WriteBits(T value, size_t bits)
void WriteByteSeq(uint8 b)
@ SMSG_PET_BATTLE_FIRST_ROUND
@ SMSG_PET_BATTLE_ROUND_RESULT
@ SMSG_PET_BATTLE_PVP_CHALLENGE
@ SMSG_PET_BATTLE_INITIAL_UPDATE
@ SMSG_PET_BATTLE_QUEUE_PROPOSE_MATCH
@ SMSG_PET_BATTLE_FINALIZE_LOCATION
@ SMSG_PET_BATTLE_REQUEST_FAILED
@ SMSG_PET_BATTLE_QUEUE_STATUS
@ SMSG_PET_BATTLE_FINAL_ROUND
@ SMSG_PET_BATTLE_FINISHED
BattlePetRoundEffect BuildPetSwapEffect(uint8 casterPet, uint8 targetPet)
WorldPacket BuildQueueStatusPacket(ObjectGuid requesterGuid, uint32 status, uint32 const *slotResults)
WorldPacket BuildRequestFailedPacket(uint8 reason)
BattlePetInput ReadBattlePetInput(WorldPacket &data)
@ BATTLE_PET_INPUT_MOVE_TRAP
@ BATTLE_PET_INPUT_MOVE_ABILITY
@ BATTLE_PET_INPUT_MOVE_SWAP
@ BATTLE_PET_INPUT_MOVE_FORFEIT
uint8 const PET_BATTLE_QUEUE_SLOT_COUNT
InitialUpdatePetData BuildInitialUpdatePetData(BattlePet const &battlePet)
BattlePetRoundResult BuildRoundResultFromTurn(ActivePetBattleTurn const &turn, uint32 abilityEffectId)
BattlePetFirstPetSelection ReadBattlePetFirstPetSelection(WorldPacket &data)
void AppendDamageRoundEffect(BattlePetRoundResult &round, uint8 casterPet, uint8 targetPet, int32 remainingHealth, uint32 abilityEffectId, bool targetDied)
BattlePetInputCommand BuildBattlePetInputCommand(BattlePetInput const &input)
WorldPacket BuildFinalizeLocationPacket(G3D::Vector3 const &origin, G3D::Vector3 const *positions, bool hasOrientation, float orientation, bool hasLocationResult, uint32 locationResult)
@ BATTLE_PET_ROUND_INPUT_FLAG_SELECT_NEW_FRONT_PET
BattlePetRequestUpdate ReadBattlePetRequestUpdate(WorldPacket &data)
WorldPacket BuildInitialUpdatePacket(ObjectGuid wildBattlePetGuid, InitialUpdateTeamData const *teams, uint8 teamCount, bool isPvP)
BattlePetRoundEffect BuildCatchEffect(uint8 casterPet, uint8 targetPet, uint32 abilityEffectId, bool captured, uint16 turnInstanceId)
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_QUEUED
@ 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)
BattlePetRoundEffect BuildDamageEffect(uint8 casterPet, uint8 targetPet, int32 remainingHealth, uint32 abilityEffectId, uint16 turnInstanceId)
WorldPacket BuildRoundResultPacket(BattlePetRoundResult const &round)
void AppendRoundCooldowns(BattlePetRoundResult &round, ActivePetBattleTurn const &turn)
float CalculateBattlePetFacing(G3D::Vector3 const &origin, G3D::Vector3 const *positions)
uint8 const INITIAL_UPDATE_MAX_TEAM_PETS
WorldPacket BuildQueueProposeMatchPacket()
BattlePetRoundResult BuildDamageRoundResult(uint32 roundId, uint8 casterPet, uint8 targetPet, int32 remainingHealth, uint32 abilityEffectId, bool targetDied)
WorldPacket BuildFinishedPacket()
BattlePetFinalRound BuildFinalRoundState(bool allyWon, bool abandoned, std::vector< BattlePetFinalRoundPet > const &pets)
void MarkRoundResultAsCatchOrKill(BattlePetRoundResult &round)
float ResolveBattlePetFacing(bool hasClientOrientation, float clientOrientation, G3D::Vector3 const &origin, G3D::Vector3 const *positions)
std::vector< ActivePetBattleCooldown > Cooldowns
std::vector< BattlePetFinalRoundPet > Pets
uint8 PetBattleEffectType
std::vector< BattlePetRoundEffectTarget > Targets
std::vector< BattlePetRoundCooldown > Cooldowns
std::vector< BattlePetRoundEffect > Effects
std::vector< uint8 > DeadPets
InitialUpdatePetData Pets[INITIAL_UPDATE_MAX_TEAM_PETS]