mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 16:37:01 +00:00
[8147] Some fixes and cleanups in mind control and charmed code. Mind control stil not finished.
* Allow command to mind controlled unit attack target at client. Rename related flag to UNIT_FLAG_PLAYER_CONTROLLED. * Move code for pet action bar remove at client side to new function Player::RemovePetActionBar * Not allow cast spells with SPELL_AURA_MOD_POSSESS and SPELL_AURA_MOD_POSSESS_PET by non-players and simplify related code base at this.
This commit is contained in:
parent
1ad013e25b
commit
3bfe549a2b
7 changed files with 153 additions and 125 deletions
|
|
@ -335,4 +335,4 @@ void PetAI::AttackedBy(Unit *attacker)
|
|||
if(!m_creature->getVictim() && m_creature->GetCharmInfo() && !m_creature->GetCharmInfo()->HasReactState(REACT_PASSIVE) &&
|
||||
(!m_creature->GetCharmInfo()->HasCommandState(COMMAND_STAY) || m_creature->canReachWithAttack(attacker)))
|
||||
AttackStart(attacker);
|
||||
}
|
||||
}
|
||||
|
|
@ -16359,9 +16359,7 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
|
|||
|
||||
if(pet->isControlled())
|
||||
{
|
||||
WorldPacket data(SMSG_PET_SPELLS, 8);
|
||||
data << uint64(0);
|
||||
GetSession()->SendPacket(&data);
|
||||
RemovePetActionBar();
|
||||
|
||||
if(GetGroup())
|
||||
SetGroupUpdateFlag(GROUP_UPDATE_PET);
|
||||
|
|
@ -16623,6 +16621,13 @@ void Player::CharmSpellInitialize()
|
|||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
void Player::RemovePetActionBar()
|
||||
{
|
||||
WorldPacket data(SMSG_PET_SPELLS, 8);
|
||||
data << uint64(0);
|
||||
SendDirectMessage(&data);
|
||||
}
|
||||
|
||||
bool Player::IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell)
|
||||
{
|
||||
if (!mod || !spellInfo)
|
||||
|
|
@ -19380,7 +19385,7 @@ void Player::EnterVehicle(Vehicle *vehicle)
|
|||
|
||||
vehicle->SetCharmerGUID(GetGUID());
|
||||
vehicle->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
|
||||
vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
||||
vehicle->setFaction(getFaction());
|
||||
|
||||
SetCharm(vehicle); // charm
|
||||
|
|
@ -19432,7 +19437,7 @@ void Player::ExitVehicle(Vehicle *vehicle)
|
|||
{
|
||||
vehicle->SetCharmerGUID(0);
|
||||
vehicle->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
|
||||
vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
||||
vehicle->setFaction((GetTeam() == ALLIANCE) ? vehicle->GetCreatureInfo()->faction_A : vehicle->GetCreatureInfo()->faction_H);
|
||||
|
||||
SetCharm(NULL);
|
||||
|
|
@ -19454,9 +19459,7 @@ void Player::ExitVehicle(Vehicle *vehicle)
|
|||
data << uint32(0); // fall time
|
||||
GetSession()->SendPacket(&data);
|
||||
|
||||
data.Initialize(SMSG_PET_SPELLS, 8);
|
||||
data << uint64(0);
|
||||
GetSession()->SendPacket(&data);
|
||||
RemovePetActionBar();
|
||||
|
||||
// maybe called at dummy aura remove?
|
||||
// CastSpell(this, 45472, true); // Parachute
|
||||
|
|
|
|||
|
|
@ -1442,6 +1442,8 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
void PetSpellInitialize();
|
||||
void CharmSpellInitialize();
|
||||
void PossessSpellInitialize();
|
||||
void RemovePetActionBar();
|
||||
|
||||
bool HasSpell(uint32 spell) const;
|
||||
bool HasActiveSpell(uint32 spell) const; // show in spellbook
|
||||
TrainerSpellState GetTrainerSpellState(TrainerSpell const* trainer_spell) const;
|
||||
|
|
|
|||
|
|
@ -4383,8 +4383,38 @@ SpellCastResult Spell::CheckCast(bool strict)
|
|||
break;
|
||||
}
|
||||
case SPELL_AURA_MOD_POSSESS:
|
||||
{
|
||||
if(m_caster->GetTypeId() != TYPEID_PLAYER)
|
||||
return SPELL_FAILED_UNKNOWN;
|
||||
|
||||
if(m_targets.getUnitTarget() == m_caster)
|
||||
return SPELL_FAILED_BAD_TARGETS;
|
||||
|
||||
if(m_caster->GetPetGUID())
|
||||
return SPELL_FAILED_ALREADY_HAVE_SUMMON;
|
||||
|
||||
if(m_caster->GetCharmGUID())
|
||||
return SPELL_FAILED_ALREADY_HAVE_CHARM;
|
||||
|
||||
if(m_caster->GetCharmerGUID())
|
||||
return SPELL_FAILED_CHARMED;
|
||||
|
||||
if(!m_targets.getUnitTarget())
|
||||
return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
|
||||
|
||||
if(m_targets.getUnitTarget()->GetCharmerGUID())
|
||||
return SPELL_FAILED_CHARMED;
|
||||
|
||||
if(int32(m_targets.getUnitTarget()->getLevel()) > CalculateDamage(i,m_targets.getUnitTarget()))
|
||||
return SPELL_FAILED_HIGHLEVEL;
|
||||
|
||||
break;
|
||||
}
|
||||
case SPELL_AURA_MOD_CHARM:
|
||||
{
|
||||
if(m_targets.getUnitTarget() == m_caster)
|
||||
return SPELL_FAILED_BAD_TARGETS;
|
||||
|
||||
if(m_caster->GetPetGUID())
|
||||
return SPELL_FAILED_ALREADY_HAVE_SUMMON;
|
||||
|
||||
|
|
@ -4407,6 +4437,9 @@ SpellCastResult Spell::CheckCast(bool strict)
|
|||
}
|
||||
case SPELL_AURA_MOD_POSSESS_PET:
|
||||
{
|
||||
if(m_caster->GetTypeId() != TYPEID_PLAYER)
|
||||
return SPELL_FAILED_UNKNOWN;
|
||||
|
||||
if(m_caster->GetCharmGUID())
|
||||
return SPELL_FAILED_ALREADY_HAVE_CHARM;
|
||||
|
||||
|
|
|
|||
|
|
@ -3074,33 +3074,33 @@ void Aura::HandleModPossess(bool apply, bool Real)
|
|||
if(!Real)
|
||||
return;
|
||||
|
||||
if(m_target->getLevel() > m_modifier.m_amount)
|
||||
return;
|
||||
|
||||
// not possess yourself
|
||||
if(GetCasterGUID() == m_target->GetGUID())
|
||||
return;
|
||||
|
||||
Unit* caster = GetCaster();
|
||||
if(!caster)
|
||||
if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
Player* p_caster = (Player*)caster;
|
||||
|
||||
|
||||
if( apply )
|
||||
{
|
||||
m_target->SetCharmerGUID(GetCasterGUID());
|
||||
m_target->setFaction(caster->getFaction());
|
||||
m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
||||
|
||||
caster->SetCharm(m_target);
|
||||
m_target->SetCharmerGUID(p_caster->GetGUID());
|
||||
m_target->setFaction(p_caster->getFaction());
|
||||
|
||||
if(caster->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
((Player*)caster)->SetFarSightGUID(m_target->GetGUID());
|
||||
((Player*)caster)->SetClientControl(m_target, 1);
|
||||
((Player*)caster)->SetMover(m_target);
|
||||
}
|
||||
p_caster->SetCharm(m_target);
|
||||
|
||||
p_caster->SetFarSightGUID(m_target->GetGUID());
|
||||
p_caster->SetClientControl(m_target, 1);
|
||||
p_caster->SetMover(m_target);
|
||||
|
||||
m_target->CombatStop();
|
||||
m_target->DeleteThreatList();
|
||||
|
||||
if(m_target->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
m_target->StopMoving();
|
||||
|
|
@ -3115,13 +3115,14 @@ void Aura::HandleModPossess(bool apply, bool Real)
|
|||
if(CharmInfo *charmInfo = m_target->InitCharmInfo(m_target))
|
||||
charmInfo->InitPossessCreateSpells();
|
||||
|
||||
if(caster->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)caster)->PossessSpellInitialize();
|
||||
p_caster->PossessSpellInitialize();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
||||
|
||||
m_target->SetCharmerGUID(0);
|
||||
caster->InterruptSpell(CURRENT_CHANNELED_SPELL); // the spell is not automatically canceled when interrupted, do it now
|
||||
p_caster->InterruptSpell(CURRENT_CHANNELED_SPELL); // the spell is not automatically canceled when interrupted, do it now
|
||||
|
||||
if(m_target->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
|
|
@ -3134,18 +3135,13 @@ void Aura::HandleModPossess(bool apply, bool Real)
|
|||
m_target->setFaction(cinfo->faction_A);
|
||||
}
|
||||
|
||||
caster->SetCharm(NULL);
|
||||
p_caster->SetCharm(NULL);
|
||||
|
||||
if(caster->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
((Player*)caster)->SetFarSightGUID(0);
|
||||
((Player*)caster)->SetClientControl(m_target, 0);
|
||||
((Player*)caster)->SetMover(NULL);
|
||||
p_caster->SetFarSightGUID(0);
|
||||
p_caster->SetClientControl(m_target, 0);
|
||||
p_caster->SetMover(NULL);
|
||||
|
||||
WorldPacket data(SMSG_PET_SPELLS, 8);
|
||||
data << uint64(0);
|
||||
((Player*)caster)->GetSession()->SendPacket(&data);
|
||||
}
|
||||
p_caster->RemovePetActionBar();
|
||||
|
||||
if(m_target->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
|
|
@ -3170,14 +3166,16 @@ void Aura::HandleModPossessPet(bool apply, bool Real)
|
|||
if(!pet || pet != m_target)
|
||||
return;
|
||||
|
||||
if(apply)
|
||||
pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
|
||||
else
|
||||
pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
|
||||
Player* p_caster = (Player*)caster;
|
||||
|
||||
((Player*)caster)->SetFarSightGUID(apply ? pet->GetGUID() : 0);
|
||||
((Player*)caster)->SetCharm(apply ? pet : NULL);
|
||||
((Player*)caster)->SetClientControl(pet, apply ? 1 : 0);
|
||||
if(apply)
|
||||
pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
||||
else
|
||||
pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
||||
|
||||
p_caster->SetFarSightGUID(apply ? pet->GetGUID() : 0);
|
||||
p_caster->SetCharm(apply ? pet : NULL);
|
||||
p_caster->SetClientControl(pet, apply ? 1 : 0);
|
||||
((Player*)caster)->SetMover(apply ? pet : NULL);
|
||||
|
||||
if(apply)
|
||||
|
|
@ -3217,100 +3215,92 @@ void Aura::HandleModCharm(bool apply, bool Real)
|
|||
if(!caster)
|
||||
return;
|
||||
|
||||
if(int32(m_target->getLevel()) <= m_modifier.m_amount)
|
||||
if( apply )
|
||||
{
|
||||
if( apply )
|
||||
m_target->SetCharmerGUID(GetCasterGUID());
|
||||
m_target->setFaction(caster->getFaction());
|
||||
m_target->CastStop(m_target == caster ? GetId() : 0);
|
||||
caster->SetCharm(m_target);
|
||||
|
||||
m_target->CombatStop();
|
||||
m_target->DeleteThreatList();
|
||||
|
||||
if(m_target->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
m_target->SetCharmerGUID(GetCasterGUID());
|
||||
m_target->setFaction(caster->getFaction());
|
||||
m_target->CastStop(m_target == caster ? GetId() : 0);
|
||||
caster->SetCharm(m_target);
|
||||
((Creature*)m_target)->AIM_Initialize();
|
||||
CharmInfo *charmInfo = m_target->InitCharmInfo(m_target);
|
||||
charmInfo->InitCharmCreateSpells();
|
||||
charmInfo->SetReactState( REACT_DEFENSIVE );
|
||||
|
||||
m_target->CombatStop();
|
||||
m_target->DeleteThreatList();
|
||||
|
||||
if(m_target->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
((Creature*)m_target)->AIM_Initialize();
|
||||
CharmInfo *charmInfo = m_target->InitCharmInfo(m_target);
|
||||
charmInfo->InitCharmCreateSpells();
|
||||
charmInfo->SetReactState( REACT_DEFENSIVE );
|
||||
|
||||
if(caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK)
|
||||
{
|
||||
CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
|
||||
if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
|
||||
{
|
||||
//does not appear to have relevance. Why code added initially? See note below at !apply
|
||||
//to prevent client crash
|
||||
//m_target->SetFlag(UNIT_FIELD_BYTES_0, 2048);
|
||||
//just to enable stat window
|
||||
charmInfo->SetPetNumber(objmgr.GeneratePetNumber(), true);
|
||||
//if charmed two demons the same session, the 2nd gets the 1st one's name
|
||||
m_target->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(caster->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
((Player*)caster)->CharmSpellInitialize();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_target->SetCharmerGUID(0);
|
||||
|
||||
if(m_target->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)m_target)->setFactionForRace(m_target->getRace());
|
||||
else
|
||||
if(caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK)
|
||||
{
|
||||
CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
|
||||
|
||||
// restore faction
|
||||
if(((Creature*)m_target)->isPet())
|
||||
if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
|
||||
{
|
||||
if(Unit* owner = m_target->GetOwner())
|
||||
m_target->setFaction(owner->getFaction());
|
||||
else if(cinfo)
|
||||
m_target->setFaction(cinfo->faction_A);
|
||||
//does not appear to have relevance. Why code added initially? See note below at !apply
|
||||
//to prevent client crash
|
||||
//m_target->SetFlag(UNIT_FIELD_BYTES_0, 2048);
|
||||
//just to enable stat window
|
||||
charmInfo->SetPetNumber(objmgr.GeneratePetNumber(), true);
|
||||
//if charmed two demons the same session, the 2nd gets the 1st one's name
|
||||
m_target->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
|
||||
}
|
||||
else if(cinfo) // normal creature
|
||||
}
|
||||
}
|
||||
|
||||
if(caster->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)caster)->CharmSpellInitialize();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_target->SetCharmerGUID(0);
|
||||
|
||||
if(m_target->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)m_target)->setFactionForRace(m_target->getRace());
|
||||
else
|
||||
{
|
||||
CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
|
||||
|
||||
// restore faction
|
||||
if(((Creature*)m_target)->isPet())
|
||||
{
|
||||
if(Unit* owner = m_target->GetOwner())
|
||||
m_target->setFaction(owner->getFaction());
|
||||
else if(cinfo)
|
||||
m_target->setFaction(cinfo->faction_A);
|
||||
|
||||
// restore UNIT_FIELD_BYTES_0
|
||||
if(cinfo && caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK && cinfo->type == CREATURE_TYPE_DEMON)
|
||||
{
|
||||
//does not appear to have relevance. Why code added initially? Class, gender, powertype should be same.
|
||||
//db field removed and replaced with better way to set class, restore using this if problems
|
||||
/*CreatureDataAddon const *cainfo = ((Creature*)m_target)->GetCreatureAddon();
|
||||
if(cainfo && cainfo->bytes0 != 0)
|
||||
m_target->SetUInt32Value(UNIT_FIELD_BYTES_0, cainfo->bytes0);
|
||||
else
|
||||
m_target->RemoveFlag(UNIT_FIELD_BYTES_0, 2048);*/
|
||||
|
||||
if(m_target->GetCharmInfo())
|
||||
m_target->GetCharmInfo()->SetPetNumber(0, true);
|
||||
else
|
||||
sLog.outError("Aura::HandleModCharm: target (GUID: %u TypeId: %u) has a charm aura but no charm info!", m_target->GetGUIDLow(), m_target->GetTypeId());
|
||||
}
|
||||
}
|
||||
else if(cinfo) // normal creature
|
||||
m_target->setFaction(cinfo->faction_A);
|
||||
|
||||
caster->SetCharm(NULL);
|
||||
|
||||
if(caster->GetTypeId() == TYPEID_PLAYER)
|
||||
// restore UNIT_FIELD_BYTES_0
|
||||
if(cinfo && caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK && cinfo->type == CREATURE_TYPE_DEMON)
|
||||
{
|
||||
WorldPacket data(SMSG_PET_SPELLS, 8);
|
||||
data << uint64(0);
|
||||
((Player*)caster)->GetSession()->SendPacket(&data);
|
||||
}
|
||||
if(m_target->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
((Creature*)m_target)->AIM_Initialize();
|
||||
if (((Creature*)m_target)->AI())
|
||||
((Creature*)m_target)->AI()->AttackedBy(caster);
|
||||
//does not appear to have relevance. Why code added initially? Class, gender, powertype should be same.
|
||||
//db field removed and replaced with better way to set class, restore using this if problems
|
||||
/*CreatureDataAddon const *cainfo = ((Creature*)m_target)->GetCreatureAddon();
|
||||
if(cainfo && cainfo->bytes0 != 0)
|
||||
m_target->SetUInt32Value(UNIT_FIELD_BYTES_0, cainfo->bytes0);
|
||||
else
|
||||
m_target->RemoveFlag(UNIT_FIELD_BYTES_0, 2048);*/
|
||||
|
||||
if(m_target->GetCharmInfo())
|
||||
m_target->GetCharmInfo()->SetPetNumber(0, true);
|
||||
else
|
||||
sLog.outError("Aura::HandleModCharm: target (GUID: %u TypeId: %u) has a charm aura but no charm info!", m_target->GetGUIDLow(), m_target->GetTypeId());
|
||||
}
|
||||
}
|
||||
|
||||
caster->SetCharm(NULL);
|
||||
|
||||
if(caster->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)caster)->RemovePetActionBar();
|
||||
|
||||
if(m_target->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
((Creature*)m_target)->AIM_Initialize();
|
||||
if (((Creature*)m_target)->AI())
|
||||
((Creature*)m_target)->AI()->AttackedBy(caster);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -514,7 +514,7 @@ enum UnitFlags
|
|||
UNIT_FLAG_DISARMED = 0x00200000, // 3.0.3, disable melee spells casting..., "Required melee weapon" added to melee spells tooltip.
|
||||
UNIT_FLAG_CONFUSED = 0x00400000,
|
||||
UNIT_FLAG_FLEEING = 0x00800000,
|
||||
UNIT_FLAG_UNK_24 = 0x01000000, // used in spell Eyes of the Beast for pet...
|
||||
UNIT_FLAG_PLAYER_CONTROLLED= 0x01000000, // used in spell Eyes of the Beast for pet... let attack by controlled creature
|
||||
UNIT_FLAG_NOT_SELECTABLE = 0x02000000,
|
||||
UNIT_FLAG_SKINNABLE = 0x04000000,
|
||||
UNIT_FLAG_MOUNT = 0x08000000,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "8146"
|
||||
#define REVISION_NR "8147"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue