aboutsummaryrefslogtreecommitdiff
path: root/src/game/Unit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/Unit.cpp')
-rw-r--r--src/game/Unit.cpp145
1 files changed, 105 insertions, 40 deletions
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 8e4de36a27b..5b8eac9bf59 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -8135,13 +8135,9 @@ void Unit::CombatStop(bool cast)
void Unit::CombatStopWithPets(bool cast)
{
CombatStop(cast);
- if(Pet* pet = GetPet())
- pet->CombatStop(cast);
- if(Unit* charm = GetCharm())
- charm->CombatStop(cast);
- for(GuardianList::const_iterator itr = m_Guardians.begin(); itr != m_Guardians.end(); ++itr)
- if(Unit* guardian = Unit::GetUnit(*this,*itr))
- guardian->CombatStop(cast);
+
+ for(ControlList::const_iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
+ (*itr)->CombatStop(cast);
}
bool Unit::isAttackingPlayer() const
@@ -8228,11 +8224,14 @@ Pet* Unit::GetPet() const
{
if(uint64 pet_guid = GetPetGUID())
{
+ if(!IS_PET_GUID(pet_guid))
+ return NULL;
+
if(Pet* pet = ObjectAccessor::GetPet(pet_guid))
return pet;
sLog.outError("Unit::GetPet: Pet %u not exist.",GUID_LOPART(pet_guid));
- const_cast<Unit*>(this)->SetPet(0);
+ const_cast<Unit*>(this)->SetPet(NULL, false);
}
return NULL;
@@ -8246,27 +8245,103 @@ Unit* Unit::GetCharm() const
return pet;
sLog.outError("Unit::GetCharm: Charmed creature %u not exist.",GUID_LOPART(charm_guid));
- const_cast<Unit*>(this)->SetCharm(0);
- //const_cast<Unit*>(this)->SetMover(0);
+ const_cast<Unit*>(this)->SetCharm(NULL, false);
}
return NULL;
}
-void Unit::SetPet(Pet* pet)
+void Unit::SetPet(Creature* pet, bool apply)
{
- SetUInt64Value(UNIT_FIELD_SUMMON, pet ? pet->GetGUID() : 0);
+ sLog.outError("before %u", GetPetGUID());
+ if(apply)
+ {
+ if(!GetPetGUID())
+ SetUInt64Value(UNIT_FIELD_SUMMON, pet->GetGUID());
+ m_Controlled.insert(pet);
- // FIXME: hack, speed must be set only at follow
- if(pet)
- for(int i = 0; i < MAX_MOVE_TYPE; ++i)
- pet->SetSpeed(UnitMoveType(i), m_speed_rate[i], true);
+ // FIXME: hack, speed must be set only at follow
+ if(GetTypeId() == TYPEID_PLAYER && pet->HasSummonMask(SUMMON_MASK_PET))
+ for(int i = 0; i < MAX_MOVE_TYPE; ++i)
+ pet->SetSpeed(UnitMoveType(i), m_speed_rate[i], true);
+ }
+ else
+ {
+ SetUInt64Value(UNIT_FIELD_SUMMON, 0);
+ m_Controlled.erase(pet);
+
+ //Check if there is other pet (guardian actually)
+ for(ControlList::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
+ {
+ if((*itr)->GetOwnerGUID() == GetGUID())
+ {
+ SetUInt64Value(UNIT_FIELD_SUMMON, (*itr)->GetGUID());
+ break;
+ }
+ }
+ }
+ sLog.outError("after %u", GetPetGUID());
}
-void Unit::SetCharm(Unit* pet)
+void Unit::SetCharm(Unit* charm, bool apply)
{
- if(GetTypeId() == TYPEID_PLAYER)
- SetUInt64Value(UNIT_FIELD_CHARM, pet ? pet->GetGUID() : 0);
+ if(apply)
+ {
+ if(GetTypeId() == TYPEID_PLAYER)
+ {
+ if(GetCharmGUID())
+ sLog.outError("Player %s is trying to charm unit %u, but he already has a charmed unit %u", GetName(), charm->GetEntry(), GetCharmGUID());
+ SetUInt64Value(UNIT_FIELD_CHARM, charm->GetGUID());
+ }
+ m_Controlled.insert(charm);
+ }
+ else
+ {
+ if(GetTypeId() == TYPEID_PLAYER)
+ SetUInt64Value(UNIT_FIELD_CHARM, 0);
+ m_Controlled.erase(charm);
+ }
+}
+
+Unit* Unit::GetFirstControlled() const
+{
+ Unit *unit = GetCharm();
+ if(!unit)
+ {
+ if(uint64 guid = GetPetGUID())
+ unit = ObjectAccessor::GetUnit(*this, guid);
+ }
+ return unit;
+}
+
+void Unit::RemoveAllControlled()
+{
+ while(!m_Controlled.empty())
+ {
+ Unit *target = *m_Controlled.begin();
+ m_Controlled.erase(m_Controlled.begin());
+ if(target->GetCharmerGUID() == GetGUID())
+ {
+ //TODO: possessed and vehicle
+ target->RemoveCharmAuras();
+ }
+ else if(target->GetOwnerGUID() == GetGUID())
+ {
+ if(target->GetTypeId() == TYPEID_UNIT)
+ {
+ if(((Creature*)target)->HasSummonMask(SUMMON_MASK_SUMMON))
+ ((TempSummon*)target)->UnSummon();
+ }
+ }
+ else
+ {
+ sLog.outError("Unit %u is trying to release unit %u which is neither charmed nor owned by it", GetEntry(), target->GetEntry());
+ }
+ }
+ if(GetPetGUID())
+ sLog.outError("Unit %u is not able to release its summon %u", GetEntry(), GetPetGUID());
+ if(GetCharmGUID())
+ sLog.outError("Unit %u is not able to release its charm %u", GetEntry(), GetCharmGUID());
}
Unit* Unit::GetNextRandomRaidMemberOrPet(float radius)
@@ -10185,7 +10260,7 @@ void Unit::setDeathState(DeathState s)
if (s == JUST_DIED)
{
UnsummonAllTotems();
- RemoveGuardians();
+ RemoveAllControlled();
RemoveAllAurasOnDeath();
//This is needed to clear visible auras after unit dies
UpdateAuras();
@@ -11142,12 +11217,19 @@ void Unit::RemoveFromWorld()
if(IsInWorld())
{
UnsummonAllTotems();
- RemoveGuardians();
+ RemoveAllControlled();
RemoveCharmAuras();
RemoveBindSightAuras();
RemoveNotOwnSingleTargetAuras();
}
+ //if(m_uint32Values)
+ {
+ // if it has charmer or owner, it must be in someone's controllist and server will crash
+ assert(!GetCharmerGUID());
+ assert(!GetOwnerGUID());
+ }
+
WorldObject::RemoveFromWorld();
}
@@ -12950,10 +13032,10 @@ void Unit::SetCharmedOrPossessedBy(Unit* charmer, bool possess)
return;
// Set charmed
- charmer->SetCharm(this);
SetCharmerGUID(charmer->GetGUID());
setFaction(charmer->getFaction());
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
+ charmer->SetCharm(this, true);
if(GetTypeId() == TYPEID_UNIT)
{
@@ -13062,7 +13144,7 @@ void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
assert(!possess || charmer->GetTypeId() == TYPEID_PLAYER);
- charmer->SetCharm(0);
+ charmer->SetCharm(this, false);
if(possess)
{
((Player*)charmer)->SetClientControl(charmer, 1);
@@ -13103,23 +13185,6 @@ void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
}
}
-void Unit::RemoveGuardians()
-{
- while(!m_Guardians.empty())
- {
- uint64 guid = *m_Guardians.begin();
- if(Unit* guardian = ObjectAccessor::GetUnit(*this, guid))
- {
- if(guardian->GetTypeId() == TYPEID_UNIT)
- {
- if(((Creature*)guardian)->isSummon())
- ((TempSummon*)guardian)->UnSummon();
- }
- }
- m_Guardians.erase(guid);
- }
-}
-
void Unit::RestoreFaction()
{
if(GetTypeId() == TYPEID_PLAYER)