aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/game/Player.cpp5
-rw-r--r--src/game/Spell.cpp9
-rw-r--r--src/game/SpellAuras.cpp20
-rw-r--r--src/game/TemporarySummon.cpp4
-rw-r--r--src/game/Unit.cpp150
-rw-r--r--src/game/Unit.h11
-rw-r--r--src/game/Vehicle.cpp17
7 files changed, 115 insertions, 101 deletions
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 0865e65ddff..529dfbeba36 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -16664,8 +16664,6 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
void Player::StopCastingCharm()
{
- ExitVehicle();
-
Unit* charm = GetCharm();
if(!charm)
return;
@@ -16674,6 +16672,8 @@ void Player::StopCastingCharm()
{
if(((Creature*)charm)->HasSummonMask(SUMMON_MASK_PUPPET))
((Puppet*)charm)->UnSummon();
+ else if(((Creature*)charm)->isVehicle())
+ ExitVehicle();
}
if(GetCharmGUID())
{
@@ -16685,6 +16685,7 @@ void Player::StopCastingCharm()
if(GetCharmGUID())
{
sLog.outCrash("Player %s is not able to uncharm unit (Entry: %u, Type: %u)", GetName(), charm->GetEntry(), charm->GetTypeId());
+ assert(false);
}
}
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 8e247230a40..bfa843c873e 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -4659,6 +4659,7 @@ SpellCastResult Spell::CheckCast(bool strict)
}
case SPELL_AURA_MOD_POSSESS:
case SPELL_AURA_MOD_CHARM:
+ //case SPELL_AURA_MOD_POSSESS_PET:
{
if(m_caster->GetPetGUID())
return SPELL_FAILED_ALREADY_HAVE_SUMMON;
@@ -4669,13 +4670,15 @@ SpellCastResult Spell::CheckCast(bool strict)
if(m_caster->GetCharmerGUID())
return SPELL_FAILED_CHARMED;
- if(!m_targets.getUnitTarget())
+ Unit *target = m_targets.getUnitTarget();
+ if(!target || target->GetTypeId() == TYPEID_UNIT
+ && ((Creature*)target)->isVehicle())
return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
- if(m_targets.getUnitTarget()->GetCharmerGUID())
+ if(target->GetCharmerGUID())
return SPELL_FAILED_CHARMED;
- if(int32(m_targets.getUnitTarget()->getLevel()) > CalculateDamage(i,m_targets.getUnitTarget()))
+ if(int32(target->getLevel()) > CalculateDamage(i, target))
return SPELL_FAILED_HIGHLEVEL;
break;
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index d34a1bdda03..13eca16b699 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -532,12 +532,12 @@ AreaAuraEffect::AreaAuraEffect(Aura * parentAura, uint32 effIndex, int32 * curre
case SPELL_EFFECT_APPLY_AREA_AURA_PARTY:
m_areaAuraType = AREA_AURA_PARTY;
if(m_target->GetTypeId() == TYPEID_UNIT && ((Creature*)m_target)->isTotem())
- const_cast<AuraType>(m_auraName) = SPELL_AURA_NONE;
+ (AuraType)m_auraName = SPELL_AURA_NONE;
break;
case SPELL_EFFECT_APPLY_AREA_AURA_RAID:
m_areaAuraType = AREA_AURA_RAID;
if(m_target->GetTypeId() == TYPEID_UNIT && ((Creature*)m_target)->isTotem())
- const_cast<AuraType>(m_auraName) = SPELL_AURA_NONE;
+ (AuraType)m_auraName = SPELL_AURA_NONE;
break;
case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
m_areaAuraType = AREA_AURA_FRIEND;
@@ -545,7 +545,7 @@ AreaAuraEffect::AreaAuraEffect(Aura * parentAura, uint32 effIndex, int32 * curre
case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
m_areaAuraType = AREA_AURA_ENEMY;
if(m_target == caster_ptr)
- const_cast<AuraType>(m_auraName) = SPELL_AURA_NONE; // Do not do any effect on self
+ (AuraType)m_auraName = SPELL_AURA_NONE; // Do not do any effect on self
break;
case SPELL_EFFECT_APPLY_AREA_AURA_PET:
m_areaAuraType = AREA_AURA_PET;
@@ -553,7 +553,7 @@ AreaAuraEffect::AreaAuraEffect(Aura * parentAura, uint32 effIndex, int32 * curre
case SPELL_EFFECT_APPLY_AREA_AURA_OWNER:
m_areaAuraType = AREA_AURA_OWNER;
if(m_target == caster_ptr)
- const_cast<AuraType>(m_auraName) = SPELL_AURA_NONE;
+ (AuraType)m_auraName = SPELL_AURA_NONE;
break;
default:
sLog.outError("Wrong spell effect in AreaAura constructor");
@@ -6906,10 +6906,10 @@ void AuraEffect::HandleModPossess(bool apply, bool Real, bool /*changeAmount*/)
if(m_target->getLevel() > m_amount)
return;
- m_target->SetCharmedOrPossessedBy(caster, true);
+ m_target->SetCharmedBy(caster, CHARM_TYPE_POSSESS);
}
else
- m_target->RemoveCharmedOrPossessedBy(caster);
+ m_target->RemoveCharmedBy(caster);
}
void AuraEffect::HandleModPossessPet(bool apply, bool Real, bool /*changeAmount*/)
@@ -6926,11 +6926,11 @@ void AuraEffect::HandleModPossessPet(bool apply, bool Real, bool /*changeAmount*
if(caster->GetGuardianPet() != m_target)
return;
- m_target->SetCharmedOrPossessedBy(caster, true);
+ m_target->SetCharmedBy(caster, CHARM_TYPE_POSSESS);
}
else
{
- m_target->RemoveCharmedOrPossessedBy(caster);
+ m_target->RemoveCharmedBy(caster);
// Reinitialize the pet bar and make the pet come back to the owner
((Player*)caster)->PetSpellInitialize();
@@ -6954,10 +6954,10 @@ void AuraEffect::HandleModCharm(bool apply, bool Real, bool /*changeAmount*/)
if(int32(m_target->getLevel()) > m_amount)
return;
- m_target->SetCharmedOrPossessedBy(caster, false);
+ m_target->SetCharmedBy(caster, CHARM_TYPE_CHARM);
}
else
- m_target->RemoveCharmedOrPossessedBy(caster);
+ m_target->RemoveCharmedBy(caster);
}
void AuraEffect::HandlePhase(bool apply, bool Real, bool /*changeAmount*/)
diff --git a/src/game/TemporarySummon.cpp b/src/game/TemporarySummon.cpp
index 2be94e29c38..d4c4d54fb1d 100644
--- a/src/game/TemporarySummon.cpp
+++ b/src/game/TemporarySummon.cpp
@@ -332,7 +332,7 @@ void Puppet::InitStats(uint32 duration)
void Puppet::InitSummon()
{
Minion::InitSummon();
- SetCharmedOrPossessedBy(m_owner, true);
+ SetCharmedBy(m_owner, CHARM_TYPE_POSSESS);
}
void Puppet::Update(uint32 time)
@@ -351,6 +351,6 @@ void Puppet::RemoveFromWorld()
if(!IsInWorld())
return;
- RemoveCharmedOrPossessedBy(NULL);
+ RemoveCharmedBy(NULL);
Minion::RemoveFromWorld();
}
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index a39b43a88a7..9f4d550e24e 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -13525,12 +13525,13 @@ void Unit::SetConfused(bool apply)
((Player*)this)->SetClientControl(this, !apply);
}
-void Unit::SetCharmedOrPossessedBy(Unit* charmer, bool possess)
+void Unit::SetCharmedBy(Unit* charmer, CharmType type)
{
if(!charmer)
return;
- assert(!possess || charmer->GetTypeId() == TYPEID_PLAYER);
+ assert(type != CHARM_TYPE_POSSESS || charmer->GetTypeId() == TYPEID_PLAYER);
+ assert(type != CHARM_TYPE_VEHICLE || GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isVehicle());
if(this == charmer)
return;
@@ -13581,50 +13582,57 @@ void Unit::SetCharmedOrPossessedBy(Unit* charmer, bool possess)
}
// Pets already have a properly initialized CharmInfo, don't overwrite it.
- if(GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT
- && !((Creature*)this)->HasSummonMask(SUMMON_MASK_GUARDIAN))
+ if(type != CHARM_TYPE_VEHICLE && !GetCharmInfo())
{
CharmInfo *charmInfo = InitCharmInfo();
- if(possess)
+ if(type == CHARM_TYPE_POSSESS)
charmInfo->InitPossessCreateSpells();
else
charmInfo->InitCharmCreateSpells();
}
- //Set possessed
- if(possess)
- {
- addUnitState(UNIT_STAT_POSSESSED);
- SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
- ((Player*)charmer)->SetClientControl(this, 1);
- ((Player*)charmer)->SetViewpoint(this, true);
- charmer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
- }
- // Charm demon
- else if(GetTypeId() == TYPEID_UNIT && charmer->GetTypeId() == TYPEID_PLAYER && charmer->getClass() == CLASS_WARLOCK)
+ if(charmer->GetTypeId() == TYPEID_PLAYER)
{
- CreatureInfo const *cinfo = ((Creature*)this)->GetCreatureInfo();
- if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
+ switch(type)
{
- //to prevent client crash
- //SetFlag(UNIT_FIELD_BYTES_0, 2048);
+ case CHARM_TYPE_VEHICLE:
+ ((Player*)charmer)->SetViewpoint(this, true);
+ ((Player*)charmer)->VehicleSpellInitialize();
+ break;
+ case CHARM_TYPE_POSSESS:
+ addUnitState(UNIT_STAT_POSSESSED);
+ SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
+ charmer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+ ((Player*)charmer)->SetClientControl(this, 1);
+ ((Player*)charmer)->SetViewpoint(this, true);
+ ((Player*)charmer)->PossessSpellInitialize();
+ break;
+ case CHARM_TYPE_CHARM:
+ if(GetTypeId() == TYPEID_UNIT && charmer->getClass() == CLASS_WARLOCK)
+ {
+ CreatureInfo const *cinfo = ((Creature*)this)->GetCreatureInfo();
+ if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
+ {
+ //to prevent client crash
+ //SetFlag(UNIT_FIELD_BYTES_0, 2048);
- //just to enable stat window
- if(GetCharmInfo())
- GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true);
+ //just to enable stat window
+ if(GetCharmInfo())
+ GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true);
- //if charmed two demons the same session, the 2nd gets the 1st one's name
- SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
+ //if charmed two demons the same session, the 2nd gets the 1st one's name
+ SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
+ }
+ }
+ ((Player*)charmer)->CharmSpellInitialize();
+ break;
+ default:
+ break;
}
- }
-
- if(possess)
- ((Player*)charmer)->PossessSpellInitialize();
- else if(charmer->GetTypeId() == TYPEID_PLAYER)
- ((Player*)charmer)->CharmSpellInitialize();
+ }
}
-void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
+void Unit::RemoveCharmedBy(Unit *charmer)
{
if(!isCharmed())
return;
@@ -13634,7 +13642,13 @@ void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
else if(charmer != GetCharmer()) // one aura overrides another?
return;
- bool possess = hasUnitState(UNIT_STAT_POSSESSED);
+ CharmType type;
+ if(hasUnitState(UNIT_STAT_POSSESSED))
+ type = CHARM_TYPE_POSSESS;
+ else if(this == charmer->m_Vehicle)
+ type = CHARM_TYPE_VEHICLE;
+ else
+ type = CHARM_TYPE_CHARM;
CastStop();
CombatStop(); //TODO: CombatStop(true) may cause crash (interrupt spells)
@@ -13643,7 +13657,7 @@ void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
RestoreFaction();
GetMotionMaster()->InitDefault();
- if(possess)
+ if(type == CHARM_TYPE_POSSESS)
{
clearUnitState(UNIT_STAT_POSSESSED);
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
@@ -13651,20 +13665,18 @@ void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
if(GetTypeId() == TYPEID_UNIT)
{
- if(!((Creature*)this)->isPet())
- RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
-
((Creature*)this)->AI()->OnCharmed(false);
- if(isAlive() && ((Creature*)this)->IsAIEnabled)
+ if(isAlive() && charmer && !IsFriendlyTo(charmer))
+ ((Creature*)this)->AddThreat(charmer, 10000.0f);
+ /*if(isAlive() && ((Creature*)this)->IsAIEnabled)
{
if(charmer && !IsFriendlyTo(charmer))
{
- ((Creature*)this)->AddThreat(charmer, 10000.0f);
((Creature*)this)->AI()->AttackStart(charmer);
}
else
((Creature*)this)->AI()->EnterEvadeMode();
- }
+ }*/
}
else
((Player*)this)->SetClientControl(this, 1);
@@ -13673,42 +13685,46 @@ void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
if(!charmer)
return;
- assert(!possess || charmer->GetTypeId() == TYPEID_PLAYER);
+ assert(type != CHARM_TYPE_POSSESS || charmer->GetTypeId() == TYPEID_PLAYER);
+ assert(type != CHARM_TYPE_VEHICLE || GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isVehicle());
charmer->SetCharm(this, false);
- if(possess)
- {
- ((Player*)charmer)->SetClientControl(charmer, 1);
- ((Player*)charmer)->SetViewpoint(this, false);
- charmer->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
- }
- // restore UNIT_FIELD_BYTES_0
- else if(GetTypeId() == TYPEID_UNIT && charmer->GetTypeId() == TYPEID_PLAYER && charmer->getClass() == CLASS_WARLOCK)
+
+ if(charmer->GetTypeId() == TYPEID_PLAYER)
{
- CreatureInfo const *cinfo = ((Creature*)this)->GetCreatureInfo();
- if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
+ switch(type)
{
- if(GetCharmInfo())
- GetCharmInfo()->SetPetNumber(0, true);
- else
- sLog.outError("Aura::HandleModCharm: target="UI64FMTD" with typeid=%d has a charm aura but no charm info!", GetGUID(), GetTypeId());
+ case CHARM_TYPE_VEHICLE:
+ ((Player*)charmer)->SetViewpoint(this, false);
+ break;
+ case CHARM_TYPE_POSSESS:
+ ((Player*)charmer)->SetClientControl(charmer, 1);
+ ((Player*)charmer)->SetViewpoint(this, false);
+ charmer->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+ break;
+ case CHARM_TYPE_CHARM:
+ if(GetTypeId() == TYPEID_UNIT && charmer->getClass() == CLASS_WARLOCK)
+ {
+ CreatureInfo const *cinfo = ((Creature*)this)->GetCreatureInfo();
+ if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
+ {
+ if(GetCharmInfo())
+ GetCharmInfo()->SetPetNumber(0, true);
+ else
+ sLog.outError("Aura::HandleModCharm: target="UI64FMTD" with typeid=%d has a charm aura but no charm info!", GetGUID(), GetTypeId());
+ }
+ }
+ break;
+ default:
+ break;
}
}
//a guardian should always have charminfo
- if(GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT
- && !((Creature*)this)->HasSummonMask(SUMMON_MASK_GUARDIAN))
- {
+ if(charmer->GetTypeId() == TYPEID_PLAYER && this != charmer->GetFirstControlled())
+ ((Player*)charmer)->SendRemoveControlBar();
+ else if(GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT && !((Creature*)this)->isGuardian())
DeleteCharmInfo();
- }
-
- if(possess || charmer->GetTypeId() == TYPEID_PLAYER)
- {
- // Remove pet spell action bar
- WorldPacket data(SMSG_PET_SPELLS, 8);
- data << uint64(0);
- ((Player*)charmer)->GetSession()->SendPacket(&data);
- }
}
void Unit::RestoreFaction()
diff --git a/src/game/Unit.h b/src/game/Unit.h
index d788a9ad4f6..ea934356842 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -885,6 +885,13 @@ struct CharmSpellEntry
typedef std::list<Player*> SharedVisionList;
+enum CharmType
+{
+ CHARM_TYPE_CHARM,
+ CHARM_TYPE_POSSESS,
+ CHARM_TYPE_VEHICLE,
+};
+
enum ActionBarIndex
{
ACTION_BAR_INDEX_START = 0,
@@ -1340,8 +1347,8 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void SetMinion(Minion *minion, bool apply);
void SetCharm(Unit* target, bool apply);
Unit* GetNextRandomRaidMemberOrPet(float radius);
- void SetCharmedOrPossessedBy(Unit* charmer, bool possess);
- void RemoveCharmedOrPossessedBy(Unit* charmer);
+ void SetCharmedBy(Unit* charmer, CharmType type);
+ void RemoveCharmedBy(Unit* charmer);
void RestoreFaction();
ControlList m_Controlled;
diff --git a/src/game/Vehicle.cpp b/src/game/Vehicle.cpp
index f915c828c1d..94f828bfaf6 100644
--- a/src/game/Vehicle.cpp
+++ b/src/game/Vehicle.cpp
@@ -247,14 +247,7 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId)
//ChatHandler(player).PSendSysMessage("Enter seat %u %u", veSeat->m_ID, seat->first);
if(seat->first == 0 && seat->second.seatInfo->IsUsable()) // not right
- {
- setFaction(unit->getFaction());
- AI()->OnCharmed(true);
- GetMotionMaster()->MoveIdle();
- ((Player*)unit)->SetCharm(this, true);
- ((Player*)unit)->SetViewpoint(this, true);
- ((Player*)unit)->VehicleSpellInitialize();
- }
+ SetCharmedBy(unit, CHARM_TYPE_VEHICLE);
((Player*)unit)->BuildTeleportAckMsg(&data, unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetOrientation());
((Player*)unit)->GetSession()->SendPacket(&data);
@@ -294,13 +287,7 @@ void Vehicle::RemovePassenger(Unit *unit)
//SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
if(unit->GetTypeId() == TYPEID_PLAYER && seat->first == 0 && seat->second.seatInfo->IsUsable())
- {
- RestoreFaction();
- AI()->OnCharmed(false);
- ((Player*)unit)->SetCharm(this, false);
- ((Player*)unit)->SetViewpoint(this, false);
- ((Player*)unit)->SendRemoveControlBar();
- }
+ RemoveCharmedBy(unit);
// only for flyable vehicles?
//CastSpell(this, 45472, true); // Parachute