diff options
author | ariel- <ariel-@users.noreply.github.com> | 2018-01-22 01:54:15 -0300 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2021-06-16 19:26:32 +0200 |
commit | 861cf261c5dfc29d6980908ec36ebe7aad68a462 (patch) | |
tree | 07114f8f4c1d972834a49319459e948324a633f9 /src | |
parent | 0c56ec914f5f6b55251a7a8889b61ef93d56c924 (diff) |
Core/Formations: update codestyle and fix crash
Closes #21288
(cherry picked from commit 73cc613dc86d7d72d78f22affe2faba6786bccc5)
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartAI.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 26 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/CreatureGroups.cpp | 245 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/CreatureGroups.h | 49 | ||||
-rw-r--r-- | src/server/game/Maps/Map.h | 4 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_npc.cpp | 21 | ||||
-rw-r--r-- | src/server/scripts/EasternKingdoms/zone_goldshire.cpp | 2 | ||||
-rw-r--r-- | src/server/scripts/Maelstrom/Stonecore/instance_stonecore.cpp | 2 |
8 files changed, 207 insertions, 146 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index 5769ea307ca..a90dc7e1b6b 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -548,14 +548,14 @@ void SmartAI::JustReachedHome() GetScript()->ProcessEventsFor(SMART_EVENT_REACHED_HOME); CreatureGroup* formation = me->GetFormation(); - if (!formation || formation->getLeader() == me || !formation->isFormed()) + if (!formation || formation->GetLeader() == me || !formation->IsFormed()) { if (me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_IDLE) != WAYPOINT_MOTION_TYPE && me->GetWaypointPath()) me->GetMotionMaster()->MovePath(me->GetWaypointPath(), true); else me->ResumeMovement(); } - else if (formation->isFormed()) + else if (formation->IsFormed()) me->GetMotionMaster()->MoveIdle(); // wait the order of leader } diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 04752e739d1..8261a795915 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -374,9 +374,8 @@ void Creature::SearchFormation() if (!lowguid) return; - CreatureGroupInfoType::iterator frmdata = sFormationMgr->CreatureGroupMap.find(lowguid); - if (frmdata != sFormationMgr->CreatureGroupMap.end()) - sFormationMgr->AddCreatureToGroup(frmdata->second->leaderGUID, this); + if (FormationInfo const* formationInfo = sFormationMgr->GetFormationInfo(lowguid)) + sFormationMgr->AddCreatureToGroup(formationInfo->LeaderSpawnId, this); } bool Creature::IsFormationLeader() const @@ -1066,17 +1065,18 @@ bool Creature::AIM_Initialize(CreatureAI* ai) void Creature::Motion_Initialize() { - if (!m_formation) - GetMotionMaster()->Initialize(); - else if (m_formation->getLeader() == this) + if (m_formation) { - m_formation->FormationReset(false); - GetMotionMaster()->Initialize(); + if (m_formation->GetLeader() == this) + m_formation->FormationReset(false); + else if (m_formation->IsFormed()) + { + GetMotionMaster()->MoveIdle(); //wait the order of leader + return; + } } - else if (m_formation->isFormed()) - GetMotionMaster()->MoveIdle(); //wait the order of leader - else - GetMotionMaster()->Initialize(); + + GetMotionMaster()->Initialize(); } bool Creature::Create(ObjectGuid::LowType guidlow, Map* map, uint32 entry, Position const& pos, CreatureData const* data /*= nullptr*/, uint32 vehId /*= 0*/, bool dynamic) @@ -2152,7 +2152,7 @@ void Creature::setDeathState(DeathState s) } //Dismiss group if is leader - if (m_formation && m_formation->getLeader() == this) + if (m_formation && m_formation->GetLeader() == this) m_formation->FormationReset(true); if ((CanFly() || IsFlying())) diff --git a/src/server/game/Entities/Creature/CreatureGroups.cpp b/src/server/game/Entities/Creature/CreatureGroups.cpp index 3f6cbd9279c..8e285f3e931 100644 --- a/src/server/game/Entities/Creature/CreatureGroups.cpp +++ b/src/server/game/Entities/Creature/CreatureGroups.cpp @@ -16,6 +16,7 @@ */ #include "CreatureGroups.h" +#include "Containers.h" #include "Creature.h" #include "CreatureAI.h" #include "DatabaseEnv.h" @@ -26,10 +27,12 @@ #define MAX_DESYNC 5.0f +FormationMgr::FormationMgr() +{ +} + FormationMgr::~FormationMgr() { - for (CreatureGroupInfoType::iterator itr = CreatureGroupMap.begin(); itr != CreatureGroupMap.end(); ++itr) - delete itr->second; } FormationMgr* FormationMgr::instance() @@ -38,43 +41,53 @@ FormationMgr* FormationMgr::instance() return &instance; } -void FormationMgr::AddCreatureToGroup(ObjectGuid::LowType leaderGuid, Creature* creature) +void FormationMgr::AddCreatureToGroup(ObjectGuid::LowType leaderSpawnId, Creature* creature) { - Map* map = creature->FindMap(); - if (!map) - return; + Map* map = creature->GetMap(); - CreatureGroupHolderType::iterator itr = map->CreatureGroupHolder.find(leaderGuid); - - //Add member to an existing group + auto itr = map->CreatureGroupHolder.find(leaderSpawnId); if (itr != map->CreatureGroupHolder.end()) { - TC_LOG_DEBUG("entities.unit", "Group found: " UI64FMTD ", inserting %s, Group InstanceID %u", leaderGuid, creature->GetGUID().ToString().c_str(), creature->GetInstanceId()); - itr->second->AddMember(creature); + //Add member to an existing group + TC_LOG_DEBUG("entities.unit", "Group found: " UI64FMTD ", inserting: %s, Group InstanceID %u", leaderSpawnId, creature->GetGUID().ToString().c_str(), creature->GetInstanceId()); + + // With dynamic spawn the creature may have just respawned + // we need to find previous instance of creature and delete it from the formation, as it'll be invalidated + auto bounds = Trinity::Containers::MapEqualRange(map->GetCreatureBySpawnIdStore(), creature->GetSpawnId()); + for (auto const& pair : bounds) + { + Creature* other = pair.second; + if (other == creature) + continue; + + if (itr->second->HasMember(other)) + itr->second->RemoveMember(other); + } } - //Create new group else { - TC_LOG_DEBUG("entities.unit", "Group not found: " UI64FMTD ". Creating new group.", leaderGuid); - CreatureGroup* group = new CreatureGroup(leaderGuid); - map->CreatureGroupHolder[leaderGuid] = group; - group->AddMember(creature); + //Create new group + TC_LOG_DEBUG("entities.unit", "Group not found: " UI64FMTD ". Creating new group.", leaderSpawnId); + CreatureGroup* group = new CreatureGroup(leaderSpawnId); + std::tie(itr, std::ignore) = map->CreatureGroupHolder.emplace(leaderSpawnId, group); } + + itr->second->AddMember(creature); } void FormationMgr::RemoveCreatureFromGroup(CreatureGroup* group, Creature* member) { - TC_LOG_DEBUG("entities.unit", "Deleting member pointer to GUID: " UI64FMTD " from group " UI64FMTD, group->GetId(), member->GetSpawnId()); + TC_LOG_DEBUG("entities.unit", "Deleting member pointer to GUID: " UI64FMTD " from group " UI64FMTD, group->GetLeaderSpawnId(), member->GetSpawnId()); group->RemoveMember(member); - if (group->isEmpty()) + if (group->IsEmpty()) { - Map* map = member->FindMap(); - if (!map) - return; + Map* map = member->GetMap(); TC_LOG_DEBUG("entities.unit", "Deleting group with InstanceID %u", member->GetInstanceId()); - map->CreatureGroupHolder.erase(group->GetId()); + auto itr = map->CreatureGroupHolder.find(group->GetLeaderSpawnId()); + ASSERT(itr != map->CreatureGroupHolder.end(), "Not registered group " UI64FMTD " in map %u", group->GetLeaderSpawnId(), map->GetId()); + map->CreatureGroupHolder.erase(itr); delete group; } } @@ -83,13 +96,8 @@ void FormationMgr::LoadCreatureFormations() { uint32 oldMSTime = getMSTime(); - for (CreatureGroupInfoType::iterator itr = CreatureGroupMap.begin(); itr != CreatureGroupMap.end(); ++itr) // for reload case - delete itr->second; - CreatureGroupMap.clear(); - //Get group data QueryResult result = WorldDatabase.Query("SELECT leaderGUID, memberGUID, dist, angle, groupAI, point_1, point_2 FROM creature_formations ORDER BY leaderGUID"); - if (!result) { TC_LOG_INFO("server.loading", ">> Loaded 0 creatures in formations. DB table `creature_formations` is empty!"); @@ -97,88 +105,134 @@ void FormationMgr::LoadCreatureFormations() } uint32 count = 0; - Field* fields; - FormationInfo* group_member; - + std::unordered_set<ObjectGuid::LowType> leaderSpawnIds; do { - fields = result->Fetch(); + Field* fields = result->Fetch(); //Load group member data - group_member = new FormationInfo(); - group_member->leaderGUID = fields[0].GetUInt64(); - ObjectGuid::LowType memberGUID = fields[1].GetUInt64(); - group_member->groupAI = fields[4].GetUInt32(); - group_member->point_1 = fields[5].GetUInt16(); - group_member->point_2 = fields[6].GetUInt16(); + FormationInfo member; + member.LeaderSpawnId = fields[0].GetUInt64(); + ObjectGuid::LowType memberSpawnId = fields[1].GetUInt64(); + member.FollowDist = 0.f; + member.FollowAngle = 0.f; + //If creature is group leader we may skip loading of dist/angle - if (group_member->leaderGUID != memberGUID) + if (member.LeaderSpawnId != memberSpawnId) { - group_member->follow_dist = fields[2].GetFloat(); - group_member->follow_angle = fields[3].GetFloat() * float(M_PI) / 180; - } - else - { - group_member->follow_dist = 0; - group_member->follow_angle = 0; + member.FollowDist = fields[2].GetFloat(); + member.FollowAngle = fields[3].GetFloat() * float(M_PI) / 180.0f; } + member.GroupAI = fields[4].GetUInt32(); + for (uint8 i = 0; i < 2; ++i) + member.LeaderWaypointIDs[i] = fields[5 + i].GetUInt16(); + // check data correctness { - if (!sObjectMgr->GetCreatureData(group_member->leaderGUID)) + if (!sObjectMgr->GetCreatureData(member.LeaderSpawnId)) { - TC_LOG_ERROR("sql.sql", "creature_formations table leader guid " UI64FMTD " incorrect (not exist)", group_member->leaderGUID); - delete group_member; + TC_LOG_ERROR("sql.sql", "creature_formations table leader guid " UI64FMTD " incorrect (not exist)", member.LeaderSpawnId); continue; } - if (!sObjectMgr->GetCreatureData(memberGUID)) + if (!sObjectMgr->GetCreatureData(memberSpawnId)) { - TC_LOG_ERROR("sql.sql", "creature_formations table member guid " UI64FMTD " incorrect (not exist)", memberGUID); - delete group_member; + TC_LOG_ERROR("sql.sql", "creature_formations table member guid " UI64FMTD " incorrect (not exist)", memberSpawnId); continue; } + + leaderSpawnIds.insert(member.LeaderSpawnId); } - CreatureGroupMap[memberGUID] = group_member; + _creatureGroupMap.emplace(memberSpawnId, std::move(member)); ++count; + } while (result->NextRow()); + + for (ObjectGuid::LowType leaderSpawnId : leaderSpawnIds) + { + if (!_creatureGroupMap.count(leaderSpawnId)) + { + TC_LOG_ERROR("sql.sql", "creature_formation contains leader spawn " UI64FMTD " which is not included on its formation, removing", leaderSpawnId); + for (auto itr = _creatureGroupMap.begin(); itr != _creatureGroupMap.end();) + { + if (itr->second.LeaderSpawnId == leaderSpawnId) + { + itr = _creatureGroupMap.erase(itr); + continue; + } + + ++itr; + } + } } - while (result->NextRow()); TC_LOG_INFO("server.loading", ">> Loaded %u creatures in formations in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } +FormationInfo* FormationMgr::GetFormationInfo(ObjectGuid::LowType spawnId) +{ + return Trinity::Containers::MapGetValuePtr(_creatureGroupMap, spawnId); +} + +void FormationMgr::AddFormationMember(ObjectGuid::LowType spawnId, float followAng, float followDist, ObjectGuid::LowType leaderSpawnId, uint32 groupAI) +{ + FormationInfo member; + member.LeaderSpawnId = leaderSpawnId; + member.FollowDist = followDist; + member.FollowAngle = followAng; + member.GroupAI = groupAI; + for (uint8 i = 0; i < 2; ++i) + member.LeaderWaypointIDs[i] = 0; + + _creatureGroupMap.emplace(spawnId, std::move(member)); +} + +CreatureGroup::CreatureGroup(ObjectGuid::LowType leaderSpawnId) : _leader(nullptr), _members(), _leaderSpawnId(leaderSpawnId), _formed(false), _engaging(false) +{ +} + +CreatureGroup::~CreatureGroup() +{ +} + void CreatureGroup::AddMember(Creature* member) { TC_LOG_DEBUG("entities.unit", "CreatureGroup::AddMember: Adding %s.", member->GetGUID().ToString().c_str()); //Check if it is a leader - if (member->GetSpawnId() == m_groupID) + if (member->GetSpawnId() == _leaderSpawnId) { TC_LOG_DEBUG("entities.unit", "%s is formation leader. Adding group.", member->GetGUID().ToString().c_str()); - m_leader = member; + _leader = member; } - m_members[member] = sFormationMgr->CreatureGroupMap.find(member->GetSpawnId())->second; + // formation must be registered at this point + FormationInfo* formationInfo = ASSERT_NOTNULL(sFormationMgr->GetFormationInfo(member->GetSpawnId())); + _members.emplace(member, formationInfo); member->SetFormation(this); } void CreatureGroup::RemoveMember(Creature* member) { - if (m_leader == member) - m_leader = nullptr; + if (_leader == member) + _leader = nullptr; - m_members.erase(member); + _members.erase(member); member->SetFormation(nullptr); } void CreatureGroup::MemberEngagingTarget(Creature* member, Unit* target) { - uint8 groupAI = sFormationMgr->CreatureGroupMap[member->GetSpawnId()]->groupAI; + // used to prevent recursive calls + if (_engaging) + return; + + uint8 groupAI = ASSERT_NOTNULL(sFormationMgr->GetFormationInfo(member->GetSpawnId()))->GroupAI; if (!groupAI) return; - if (member == m_leader) + if (member == _leader) { if (!(groupAI & FLAG_MEMBERS_ASSIST_LEADER)) return; @@ -186,64 +240,75 @@ void CreatureGroup::MemberEngagingTarget(Creature* member, Unit* target) else if (!(groupAI & FLAG_LEADER_ASSISTS_MEMBER)) return; - for (CreatureGroupMemberType::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) + _engaging = true; + + for (auto const& pair : _members) { - Creature* other = itr->first; - // Skip self + Creature* other = pair.first; if (other == member) continue; if (!other->IsAlive()) continue; - if (((other != m_leader && (groupAI & FLAG_MEMBERS_ASSIST_LEADER)) || (other == m_leader && (groupAI & FLAG_LEADER_ASSISTS_MEMBER))) && other->IsValidAttackTarget(target)) + if (((other != _leader && (groupAI & FLAG_MEMBERS_ASSIST_LEADER)) || (other == _leader && (groupAI & FLAG_LEADER_ASSISTS_MEMBER))) && other->IsValidAttackTarget(target)) other->EngageWithTarget(target); } + + _engaging = false; } void CreatureGroup::FormationReset(bool dismiss) { - for (CreatureGroupMemberType::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) + for (auto const& pair : _members) { - if (itr->first != m_leader && itr->first->IsAlive()) + if (pair.first != _leader && pair.first->IsAlive()) { if (dismiss) - itr->first->GetMotionMaster()->Initialize(); + pair.first->GetMotionMaster()->Initialize(); else - itr->first->GetMotionMaster()->MoveIdle(); - TC_LOG_DEBUG("entities.unit", "Set %s movement for member %s", dismiss ? "default" : "idle", itr->first->GetGUID().ToString().c_str()); + pair.first->GetMotionMaster()->MoveIdle(); + TC_LOG_DEBUG("entities.unit", "Set %s movement for member: %s", dismiss ? "default" : "idle", pair.first->GetGUID().ToString().c_str()); } } - m_Formed = !dismiss; + + _formed = !dismiss; } void CreatureGroup::LeaderMoveTo(Position const& destination, uint32 id /*= 0*/, uint32 moveType /*= 0*/, bool orientation /*= false*/) { //! To do: This should probably get its own movement generator or use WaypointMovementGenerator. //! If the leader's path is known, member's path can be plotted as well using formation offsets. - if (!m_leader) + if (!_leader) return; - float x = destination.GetPositionX(), y = destination.GetPositionY(), z = destination.GetPositionZ(); - - float pathangle = std::atan2(m_leader->GetPositionY() - y, m_leader->GetPositionX() - x); + Position pos(destination); + float pathangle = std::atan2(_leader->GetPositionY() - pos.GetPositionY(), _leader->GetPositionX() - pos.GetPositionX()); - for (CreatureGroupMemberType::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) + for (auto const& pair : _members) { - Creature* member = itr->first; - if (member == m_leader || !member->IsAlive() || member->GetVictim() || !(itr->second->groupAI & FLAG_IDLE_IN_FORMATION)) + Creature* member = pair.first; + if (member == _leader || !member->IsAlive() || member->IsEngaged() || !(pair.second->GroupAI & FLAG_IDLE_IN_FORMATION)) continue; - if (itr->second->point_1) - if (m_leader->GetCurrentWaypointInfo().first == itr->second->point_1 || m_leader->GetCurrentWaypointInfo().first == itr->second->point_2) - itr->second->follow_angle = float(M_PI) * 2 - itr->second->follow_angle; + if (pair.second->LeaderWaypointIDs[0]) + { + for (uint8 i = 0; i < 2; ++i) + { + if (_leader->GetCurrentWaypointInfo().first == pair.second->LeaderWaypointIDs[i]) + { + pair.second->FollowAngle = float(M_PI) * 2.f - pair.second->FollowAngle; + break; + } + } + } - float angle = itr->second->follow_angle; - float dist = itr->second->follow_dist; + float angle = pair.second->FollowAngle; + float dist = pair.second->FollowDist; - float dx = x + std::cos(angle + pathangle) * dist; - float dy = y + std::sin(angle + pathangle) * dist; - float dz = z; + float dx = pos.GetPositionX() + std::cos(angle + pathangle) * dist; + float dy = pos.GetPositionY() + std::sin(angle + pathangle) * dist; + float dz = pos.GetPositionZ(); Trinity::NormalizeMapCoord(dx); Trinity::NormalizeMapCoord(dy); @@ -253,18 +318,18 @@ void CreatureGroup::LeaderMoveTo(Position const& destination, uint32 id /*= 0*/, Position point(dx, dy, dz, destination.GetOrientation()); - member->GetMotionMaster()->MoveFormation(id, point, moveType, !member->IsWithinDist(m_leader, dist + MAX_DESYNC), orientation); + member->GetMotionMaster()->MoveFormation(id, point, moveType, !member->IsWithinDist(_leader, dist + MAX_DESYNC), orientation); member->SetHomePosition(dx, dy, dz, pathangle); } } bool CreatureGroup::CanLeaderStartMoving() const { - for (auto itr = m_members.begin(); itr != m_members.end(); ++itr) + for (auto const& pair : _members) { - if (itr->first != m_leader && itr->first->IsAlive()) + if (pair.first != _leader && pair.first->IsAlive()) { - if (itr->first->IsEngaged() || itr->first->IsReturningHome()) + if (pair.first->IsEngaged() || pair.first->IsReturningHome()) return false; } } diff --git a/src/server/game/Entities/Creature/CreatureGroups.h b/src/server/game/Entities/Creature/CreatureGroups.h index a5735ca3f88..2b4924774ec 100644 --- a/src/server/game/Entities/Creature/CreatureGroups.h +++ b/src/server/game/Entities/Creature/CreatureGroups.h @@ -39,52 +39,55 @@ struct Position; struct FormationInfo { - ObjectGuid::LowType leaderGUID; - float follow_dist; - float follow_angle; - uint32 groupAI; - uint32 point_1; - uint32 point_2; + ObjectGuid::LowType LeaderSpawnId; + float FollowDist; + float FollowAngle; + uint32 GroupAI; + uint32 LeaderWaypointIDs[2]; }; -typedef std::unordered_map<ObjectGuid::LowType/*memberDBGUID*/, FormationInfo*> CreatureGroupInfoType; - class TC_GAME_API FormationMgr { private: - FormationMgr() { } + FormationMgr(); ~FormationMgr(); + std::unordered_map<ObjectGuid::LowType /*spawnID*/, FormationInfo> _creatureGroupMap; + public: static FormationMgr* instance(); - void AddCreatureToGroup(ObjectGuid::LowType leaderGuid, Creature* creature); + void AddCreatureToGroup(ObjectGuid::LowType leaderSpawnId, Creature* creature); void RemoveCreatureFromGroup(CreatureGroup* group, Creature* creature); + void LoadCreatureFormations(); - CreatureGroupInfoType CreatureGroupMap; + FormationInfo* GetFormationInfo(ObjectGuid::LowType spawnId); + + void AddFormationMember(ObjectGuid::LowType spawnId, float followAng, float followDist, ObjectGuid::LowType leaderSpawnId, uint32 groupAI); }; class TC_GAME_API CreatureGroup { private: - Creature* m_leader; //Important do not forget sometimes to work with pointers instead synonims :D:D - typedef std::map<Creature*, FormationInfo*> CreatureGroupMemberType; - CreatureGroupMemberType m_members; + Creature* _leader; //Important do not forget sometimes to work with pointers instead synonims :D:D + std::unordered_map<Creature*, FormationInfo*> _members; - ObjectGuid::LowType m_groupID; - bool m_Formed; + ObjectGuid::LowType _leaderSpawnId; + bool _formed; + bool _engaging; public: //Group cannot be created empty - explicit CreatureGroup(ObjectGuid::LowType id) : m_leader(nullptr), m_groupID(id), m_Formed(false) { } - ~CreatureGroup() { } + explicit CreatureGroup(ObjectGuid::LowType leaderSpawnId); + ~CreatureGroup(); - Creature* getLeader() const { return m_leader; } - ObjectGuid::LowType GetId() const { return m_groupID; } - bool isEmpty() const { return m_members.empty(); } - bool isFormed() const { return m_Formed; } - bool IsLeader(Creature const* creature) const { return m_leader == creature; } + Creature* GetLeader() const { return _leader; } + ObjectGuid::LowType GetLeaderSpawnId() const { return _leaderSpawnId; } + bool IsEmpty() const { return _members.empty(); } + bool IsFormed() const { return _formed; } + bool IsLeader(Creature const* creature) const { return _leader == creature; } + bool HasMember(Creature* member) const { return _members.count(member) > 0; } void AddMember(Creature* member); void RemoveMember(Creature* member); void FormationReset(bool dismiss); diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 174520be8a0..289fb4180b3 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -210,8 +210,6 @@ struct ZoneDynamicInfo #define MIN_UNLOAD_DELAY 1 // immediate unload #define MAP_INVALID_ZONE 0xFFFFFFFF -typedef std::map<ObjectGuid::LowType/*leaderDBGUID*/, CreatureGroup*> CreatureGroupHolderType; - struct RespawnInfo; // forward declaration struct CompareRespawnInfo { @@ -435,7 +433,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType> void RemoveFromActive(T* obj); template<class T> void SwitchGridContainers(T* obj, bool on); - CreatureGroupHolderType CreatureGroupHolder; + std::unordered_map<ObjectGuid::LowType /*leaderSpawnId*/, CreatureGroup*> CreatureGroupHolder; void UpdateIteratorBack(Player* player); diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 48c13f9bf8b..b33548acc68 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -1722,7 +1722,7 @@ public: ObjectGuid::LowType lowguid = creature->GetSpawnId(); if (creature->GetFormation()) { - handler->PSendSysMessage("Selected creature is already member of group " UI64FMTD, creature->GetFormation()->GetId()); + handler->PSendSysMessage("Selected creature is already member of group " UI64FMTD, creature->GetFormation()->GetLeaderSpawnId()); return false; } @@ -1730,24 +1730,19 @@ public: return false; Player* chr = handler->GetSession()->GetPlayer(); - FormationInfo* group_member; - group_member = new FormationInfo; - group_member->follow_angle = (creature->GetAngle(chr) - chr->GetOrientation()) * 180 / float(M_PI); - group_member->follow_dist = std::sqrt(std::pow(chr->GetPositionX() - creature->GetPositionX(), 2.f) + std::pow(chr->GetPositionY() - creature->GetPositionY(), 2.f)); - group_member->leaderGUID = leaderGUID; - group_member->groupAI = 0; - - sFormationMgr->CreatureGroupMap[lowguid] = group_member; + float followAngle = (creature->GetAngle(chr) - chr->GetOrientation()) * 180.0f / float(M_PI); + float followDist = std::sqrt(std::pow(chr->GetPositionX() - creature->GetPositionX(), 2.f) + std::pow(chr->GetPositionY() - creature->GetPositionY(), 2.f)); + uint32 groupAI = 0; + sFormationMgr->AddFormationMember(lowguid, followAngle, followDist, leaderGUID, groupAI); creature->SearchFormation(); WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_CREATURE_FORMATION); - stmt->setUInt64(0, leaderGUID); stmt->setUInt64(1, lowguid); - stmt->setFloat(2, group_member->follow_dist); - stmt->setFloat(3, group_member->follow_angle); - stmt->setUInt32(4, uint32(group_member->groupAI)); + stmt->setFloat (2, followAngle); + stmt->setFloat (3, followDist); + stmt->setUInt32(4, groupAI); WorldDatabase.Execute(stmt); diff --git a/src/server/scripts/EasternKingdoms/zone_goldshire.cpp b/src/server/scripts/EasternKingdoms/zone_goldshire.cpp index 3ba89e98f1f..fe6450cf4fe 100644 --- a/src/server/scripts/EasternKingdoms/zone_goldshire.cpp +++ b/src/server/scripts/EasternKingdoms/zone_goldshire.cpp @@ -252,7 +252,7 @@ struct npc_cameron : public ScriptedAI _childrenGUIDs.push_back(jose->GetGUID()); // If Formation was disbanded, remake. - if (!me->GetFormation()->isFormed()) + if (!me->GetFormation()->IsFormed()) for (ObjectGuid guid : _childrenGUIDs) if (Creature* child = ObjectAccessor::GetCreature(*me, guid)) child->SearchFormation(); diff --git a/src/server/scripts/Maelstrom/Stonecore/instance_stonecore.cpp b/src/server/scripts/Maelstrom/Stonecore/instance_stonecore.cpp index c999435f051..77e8eabe75c 100644 --- a/src/server/scripts/Maelstrom/Stonecore/instance_stonecore.cpp +++ b/src/server/scripts/Maelstrom/Stonecore/instance_stonecore.cpp @@ -93,7 +93,7 @@ class instance_stonecore : public InstanceMapScript creature->SearchFormation(); if (CreatureGroup* group = creature->GetFormation()) { - switch (group->GetId()) + switch (group->GetLeaderSpawnId()) { case CREATURE_FORMATION_MILLHOUSE_EVENT_TRASH: millhouseTrashGUIDs.push_back(creature->GetGUID()); |