Core/Creatures: Allow adding summons to CreatureGroup (only adding, no formation movement of linked aggro yet)
Port From (https://github.com/TrinityCore/TrinityCore/commit/16bfbe1a3a12256d9476f3ae23e1f34f31f9cf07)
This commit is contained in:
@@ -50,16 +50,22 @@ namespace Game.Entities
|
|||||||
|
|
||||||
public static void RemoveCreatureFromGroup(CreatureGroup group, Creature member)
|
public static void RemoveCreatureFromGroup(CreatureGroup group, Creature member)
|
||||||
{
|
{
|
||||||
Log.outDebug(LogFilter.Unit, "Deleting member GUID: {0} from group {1}", group.GetLeaderSpawnId(), member.GetSpawnId());
|
ulong leaderSpawnId = group.GetLeaderSpawnId();
|
||||||
|
|
||||||
|
Log.outDebug(LogFilter.Unit, $"Deleting member GUID: {leaderSpawnId} from group {member.GetSpawnId()}");
|
||||||
group.RemoveMember(member);
|
group.RemoveMember(member);
|
||||||
|
|
||||||
if (group.IsEmpty())
|
if (group.IsEmpty())
|
||||||
{
|
{
|
||||||
Map map = member.GetMap();
|
if (leaderSpawnId != 0)
|
||||||
|
{
|
||||||
|
Map map = member.GetMap();
|
||||||
|
|
||||||
Log.outDebug(LogFilter.Unit, "Deleting group with InstanceID {0}", member.GetInstanceId());
|
Log.outDebug(LogFilter.Unit, $"Deleting group with InstanceID {member.GetInstanceId()}");
|
||||||
Cypher.Assert(map.CreatureGroupHolder.ContainsKey(group.GetLeaderSpawnId()), $"Not registered group {group.GetLeaderSpawnId()} in map {map.GetId()}");
|
bool erased = map.CreatureGroupHolder.Remove(leaderSpawnId);
|
||||||
map.CreatureGroupHolder.Remove(group.GetLeaderSpawnId());
|
Cypher.Assert(erased, $"Not registered group {leaderSpawnId} in map {map.GetId()}");
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,29 +86,14 @@ namespace Game.Entities
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
//Load group member data
|
//Load group member data
|
||||||
FormationInfo member = new();
|
ulong leaderSpawnId = result.Read<ulong>(0);
|
||||||
member.LeaderSpawnId = result.Read<ulong>(0);
|
|
||||||
ulong memberSpawnId = result.Read<ulong>(1);
|
ulong memberSpawnId = result.Read<ulong>(1);
|
||||||
member.FollowDist = 0f;
|
|
||||||
member.FollowAngle = 0f;
|
|
||||||
|
|
||||||
//If creature is group leader we may skip loading of dist/angle
|
|
||||||
if (member.LeaderSpawnId != memberSpawnId)
|
|
||||||
{
|
|
||||||
member.FollowDist = result.Read<float>(2);
|
|
||||||
member.FollowAngle = result.Read<float>(3) * MathFunctions.PI / 180;
|
|
||||||
}
|
|
||||||
|
|
||||||
member.GroupAI = result.Read<uint>(4);
|
|
||||||
|
|
||||||
for (var i = 0; i < 2; ++i)
|
|
||||||
member.LeaderWaypointIDs[i] = result.Read<ushort>(5 + i);
|
|
||||||
|
|
||||||
// check data correctness
|
// check data correctness
|
||||||
{
|
{
|
||||||
if (Global.ObjectMgr.GetCreatureData(member.LeaderSpawnId) == null)
|
if (Global.ObjectMgr.GetCreatureData(leaderSpawnId) == null)
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, $"creature_formations table leader guid {member.LeaderSpawnId} incorrect (not exist)");
|
Log.outError(LogFilter.Sql, $"creature_formations table leader guid {leaderSpawnId} incorrect (not exist)");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,9 +103,25 @@ namespace Game.Entities
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
leaderSpawnIds.Add(member.LeaderSpawnId);
|
leaderSpawnIds.Add(leaderSpawnId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FormationInfo member = new();
|
||||||
|
member.LeaderSpawnId = leaderSpawnId;
|
||||||
|
member.FollowDist = 0.0f;
|
||||||
|
member.FollowAngle = 0.0f;
|
||||||
|
|
||||||
|
//If creature is group leader we may skip loading of dist/angle
|
||||||
|
if (member.LeaderSpawnId != memberSpawnId)
|
||||||
|
{
|
||||||
|
member.FollowDist = result.Read<float>(2);
|
||||||
|
member.FollowAngle = result.Read<float>(3) * MathF.PI / 180.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
member.GroupAI = result.Read<uint>(4);
|
||||||
|
for (byte i = 0; i < 2; ++i)
|
||||||
|
member.LeaderWaypointIDs[i] = result.Read<ushort>(5 + i);
|
||||||
|
|
||||||
_creatureGroupMap.Add(memberSpawnId, member);
|
_creatureGroupMap.Add(memberSpawnId, member);
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
@@ -180,18 +187,17 @@ namespace Game.Entities
|
|||||||
|
|
||||||
public void AddMember(Creature member)
|
public void AddMember(Creature member)
|
||||||
{
|
{
|
||||||
Log.outDebug(LogFilter.Unit, "CreatureGroup.AddMember: Adding {0}.", member.GetGUID().ToString());
|
Log.outDebug(LogFilter.Unit, $"CreatureGroup.AddMember: Adding {member.GetGUID()}.");
|
||||||
|
|
||||||
//Check if it is a leader
|
//Check if it is a leader
|
||||||
if (member.GetSpawnId() == _leaderSpawnId)
|
if ((_leaderSpawnId != 0 && member.GetSpawnId() == _leaderSpawnId)
|
||||||
|
|| (_leaderSpawnId == 0 && _leader == null)) // in formations made of tempsummons first member to be added is leader
|
||||||
{
|
{
|
||||||
Log.outDebug(LogFilter.Unit, "{0} is formation leader. Adding group.", member.GetGUID().ToString());
|
Log.outDebug(LogFilter.Unit, $"{member.GetGUID()} is formation leader. Adding group.");
|
||||||
_leader = member;
|
_leader = member;
|
||||||
}
|
}
|
||||||
|
|
||||||
// formation must be registered at this point
|
_members.Add(member, FormationMgr.GetFormationInfo(member.GetSpawnId()));
|
||||||
FormationInfo formationInfo = FormationMgr.GetFormationInfo(member.GetSpawnId());
|
|
||||||
_members.Add(member, formationInfo);
|
|
||||||
member.SetFormation(this);
|
member.SetFormation(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,7 +216,11 @@ namespace Game.Entities
|
|||||||
if (_engaging)
|
if (_engaging)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GroupAIFlags groupAI = (GroupAIFlags)FormationMgr.GetFormationInfo(member.GetSpawnId()).GroupAI;
|
FormationInfo formationInfo = _members.LookupByKey(member);
|
||||||
|
if (formationInfo == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GroupAIFlags groupAI = (GroupAIFlags)formationInfo.GroupAI;
|
||||||
if (groupAI == 0)
|
if (groupAI == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -224,10 +234,8 @@ namespace Game.Entities
|
|||||||
|
|
||||||
_engaging = true;
|
_engaging = true;
|
||||||
|
|
||||||
foreach (var pair in _members)
|
foreach (var (other, _) in _members)
|
||||||
{
|
{
|
||||||
Creature other = pair.Key;
|
|
||||||
|
|
||||||
// Skip self
|
// Skip self
|
||||||
if (other == member)
|
if (other == member)
|
||||||
continue;
|
continue;
|
||||||
@@ -244,13 +252,16 @@ namespace Game.Entities
|
|||||||
|
|
||||||
public void FormationReset(bool dismiss)
|
public void FormationReset(bool dismiss)
|
||||||
{
|
{
|
||||||
foreach (var (creature, _) in _members)
|
foreach (var (member, _) in _members)
|
||||||
{
|
{
|
||||||
if (dismiss)
|
if (member != _leader && member.IsAlive())
|
||||||
creature.GetMotionMaster().Remove(MovementGeneratorType.Formation, MovementSlot.Default);
|
{
|
||||||
else
|
if (dismiss)
|
||||||
creature.GetMotionMaster().MoveIdle();
|
member.GetMotionMaster().Remove(MovementGeneratorType.Formation, MovementSlot.Default);
|
||||||
Log.outDebug(LogFilter.Unit, $"CreatureGroup::FormationReset: Set {(dismiss ? "default" : "idle")} movement for member {creature.GetGUID()}");
|
else
|
||||||
|
member.GetMotionMaster().MoveIdle();
|
||||||
|
Log.outDebug(LogFilter.Unit, $"CreatureGroup::FormationReset: Set {(dismiss ? "default" : "idle")} movement for member {member.GetGUID()}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_formed = !dismiss;
|
_formed = !dismiss;
|
||||||
@@ -261,27 +272,26 @@ namespace Game.Entities
|
|||||||
if (_leader == null)
|
if (_leader == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (var pair in _members)
|
foreach (var (member, formationInfo) in _members)
|
||||||
{
|
{
|
||||||
Creature member = pair.Key;
|
if (member == _leader || !member.IsAlive() || member.IsEngaged() || formationInfo == null || !formationInfo.GroupAI.HasAnyFlag((uint)GroupAIFlags.IdleInFormation))
|
||||||
if (member == _leader || !member.IsAlive() || member.IsEngaged() || !pair.Value.GroupAI.HasAnyFlag((uint)GroupAIFlags.IdleInFormation))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
float angle = pair.Value.FollowAngle + MathF.PI; // for some reason, someone thought it was a great idea to invert relativ angles...
|
float angle = formationInfo.FollowAngle + MathF.PI; // for some reason, someone thought it was a great idea to invert relativ angles...
|
||||||
float dist = pair.Value.FollowDist;
|
float dist = formationInfo.FollowDist;
|
||||||
|
|
||||||
if (!member.HasUnitState(UnitState.FollowFormation))
|
if (!member.HasUnitState(UnitState.FollowFormation))
|
||||||
member.GetMotionMaster().MoveFormation(_leader, dist, angle, pair.Value.LeaderWaypointIDs[0], pair.Value.LeaderWaypointIDs[1]);
|
member.GetMotionMaster().MoveFormation(_leader, dist, angle, formationInfo.LeaderWaypointIDs[0], formationInfo.LeaderWaypointIDs[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanLeaderStartMoving()
|
public bool CanLeaderStartMoving()
|
||||||
{
|
{
|
||||||
foreach (var pair in _members)
|
foreach (var (member, _) in _members)
|
||||||
{
|
{
|
||||||
if (pair.Key != _leader && pair.Key.IsAlive())
|
if (member != _leader && member.IsAlive())
|
||||||
{
|
{
|
||||||
if (pair.Key.IsEngaged() || pair.Key.IsReturningHome())
|
if (member.IsEngaged() || member.IsReturningHome())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user