diff options
author | megamage <none@none> | 2009-08-26 19:28:21 -0500 |
---|---|---|
committer | megamage <none@none> | 2009-08-26 19:28:21 -0500 |
commit | 21af4cf832daeccb1617e37e15cd7b9bcebfb6c8 (patch) | |
tree | 04d46e30bc492ba8aa7b449ab2a3f721e95d96a3 /src | |
parent | 390257b2f6d4d4b03a3226a39b478b3ea92b4dea (diff) |
*Some clean up and add debug info to find the reason of crash.
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/game/Creature.cpp | 24 | ||||
-rw-r--r-- | src/game/Object.cpp | 57 | ||||
-rw-r--r-- | src/game/Pet.cpp | 2 | ||||
-rw-r--r-- | src/game/PointMovementGenerator.cpp | 2 | ||||
-rw-r--r-- | src/game/SharedDefines.h | 1 | ||||
-rw-r--r-- | src/game/Spell.cpp | 2 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 1 | ||||
-rw-r--r-- | src/game/TemporarySummon.cpp | 5 | ||||
-rw-r--r-- | src/game/TemporarySummon.h | 3 | ||||
-rw-r--r-- | src/game/Unit.cpp | 43 | ||||
-rw-r--r-- | src/game/Vehicle.cpp | 4 |
11 files changed, 87 insertions, 57 deletions
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 330c93429b6..5441a42c94a 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -204,7 +204,8 @@ void Creature::DisappearAndDie() //DestroyForNearbyPlayers(); SetVisibility(VISIBILITY_OFF); ObjectAccessor::UpdateObjectVisibility(this); - setDeathState(JUST_DIED); + if(isAlive()) + setDeathState(JUST_DIED); } void Creature::SearchFormationAndPath() @@ -561,10 +562,6 @@ void Creature::Update(uint32 diff) break; } case DEAD_FALLING: - { - if (!FallGround()) - setDeathState(JUST_DIED); - } default: break; } @@ -1763,9 +1760,6 @@ void Creature::setDeathState(DeathState s) // always save boss respawn time at death to prevent crash cheating if(sWorld.getConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATELY) || isWorldBoss()) SaveRespawnTime(); - - if (canFly() && FallGround()) - return; } Unit::setDeathState(s); @@ -1780,17 +1774,18 @@ void Creature::setDeathState(DeathState s) if ( LootTemplates_Skinning.HaveLootFor(GetCreatureInfo()->SkinLootId) ) SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); - if (canFly() && FallGround()) - return; - SetNoSearchAssistance(false); - Unit::setDeathState(CORPSE); //Dismiss group if is leader if(m_formation && m_formation->getLeader() == this) m_formation->FormationReset(true); + + if (canFly() && FallGround()) + return; + + Unit::setDeathState(CORPSE); } - if(s == JUST_ALIVED) + else if(s == JUST_ALIVED) { //if(isPet()) // setActive(true); @@ -1822,9 +1817,8 @@ bool Creature::FallGround() if (fabs(ground_Z - z) < 0.1f) return false; + GetMotionMaster()->MovePoint(EVENT_FALL_GROUND, x, y, ground_Z); Unit::setDeathState(DEAD_FALLING); - GetMotionMaster()->MovePoint(0, x, y, ground_Z); - Relocate(x, y, ground_Z); return true; } diff --git a/src/game/Object.cpp b/src/game/Object.cpp index e2d50d89753..9af456989c7 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1756,23 +1756,31 @@ TempSummon *Map::SummonCreature(uint32 entry, float x, float y, float z, float a uint32 mask = UNIT_MASK_SUMMON; if(properties) { - if(properties->Category == SUMMON_CATEGORY_PET - || properties->Type == SUMMON_TYPE_GUARDIAN - || properties->Type == SUMMON_TYPE_MINION) - mask = UNIT_MASK_GUARDIAN; - else if(properties->Type == SUMMON_TYPE_TOTEM) - mask = UNIT_MASK_TOTEM; - else if(properties->Category == SUMMON_CATEGORY_VEHICLE) - mask = UNIT_MASK_MINION; - else if(properties->Type == SUMMON_TYPE_VEHICLE - || properties->Type == SUMMON_TYPE_VEHICLE2) - mask = UNIT_MASK_SUMMON; - else if(properties->Category == SUMMON_CATEGORY_PUPPET) - mask = UNIT_MASK_PUPPET; - else if(properties->Type == SUMMON_TYPE_MINIPET) - mask = UNIT_MASK_MINION; - else if (properties->Flags & 512) // Mirror Image, Summon Gargoyle - mask = UNIT_MASK_GUARDIAN; + switch(properties->Category) + { + case SUMMON_CATEGORY_PET: mask = UNIT_MASK_GUARDIAN; break; + case SUMMON_CATEGORY_PUPPET: mask = UNIT_MASK_PUPPET; break; + case SUMMON_CATEGORY_VEHICLE: mask = UNIT_MASK_MINION; break; + default: + switch(properties->Type) + { + case SUMMON_TYPE_MINION: + case SUMMON_TYPE_GUARDIAN: + mask = UNIT_MASK_GUARDIAN; break; + case SUMMON_TYPE_TOTEM: + mask = UNIT_MASK_TOTEM; break; + case SUMMON_TYPE_VEHICLE: + case SUMMON_TYPE_VEHICLE2: + mask = UNIT_MASK_SUMMON; break; + case SUMMON_TYPE_MINIPET: + mask = UNIT_MASK_MINION; break; + default: + if(properties->Flags & 512) // Mirror Image, Summon Gargoyle + mask = UNIT_MASK_GUARDIAN; + break; + } + break; + } } uint32 phase = PHASEMASK_NORMAL, team = 0; @@ -1872,20 +1880,19 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy return NULL; } - Map *map = GetMap(); - uint32 pet_number = objmgr.GeneratePetNumber(); - if(!pet->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), map, GetPhaseMask(), entry, pet_number)) + pet->Relocate(x, y, z, ang); + if(!pet->IsPositionValid()) { - sLog.outError("no such creature entry %u", entry); + sLog.outError("ERROR: Pet (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %f Y: %f)",pet->GetGUIDLow(),pet->GetEntry(),pet->GetPositionX(),pet->GetPositionY()); delete pet; return NULL; } - pet->Relocate(x, y, z, ang); - - if(!pet->IsPositionValid()) + Map *map = GetMap(); + uint32 pet_number = objmgr.GeneratePetNumber(); + if(!pet->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), map, GetPhaseMask(), entry, pet_number)) { - sLog.outError("ERROR: Pet (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %f Y: %f)",pet->GetGUIDLow(),pet->GetEntry(),pet->GetPositionX(),pet->GetPositionY()); + sLog.outError("no such creature entry %u", entry); delete pet; return NULL; } diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 7ebd7531daf..e6dcf0ed19c 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -792,7 +792,7 @@ bool Guardian::InitStatsForLevel(uint32 petlevel) //Determine pet type PetType petType = MAX_PET_TYPE; - if(HasUnitTypeMask(UNIT_MASK_PET) && m_owner->GetTypeId() == TYPEID_PLAYER) + if(isPet() && m_owner->GetTypeId() == TYPEID_PLAYER) { if(m_owner->getClass() == CLASS_WARLOCK) petType = SUMMON_PET; diff --git a/src/game/PointMovementGenerator.cpp b/src/game/PointMovementGenerator.cpp index 3452c0a3b4d..ac5a4568480 100644 --- a/src/game/PointMovementGenerator.cpp +++ b/src/game/PointMovementGenerator.cpp @@ -79,6 +79,8 @@ void PointMovementGenerator<T>::MovementInform(T &unit) template <> void PointMovementGenerator<Creature>::MovementInform(Creature &unit) { + if(id == EVENT_FALL_GROUND) + unit.setDeathState(JUST_DIED); unit.AI()->MovementInform(POINT_MOTION_TYPE, id); } diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 644a5d03d83..11108cedf80 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -2502,6 +2502,7 @@ enum SummonType enum EventId { EVENT_SPELLCLICK = 1001, + EVENT_FALL_GROUND = 1002, }; enum ResponseCodes diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 550b6e25906..132eb5fafb2 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -6154,7 +6154,7 @@ bool Spell::CheckTarget(Unit* target, uint32 eff) case SPELL_AURA_MOD_CHARM: case SPELL_AURA_MOD_POSSESS_PET: case SPELL_AURA_AOE_CHARM: - if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->IsVehicle()) + if(target->GetTypeId() == TYPEID_UNIT && target->IsVehicle()) return false; if(target->GetCharmerGUID()) return false; diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index ffb7260d2f1..4f1195d001c 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -3488,6 +3488,7 @@ void Spell::EffectSummonType(uint32 i) { summon->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, m_originalCaster->GetGUID()); summon->setFaction(m_originalCaster->getFaction()); + summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); } } break; diff --git a/src/game/TemporarySummon.cpp b/src/game/TemporarySummon.cpp index 75d34ed2f3b..da039c2276c 100644 --- a/src/game/TemporarySummon.cpp +++ b/src/game/TemporarySummon.cpp @@ -298,6 +298,11 @@ void Minion::RemoveFromWorld() TempSummon::RemoveFromWorld(); } +bool Minion::IsGuardianPet() const +{ + return isPet() || m_Properties && m_Properties->Category == SUMMON_CATEGORY_PET; +} + Guardian::Guardian(SummonPropertiesEntry const *properties, Unit *owner) : Minion(properties, owner) , m_bonusdamage(0) { diff --git a/src/game/TemporarySummon.h b/src/game/TemporarySummon.h index 3fd960fc4e3..e67a5573ce2 100644 --- a/src/game/TemporarySummon.h +++ b/src/game/TemporarySummon.h @@ -38,7 +38,7 @@ class TRINITY_DLL_SPEC TempSummon : public Creature Unit* GetSummoner() const; uint64 const& GetSummonerGUID() { return m_summonerGUID; } - SummonPropertiesEntry const *m_Properties; + const SummonPropertiesEntry * const m_Properties; private: TempSummonType m_type; uint32 m_timer; @@ -56,6 +56,7 @@ class Minion : public TempSummon float GetFollowAngle() const { return m_followAngle; } void SetFollowAngle(float angle) { m_followAngle = angle; } bool IsPetGhoul() const {return GetEntry() == 26125;} // Ghoul may be guardian or pet + bool IsGuardianPet() const; protected: Unit * const m_owner; float m_followAngle; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index c1981a05df0..5fb41cf147c 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -8589,7 +8589,7 @@ Guardian* Unit::GetGuardianPet() const if(pet->HasUnitTypeMask(UNIT_MASK_GUARDIAN)) return (Guardian*)pet; - sLog.outError("Unit::GetGuardianPet: Guardian %u not exist.",GUID_LOPART(pet_guid)); + sLog.outCrash("Unit::GetGuardianPet: Guardian " I64FMT " not exist.", pet_guid); const_cast<Unit*>(this)->SetPetGUID(0); } @@ -8631,7 +8631,7 @@ void Unit::SetMinion(Minion *minion, bool apply) } // Can only have one pet. If a new one is summoned, dismiss the old one. - if(minion->isPet() || minion->m_Properties && minion->m_Properties->Category == SUMMON_CATEGORY_PET) + if(minion->IsGuardianPet()) { if(Guardian* oldPet = GetGuardianPet()) { @@ -8653,7 +8653,7 @@ void Unit::SetMinion(Minion *minion, bool apply) } } - if(minion->HasUnitTypeMask(UNIT_MASK_GUARDIAN)) + if(minion->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN)) { if(AddUInt64Value(UNIT_FIELD_SUMMON, minion->GetGUID())) { @@ -8666,7 +8666,7 @@ void Unit::SetMinion(Minion *minion, bool apply) minion->SetByteValue(UNIT_FIELD_BYTES_2, 1, GetByteValue(UNIT_FIELD_BYTES_2, 1)); // FIXME: hack, speed must be set only at follow - if(GetTypeId() == TYPEID_PLAYER && minion->HasUnitTypeMask(UNIT_MASK_PET)) + if(GetTypeId() == TYPEID_PLAYER && minion->isPet()) for(uint8 i = 0; i < MAX_MOVE_TYPE; ++i) minion->SetSpeed(UnitMoveType(i), m_speed_rate[i], true); @@ -8696,11 +8696,9 @@ void Unit::SetMinion(Minion *minion, bool apply) m_Controlled.erase(minion); - if(minion->isPet() || minion->m_Properties && minion->m_Properties->Category == SUMMON_CATEGORY_PET) - { + if(minion->IsGuardianPet()) if(GetPetGUID() == minion->GetGUID()) SetPetGUID(0); - } if (GetTypeId() == TYPEID_PLAYER) { @@ -8733,15 +8731,15 @@ void Unit::SetMinion(Minion *minion, bool apply) } assert((*itr)->GetTypeId() == TYPEID_UNIT); - if(!((Creature*)(*itr))->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN)) + if(!(*itr)->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN)) continue; if(AddUInt64Value(UNIT_FIELD_SUMMON, (*itr)->GetGUID())) { //show another pet bar if there is no charm bar - if(GetTypeId() == TYPEID_PLAYER && !GetCharmGUID() && ((Creature*)(*itr))->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN)) + if(GetTypeId() == TYPEID_PLAYER && !GetCharmGUID()) { - if(((Creature*)(*itr))->isPet()) + if((*itr)->isPet()) ((Player*)this)->PetSpellInitialize(); else ((Player*)this)->CharmSpellInitialize(); @@ -8930,9 +8928,7 @@ void Unit::RemoveAllControlled() { target->RemoveCharmAuras(); } - else if(target->GetOwnerGUID() == GetGUID() - && target->GetTypeId() == TYPEID_UNIT - && ((Creature*)target)->HasUnitTypeMask(UNIT_MASK_SUMMON)) + else if(target->GetOwnerGUID() == GetGUID() && target->isSummon()) { ((TempSummon*)target)->UnSummon(); } @@ -12225,6 +12221,15 @@ void Unit::RemoveFromWorld() assert(false); } + if(Unit *owner = GetOwner()) + { + if(owner->m_Controlled.find(this) != owner->m_Controlled.end()) + { + sLog.outCrash("Unit %u is in controlled list of %u when removed from world", GetEntry(), owner->GetEntry()); + assert(false); + } + } + WorldObject::RemoveFromWorld(); } } @@ -14084,17 +14089,26 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type) sLog.outDebug("SetCharmedBy: charmer %u, charmed %u, type %u.", charmer->GetEntry(), GetEntry(), (uint32)type); if(this == charmer) + { + sLog.outCrash("Unit::SetCharmedBy: Unit %u is trying to charm itself!", GetEntry()); return false; + } //if(hasUnitState(UNIT_STAT_UNATTACKABLE)) // return false; if(GetTypeId() == TYPEID_PLAYER && ((Player*)this)->GetTransport()) + { + sLog.outCrash("Unit::SetCharmedBy: Player on transport is trying to charm %u", GetEntry()); return false; + } // Already charmed if(GetCharmerGUID()) + { + sLog.outCrash("Unit::SetCharmedBy: %u has already been charmed but %u is trying to charm it!", GetEntry(), charmer->GetEntry()); return false; + } CastStop(); CombatStop(); //TODO: CombatStop(true) may cause crash (interrupt spells) @@ -14116,7 +14130,10 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type) // StopCastingCharm may remove a possessed pet? if(!IsInWorld()) + { + sLog.outCrash("Unit::SetCharmedBy: %u is not in world but %u is trying to charm it!", GetEntry(), charmer->GetEntry()); return false; + } // Set charmed setFaction(charmer->getFaction()); diff --git a/src/game/Vehicle.cpp b/src/game/Vehicle.cpp index 7df2da734cc..4df462f57f4 100644 --- a/src/game/Vehicle.cpp +++ b/src/game/Vehicle.cpp @@ -44,6 +44,8 @@ Vehicle::Vehicle(Unit *unit, VehicleEntry const *vehInfo) : me(unit), m_vehicleI Vehicle::~Vehicle() { + for(SeatMap::const_iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr) + assert(!itr->second.passenger); } void Vehicle::Install() @@ -198,7 +200,7 @@ void Vehicle::InstallAccessory(uint32 entry, int8 seatId) passenger->ExitVehicle(); // this should not happen } - Creature *accessory = me->SummonCreature(entry, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, 0); + Creature *accessory = me->SummonCreature(entry, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); if(!accessory) return; accessory->AddUnitTypeMask(UNIT_MASK_ACCESSORY); |