fix: Fixes stabled, abilities targeting self, and unsummon memory leak (#1418)
## **MAJOR CHANGE** * `Stabled` has been moved to `PlayerMobile`. * New methods added, `PlayerMobile.AddStabled` and `PlayerMobile.RemoveStabled`. * Added `PlayerMobile.AddFollower` and `PlayerMobile.RemoveFollower`. * `Stabled`, `AutoStabled`, and `AllFollowers` are now `HashSet` and **_CAN BE NULL_**. ### Summary * Fixes monster abilities causing harm to the monster through reflect * Adds `CanTriggerAgainstSelf` to override this for healing or some other self-affecting ability * Fixes a major memory leak where `UnsummonTimer` from animated dead spell lasts up-to 24hrs and therefore holds onto references of dead/deleted mobs. * Fixes another minor leak where a mob is not unregistered from the animated dead spell list until the next spell cast.
This commit is contained in:
parent
d99e72db8f
commit
3b97e8d39c
13 changed files with 391 additions and 280 deletions
|
|
@ -2082,23 +2082,9 @@ namespace Server.Mobiles
|
|||
OwnerAbandonTime = reader.ReadDateTime();
|
||||
}
|
||||
|
||||
if (version >= 11)
|
||||
{
|
||||
m_HasGeneratedLoot = reader.ReadBool();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_HasGeneratedLoot = true;
|
||||
}
|
||||
m_HasGeneratedLoot = version < 11 || reader.ReadBool();
|
||||
|
||||
if (version >= 12)
|
||||
{
|
||||
m_Paragon = reader.ReadBool();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Paragon = false;
|
||||
}
|
||||
m_Paragon = version >= 12 && reader.ReadBool();
|
||||
|
||||
if (version >= 13 && reader.ReadBool())
|
||||
{
|
||||
|
|
@ -2275,30 +2261,17 @@ namespace Server.Mobiles
|
|||
{
|
||||
if (m_ControlMaster != null)
|
||||
{
|
||||
m_ControlMaster.Followers -= ControlSlots;
|
||||
m_ControlMaster.Followers -= Math.Min(ControlSlots, m_ControlMaster.Followers);
|
||||
if (m_ControlMaster is PlayerMobile mobile)
|
||||
{
|
||||
mobile.AllFollowers.Remove(this);
|
||||
if (mobile.AutoStabled.Contains(this))
|
||||
{
|
||||
mobile.AutoStabled.Remove(this);
|
||||
}
|
||||
mobile.AllFollowers?.Remove(this);
|
||||
mobile.AutoStabled?.Remove(this);
|
||||
}
|
||||
}
|
||||
else if (m_SummonMaster != null)
|
||||
{
|
||||
m_SummonMaster.Followers -= ControlSlots;
|
||||
(m_SummonMaster as PlayerMobile)?.AllFollowers.Remove(this);
|
||||
}
|
||||
|
||||
if (m_ControlMaster?.Followers < 0)
|
||||
{
|
||||
m_ControlMaster.Followers = 0;
|
||||
}
|
||||
|
||||
if (m_SummonMaster?.Followers < 0)
|
||||
{
|
||||
m_SummonMaster.Followers = 0;
|
||||
m_SummonMaster.Followers -= Math.Min(ControlSlots, m_SummonMaster.Followers);
|
||||
(m_SummonMaster as PlayerMobile)?.AllFollowers?.Remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2307,17 +2280,17 @@ namespace Server.Mobiles
|
|||
if (m_ControlMaster != null)
|
||||
{
|
||||
m_ControlMaster.Followers += ControlSlots;
|
||||
if (m_ControlMaster is PlayerMobile mobile)
|
||||
if (m_ControlMaster is PlayerMobile pm)
|
||||
{
|
||||
mobile.AllFollowers.Add(this);
|
||||
pm.AddFollower(this);
|
||||
}
|
||||
}
|
||||
else if (m_SummonMaster != null)
|
||||
{
|
||||
m_SummonMaster.Followers += ControlSlots;
|
||||
if (m_SummonMaster is PlayerMobile mobile)
|
||||
if (m_SummonMaster is PlayerMobile pm)
|
||||
{
|
||||
mobile.AllFollowers.Add(this);
|
||||
pm.AddFollower(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2407,6 +2380,8 @@ namespace Server.Mobiles
|
|||
MLQuestSystem.HandleDeletion(this);
|
||||
}
|
||||
|
||||
UnsummonTimer.StopTimer(this);
|
||||
|
||||
base.OnAfterDelete();
|
||||
}
|
||||
|
||||
|
|
@ -3440,6 +3415,8 @@ namespace Server.Mobiles
|
|||
}
|
||||
}
|
||||
|
||||
RemoveFollowers();
|
||||
|
||||
base.OnDeath(c);
|
||||
|
||||
if (DeleteCorpseOnDeath)
|
||||
|
|
@ -3455,6 +3432,7 @@ namespace Server.Mobiles
|
|||
|
||||
SummonMaster = null;
|
||||
ReceivedHonorContext?.Cancel();
|
||||
|
||||
base.OnDelete();
|
||||
m?.InvalidateProperties();
|
||||
}
|
||||
|
|
@ -3834,11 +3812,10 @@ namespace Server.Mobiles
|
|||
|
||||
public static void TeleportPets(Mobile master, Point3D loc, Map map, bool onlyBonded = false)
|
||||
{
|
||||
if (master is PlayerMobile pm)
|
||||
if (master is PlayerMobile { AllFollowers: not null } pm)
|
||||
{
|
||||
for (var i = 0; i < pm.AllFollowers.Count; i++)
|
||||
foreach (var m in pm.AllFollowers)
|
||||
{
|
||||
var m = pm.AllFollowers[i];
|
||||
if (m.Map == master.Map && master.InRange(m, 3) && m is BaseCreature
|
||||
{ Controlled: true, ControlOrder: OrderType.Guard or OrderType.Follow or OrderType.Come } pet &&
|
||||
pet.ControlMaster == master && (!onlyBonded || pet.IsBonded))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue