diff options
author | megamage <none@none> | 2009-03-21 09:48:44 -0600 |
---|---|---|
committer | megamage <none@none> | 2009-03-21 09:48:44 -0600 |
commit | a84e757793e6310c84af8b05f9b27f1ee5abd188 (patch) | |
tree | 1605f4fd9a6122c826048c1abc2220dcae68a788 /src/game | |
parent | 55695eda786667a34d6c0ae59496d787dfba4b3e (diff) |
*Update summon system. Show pet bar for guardians. Allow multiple charms/guardians.
--HG--
branch : trunk
Diffstat (limited to 'src/game')
-rw-r--r-- | src/game/Level2.cpp | 4 | ||||
-rw-r--r-- | src/game/Object.cpp | 33 | ||||
-rw-r--r-- | src/game/Pet.cpp | 6 | ||||
-rw-r--r-- | src/game/Player.cpp | 21 | ||||
-rw-r--r-- | src/game/Player.h | 2 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 2 | ||||
-rw-r--r-- | src/game/TemporarySummon.cpp | 61 | ||||
-rw-r--r-- | src/game/TemporarySummon.h | 5 | ||||
-rw-r--r-- | src/game/Unit.cpp | 145 | ||||
-rw-r--r-- | src/game/Unit.h | 14 |
10 files changed, 162 insertions, 131 deletions
diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 342d4e85234..ba7092ec72f 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -1845,7 +1845,7 @@ bool ChatHandler::HandleNpcTameCommand(const char* /*args*/) pet->SetUInt32Value(UNIT_FIELD_LEVEL, level); // caster have pet now - player->SetPet(pet); + player->SetPet(pet, true); pet->SavePetToDB(PET_SAVE_AS_CURRENT); player->PetSpellInitialize(); @@ -4375,7 +4375,7 @@ bool ChatHandler::HandleCreatePetCommand(const char* args) // visual effect for levelup pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()); - player->SetPet(pet); + player->SetPet(pet, true); pet->SavePetToDB(PET_SAVE_AS_CURRENT); player->PetSpellInitialize(); diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 770c2d14899..63ad7de7c75 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1595,8 +1595,6 @@ TempSummon *Map::SummonCreature(uint32 entry, float x, float y, float z, float a mask = SUMMON_MASK_VEHICLE; } - TempSummon *summon = NULL; - bool ok = true; uint32 phase = PHASEMASK_NORMAL, team = 0; if(summoner) { @@ -1605,27 +1603,15 @@ TempSummon *Map::SummonCreature(uint32 entry, float x, float y, float z, float a team = ((Player*)summoner)->GetTeam(); } + TempSummon *summon = NULL; switch(mask) { - case SUMMON_MASK_SUMMON: - summon = new TempSummon(properties, summoner); - ok = summon->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), this, phase, entry, team); - break; - case SUMMON_MASK_GUARDIAN: - summon = new Guardian(properties, summoner); - team = objmgr.GeneratePetNumber(); - ok = summon->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), this, phase, entry, team); - // this enables pet details window (Shift+P) - summon->GetCharmInfo()->SetPetNumber(team, false); - break; - case SUMMON_MASK_TOTEM: - summon = new Totem(properties, summoner); - ok = summon->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), this, phase, entry, team); - break; - default: - return NULL; + case SUMMON_MASK_SUMMON: summon = new TempSummon (properties, summoner); break; + case SUMMON_MASK_GUARDIAN: summon = new Guardian (properties, summoner); break; + case SUMMON_MASK_TOTEM: summon = new Totem (properties, summoner); break; + default: return NULL; } - if(!ok) + if(!summon->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), this, phase, entry, team)) { delete summon; return NULL; @@ -1639,9 +1625,8 @@ TempSummon *Map::SummonCreature(uint32 entry, float x, float y, float z, float a return NULL; } - summon->InitSummon(duration); - Add((Creature*)summon); + summon->InitSummon(duration); return summon; } @@ -1779,11 +1764,12 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy pet->SetUInt32Value(UNIT_FIELD_BYTES_1,0); pet->InitStatsForLevel(getLevel()); + SetPet(pet, true); + switch(petType) { case POSSESSED_PET: pet->SetUInt32Value(UNIT_FIELD_FLAGS,0); - AddGuardian(pet); break; case SUMMON_PET: pet->SetUInt32Value(UNIT_FIELD_BYTES_0, 2048); @@ -1793,7 +1779,6 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy pet->SetPower(POWER_MANA, pet->GetMaxPower(POWER_MANA)); pet->InitPetCreateSpells(); pet->SavePetToDB(PET_SAVE_AS_CURRENT); - SetPet(pet); PetSpellInitialize(); break; } diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index af3725c626c..c21a0e0eb35 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -304,7 +304,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool _LoadSpells(); _LoadSpellCooldowns(); - owner->SetPet(this); // in DB stored only full controlled creature + owner->SetPet(this, true); // in DB stored only full controlled creature sLog.outDebug("New Pet has guid %u", GetGUIDLow()); if(owner->GetTypeId() == TYPEID_PLAYER) @@ -646,9 +646,7 @@ void Pet::Remove(PetSaveMode mode, bool returnreagent) return; } - // only if current pet in slot - if(owner->GetPetGUID()==GetGUID()) - owner->SetPet(0); + owner->SetPet(this, false); } CleanupsBeforeDelete(); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 4373ae2098a..20957614089 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -14581,7 +14581,6 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) //Need to call it to initialize m_team (m_team can be calculated from m_race) //Other way is to saves m_team into characters table. setFactionForRace(m_race); - SetCharm(0); SetMover(this); m_class = fields[5].GetUInt8(); @@ -14896,9 +14895,8 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) SetUInt32Value(UNIT_CHANNEL_SPELL,0); // clear charm/summon related fields - SetCharm(NULL); - SetMover(this); - SetPet(NULL); + SetUInt64Value(UNIT_FIELD_CHARM, 0); + SetUInt64Value(UNIT_FIELD_SUMMON, 0); SetCharmerGUID(0); SetOwnerGUID(0); SetCreatorGUID(0); @@ -17048,12 +17046,9 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent) switch(pet->getPetType()) { case POSSESSED_PET: - m_Guardians.erase(pet->GetGUID()); pet->RemoveCharmedOrPossessedBy(NULL); - break; default: - if(GetPetGUID() == pet->GetGUID()) - SetPet(NULL); + SetPet(pet, false); break; } @@ -17191,6 +17186,7 @@ void Player::Whisper(const std::string& text, uint32 language,uint64 receiver) void Player::PetSpellInitialize() { + return; Pet* pet = GetPet(); if(!pet) @@ -17346,9 +17342,7 @@ void Player::VehicleSpellInitialize() void Player::CharmSpellInitialize() { - Unit* charm = GetCharm(); - if(!charm && GetPetGUID()) - charm = GetUnit(*this, GetPetGUID()); + Unit* charm = GetFirstControlled(); if(!charm) return; @@ -17411,6 +17405,7 @@ void Player::CharmSpellInitialize() data << uint8(count); // cooldowns count data.hexlike(); + GetSession()->SendPacket(&data); } @@ -20275,7 +20270,7 @@ void Player::EnterVehicle(Vehicle *vehicle) vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24); vehicle->setFaction(getFaction()); - SetCharm(vehicle); // charm + SetCharm(vehicle, true); // charm SetMover(vehicle); SetClientControl(vehicle, 1); // redirect controls to vehicle @@ -20315,7 +20310,7 @@ void Player::ExitVehicle(Vehicle *vehicle) vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24); vehicle->setFaction((GetTeam() == ALLIANCE) ? vehicle->GetCreatureInfo()->faction_A : vehicle->GetCreatureInfo()->faction_H); - SetCharm(NULL); + SetCharm(vehicle, false); SetMover(this); SetClientControl(vehicle, 0); diff --git a/src/game/Player.h b/src/game/Player.h index 5c821134c86..3649b04d4ca 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -877,7 +877,7 @@ struct AccessRequirement std::string questFailedText; uint32 heroicQuest; std::string heroicQuestFailedText; - }; +}; class TRINITY_DLL_SPEC PlayerTaxi { diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index d6995420d40..97a5418c3e1 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -4043,7 +4043,7 @@ void Spell::EffectTameCreature(uint32 /*i*/) pet->SetUInt32Value(UNIT_FIELD_LEVEL, level); // caster have pet now - m_caster->SetPet(pet); + m_caster->SetPet(pet, true); if(m_caster->GetTypeId() == TYPEID_PLAYER) { diff --git a/src/game/TemporarySummon.cpp b/src/game/TemporarySummon.cpp index 408c4e3ba4a..76c7ecfb8c1 100644 --- a/src/game/TemporarySummon.cpp +++ b/src/game/TemporarySummon.cpp @@ -199,14 +199,23 @@ void TempSummon::SetTempSummonType(TempSummonType type) void TempSummon::UnSummon() { Unit* owner = GetSummoner(); - if(owner) - { - if(owner->GetTypeId() == TYPEID_UNIT && ((Creature*)owner)->IsAIEnabled) - ((Creature*)owner)->AI()->SummonedCreatureDespawn(this); + if(owner && owner->GetTypeId() == TYPEID_UNIT && ((Creature*)owner)->IsAIEnabled) + ((Creature*)owner)->AI()->SummonedCreatureDespawn(this); + + CleanupsBeforeDelete(); + AddObjectToRemoveList(); +} - if(m_Properties) +void TempSummon::RemoveFromWorld() +{ + if(!IsInWorld()) + return; + + if(m_Properties) + { + if(uint32 slot = m_Properties->Slot) { - if(uint32 slot = m_Properties->Slot) + if(Unit* owner = GetSummoner()) { --slot; if(owner->m_TotemSlot[slot] = GetGUID()) @@ -214,9 +223,7 @@ void TempSummon::UnSummon() } } } - - CleanupsBeforeDelete(); - AddObjectToRemoveList(); + Creature::RemoveFromWorld(); } void TempSummon::SaveToDB() @@ -230,43 +237,20 @@ Guardian::Guardian(SummonPropertiesEntry const *properties, Unit *owner) : TempS InitCharmInfo(); } -bool Guardian::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 pet_number) -{ - SetMapId(map->GetId()); - SetInstanceId(map->GetInstanceId()); - SetPhaseMask(phaseMask,false); - - Object::_Create(guidlow, pet_number, HIGHGUID_PET); - - m_DBTableGuid = guidlow; - m_originalEntry = Entry; - - if(!InitEntry(Entry)) - return false; - - SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE); - - return true; -} - void Guardian::InitSummon(uint32 duration) { TempSummon::InitSummon(duration); SetReactState(REACT_AGGRESSIVE); - SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, 0); SetOwnerGUID(m_owner->GetGUID()); SetCreatorGUID(m_owner->GetGUID()); - SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, m_owner->getFaction()); - m_owner->AddGuardian(this); - SetUInt32Value(UNIT_FIELD_BYTES_0, 2048); + setFaction(m_owner->getFaction()); + m_owner->SetPet(this, true); if(m_owner->GetTypeId() == TYPEID_PLAYER) { - m_owner->SetUInt64Value(UNIT_FIELD_SUMMON, GetGUID()); m_charmInfo->InitCharmCreateSpells(); - //charmInfo->SetPetNumber(objmgr.GeneratePetNumber(), true); ((Player*)m_owner)->CharmSpellInitialize(); } } @@ -305,9 +289,12 @@ void Guardian::InitStatsForLevel(uint32 petlevel) } } -void Guardian::UnSummon() +void Guardian::RemoveFromWorld() { - m_owner->m_Guardians.erase(GetGUID()); - TempSummon::UnSummon(); + if(!IsInWorld()) + return; + + m_owner->SetPet(this, false); + TempSummon::RemoveFromWorld(); } diff --git a/src/game/TemporarySummon.h b/src/game/TemporarySummon.h index bec5e36f546..0fb999f3496 100644 --- a/src/game/TemporarySummon.h +++ b/src/game/TemporarySummon.h @@ -31,7 +31,8 @@ class TempSummon : public Creature virtual ~TempSummon(){}; void Update(uint32 time); virtual void InitSummon(uint32 lifetime); - virtual void UnSummon(); + void UnSummon(); + void RemoveFromWorld(); void SetTempSummonType(TempSummonType type); void SaveToDB(); Unit* GetSummoner() const { return m_summonerGUID ? ObjectAccessor::GetUnit(*this, m_summonerGUID) : NULL; } @@ -50,7 +51,7 @@ class Guardian : public TempSummon Guardian(SummonPropertiesEntry const *properties, Unit *owner); bool Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 pet_number); void InitSummon(uint32 duration); - void UnSummon(); + void RemoveFromWorld(); void InitStatsForLevel(uint32 level); protected: Unit *m_owner; 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) diff --git a/src/game/Unit.h b/src/game/Unit.h index ff2826c3b44..98b30e75d31 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -842,7 +842,7 @@ struct AuraSlotEntry struct SpellProcEventEntry; // used only privately -typedef std::set<uint64> GuardianList; +typedef std::set<Unit*> ControlList; class TRINITY_DLL_SPEC Unit : public WorldObject { @@ -1200,13 +1200,17 @@ class TRINITY_DLL_SPEC Unit : public WorldObject } Player* GetCharmerOrOwnerPlayerOrPlayerItself() const; - void SetPet(Pet* pet); - void SetCharm(Unit* pet); + void SetPet(Creature* target, bool apply); + void SetCharm(Unit* target, bool apply); Unit* GetNextRandomRaidMemberOrPet(float radius); void SetCharmedOrPossessedBy(Unit* charmer, bool possess); void RemoveCharmedOrPossessedBy(Unit* charmer); void RestoreFaction(); + ControlList m_Controlled; + Unit* GetFirstControlled() const; + void RemoveAllControlled(); + bool isCharmed() const { return GetCharmerGUID() != 0; } bool isPossessed() const { return hasUnitState(UNIT_STAT_POSSESSED); } bool isPossessedByPlayer() const { return hasUnitState(UNIT_STAT_POSSESSED) && IS_PLAYER_GUID(GetCharmerGUID()); } @@ -1310,10 +1314,6 @@ class TRINITY_DLL_SPEC Unit : public WorldObject uint32 m_detectInvisibilityMask; uint32 m_invisibilityMask; - GuardianList m_Guardians; - void RemoveGuardians(); - void AddGuardian(Unit* pet) { m_Guardians.insert(pet->GetGUID()); } - uint32 m_ShapeShiftFormSpellId; ShapeshiftForm m_form; bool IsInFeralForm() const { return m_form == FORM_CAT || m_form == FORM_BEAR || m_form == FORM_DIREBEAR; } |