fix: BaseCreature cleanup (#858)
* Removes LINQ * Removes some list allocations
This commit is contained in:
parent
43db0d09c9
commit
1bec4feb0d
1 changed files with 198 additions and 256 deletions
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Server.Collections;
|
||||
using Server.ContextMenus;
|
||||
using Server.Engines.ConPVP;
|
||||
using Server.Engines.MLQuests;
|
||||
|
|
@ -512,11 +512,11 @@ namespace Server.Mobiles
|
|||
public virtual bool DeathAdderCharmable => false;
|
||||
|
||||
// TODO: Find the pub 31 tweaks to the DispelDifficulty and apply them of course.
|
||||
public virtual double DispelDifficulty // at this skill level we dispel 50% chance
|
||||
=> 0.0;
|
||||
// at this skill level we dispel 50% chance
|
||||
public virtual double DispelDifficulty => 0.0;
|
||||
|
||||
public virtual double DispelFocus // at difficulty - focus we have 0%, at difficulty + focus we have 100%
|
||||
=> 20.0;
|
||||
// at difficulty - focus we have 0%, at difficulty + focus we have 100%
|
||||
public virtual double DispelFocus => 20.0;
|
||||
|
||||
public virtual bool DisplayWeight => Backpack is StrongBackpack;
|
||||
|
||||
|
|
@ -1169,9 +1169,8 @@ namespace Server.Mobiles
|
|||
|
||||
if (m_MLQuests == null)
|
||||
{
|
||||
return
|
||||
MLQuestSystem
|
||||
.EmptyList; // return EmptyList, but don't cache it (run construction again next time)
|
||||
// return EmptyList, but don't cache it (run construction again next time)
|
||||
return MLQuestSystem.EmptyList;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1211,7 +1210,7 @@ namespace Server.Mobiles
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!(m is BaseCreature c) || m is MilitiaFighter)
|
||||
if (m is not BaseCreature c || m is MilitiaFighter)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2153,11 +2152,8 @@ namespace Server.Mobiles
|
|||
// even if they can't offer you anything at the moment
|
||||
if (MLQuestSystem.Enabled && CanGiveMLQuest && from is PlayerMobile mobile)
|
||||
{
|
||||
MLQuestSystem.Tell(
|
||||
this,
|
||||
mobile,
|
||||
1074893
|
||||
); // You need to mark your quest items so I don't take the wrong object. Then speak to me.
|
||||
// You need to mark your quest items so I don't take the wrong object. Then speak to me.
|
||||
MLQuestSystem.Tell(this, mobile, 1074893);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2536,8 +2532,8 @@ namespace Server.Mobiles
|
|||
|
||||
public override bool IsHarmfulCriminal(Mobile target) =>
|
||||
(!Controlled || target != m_ControlMaster) && (!Summoned || target != m_SummonMaster) &&
|
||||
(!(target is BaseCreature creature) || !creature.InitialInnocent || creature.Controlled) &&
|
||||
(!(target is PlayerMobile mobile) || mobile.PermaFlags.Count <= 0) && base.IsHarmfulCriminal(target);
|
||||
(target is not BaseCreature { InitialInnocent: true } creature || creature.Controlled) &&
|
||||
(target is not PlayerMobile mobile || mobile.PermaFlags.Count <= 0) && base.IsHarmfulCriminal(target);
|
||||
|
||||
public override void CriminalAction(bool message)
|
||||
{
|
||||
|
|
@ -2837,18 +2833,6 @@ namespace Server.Mobiles
|
|||
return null;
|
||||
}
|
||||
|
||||
public static void Cap(ref int val, int min, int max)
|
||||
{
|
||||
if (val < min)
|
||||
{
|
||||
val = min;
|
||||
}
|
||||
else if (val > max)
|
||||
{
|
||||
val = max;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.AccessLevel >= AccessLevel.GameMaster && !Body.IsHuman)
|
||||
|
|
@ -2903,7 +2887,8 @@ namespace Server.Mobiles
|
|||
}
|
||||
else if (Controlled && Commandable)
|
||||
{
|
||||
if (IsBonded) // Intentional difference (showing ONLY bonded when bonded instead of bonded & tame)
|
||||
// Intentional difference (showing ONLY bonded when bonded instead of bonded & tame)
|
||||
if (IsBonded)
|
||||
{
|
||||
list.Add(1049608); // (bonded)
|
||||
}
|
||||
|
|
@ -3028,7 +3013,7 @@ namespace Server.Mobiles
|
|||
{
|
||||
var de = list[i];
|
||||
|
||||
if (de.Damager == m || !(de.Damager is BaseCreature bc))
|
||||
if (de.Damager == m || de.Damager is not BaseCreature bc)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -3144,10 +3129,8 @@ namespace Server.Mobiles
|
|||
|
||||
if (rights.Count > 0)
|
||||
{
|
||||
rights[0].m_Damage =
|
||||
(int)(rights[0].m_Damage *
|
||||
1.25
|
||||
); // This would be the first valid person attacking it. Gets a 25% bonus. Per 1/19/07 Five on Friday
|
||||
// This would be the first valid person attacking it. Gets a 25% bonus. Per 1/19/07 Five on Friday
|
||||
rights[0].m_Damage = (int)(rights[0].m_Damage * 1.25);
|
||||
|
||||
if (rights.Count > 1)
|
||||
{
|
||||
|
|
@ -3155,24 +3138,14 @@ namespace Server.Mobiles
|
|||
}
|
||||
|
||||
var topDamage = rights[0].m_Damage;
|
||||
int minDamage;
|
||||
|
||||
if (hitsMax >= 3000)
|
||||
int minDamage = hitsMax switch
|
||||
{
|
||||
minDamage = topDamage / 16;
|
||||
}
|
||||
else if (hitsMax >= 1000)
|
||||
{
|
||||
minDamage = topDamage / 8;
|
||||
}
|
||||
else if (hitsMax >= 200)
|
||||
{
|
||||
minDamage = topDamage / 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
minDamage = topDamage / 2;
|
||||
}
|
||||
>= 3000 => topDamage / 16,
|
||||
>= 1000 => topDamage / 8,
|
||||
>= 200 => topDamage / 4,
|
||||
_ => topDamage / 2
|
||||
};
|
||||
|
||||
for (var i = 0; i < rights.Count; ++i)
|
||||
{
|
||||
|
|
@ -3271,127 +3244,126 @@ namespace Server.Mobiles
|
|||
GiftOfLifeSpell.HandleDeath(this);
|
||||
|
||||
CheckStatTimers();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Summoned && !NoKillAwards)
|
||||
{
|
||||
var totalFame = Fame / 100;
|
||||
var totalKarma = -Karma / 100;
|
||||
|
||||
if (Map == Map.Felucca)
|
||||
if (!Summoned && !NoKillAwards)
|
||||
{
|
||||
var totalFame = Fame / 100;
|
||||
var totalKarma = -Karma / 100;
|
||||
|
||||
if (Map == Map.Felucca)
|
||||
{
|
||||
totalFame += totalFame / 10 * 3;
|
||||
totalKarma += totalKarma / 10 * 3;
|
||||
}
|
||||
|
||||
var list = GetLootingRights(DamageEntries, HitsMax);
|
||||
var titles = new List<Mobile>();
|
||||
var fame = new List<int>();
|
||||
var karma = new List<int>();
|
||||
|
||||
var givenQuestKill = false;
|
||||
var givenFactionKill = false;
|
||||
var givenToTKill = false;
|
||||
|
||||
for (var i = 0; i < list.Count; ++i)
|
||||
{
|
||||
var ds = list[i];
|
||||
|
||||
if (!ds.m_HasRight)
|
||||
{
|
||||
totalFame += totalFame / 10 * 3;
|
||||
totalKarma += totalKarma / 10 * 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
var list = GetLootingRights(DamageEntries, HitsMax);
|
||||
var titles = new List<Mobile>();
|
||||
var fame = new List<int>();
|
||||
var karma = new List<int>();
|
||||
var party = Engines.PartySystem.Party.Get(ds.m_Mobile);
|
||||
|
||||
var givenQuestKill = false;
|
||||
var givenFactionKill = false;
|
||||
var givenToTKill = false;
|
||||
|
||||
for (var i = 0; i < list.Count; ++i)
|
||||
if (party != null)
|
||||
{
|
||||
var ds = list[i];
|
||||
var divedFame = totalFame / party.Members.Count;
|
||||
var divedKarma = totalKarma / party.Members.Count;
|
||||
|
||||
if (!ds.m_HasRight)
|
||||
for (var j = 0; j < party.Members.Count; ++j)
|
||||
{
|
||||
var info = party.Members[j];
|
||||
|
||||
if (info?.Mobile != null)
|
||||
{
|
||||
var index = titles.IndexOf(info.Mobile);
|
||||
|
||||
if (index == -1)
|
||||
{
|
||||
titles.Add(info.Mobile);
|
||||
fame.Add(divedFame);
|
||||
karma.Add(divedKarma);
|
||||
}
|
||||
else
|
||||
{
|
||||
fame[index] += divedFame;
|
||||
karma[index] += divedKarma;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
titles.Add(ds.m_Mobile);
|
||||
fame.Add(totalFame);
|
||||
karma.Add(totalKarma);
|
||||
}
|
||||
|
||||
OnKilledBy(ds.m_Mobile);
|
||||
|
||||
if (!givenFactionKill)
|
||||
{
|
||||
givenFactionKill = true;
|
||||
Faction.HandleDeath(this, ds.m_Mobile);
|
||||
}
|
||||
|
||||
var region = ds.m_Mobile.Region;
|
||||
|
||||
if (!givenToTKill && (Map == Map.Tokuno || region.IsPartOf("Yomotsu Mines") ||
|
||||
region.IsPartOf("Fan Dancer's Dojo")))
|
||||
{
|
||||
givenToTKill = true;
|
||||
TreasuresOfTokuno.HandleKill(this, ds.m_Mobile);
|
||||
}
|
||||
|
||||
if (ds.m_Mobile is PlayerMobile pm)
|
||||
{
|
||||
if (MLQuestSystem.Enabled)
|
||||
{
|
||||
MLQuestSystem.HandleKill(pm, this);
|
||||
}
|
||||
|
||||
if (givenQuestKill)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var party = Engines.PartySystem.Party.Get(ds.m_Mobile);
|
||||
var qs = pm.Quest;
|
||||
|
||||
if (party != null)
|
||||
if (qs != null)
|
||||
{
|
||||
var divedFame = totalFame / party.Members.Count;
|
||||
var divedKarma = totalKarma / party.Members.Count;
|
||||
|
||||
for (var j = 0; j < party.Members.Count; ++j)
|
||||
{
|
||||
var info = party.Members[j];
|
||||
|
||||
if (info?.Mobile != null)
|
||||
{
|
||||
var index = titles.IndexOf(info.Mobile);
|
||||
|
||||
if (index == -1)
|
||||
{
|
||||
titles.Add(info.Mobile);
|
||||
fame.Add(divedFame);
|
||||
karma.Add(divedKarma);
|
||||
}
|
||||
else
|
||||
{
|
||||
fame[index] += divedFame;
|
||||
karma[index] += divedKarma;
|
||||
}
|
||||
}
|
||||
}
|
||||
qs.OnKill(this, c);
|
||||
givenQuestKill = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
titles.Add(ds.m_Mobile);
|
||||
fame.Add(totalFame);
|
||||
karma.Add(totalKarma);
|
||||
}
|
||||
|
||||
OnKilledBy(ds.m_Mobile);
|
||||
|
||||
if (!givenFactionKill)
|
||||
{
|
||||
givenFactionKill = true;
|
||||
Faction.HandleDeath(this, ds.m_Mobile);
|
||||
}
|
||||
|
||||
var region = ds.m_Mobile.Region;
|
||||
|
||||
if (!givenToTKill && (Map == Map.Tokuno || region.IsPartOf("Yomotsu Mines") ||
|
||||
region.IsPartOf("Fan Dancer's Dojo")))
|
||||
{
|
||||
givenToTKill = true;
|
||||
TreasuresOfTokuno.HandleKill(this, ds.m_Mobile);
|
||||
}
|
||||
|
||||
if (ds.m_Mobile is PlayerMobile pm)
|
||||
{
|
||||
if (MLQuestSystem.Enabled)
|
||||
{
|
||||
MLQuestSystem.HandleKill(pm, this);
|
||||
}
|
||||
|
||||
if (givenQuestKill)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var qs = pm.Quest;
|
||||
|
||||
if (qs != null)
|
||||
{
|
||||
qs.OnKill(this, c);
|
||||
givenQuestKill = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < titles.Count; ++i)
|
||||
{
|
||||
Titles.AwardFame(titles[i], fame[i], true);
|
||||
Titles.AwardKarma(titles[i], karma[i], true);
|
||||
}
|
||||
}
|
||||
|
||||
base.OnDeath(c);
|
||||
|
||||
if (DeleteCorpseOnDeath)
|
||||
for (var i = 0; i < titles.Count; ++i)
|
||||
{
|
||||
c.Delete();
|
||||
Titles.AwardFame(titles[i], fame[i], true);
|
||||
Titles.AwardKarma(titles[i], karma[i], true);
|
||||
}
|
||||
}
|
||||
|
||||
base.OnDeath(c);
|
||||
|
||||
if (DeleteCorpseOnDeath)
|
||||
{
|
||||
c.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
|
|
@ -3642,17 +3614,25 @@ namespace Server.Mobiles
|
|||
|
||||
public virtual bool Rummage()
|
||||
{
|
||||
var eable = GetItemsInRange<Corpse>(2);
|
||||
var toRummage = eable.FirstOrDefault(item => item.Items.Count > 0);
|
||||
|
||||
eable.Free();
|
||||
|
||||
if (toRummage == null)
|
||||
if (Backpack == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Backpack == null)
|
||||
var eable = GetItemsInRange<Corpse>(2);
|
||||
Corpse toRummage = null;
|
||||
foreach (var c in eable)
|
||||
{
|
||||
if (c.Items.Count > 0)
|
||||
{
|
||||
toRummage = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
if (toRummage == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -3788,27 +3768,24 @@ namespace Server.Mobiles
|
|||
|
||||
public static void TeleportPets(Mobile master, Point3D loc, Map map, bool onlyBonded = false)
|
||||
{
|
||||
var move = new List<Mobile>();
|
||||
using var queue = PooledRefQueue<Mobile>.Create();
|
||||
|
||||
foreach (var m in master.GetMobilesInRange(3))
|
||||
var eable = master.GetMobilesInRange(3);
|
||||
foreach (var m in eable)
|
||||
{
|
||||
if (
|
||||
m is BaseCreature {
|
||||
Controlled: true,
|
||||
ControlOrder: OrderType.Guard or OrderType.Follow or OrderType.Come
|
||||
} pet
|
||||
)
|
||||
if (m is BaseCreature
|
||||
{ Controlled: true, ControlOrder: OrderType.Guard or OrderType.Follow or OrderType.Come } pet &&
|
||||
pet.ControlMaster == master && (!onlyBonded || pet.IsBonded))
|
||||
{
|
||||
if (pet.ControlMaster == master && (!onlyBonded || pet.IsBonded))
|
||||
{
|
||||
move.Add(pet);
|
||||
}
|
||||
queue.Enqueue(pet);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var m in move)
|
||||
eable.Free();
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
m.MoveToWorld(loc, map);
|
||||
queue.Dequeue().MoveToWorld(loc, map);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3844,18 +3821,14 @@ namespace Server.Mobiles
|
|||
|
||||
var owner = ControlMaster;
|
||||
|
||||
if (owner?.Deleted != false || owner.Map != Map || !owner.InRange(this, 12) || !CanSee(owner) ||
|
||||
!InLOS(owner))
|
||||
{
|
||||
if (OwnerAbandonTime == DateTime.MinValue)
|
||||
{
|
||||
OwnerAbandonTime = Core.Now;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (owner?.Deleted == false && owner.Map == Map && owner.InRange(this, 12) && CanSee(owner) && InLOS(owner))
|
||||
{
|
||||
OwnerAbandonTime = DateTime.MinValue;
|
||||
}
|
||||
else if (OwnerAbandonTime == DateTime.MinValue)
|
||||
{
|
||||
OwnerAbandonTime = Core.Now;
|
||||
}
|
||||
|
||||
CheckStatTimers();
|
||||
}
|
||||
|
|
@ -3961,7 +3934,7 @@ namespace Server.Mobiles
|
|||
|
||||
public void BeginDeleteTimer()
|
||||
{
|
||||
if (!(this is BaseEscortable) && !Summoned && !Deleted && !IsStabled)
|
||||
if (this is not BaseEscortable && !Summoned && !Deleted && !IsStabled)
|
||||
{
|
||||
StopDeleteTimer();
|
||||
m_DeleteTimer = new DeleteTimer(this, TimeSpan.FromDays(3.0));
|
||||
|
|
@ -4261,40 +4234,13 @@ namespace Server.Mobiles
|
|||
{
|
||||
}
|
||||
|
||||
public virtual bool CheckFoodPreference(Item f)
|
||||
{
|
||||
if (CheckFoodPreference(f, FoodType.Eggs, m_Eggs))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (CheckFoodPreference(f, FoodType.Fish, m_Fish))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (CheckFoodPreference(f, FoodType.GrainsAndHay, m_GrainsAndHay))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (CheckFoodPreference(f, FoodType.Meat, m_Meat))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (CheckFoodPreference(f, FoodType.FruitsAndVegies, m_FruitsAndVegies))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (CheckFoodPreference(f, FoodType.Gold, m_Gold))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
public virtual bool CheckFoodPreference(Item f) =>
|
||||
CheckFoodPreference(f, FoodType.Eggs, m_Eggs) ||
|
||||
CheckFoodPreference(f, FoodType.Fish, m_Fish) ||
|
||||
CheckFoodPreference(f, FoodType.GrainsAndHay, m_GrainsAndHay) ||
|
||||
CheckFoodPreference(f, FoodType.Meat, m_Meat) ||
|
||||
CheckFoodPreference(f, FoodType.FruitsAndVegies, m_FruitsAndVegies) ||
|
||||
CheckFoodPreference(f, FoodType.Gold, m_Gold);
|
||||
|
||||
public virtual bool CheckFoodPreference(Item fed, FoodType type, Type[] types)
|
||||
{
|
||||
|
|
@ -4396,9 +4342,8 @@ namespace Server.Mobiles
|
|||
}
|
||||
else if (Core.ML)
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
1075268
|
||||
); // Your pet cannot form a bond with you until your animal taming ability has risen.
|
||||
// Your pet cannot form a bond with you until your animal taming ability has risen.
|
||||
from.SendLocalizedMessage(1075268);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4454,12 +4399,7 @@ namespace Server.Mobiles
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!Core.AOS && (skill == SkillName.Focus || skill == SkillName.Chivalry || skill == SkillName.Necromancy))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return Core.AOS || skill != SkillName.Focus && skill != SkillName.Chivalry && skill != SkillName.Necromancy;
|
||||
}
|
||||
|
||||
public virtual TeachResult CheckTeachSkills(
|
||||
|
|
@ -5033,8 +4973,8 @@ namespace Server.Mobiles
|
|||
return false;
|
||||
}
|
||||
|
||||
Cap(ref minLevel, 0, 5);
|
||||
Cap(ref maxLevel, 0, 5);
|
||||
minLevel = Math.Clamp(minLevel, 0, 5);
|
||||
maxLevel = Math.Clamp(maxLevel, 0, 5);
|
||||
|
||||
if (Core.AOS)
|
||||
{
|
||||
|
|
@ -5121,9 +5061,7 @@ namespace Server.Mobiles
|
|||
|
||||
if (min > max)
|
||||
{
|
||||
var hold = min;
|
||||
min = max;
|
||||
max = hold;
|
||||
(min, max) = (max, min);
|
||||
}
|
||||
|
||||
/* Example:
|
||||
|
|
@ -5204,8 +5142,8 @@ namespace Server.Mobiles
|
|||
return false;
|
||||
}
|
||||
|
||||
Cap(ref minLevel, 0, 5);
|
||||
Cap(ref maxLevel, 0, 5);
|
||||
minLevel = Math.Clamp(minLevel, 0, 5);
|
||||
maxLevel = Math.Clamp(maxLevel, 0, 5);
|
||||
|
||||
if (Core.AOS)
|
||||
{
|
||||
|
|
@ -5481,15 +5419,21 @@ namespace Server.Mobiles
|
|||
}
|
||||
|
||||
var eable = GetMobilesInRange(AuraRange);
|
||||
|
||||
var list = eable.Where(
|
||||
m =>
|
||||
m != this && CanBeHarmful(m, false) && (Core.AOS || InLOS(m)) &&
|
||||
(m is BaseCreature bc && (bc.Controlled || bc.Summoned || bc.Team != Team) || m.Player)
|
||||
);
|
||||
|
||||
foreach (var m in list)
|
||||
using var queue = PooledRefQueue<Mobile>.Create();
|
||||
foreach (var m in eable)
|
||||
{
|
||||
if (m != this && CanBeHarmful(m, false) && (Core.AOS || InLOS(m)) &&
|
||||
(m is BaseCreature bc && (bc.Controlled || bc.Summoned || bc.Team != Team) || m.Player))
|
||||
{
|
||||
queue.Enqueue(m);
|
||||
}
|
||||
}
|
||||
eable.Free();
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
var m = queue.Dequeue();
|
||||
|
||||
AOS.Damage(
|
||||
m,
|
||||
this,
|
||||
|
|
@ -5503,8 +5447,6 @@ namespace Server.Mobiles
|
|||
);
|
||||
AuraEffect(m);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public virtual void AuraEffect(Mobile m)
|
||||
|
|
@ -5599,10 +5541,8 @@ namespace Server.Mobiles
|
|||
|
||||
private DateTime m_NextHourlyCheck;
|
||||
|
||||
public LoyaltyTimer() : base(InternalDelay, InternalDelay)
|
||||
{
|
||||
public LoyaltyTimer() : base(InternalDelay, InternalDelay) =>
|
||||
m_NextHourlyCheck = Core.Now + TimeSpan.FromHours(1.0);
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
|
|
@ -5618,14 +5558,14 @@ namespace Server.Mobiles
|
|||
|
||||
m_NextHourlyCheck = Core.Now + TimeSpan.FromHours(1.0);
|
||||
|
||||
var toRelease = new List<BaseCreature>();
|
||||
using var toRelease = PooledRefQueue<BaseCreature>.Create();
|
||||
|
||||
// added array for wild creatures in house regions to be removed
|
||||
var toRemove = new List<BaseCreature>();
|
||||
using var toRemove = PooledRefQueue<Mobile>.Create();
|
||||
|
||||
foreach (var m in World.Mobiles.Values)
|
||||
{
|
||||
if (!(m is BaseCreature c))
|
||||
if (m is not BaseCreature c)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -5649,7 +5589,7 @@ namespace Server.Mobiles
|
|||
}
|
||||
else if (c.OwnerAbandonTime + c.BondingAbandonDelay <= Core.Now)
|
||||
{
|
||||
toRemove.Add(c);
|
||||
toRemove.Enqueue(c);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -5673,7 +5613,7 @@ namespace Server.Mobiles
|
|||
|
||||
if (c.Loyalty <= 0)
|
||||
{
|
||||
toRelease.Add(c);
|
||||
toRelease.Enqueue(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5686,7 +5626,7 @@ namespace Server.Mobiles
|
|||
|
||||
if (c.RemoveStep >= 20)
|
||||
{
|
||||
toRemove.Add(c);
|
||||
toRemove.Enqueue(c);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -5695,22 +5635,24 @@ namespace Server.Mobiles
|
|||
}
|
||||
}
|
||||
|
||||
foreach (var c in toRelease)
|
||||
while (toRelease.Count > 0)
|
||||
{
|
||||
c.Say(1043255, c.Name); // ~1_NAME~ appears to have decided that is better off without a master!
|
||||
var c = toRelease.Dequeue();
|
||||
|
||||
c.Say(1043255, c.Name); // ~1_NAME~ appears to have decided that is better off without a master!
|
||||
c.Loyalty = BaseCreature.MaxLoyalty; // Wonderfully Happy
|
||||
c.IsBonded = false;
|
||||
c.BondingBegin = DateTime.MinValue;
|
||||
c.OwnerAbandonTime = DateTime.MinValue;
|
||||
c.ControlTarget = null;
|
||||
c.AIObject
|
||||
.DoOrderRelease(); // this will prevent no release of creatures left alone with AI disabled (and consequent bug of Followers)
|
||||
// This will prevent no release of creatures left alone with AI disabled (and consequent bug of Followers)
|
||||
c.AIObject.DoOrderRelease();
|
||||
c.DropBackpack();
|
||||
}
|
||||
|
||||
foreach (var c in toRemove)
|
||||
while (toRemove.Count > 0)
|
||||
{
|
||||
c.Delete();
|
||||
toRemove.Dequeue().Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue