Core/Creatures: Implemented unsummoning and resummoning critter pets on flying mounts and teleports (and related static flags)

This commit is contained in:
Shauren
2024-03-02 15:06:33 +01:00
parent bd8cc0e572
commit f2ce5072d6
6 changed files with 48 additions and 4 deletions

View File

@@ -515,6 +515,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
Optional<uint32> m_lootId;
uint16 m_LootMode; // Bitmask (default: LOOT_MODE_DEFAULT) that determines what loot will be lootable
CreatureStaticFlagsHolder _staticFlags;
bool IsInvisibleDueToDespawn(WorldObject const* seer) const override;
bool CanAlwaysSee(WorldObject const* obj) const override;
@@ -546,8 +548,6 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
void ApplyAllStaticFlags(CreatureStaticFlagsHolder const& flags);
CreatureStaticFlagsHolder _staticFlags;
// Regenerate health
bool _regenerateHealth; // Set on creation

View File

@@ -69,6 +69,12 @@ class TC_GAME_API TempSummon : public Creature
bool CanFollowOwner() const { return m_canFollowOwner; }
void SetCanFollowOwner(bool can) { m_canFollowOwner = can; }
bool IsDismissedOnFlyingMount() const { return !HasFlag(CREATURE_STATIC_FLAG_5_DONT_DISMISS_ON_FLYING_MOUNT); }
void SetDontDismissOnFlyingMount(bool dontDismissOnFlyingMount) { _staticFlags.ApplyFlag(CREATURE_STATIC_FLAG_5_DONT_DISMISS_ON_FLYING_MOUNT, dontDismissOnFlyingMount); }
bool IsAutoResummoned() const { return !HasFlag(CREATURE_STATIC_FLAG_6_DO_NOT_AUTO_RESUMMON); }
void SetDontAutoResummon(bool dontAutoResummon) { _staticFlags.ApplyFlag(CREATURE_STATIC_FLAG_6_DO_NOT_AUTO_RESUMMON, dontAutoResummon); }
SummonPropertiesEntry const* const m_Properties;
std::string GetDebugInfo() const override;

View File

@@ -1568,6 +1568,7 @@ void Player::RemoveFromWorld()
StopCastingCharm();
StopCastingBindSight();
UnsummonPetTemporaryIfAny();
UnsummonBattlePetTemporaryIfAny();
SetPower(POWER_COMBO_POINTS, 0);
m_session->DoLootReleaseAll();
m_lootRolls.clear();
@@ -21663,7 +21664,7 @@ void Player::RemovePetAura(PetAura const* petSpell)
pet->RemoveAurasDueToSpell(petSpell->GetAura(pet->GetEntry()));
}
Creature* Player::GetSummonedBattlePet()
Creature* Player::GetSummonedBattlePet() const
{
if (Creature* summonedBattlePet = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, GetCritterGUID()))
if (!GetSummonedBattlePetGUID().IsEmpty() && GetSummonedBattlePetGUID() == summonedBattlePet->GetBattlePetCompanionGUID())
@@ -27120,6 +27121,35 @@ void Player::ResummonPetTemporaryUnSummonedIfAny()
m_temporaryUnsummonedPetNumber = 0;
}
void Player::UnsummonBattlePetTemporaryIfAny(bool onFlyingMount /*= false*/)
{
Creature* battlepet = GetSummonedBattlePet();
if (!battlepet || !battlepet->IsSummon())
return;
if (onFlyingMount && !battlepet->ToTempSummon()->IsDismissedOnFlyingMount())
return;
if (battlepet->ToTempSummon()->IsAutoResummoned())
m_temporaryUnsummonedBattlePet = battlepet->GetBattlePetCompanionGUID();
GetSession()->GetBattlePetMgr()->DismissPet();
}
void Player::ResummonBattlePetTemporaryUnSummonedIfAny()
{
if (m_temporaryUnsummonedBattlePet.IsEmpty())
return;
// not resummon in not appropriate state
if (IsPetNeedBeTemporaryUnsummoned())
return;
GetSession()->GetBattlePetMgr()->SummonPet(m_temporaryUnsummonedBattlePet);
m_temporaryUnsummonedBattlePet.Clear();
}
bool Player::IsPetNeedBeTemporaryUnsummoned() const
{
return !IsInWorld() || !IsAlive() || HasUnitMovementFlag(MOVEMENTFLAG_FLYING) || HasExtraUnitMovementFlag2(MOVEMENTFLAG3_ADV_FLYING);

View File

@@ -1238,7 +1238,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
void AddPetAura(PetAura const* petSpell);
void RemovePetAura(PetAura const* petSpell);
Creature* GetSummonedBattlePet();
Creature* GetSummonedBattlePet() const;
void SetBattlePetData(BattlePets::BattlePet const* pet = nullptr);
/// Handles said message in regular chat based on declared language and in config pre-defined Range.
@@ -2548,6 +2548,8 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
void EnablePetControlsOnDismount();
void UnsummonPetTemporaryIfAny();
void ResummonPetTemporaryUnSummonedIfAny();
void UnsummonBattlePetTemporaryIfAny(bool onFlyingMount = false);
void ResummonBattlePetTemporaryUnSummonedIfAny();
bool IsPetNeedBeTemporaryUnsummoned() const;
void SendCinematicStart(uint32 CinematicSequenceId) const;
@@ -3188,6 +3190,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
uint32 m_temporaryUnsummonedPetNumber;
Optional<ReactStates> m_temporaryPetReactState;
uint32 m_oldpetspell;
ObjectGuid m_temporaryUnsummonedBattlePet;
std::unique_ptr<PlayerAchievementMgr> m_achievementMgr;
std::unique_ptr<ReputationMgr> m_reputationMgr;

View File

@@ -7935,6 +7935,7 @@ void Unit::Dismount()
{
player->EnablePetControlsOnDismount();
player->ResummonPetTemporaryUnSummonedIfAny();
player->ResummonBattlePetTemporaryUnSummonedIfAny();
}
}

View File

@@ -234,6 +234,7 @@ void WorldSession::HandleMoveWorldportAck()
// resummon pet
player->ResummonPetTemporaryUnSummonedIfAny();
player->ResummonBattlePetTemporaryUnSummonedIfAny();
//lets process all delayed operations on successful teleport
player->ProcessDelayedOperations();
@@ -402,7 +403,10 @@ void WorldSession::HandleMovementOpcode(OpcodeClient opcode, MovementInfo& movem
mover->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::LandingOrFlight); // Parachutes
if (opcode == CMSG_MOVE_SET_FLY || opcode == CMSG_MOVE_SET_ADV_FLY)
{
_player->UnsummonPetTemporaryIfAny(); // always do the pet removal on current client activeplayer only
_player->UnsummonBattlePetTemporaryIfAny(true);
}
/* process position-change */
movementInfo.guid = mover->GetGUID();