mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 07:37:01 +00:00
[9077] Fixes for pet work in case mounted owner.
* No unsummon temporary pet at non-fly mounting. * Implement client side disable pet's action bar for mountted owner time Signed-off-by: VladimirMangos <vladimir@getmangos.com> * implement server side action disabled case (action bar modify, aggro reaction and autocast) Signed-off-by: VladimirMangos <vladimir@getmangos.com>
This commit is contained in:
parent
7d0a830bd4
commit
9c98bd92e2
10 changed files with 112 additions and 19 deletions
|
|
@ -40,7 +40,7 @@ char const* petTypeSuffix[MAX_PET_TYPE] =
|
|||
Pet::Pet(PetType type) :
|
||||
Creature(), m_removed(false), m_petType(type), m_happinessTimer(7500), m_duration(0), m_resetTalentsCost(0),
|
||||
m_bonusdamage(0), m_resetTalentsTime(0), m_usedTalentCount(0), m_auraUpdateMask(0), m_loading(false),
|
||||
m_declinedname(NULL)
|
||||
m_declinedname(NULL), m_petModeFlags(PET_MODE_DEFAULT)
|
||||
{
|
||||
m_isPet = true;
|
||||
m_name = "Pet";
|
||||
|
|
@ -1948,3 +1948,20 @@ void Pet::SynchronizeLevelWithOwner()
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Pet::ApplyModeFlags(PetModeFlags mode, bool apply)
|
||||
{
|
||||
if (apply)
|
||||
m_petModeFlags = PetModeFlags(m_petModeFlags | mode);
|
||||
else
|
||||
m_petModeFlags = PetModeFlags(m_petModeFlags & ~mode);
|
||||
|
||||
Unit* owner = GetOwner();
|
||||
if(!owner || owner->GetTypeId()!=TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
WorldPacket data(SMSG_PET_MODE, 12);
|
||||
data << uint64(GetGUID());
|
||||
data << uint32(m_petModeFlags);
|
||||
((Player*)owner)->GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,17 @@ enum PetSaveMode
|
|||
PET_SAVE_NOT_IN_SLOT = 100 // for avoid conflict with stable size grow will use 100
|
||||
};
|
||||
|
||||
// There might be a lot more
|
||||
enum PetModeFlags
|
||||
{
|
||||
PET_MODE_UNKNOWN_0 = 0x0000001,
|
||||
PET_MODE_UNKNOWN_2 = 0x0000100,
|
||||
PET_MODE_DISABLE_ACTIONS = 0x8000000,
|
||||
|
||||
// autoset in client at summon
|
||||
PET_MODE_DEFAULT = PET_MODE_UNKNOWN_0 | PET_MODE_UNKNOWN_2,
|
||||
};
|
||||
|
||||
enum HappinessState
|
||||
{
|
||||
UNHAPPY = 1,
|
||||
|
|
@ -182,6 +193,9 @@ class Pet : public Creature
|
|||
bool CanTakeMoreActiveSpells(uint32 SpellIconID);
|
||||
void ToggleAutocast(uint32 spellid, bool apply);
|
||||
|
||||
void ApplyModeFlags(PetModeFlags mode, bool apply);
|
||||
PetModeFlags GetModeFlags() const { return m_petModeFlags; }
|
||||
|
||||
bool HasSpell(uint32 spell) const;
|
||||
|
||||
void LearnPetPassives();
|
||||
|
|
@ -242,6 +256,8 @@ class Pet : public Creature
|
|||
DeclinedName *m_declinedname;
|
||||
|
||||
private:
|
||||
PetModeFlags m_petModeFlags;
|
||||
|
||||
void SaveToDB(uint32, uint8) // overwrited of Creature::SaveToDB - don't must be called
|
||||
{
|
||||
assert(false);
|
||||
|
|
|
|||
|
|
@ -44,9 +44,16 @@ PetAI::PetAI(Creature *c) : CreatureAI(c), i_tracker(TIME_INTERVAL_LOOK), inComb
|
|||
|
||||
void PetAI::MoveInLineOfSight(Unit *u)
|
||||
{
|
||||
if( !m_creature->getVictim() && m_creature->GetCharmInfo() &&
|
||||
m_creature->GetCharmInfo()->HasReactState(REACT_AGGRESSIVE) &&
|
||||
u->isTargetableForAttack() && m_creature->IsHostileTo( u ) &&
|
||||
if (m_creature->getVictim())
|
||||
return;
|
||||
|
||||
if (m_creature->isPet() && ((Pet*)m_creature)->GetModeFlags() & PET_MODE_DISABLE_ACTIONS)
|
||||
return;
|
||||
|
||||
if (!m_creature->GetCharmInfo() || !m_creature->GetCharmInfo()->HasReactState(REACT_AGGRESSIVE))
|
||||
return;
|
||||
|
||||
if (u->isTargetableForAttack() && m_creature->IsHostileTo( u ) &&
|
||||
u->isInAccessablePlaceFor(m_creature))
|
||||
{
|
||||
float attackRadius = m_creature->GetAttackDistance(u);
|
||||
|
|
@ -139,7 +146,7 @@ void PetAI::UpdateAI(const uint32 diff)
|
|||
else
|
||||
m_updateAlliesTimer -= diff;
|
||||
|
||||
if (inCombat && !m_creature->getVictim())
|
||||
if (inCombat && (!m_creature->getVictim() || m_creature->isPet() && ((Pet*)m_creature)->GetModeFlags() & PET_MODE_DISABLE_ACTIONS))
|
||||
_stopAttack();
|
||||
|
||||
// i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
|
||||
|
|
|
|||
|
|
@ -44,23 +44,33 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
|
|||
// used also for charmed creature
|
||||
Unit* pet= ObjectAccessor::GetUnit(*_player, guid1);
|
||||
sLog.outDetail("HandlePetAction.Pet %u flag is %u, spellid is %u, target %u.", uint32(GUID_LOPART(guid1)), uint32(flag), spellid, uint32(GUID_LOPART(guid2)) );
|
||||
if(!pet)
|
||||
if (!pet)
|
||||
{
|
||||
sLog.outError( "Pet %u not exist.", uint32(GUID_LOPART(guid1)) );
|
||||
return;
|
||||
}
|
||||
|
||||
if(pet != GetPlayer()->GetPet() && pet != GetPlayer()->GetCharm())
|
||||
if (pet != GetPlayer()->GetPet() && pet != GetPlayer()->GetCharm())
|
||||
{
|
||||
sLog.outError("HandlePetAction.Pet %u isn't pet of player %s.", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName() );
|
||||
return;
|
||||
}
|
||||
|
||||
if(!pet->isAlive())
|
||||
if (!pet->isAlive())
|
||||
return;
|
||||
|
||||
if(pet->GetTypeId() == TYPEID_PLAYER && !(flag == ACT_COMMAND && spellid == COMMAND_ATTACK))
|
||||
return;
|
||||
if (pet->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
// controller player can only do melee attack
|
||||
if (!(flag == ACT_COMMAND && spellid == COMMAND_ATTACK))
|
||||
return;
|
||||
}
|
||||
else if (((Creature*)pet)->isPet())
|
||||
{
|
||||
// pet can have action bar disabled
|
||||
if(((Pet*)pet)->GetModeFlags() & PET_MODE_DISABLE_ACTIONS)
|
||||
return;
|
||||
}
|
||||
|
||||
CharmInfo *charmInfo = pet->GetCharmInfo();
|
||||
if(!charmInfo)
|
||||
|
|
@ -316,6 +326,10 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data )
|
|||
return;
|
||||
}
|
||||
|
||||
// pet can have action bar disabled
|
||||
if(pet->isPet() && ((Pet*)pet)->GetModeFlags() & PET_MODE_DISABLE_ACTIONS)
|
||||
return;
|
||||
|
||||
CharmInfo *charmInfo = pet->GetCharmInfo();
|
||||
if(!charmInfo)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17095,6 +17095,18 @@ void Player::PetSpellInitialize()
|
|||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
void Player::SendPetGUIDs()
|
||||
{
|
||||
if(!GetPetGUID())
|
||||
return;
|
||||
|
||||
// Later this function might get modified for multiple guids
|
||||
WorldPacket data(SMSG_PET_GUIDS, 12);
|
||||
data << uint32(1); // count
|
||||
data << uint64(GetPetGUID());
|
||||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
void Player::PossessSpellInitialize()
|
||||
{
|
||||
Unit* charm = GetCharm();
|
||||
|
|
|
|||
|
|
@ -1551,6 +1551,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
}
|
||||
|
||||
void PetSpellInitialize();
|
||||
void SendPetGUIDs();
|
||||
void CharmSpellInitialize();
|
||||
void PossessSpellInitialize();
|
||||
void RemovePetActionBar();
|
||||
|
|
|
|||
|
|
@ -2817,7 +2817,7 @@ void Aura::HandleAuraMounted(bool apply, bool Real)
|
|||
if (minfo)
|
||||
display_id = minfo->modelid;
|
||||
|
||||
m_target->Mount(display_id);
|
||||
m_target->Mount(display_id, m_spellProto->Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8382,6 +8382,9 @@ void Unit::SetPet(Pet* pet)
|
|||
{
|
||||
SetPetGUID(pet ? pet->GetGUID() : 0);
|
||||
|
||||
if(pet && GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)this)->SendPetGUIDs();
|
||||
|
||||
// FIXME: hack, speed must be set only at follow
|
||||
if(pet && GetTypeId()==TYPEID_PLAYER)
|
||||
for(int i = 0; i < MAX_MOVE_TYPE; ++i)
|
||||
|
|
@ -9866,9 +9869,9 @@ float Unit::GetPPMProcChance(uint32 WeaponSpeed, float PPM) const
|
|||
return WeaponSpeed * PPM / 600.0f; // result is chance in percents (probability = Speed_in_sec * (PPM / 60))
|
||||
}
|
||||
|
||||
void Unit::Mount(uint32 mount)
|
||||
void Unit::Mount(uint32 mount, uint32 spellId)
|
||||
{
|
||||
if(!mount)
|
||||
if (!mount)
|
||||
return;
|
||||
|
||||
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOUNTING);
|
||||
|
|
@ -9877,9 +9880,27 @@ void Unit::Mount(uint32 mount)
|
|||
|
||||
SetFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT );
|
||||
|
||||
// unsummon pet
|
||||
if(GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)this)->UnsummonPetTemporaryIfAny();
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
// Called by Taxi system / GM command
|
||||
if (!spellId)
|
||||
((Player*)this)->UnsummonPetTemporaryIfAny();
|
||||
// Called by mount aura
|
||||
else if (SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId))
|
||||
{
|
||||
// Flying case (Unsummon any pet)
|
||||
if (IsSpellHaveAura(spellInfo, SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED))
|
||||
((Player*)this)->UnsummonPetTemporaryIfAny();
|
||||
// Normal case (Unsummon only permanent pet)
|
||||
else if (Pet* pet = GetPet())
|
||||
{
|
||||
if (pet->IsPermanentPetFor((Player*)this))
|
||||
((Player*)this)->UnsummonPetTemporaryIfAny();
|
||||
else
|
||||
pet->ApplyModeFlags(PET_MODE_DISABLE_ACTIONS,true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::Unmount()
|
||||
|
|
@ -9896,7 +9917,12 @@ void Unit::Unmount()
|
|||
// this prevents adding a pet to a not created map which would otherwise cause a crash
|
||||
// (it could probably happen when logging in after a previous crash)
|
||||
if(GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)this)->ResummonPetTemporaryUnSummonedIfAny();
|
||||
{
|
||||
if(Pet* pet = GetPet())
|
||||
pet->ApplyModeFlags(PET_MODE_DISABLE_ACTIONS,false);
|
||||
else
|
||||
((Player*)this)->ResummonPetTemporaryUnSummonedIfAny();
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::SetInCombatWith(Unit* enemy)
|
||||
|
|
|
|||
|
|
@ -1026,7 +1026,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
|||
|
||||
bool IsMounted() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT ); }
|
||||
uint32 GetMountID() const { return GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); }
|
||||
void Mount(uint32 mount);
|
||||
void Mount(uint32 mount, uint32 spellId = 0);
|
||||
void Unmount();
|
||||
|
||||
uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; }
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "9076"
|
||||
#define REVISION_NR "9077"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue