diff --git a/Projects/UOContent/Engines/XMLSpawner/BaseXmlSpawner.cs b/Projects/UOContent/Engines/XMLSpawner/BaseXmlSpawner.cs index 5b652409e..2ca8fa0ae 100644 --- a/Projects/UOContent/Engines/XMLSpawner/BaseXmlSpawner.cs +++ b/Projects/UOContent/Engines/XMLSpawner/BaseXmlSpawner.cs @@ -1382,8 +1382,7 @@ public class BaseXmlSpawner // count nearby players if (refobject is Item item) { - IPooledEnumerable ie = item.GetMobilesInRange(range); - foreach (Mobile p in ie) + foreach (Mobile p in item.GetMobilesInRange(range)) { if (p.Player && p.AccessLevel == AccessLevel.Player) { @@ -1394,8 +1393,7 @@ public class BaseXmlSpawner } else if (refobject is Mobile mobile) { - IPooledEnumerable ie = mobile.GetMobilesInRange(range); - foreach (Mobile p in ie) + foreach (Mobile p in mobile.GetMobilesInRange(range)) { if (p.Player && p.AccessLevel == AccessLevel.Player) { @@ -1666,27 +1664,23 @@ public class BaseXmlSpawner } else if (o is Item item) { - IPooledEnumerable ie = item.GetMobilesInRange(range); - foreach (Mobile p in ie) + foreach (Mobile p in item.GetMobilesInRange(range)) { if (p.Player && p.AccessLevel == AccessLevel.Player) { nplayers++; } } - ie.Free(); } else if (o is Mobile mobile) { - IPooledEnumerable ie = mobile.GetMobilesInRange(range); - foreach (Mobile p in ie) + foreach (Mobile p in mobile.GetMobilesInRange(range)) { if (p.Player && p.AccessLevel == AccessLevel.Player) { nplayers++; } } - ie.Free(); } return nplayers.ToString(); diff --git a/Projects/UOContent/Engines/XMLSpawner/XmlSpawner.cs b/Projects/UOContent/Engines/XMLSpawner/XmlSpawner.cs index 5405013cc..735ad243c 100644 --- a/Projects/UOContent/Engines/XMLSpawner/XmlSpawner.cs +++ b/Projects/UOContent/Engines/XMLSpawner/XmlSpawner.cs @@ -224,16 +224,13 @@ public class XmlSpawner : Item, ISpawner var count = 0; if (ProximityRange >= 0) { - IPooledEnumerable eable = GetMobilesInRange(ProximityRange); - foreach (Mobile m in eable) + foreach (Mobile m in GetMobilesInRange(ProximityRange)) { - if (m != null && m.Player) + if (m?.Player == true) { count++; } } - - eable.Free(); } return count; } @@ -281,7 +278,7 @@ public class XmlSpawner : Item, ISpawner } } - private readonly bool sectorIsActive = false; + private const bool SectorIsActive = false; public bool SingleSector { get; private set; } @@ -308,48 +305,50 @@ public class XmlSpawner : Item, ISpawner { var o = so.SpawnedObjects[x]; - if (o is BaseCreature creature) + if (o is not BaseCreature creature) { - // if the mob is damaged or outside of smartspawning detection range then return true - if (creature.Hits < creature.HitsMax || creature.Mana < creature.ManaMax || creature.Stam < creature.StamMax || creature.Map != Map) - { - return true; - } + continue; + } - // if the spawn moves into a sector that is not activatable from a sector on the sector list then dont smartspawn - if (creature.Map != null && creature.Map != Map.Internal) - { - var bsec = creature.Map.GetSector(creature.Location); + // if the mob is damaged or outside of smartspawning detection range then return true + if (creature.Hits < creature.HitsMax || creature.Mana < creature.ManaMax || creature.Stam < creature.StamMax || creature.Map != Map) + { + return true; + } - if (SingleSector) + // if the spawn moves into a sector that is not activatable from a sector on the sector list then dont smartspawn + if (creature.Map != null && creature.Map != Map.Internal) + { + var bsec = creature.Map.GetSector(creature.Location); + + if (SingleSector) + { + // is it in activatable range of the sector the spawner is in + if (!InActivationRange(bsec, ssec)) { - // is it in activatable range of the sector the spawner is in - if (!InActivationRange(bsec, ssec)) - { - return true; - } + return true; } - else - { - var outofsec = true; + } + else + { + var outofsec = true; - if (sectorList != null) + if (sectorList != null) + { + foreach (var s in sectorList) { - foreach (var s in sectorList) + // is the creatures sector within activation range of any of the sectors in the list + if (InActivationRange(bsec, s)) { - // is the creatures sector within activation range of any of the sectors in the list - if (InActivationRange(bsec, s)) - { - outofsec = false; - break; - } + outofsec = false; + break; } } + } - if (outofsec) - { - return true; - } + if (outofsec) + { + return true; } } } @@ -394,7 +393,7 @@ public class XmlSpawner : Item, ISpawner // is this a single sector spawner? if (SingleSector) { - return sectorIsActive; + return SectorIsActive; } // if there is no sector list made for this spawner then create one. @@ -575,7 +574,7 @@ public class XmlSpawner : Item, ISpawner foreach (var sot in m_KeywordTagList) { // check for any keyword tag with the holdspawn flag - if (sot != null && !sot.Deleted && (sot.Flags & BaseXmlSpawner.KeywordFlags.HoldSpawn) != 0) + if (sot?.Deleted == false && (sot.Flags & BaseXmlSpawner.KeywordFlags.HoldSpawn) != 0) { return true; } @@ -649,7 +648,7 @@ public class XmlSpawner : Item, ISpawner get => m_SpawnObjects.ToArray(); set { - if (value != null && value.Length > 0) + if (value?.Length > 0) { foreach (var so in value) @@ -709,7 +708,7 @@ public class XmlSpawner : Item, ISpawner foreach (var sot in m_KeywordTagList) { // check for any keyword tag with the holdsequence flag - if (sot != null && !sot.Deleted && (sot.Flags & BaseXmlSpawner.KeywordFlags.HoldSequence) != 0) + if (sot?.Deleted == false && (sot.Flags & BaseXmlSpawner.KeywordFlags.HoldSequence) != 0) { return true; } @@ -873,7 +872,7 @@ public class XmlSpawner : Item, ISpawner foreach (var region in Region.Regions) { - if (string.Compare(region.Name, m_RegionName, true) == 0) + if (region.Name.InsensitiveEquals(m_RegionName)) { m_Region = region; m_RegionName = region.Name; @@ -1032,7 +1031,7 @@ public class XmlSpawner : Item, ISpawner [CommandProperty(AccessLevel.GameMaster)] public bool ShowBounds { - get => m_ShowBoundsItems != null && m_ShowBoundsItems.Count > 0; + get => m_ShowBoundsItems?.Count > 0; set { if (value && ShowBounds == false) @@ -1207,7 +1206,7 @@ public class XmlSpawner : Item, ISpawner { get { - if (SetItem == null || SetItem.Deleted) + if (SetItem?.Deleted != false) { return null; } @@ -1514,7 +1513,7 @@ public class XmlSpawner : Item, ISpawner // if any spawner is smartspawning, then the smartspawning system is enabled SmartSpawningSystemEnabled = true; // check to see if the global sector timer is running - if (m_GlobalSectorTimer == null || !m_GlobalSectorTimer.Running) + if (m_GlobalSectorTimer?.Running != true) { // start the global smartspawning timer DoGlobalSectorTimer(TimeSpan.FromSeconds(1)); @@ -1537,7 +1536,7 @@ public class XmlSpawner : Item, ISpawner foreach (var so in m_SpawnObjects) { - if (so.SpawnedObjects != null && so.SpawnedObjects.Count > 0) + if (so.SpawnedObjects?.Count > 0) { if (so.SpawnedObjects[0] is Mobile) { @@ -1640,7 +1639,7 @@ public class XmlSpawner : Item, ISpawner public override void OnDoubleClick(Mobile from) { - if (from == null || from.Deleted || from.AccessLevel < AccessLevel.GameMaster || SpawnerGump != null && SomeOneHasGumpOpen) + if (from?.Deleted != false || from.AccessLevel < AccessLevel.GameMaster || SpawnerGump != null && SomeOneHasGumpOpen) { return; } @@ -1713,7 +1712,7 @@ public class XmlSpawner : Item, ISpawner for (var i = 0; i < nlist_items && i < m_SpawnObjects.Count; ++i) { var typename = m_SpawnObjects[i].TypeName; - if (typename != null && typename.Length > 20) + if (typename?.Length > 20) { typename = typename[..20]; } @@ -1746,7 +1745,7 @@ public class XmlSpawner : Item, ISpawner m_RefractoryTimer?.Stop(); // if statics were added for marking container held spawners, delete them - if (m_ShowContainerStatic != null && !m_ShowContainerStatic.Deleted) + if (m_ShowContainerStatic?.Deleted == false) { m_ShowContainerStatic.Delete(); } @@ -1831,20 +1830,10 @@ public class XmlSpawner : Item, ISpawner } } - private static bool IsConstructible(ConstructorInfo ctor) - { - return ctor.IsDefined(typeof(ConstructibleAttribute), false); - } + private static bool IsConstructible(ConstructorInfo ctor) => ctor.IsDefined(typeof(ConstructibleAttribute), false); - public static int ConvertToInt(string value) - { - if (value.StartsWith("0x")) - { - return Convert.ToInt32(value.Substring(2), 16); - } - - return Convert.ToInt32(value); - } + public static int ConvertToInt(string value) => + value.StartsWith("0x") ? Convert.ToInt32(value.Substring(2), 16) : Convert.ToInt32(value); public static void ExecuteAction(object attachedto, Mobile trigmob, string action) { @@ -1868,7 +1857,6 @@ public class XmlSpawner : Item, ISpawner var substitutedtypeName = BaseXmlSpawner.ApplySubstitution(null, attachedto, action); var typeName = BaseXmlSpawner.ParseObjectType(substitutedtypeName); - string status_str; if (BaseXmlSpawner.IsTypeOrItemKeyword(typeName)) { _ = BaseXmlSpawner.SpawnTypeKeyword(attachedto, TheSpawn, typeName, substitutedtypeName, trigmob, map, out _); @@ -1882,11 +1870,6 @@ public class XmlSpawner : Item, ISpawner var arglist = BaseXmlSpawner.ParseString(substitutedtypeName, 3, "/"); var o = CreateObject(type, arglist[0]); - if (o == null) - { - status_str = $"invalid type specification: {arglist[0]}"; - } - else if (o is Mobile mobile) { if (mobile is BaseCreature creature) @@ -1897,12 +1880,11 @@ public class XmlSpawner : Item, ISpawner mobile.Location = loc; mobile.Map = map; - _ = BaseXmlSpawner.ApplyObjectStringProperties(null, substitutedtypeName, mobile, trigmob, attachedto, out status_str); + _ = BaseXmlSpawner.ApplyObjectStringProperties(null, substitutedtypeName, mobile, trigmob, attachedto, out _); } - else - if (o is Item item) + else if (o is Item item) { - BaseXmlSpawner.AddSpawnItem(null, attachedto, TheSpawn, item, loc, map, trigmob, false, substitutedtypeName, out status_str); + BaseXmlSpawner.AddSpawnItem(null, attachedto, TheSpawn, item, loc, map, trigmob, false, substitutedtypeName, out _); } } catch (Exception e) @@ -1995,7 +1977,7 @@ public class XmlSpawner : Item, ISpawner // Check that at least a single table was loaded if (ds.Tables.Count > 0) { - if (ds.Tables[XmlTableName] != null && ds.Tables[XmlTableName].Rows.Count > 0) + if (ds.Tables[XmlTableName]?.Rows.Count > 0) { foreach (DataRow dr in ds.Tables[XmlTableName].Rows) { @@ -2411,7 +2393,7 @@ public class XmlSpawner : Item, ISpawner private bool ValidPlayerTrig(Mobile m) { - if (m == null || m.Deleted) + if (m?.Deleted != false) { return false; } @@ -2509,13 +2491,13 @@ public class XmlSpawner : Item, ISpawner if (Utility.RandomDouble() < TriggerProbability) { // play a sound indicating the spawner has been triggered - if (ProximitySound > 0 && m != null && !m.Deleted) + if (ProximitySound > 0 && m?.Deleted == false) { m.PlaySound(ProximitySound); } // display the trigger message - if (!string.IsNullOrEmpty(ProximityMsg) && m != null && !m.Deleted) + if (!string.IsNullOrEmpty(ProximityMsg) && m?.Deleted == false) { m.PublicOverheadMessage(MessageType.Regular, 0x3B2, false, ProximityMsg); } @@ -2537,7 +2519,7 @@ public class XmlSpawner : Item, ISpawner } } - public bool HandlesOnSkillUse => m_Running && SkillTrigger != null && SkillTrigger.Length > 0; + public bool HandlesOnSkillUse => m_Running && SkillTrigger?.Length > 0; // this is the handler for skill use public void OnSkillUse(Mobile m, Skill skill, bool success) @@ -2598,7 +2580,7 @@ public class XmlSpawner : Item, ISpawner m_MovementList ??= new List(); // check to see if the movement timer is running - if (m_MovementTimer == null || !m_MovementTimer.Running) + if (m_MovementTimer?.Running != true) { DoMovementTimer(TimeSpan.FromSeconds(1)); } @@ -2644,15 +2626,12 @@ public class XmlSpawner : Item, ISpawner { private readonly XmlSpawner m_Spawner; - public MovementTimer(XmlSpawner spawner, TimeSpan delay) : base(delay) - { - m_Spawner = spawner; - } + public MovementTimer(XmlSpawner spawner, TimeSpan delay) : base(delay) => m_Spawner = spawner; protected override void OnTick() { // check everyone on the movement list then clear the list - if (m_Spawner != null && !m_Spawner.Deleted) + if (m_Spawner?.Deleted == false) { if (m_Spawner.m_Running && !m_Spawner.m_proximityActivated && !m_Spawner.m_refractActivated && m_Spawner.TODInRange && m_Spawner.CanSpawn) { @@ -2732,92 +2711,92 @@ public class XmlSpawner : Item, ISpawner switch (argname) { case "XmlSpawnDir": - { - XmlSpawnDir = value; - break; - } - case "DiskAccessLevel": - { - DiskAccessLevel = (AccessLevel)Enum.Parse(typeof(AccessLevel), value, true); - break; - } - case "SmartSpawnAccessLevel": - { - SmartSpawnAccessLevel = (AccessLevel)Enum.Parse(typeof(AccessLevel), value, true); - break; - } - case "defaultTriggerSound": - { - defaultTriggerSound = ConvertToInt(value); - defProximityTriggerSound = defaultTriggerSound; - break; - } - case "BaseItemId": - { - BaseItemId = ConvertToInt(value); - break; - } - case "ShowItemId": - { - ShowItemId = ConvertToInt(value); - break; - } - case "MaxMoveCheck": - { - MaxMoveCheck = ConvertToInt(value); - break; - } - case "defMinDelay": - { - defMinDelay = TimeSpan.FromMinutes(ConvertToInt(value)); - break; - } - case "defMaxDelay": - { - defMaxDelay = TimeSpan.FromMinutes(ConvertToInt(value)); - break; - } - case "defRelativeHome": - { - defRelativeHome = bool.Parse(value); - break; - } - case "defSpawnRange": - { - defSpawnRange = ConvertToInt(value); - break; - } - case "defHomeRange": - { - defHomeRange = ConvertToInt(value); - break; - } - case "BlockKeyword": - { - // parse the keyword list and remove them from the keyword hashtables - var keywordlist = value.Split(','); - - if (keywordlist.Length > 0) { - for (var i = 0; i < keywordlist.Length; i++) - { - BaseXmlSpawner.RemoveKeyword(keywordlist[i]); - } + XmlSpawnDir = value; + break; } + case "DiskAccessLevel": + { + DiskAccessLevel = Enum.Parse(value, true); + break; + } + case "SmartSpawnAccessLevel": + { + SmartSpawnAccessLevel = Enum.Parse(value, true); + break; + } + case "defaultTriggerSound": + { + defaultTriggerSound = ConvertToInt(value); + defProximityTriggerSound = defaultTriggerSound; + break; + } + case "BaseItemId": + { + BaseItemId = ConvertToInt(value); + break; + } + case "ShowItemId": + { + ShowItemId = ConvertToInt(value); + break; + } + case "MaxMoveCheck": + { + MaxMoveCheck = ConvertToInt(value); + break; + } + case "defMinDelay": + { + defMinDelay = TimeSpan.FromMinutes(ConvertToInt(value)); + break; + } + case "defMaxDelay": + { + defMaxDelay = TimeSpan.FromMinutes(ConvertToInt(value)); + break; + } + case "defRelativeHome": + { + defRelativeHome = bool.Parse(value); + break; + } + case "defSpawnRange": + { + defSpawnRange = ConvertToInt(value); + break; + } + case "defHomeRange": + { + defHomeRange = ConvertToInt(value); + break; + } + case "BlockKeyword": + { + // parse the keyword list and remove them from the keyword hashtables + var keywordlist = value.Split(','); - break; - } + if (keywordlist.Length > 0) + { + for (var i = 0; i < keywordlist.Length; i++) + { + BaseXmlSpawner.RemoveKeyword(keywordlist[i]); + } + } + + break; + } case "BlockCommand": case "ChangeCommand": - { - // delay processing of these settings until after all commands have been registered in their Initialize methods - _ = Timer.DelayCall(TimeSpan.Zero, DelayedAssignSettings, argname, value); - break; - } + { + // delay processing of these settings until after all commands have been registered in their Initialize methods + _ = Timer.DelayCall(TimeSpan.Zero, DelayedAssignSettings, argname, value); + break; + } default: - { - return false; - } + { + return false; + } } return true; @@ -2828,137 +2807,137 @@ public class XmlSpawner : Item, ISpawner switch (argname) { case "BlockCommand": - { - // delay processing of this until after all commands have been registered in their Initialize methods - // parse the command list and remove them from the command hashtables - // the syntax is "commandname, commandname, etc." - var keywordlist = value.Split(','); - - if (keywordlist.Length > 0) { - for (var i = 0; i < keywordlist.Length; i++) + // delay processing of this until after all commands have been registered in their Initialize methods + // parse the command list and remove them from the command hashtables + // the syntax is "commandname, commandname, etc." + var keywordlist = value.Split(','); + + if (keywordlist.Length > 0) { - var commandname = keywordlist[i].Trim().ToLower(); - try + for (var i = 0; i < keywordlist.Length; i++) { - _ = CommandSystem.Entries.Remove(commandname); - } - catch - { - Console.WriteLine("{0}: invalid command {1}", argname, commandname); - } - } - } - break; - } - case "ChangeCommand": - { - // delay processing of this until after all commands have been registered in their Initialize methods - // parse the command list and rehash them into the command hashtables - // the syntax is "oldname:newname[:accesslevel], oldname:newname[:accesslevel], etc." - var keywordlist = value.Split(','); - - if (keywordlist.Length > 0) - { - for (var i = 0; i < keywordlist.Length; i++) - { - var namelist = keywordlist[i].Split(':'); - if (namelist.Length > 1) - { - var oldname = namelist[0].Trim().ToLower(); - var newname = namelist[1].Trim(); - - if (newname.Length == 0) - { - newname = oldname; - } - - var access = AccessLevel.Player; - var validaccess = false; - if (namelist.Length > 2) - { - // get the new accesslevel - try - { - access = (AccessLevel)Enum.Parse(typeof(AccessLevel), namelist[2].Trim(), true); - validaccess = true; - } - catch - { - Console.WriteLine("{0}: invalid accesslevel {1} for {2}", argname, namelist[2], newname); - } - } - // find the command entry for the old name - CommandEntry e = null; + var commandname = keywordlist[i].Trim().ToLower(); try { - e = CommandSystem.Entries[oldname]; + _ = CommandSystem.Entries.Remove(commandname); } catch { - Console.WriteLine("{0}: invalid command {1}", argname, oldname); + Console.WriteLine("{0}: invalid command {1}", argname, commandname); } - if (e != null) + } + } + break; + } + case "ChangeCommand": + { + // delay processing of this until after all commands have been registered in their Initialize methods + // parse the command list and rehash them into the command hashtables + // the syntax is "oldname:newname[:accesslevel], oldname:newname[:accesslevel], etc." + var keywordlist = value.Split(','); + + if (keywordlist.Length > 0) + { + for (var i = 0; i < keywordlist.Length; i++) + { + var namelist = keywordlist[i].Split(':'); + if (namelist.Length > 1) { - if (!validaccess) + var oldname = namelist[0].Trim().ToLower(); + var newname = namelist[1].Trim(); + + if (newname.Length == 0) { - // use the old accesslevel - access = e.AccessLevel; + newname = oldname; } - // remove the old command entry - _ = CommandSystem.Entries.Remove(oldname); - // register the new command using the old handler - CommandSystem.Register(newname, access, e.Handler); - } - // also look in the targetcommands list and adjust name and accesslevel there - foreach (var b in TargetCommands.AllCommands) - { - if (b.Commands != null) + var access = AccessLevel.Player; + var validaccess = false; + if (namelist.Length > 2) { - for (var j = 0; j < b.Commands.Length; j++) + // get the new accesslevel + try { - var commandname = b.Commands[j]; - if (commandname.ToLower() == oldname) + access = (AccessLevel)Enum.Parse(typeof(AccessLevel), namelist[2].Trim(), true); + validaccess = true; + } + catch + { + Console.WriteLine("{0}: invalid accesslevel {1} for {2}", argname, namelist[2], newname); + } + } + // find the command entry for the old name + CommandEntry e = null; + try + { + e = CommandSystem.Entries[oldname]; + } + catch + { + Console.WriteLine("{0}: invalid command {1}", argname, oldname); + } + if (e != null) + { + if (!validaccess) + { + // use the old accesslevel + access = e.AccessLevel; + } + // remove the old command entry + _ = CommandSystem.Entries.Remove(oldname); + // register the new command using the old handler + CommandSystem.Register(newname, access, e.Handler); + } + + // also look in the targetcommands list and adjust name and accesslevel there + foreach (var b in TargetCommands.AllCommands) + { + if (b.Commands != null) + { + for (var j = 0; j < b.Commands.Length; j++) { - // modify the basecommand with the new name and access - b.Commands[j] = newname; - if (validaccess) + var commandname = b.Commands[j]; + if (commandname.ToLower() == oldname) { - b.AccessLevel = access; - } - - // re-register it in the implementors hashtable - var impls = BaseCommandImplementor.Implementors; - - for (var k = 0; k < impls.Count; ++k) - { - var impl = impls[k]; - - if ((b.Supports & impl.SupportRequirement) != 0) + // modify the basecommand with the new name and access + b.Commands[j] = newname; + if (validaccess) { - try - { - _ = impl.Commands.Remove(commandname); - } - catch (Exception ex) - { - Diagnostics.ExceptionLogging.LogException(ex); - } - impl.Register(b); + b.AccessLevel = access; } - } - break; + // re-register it in the implementors hashtable + var impls = BaseCommandImplementor.Implementors; + + for (var k = 0; k < impls.Count; ++k) + { + var impl = impls[k]; + + if ((b.Supports & impl.SupportRequirement) != 0) + { + try + { + _ = impl.Commands.Remove(commandname); + } + catch (Exception ex) + { + Diagnostics.ExceptionLogging.LogException(ex); + } + impl.Register(b); + } + } + + break; + } } } } } } } + break; } - break; - } } } @@ -3136,10 +3115,8 @@ public class XmlSpawner : Item, ISpawner { private readonly CommandEventArgs m_e; public GetValueTarget(CommandEventArgs e) - : base(30, false, TargetFlags.None) - { + : base(30, false, TargetFlags.None) => m_e = e; - } protected override void OnTarget(Mobile from, object targeted) { @@ -3208,12 +3185,12 @@ public class XmlSpawner : Item, ISpawner { if (targeted is XmlSpawner spawner) { - spawner.ShowTagList(spawner); + ShowTagList(spawner); } } } - public void ShowTagList(XmlSpawner spawner) + public static void ShowTagList(XmlSpawner spawner) { var count = 0; Console.WriteLine("{0} tags", spawner.m_KeywordTagList.Count); @@ -3229,10 +3206,8 @@ public class XmlSpawner : Item, ISpawner { private readonly CommandEventArgs m_e; public XmlHomeTarget(CommandEventArgs e) - : base(30, false, TargetFlags.None) - { + : base(30, false, TargetFlags.None) => m_e = e; - } protected override void OnTarget(Mobile from, object targeted) { @@ -3405,7 +3380,7 @@ public class XmlSpawner : Item, ISpawner public static void XmlLoadDefaults(string filePath, Mobile m) { - if (m == null || m.Deleted) + if (m?.Deleted != false) { return; } @@ -3518,19 +3493,13 @@ public class XmlSpawner : Item, ISpawner { Diagnostics.ExceptionLogging.LogException(e); } - switch (todmode) + + defTODMode = todmode switch { - case (int)TODModeType.Realtime: - { - defTODMode = TODModeType.Realtime; - break; - } - case (int)TODModeType.Gametime: - { - defTODMode = TODModeType.Gametime; - break; - } - } + (int)TODModeType.Realtime => TODModeType.Realtime, + (int)TODModeType.Gametime => TODModeType.Gametime, + _ => defTODMode + }; } [Usage("XmlDefaults [defaultpropertyname value]")] @@ -3538,7 +3507,7 @@ public class XmlSpawner : Item, ISpawner public static void XmlDefaults_OnCommand(CommandEventArgs e) { var m = e.Mobile; - if (m == null || m.Deleted) + if (m?.Deleted != false) { return; } @@ -3687,19 +3656,12 @@ public class XmlSpawner : Item, ISpawner try { var todmode = Convert.ToInt32(e.Arguments[1]); - switch (todmode) + defTODMode = todmode switch { - case (int)TODModeType.Gametime: - { - defTODMode = TODModeType.Gametime; - break; - } - case (int)TODModeType.Realtime: - { - defTODMode = TODModeType.Realtime; - break; - } - } + (int)TODModeType.Gametime => TODModeType.Gametime, + (int)TODModeType.Realtime => TODModeType.Realtime, + _ => defTODMode + }; m.SendMessage($"TODMode = {defTODMode}"); } catch { m.SendMessage($"invalid value : {e.Arguments[1]}"); } @@ -3817,7 +3779,7 @@ public class XmlSpawner : Item, ISpawner // get rid of the external static marker for container-held spawners // check anything that might have been tagged with a container static - if (xmlItem.m_ShowContainerStatic != null && !xmlItem.m_ShowContainerStatic.Deleted) + if (xmlItem.m_ShowContainerStatic?.Deleted == false) { ToDelete.Add(xmlItem); } @@ -3825,7 +3787,7 @@ public class XmlSpawner : Item, ISpawner } foreach (var xml_item in ToDelete) { - if (xml_item.m_ShowContainerStatic != null && !xml_item.m_ShowContainerStatic.Deleted) + if (xml_item.m_ShowContainerStatic?.Deleted == false) { xml_item.m_ShowContainerStatic.Delete(); } @@ -3851,23 +3813,23 @@ public class XmlSpawner : Item, ISpawner // Get the map Map NewMap; // Convert the xml map value to a real map object - if (string.Compare(MapName, Map.Trammel.Name, true) == 0) + if (MapName.InsensitiveEquals(Map.Trammel.Name)) { NewMap = Map.Trammel; } - else if (string.Compare(MapName, Map.Felucca.Name, true) == 0) + else if (MapName.InsensitiveEquals(Map.Felucca.Name)) { NewMap = Map.Felucca; } - else if (string.Compare(MapName, Map.Ilshenar.Name, true) == 0) + else if (MapName.InsensitiveEquals(Map.Ilshenar.Name)) { NewMap = Map.Ilshenar; } - else if (string.Compare(MapName, Map.Malas.Name, true) == 0) + else if (MapName.InsensitiveEquals(Map.Malas.Name)) { NewMap = Map.Malas; } - else if (string.Compare(MapName, Map.Tokuno.Name, true) == 0) + else if (MapName.InsensitiveEquals(Map.Tokuno.Name)) { NewMap = Map.Tokuno; } @@ -3913,7 +3875,7 @@ public class XmlSpawner : Item, ISpawner [Description("Returns the spawn reduction due to SmartSpawning.")] public static void SmartStat_OnCommand(CommandEventArgs e) { - if (e == null || e.Mobile == null) + if (e?.Mobile == null) { return; } @@ -4145,9 +4107,7 @@ public class XmlSpawner : Item, ISpawner XmlUnLoadFromStream(fs, filename, SpawnerPrefix, from, out processedmaps, out processedspawners); } - else - // check to see if it is a directory - if (Directory.Exists(filename)) + else if (Directory.Exists(filename)) // check to see if it is a directory { // if so then import all of the .xml files in the directory string[] files = null; @@ -4156,7 +4116,7 @@ public class XmlSpawner : Item, ISpawner files = Directory.GetFiles(filename, "*.xml"); } catch { } - if (files != null && files.Length > 0) + if (files?.Length > 0) { from?.SendMessage($"UnLoading {files.Length} .xml files from directory {filename}"); @@ -4174,7 +4134,7 @@ public class XmlSpawner : Item, ISpawner dirs = Directory.GetDirectories(filename); } catch { } - if (dirs != null && dirs.Length > 0) + if (dirs?.Length > 0) { foreach (var dir in dirs) { @@ -4216,8 +4176,8 @@ public class XmlSpawner : Item, ISpawner var spawners_deleted = 0; from?.SendMessage( - $"UnLoading {"XmlSpawner"} objects{(!string.IsNullOrEmpty(SpawnerPrefix) ? $" beginning with {SpawnerPrefix}" : string.Empty)} from file {filename}." - ); + $"UnLoading {"XmlSpawner"} objects{(!string.IsNullOrEmpty(SpawnerPrefix) ? $" beginning with {SpawnerPrefix}" : string.Empty)} from file {filename}." + ); // Create the data set var ds = new DataSet(SpawnDataSetName); @@ -4246,7 +4206,7 @@ public class XmlSpawner : Item, ISpawner if (ds.Tables.Count > 0) { // Add each spawn point to the current map - if (ds.Tables[SpawnTablePointName] != null && ds.Tables[SpawnTablePointName].Rows.Count > 0) + if (ds.Tables[SpawnTablePointName]?.Rows.Count > 0) { foreach (DataRow dr in ds.Tables[SpawnTablePointName].Rows) { @@ -4281,27 +4241,27 @@ public class XmlSpawner : Item, ISpawner catch { } // Convert the xml map value to a real map object - if (string.Compare(XmlMapName, Map.Trammel.Name, true) == 0 || XmlMapName == "Trammel") + if (XmlMapName.InsensitiveEquals(Map.Trammel.Name) || XmlMapName == "Trammel") { SpawnMap = Map.Trammel; TrammelCount++; } - else if (string.Compare(XmlMapName, Map.Felucca.Name, true) == 0 || XmlMapName == "Felucca") + else if (XmlMapName.InsensitiveEquals(Map.Felucca.Name) || XmlMapName == "Felucca") { SpawnMap = Map.Felucca; FeluccaCount++; } - else if (string.Compare(XmlMapName, Map.Ilshenar.Name, true) == 0 || XmlMapName == "Ilshenar") + else if (XmlMapName.InsensitiveEquals(Map.Ilshenar.Name) || XmlMapName == "Ilshenar") { SpawnMap = Map.Ilshenar; IlshenarCount++; } - else if (string.Compare(XmlMapName, Map.Malas.Name, true) == 0 || XmlMapName == "Malas") + else if (XmlMapName.InsensitiveEquals(Map.Malas.Name) || XmlMapName == "Malas") { SpawnMap = Map.Malas; MalasCount++; } - else if (string.Compare(XmlMapName, Map.Tokuno.Name, true) == 0 || XmlMapName == "Tokuno") + else if (XmlMapName.InsensitiveEquals(Map.Tokuno.Name) || XmlMapName == "Tokuno") { SpawnMap = Map.Tokuno; TokunoCount++; @@ -4317,7 +4277,6 @@ public class XmlSpawner : Item, ISpawner } // Check if this spawner already exists - XmlSpawner OldSpawner = null; foreach (var i in World.Items.Values) { if (i is XmlSpawner checkXmlSpawner) @@ -4327,11 +4286,10 @@ public class XmlSpawner : Item, ISpawner if (checkXmlSpawner.UniqueId == SpawnId.ToString() /*&& (CheckXmlSpawner.Map == SpawnMap)*/) { - OldSpawner = checkXmlSpawner; - if (OldSpawner != null) + if (checkXmlSpawner != null) { spawners_deleted++; - OldSpawner.Delete(); + checkXmlSpawner.Delete(); } break; @@ -4352,8 +4310,8 @@ public class XmlSpawner : Item, ISpawner catch { } from?.SendMessage( - $"{spawners_deleted}/{TotalCount} spawner(s) were unloaded using file {filename} [Trammel={TrammelCount}, Felucca={FeluccaCount}, Ilshenar={IlshenarCount}, Malas={MalasCount}, Tokuno={TokunoCount}, Other={OtherCount}]." - ); + $"{spawners_deleted}/{TotalCount} spawner(s) were unloaded using file {filename} [Trammel={TrammelCount}, Felucca={FeluccaCount}, Ilshenar={IlshenarCount}, Malas={MalasCount}, Tokuno={TokunoCount}, Other={OtherCount}]." + ); if (bad_spawner_count > 0) { @@ -4425,7 +4383,7 @@ public class XmlSpawner : Item, ISpawner processedspawners = 0; var total_processed_maps = 0; var total_processed_spawners = 0; - if (filename == null || filename.Length <= 0 || from == null || from.Deleted) + if (filename == null || filename.Length <= 0 || from?.Deleted != false) { return; } @@ -4493,9 +4451,7 @@ public class XmlSpawner : Item, ISpawner processedmaps = 1; processedspawners = spawnercount; } - else - // check to see if it is a directory - if (Directory.Exists(filename)) + else if (Directory.Exists(filename)) // check to see if it is a directory { // if so then import all of the .map files in the directory string[] files = null; @@ -4504,7 +4460,7 @@ public class XmlSpawner : Item, ISpawner files = Directory.GetFiles(filename, "*.map"); } catch { } - if (files != null && files.Length > 0) + if (files?.Length > 0) { from.SendMessage($"Importing {files.Length} .map files from directory {filename}"); foreach (var file in files) @@ -4521,7 +4477,7 @@ public class XmlSpawner : Item, ISpawner dirs = Directory.GetDirectories(filename); } catch { } - if (dirs != null && dirs.Length > 0) + if (dirs?.Length > 0) { foreach (var dir in dirs) { @@ -4684,41 +4640,16 @@ public class XmlSpawner : Item, ISpawner map = overridemap; } - var spawnmap = Map.Internal; - switch (map) + var spawnmap = map switch { - case 0: - { - spawnmap = Map.Felucca; - // note it also does trammel - break; - } - case 1: - { - spawnmap = Map.Felucca; - break; - } - case 2: - { - spawnmap = Map.Trammel; - break; - } - case 3: - { - spawnmap = Map.Ilshenar; - break; - } - case 4: - { - spawnmap = Map.Malas; - break; - } - case 5: - { - spawnmap = Map.Tokuno; - break; - } - } + 0 => Map.Felucca, + 1 => Map.Felucca, + 2 => Map.Trammel, + 3 => Map.Ilshenar, + 4 => Map.Malas, + 5 => Map.Tokuno, + _ => Map.Internal + }; if (!IsValidMapLocation(x, y, spawnmap)) { @@ -4967,41 +4898,16 @@ public class XmlSpawner : Item, ISpawner map = overridemap; } - var spawnmap = Map.Internal; - switch (map) + var spawnmap = map switch { - case 0: - { - spawnmap = Map.Felucca; - // note it also does trammel - break; - } - case 1: - { - spawnmap = Map.Felucca; - break; - } - case 2: - { - spawnmap = Map.Trammel; - break; - } - case 3: - { - spawnmap = Map.Ilshenar; - break; - } - case 4: - { - spawnmap = Map.Malas; - break; - } - case 5: - { - spawnmap = Map.Tokuno; - break; - } - } + 0 => Map.Felucca, + 1 => Map.Felucca, + 2 => Map.Trammel, + 3 => Map.Ilshenar, + 4 => Map.Malas, + 5 => Map.Tokuno, + _ => Map.Internal + }; if (!IsValidMapLocation(x, y, spawnmap)) { @@ -5232,256 +5138,10 @@ public class XmlSpawner : Item, ISpawner } } } + return names; } - [Usage("XmlImportMSF filename")] - [Description("Loads msf files created by Morxeton's megaspawner as xmlspawners.")] - public static void XmlImportMSF_OnCommand(CommandEventArgs e) - { - if (e.Arguments.Length >= 1) - { - /* - // I'm not sure what the default location for .msf files is - string filename = e.GetString(0); - string filePath = Path.Combine("Data/Megaspawner", filename); - */ - var filePath = e.GetString(0); - if (File.Exists(filePath)) - { - var doc = new XmlDocument(); - doc.Load(filePath); - var root = doc["MegaSpawners"]; - if (root != null) - { - int successes = 0, failures = 0; - foreach (XmlElement spawner in root.GetElementsByTagName("MegaSpawner")) - { - - try - { - ImportMegaSpawner(e.Mobile, spawner); - successes++; - } - catch (Exception ex) { e.Mobile.SendMessage(33, $"{ex.Message} {spawner.InnerText}"); failures++; } - } - e.Mobile.SendMessage($"{successes:N0} megaspawners loaded successfully from {filePath}, {failures:N0} failures."); - } - else - { - e.Mobile.SendMessage("Invalid .msf file. No MegaSpawners node found"); - } - } - else - { - e.Mobile.SendMessage($"File {filePath} does not exist."); - } - } - else - { - e.Mobile.SendMessage("Usage: [XmlImportMSF "); - } - } - - private static void ImportMegaSpawner(Mobile from, XmlElement node) - { - var name = GetText(node["Name"], "MegaSpawner"); - _ = bool.Parse(GetText(node["Active"], "True")); - var location = Point3D.Parse(GetText(node["Location"], "Error")); - var map = Map.Parse(GetText(node["Map"], "Error")); - - var team = 0; - var group = false; - var maxcount = 0; // default maxcount of the spawner - var homeRange = 4; // default homerange - var spawnRange = 4; // default homerange - var maxDelay = TimeSpan.FromMinutes(10); - var minDelay = TimeSpan.FromMinutes(5); - - var listnode = node["EntryLists"]; - - var nentries = 0; - SpawnObject[] so = null; - - if (listnode != null) - { - // get the number of entries - if (listnode.HasAttributes) - { - var attr = listnode.Attributes; - - nentries = int.Parse(attr.GetNamedItem("count").Value); - } - if (nentries > 0) - { - so = new SpawnObject[nentries]; - - var entrycount = 0; - var diff = false; - foreach (XmlElement entrynode in listnode.GetElementsByTagName("EntryList")) - { - // go through each entry and add a spawn object for it - if (entrynode != null) - { - if (entrycount == 0) - { - // get the spawner defaults from the first entry - // dont handle the individually specified entry attributes - group = bool.Parse(GetText(entrynode["GroupSpawn"], "False")); - maxDelay = TimeSpan.FromSeconds(int.Parse(GetText(entrynode["MaxDelay"], "10:00"))); - minDelay = TimeSpan.FromSeconds(int.Parse(GetText(entrynode["MinDelay"], "05:00"))); - homeRange = int.Parse(GetText(entrynode["WalkRange"], "10")); - spawnRange = int.Parse(GetText(entrynode["SpawnRange"], "4")); - } - else - { - // just check for consistency with other entries and report discrepancies - if (group != bool.Parse(GetText(entrynode["GroupSpawn"], "False"))) - { - diff = true; - // log it - try - { - using var op = new StreamWriter("badimport.log", true); - op.WriteLine("MSFimport : individual group entry difference: {0} vs {1}", - GetText(entrynode["GroupSpawn"], "False"), group); - } - catch { } - } - if (minDelay != TimeSpan.FromSeconds(int.Parse(GetText(entrynode["MinDelay"], "05:00")))) - { - diff = true; - // log it - try - { - using var op = new StreamWriter("badimport.log", true); - op.WriteLine("MSFimport : individual mindelay entry difference: {0} vs {1}", - GetText(entrynode["MinDelay"], "05:00"), minDelay); - } - catch { } - } - if (maxDelay != TimeSpan.FromSeconds(int.Parse(GetText(entrynode["MaxDelay"], "10:00")))) - { - diff = true; - // log it - try - { - using var op = new StreamWriter("badimport.log", true); - op.WriteLine("MSFimport : individual maxdelay entry difference: {0} vs {1}", - GetText(entrynode["MaxDelay"], "10:00"), maxDelay); - } - catch { } - } - if (homeRange != int.Parse(GetText(entrynode["WalkRange"], "10"))) - { - diff = true; - // log it - try - { - using var op = new StreamWriter("badimport.log", true); - op.WriteLine("MSFimport : individual homerange entry difference: {0} vs {1}", - GetText(entrynode["WalkRange"], "10"), homeRange); - } - catch { } - } - if (spawnRange != int.Parse(GetText(entrynode["SpawnRange"], "4"))) - { - diff = true; - // log it - try - { - using var op = new StreamWriter("badimport.log", true); - op.WriteLine("MSFimport : individual spawnrange entry difference: {0} vs {1}", - GetText(entrynode["SpawnRange"], "4"), spawnRange); - } - catch { } - } - } - - // these apply to individual entries - var amount = int.Parse(GetText(entrynode["Amount"], "1")); - var entryname = GetText(entrynode["EntryType"], ""); - - // keep track of the maxcount for the spawner by adding the individual amounts - maxcount += amount; - - // add the creature entry - so[entrycount] = new SpawnObject(entryname, amount); - - entrycount++; - if (entrycount > nentries) - { - // log it - try - { - using var op = new StreamWriter("badimport.log", true); - op.WriteLine($"{Core.Now} MSFImport Error; inconsistent entry count {location} {map}"); - op.WriteLine(); - } - catch { } - from.SendMessage($"Inconsistent entry count detected at {location} {map}."); - break; - } - - } - } - if (diff) - { - from.SendMessage($"Individual entry setting detected at {location} {map}."); - // log it - try - { - using var op = new StreamWriter("badimport.log", true); - op.WriteLine($"{Core.Now} MSFImport: Individual entry setting differences listed above from spawner at {location} {map}"); - op.WriteLine(); - } - catch { } - } - } - } - - // assign it a unique id - var SpawnId = Guid.NewGuid(); - // Create the new xml spawner - var spawner = new XmlSpawner(SpawnId, location.X, location.Y, 0, 0, name, maxcount, - minDelay, maxDelay, TimeSpan.FromMinutes(0), -1, defaultTriggerSound, 1, - team, homeRange, false, so, TimeSpan.FromMinutes(0), TimeSpan.FromMinutes(0), TimeSpan.FromMinutes(0), - TimeSpan.FromMinutes(0), null, null, null, null, null, - null, null, null, null, 1, null, group, defTODMode, defKillReset, false, -1, null, false, false, false, null, defDespawnTime, null, false, null) - { - SpawnRange = spawnRange, - PlayerCreated = true - }; - - // Try to find a valid Z height if required (Z == -999) - - if (location.Z == -999) - { - var NewZ = map.GetAverageZ(location.X, location.Y); - - if (map.CanFit(location.X, location.Y, NewZ, SpawnFitSize) == false) - { - for (var x = 1; x <= 39; x++) - { - if (map.CanFit(location.X, location.Y, NewZ + x, SpawnFitSize)) - { - NewZ += x; - break; - } - } - } - location.Z = NewZ; - } - - spawner.MoveToWorld(location, map); - - if (!IsValidMapLocation(location, spawner.Map)) - { - spawner.Delete(); - throw new Exception("Invalid spawner location."); - } - } - public static void XmlLoadFromFile(string filename, string SpawnerPrefix, Mobile from, Point3D fromloc, Map frommap, bool loadrelative, int maxrange, bool loadnew, out int processedmaps, out int processedspawners) { processedmaps = 0; @@ -5524,7 +5184,7 @@ public class XmlSpawner : Item, ISpawner files = Directory.GetFiles(filename, "*.xml"); } catch { } - if (files != null && files.Length > 0) + if (files?.Length > 0) { from?.SendMessage($"Loading {files.Length} .xml files from directory {filename}"); @@ -5542,7 +5202,7 @@ public class XmlSpawner : Item, ISpawner dirs = Directory.GetDirectories(filename); } catch { } - if (dirs != null && dirs.Length > 0) + if (dirs?.Length > 0) { foreach (var dir in dirs) { @@ -5653,7 +5313,7 @@ public class XmlSpawner : Item, ISpawner if (ds.Tables.Count > 0) { // Add each spawn point to the current map - if (ds.Tables[SpawnTablePointName] != null && ds.Tables[SpawnTablePointName].Rows.Count > 0) + if (ds.Tables[SpawnTablePointName]?.Rows.Count > 0) { foreach (DataRow dr in ds.Tables[SpawnTablePointName].Rows) { @@ -5745,27 +5405,27 @@ public class XmlSpawner : Item, ISpawner catch { questionable_spawner = true; } // Convert the xml map value to a real map object - if (string.Compare(XmlMapName, Map.Trammel.Name, true) == 0 || XmlMapName == "Trammel") + if (XmlMapName.InsensitiveEquals(Map.Trammel.Name) || XmlMapName == "Trammel") { SpawnMap = Map.Trammel; TrammelCount++; } - else if (string.Compare(XmlMapName, Map.Felucca.Name, true) == 0 || XmlMapName == "Felucca") + else if (XmlMapName.InsensitiveEquals(Map.Felucca.Name) || XmlMapName == "Felucca") { SpawnMap = Map.Felucca; FeluccaCount++; } - else if (string.Compare(XmlMapName, Map.Ilshenar.Name, true) == 0 || XmlMapName == "Ilshenar") + else if (XmlMapName.InsensitiveEquals(Map.Ilshenar.Name) || XmlMapName == "Ilshenar") { SpawnMap = Map.Ilshenar; IlshenarCount++; } - else if (string.Compare(XmlMapName, Map.Malas.Name, true) == 0 || XmlMapName == "Malas") + else if (XmlMapName.InsensitiveEquals(Map.Malas.Name) || XmlMapName == "Malas") { SpawnMap = Map.Malas; MalasCount++; } - else if (string.Compare(XmlMapName, Map.Tokuno.Name, true) == 0 || XmlMapName == "Tokuno") + else if (XmlMapName.InsensitiveEquals(Map.Tokuno.Name) || XmlMapName == "Tokuno") { SpawnMap = Map.Tokuno; TokunoCount++; @@ -5873,19 +5533,13 @@ public class XmlSpawner : Item, ISpawner var SpawnTODMode = TODModeType.Realtime; try { todmode = int.Parse((string)dr["TODMode"]); } catch { } - switch (todmode) + + SpawnTODMode = todmode switch { - case (int)TODModeType.Gametime: - { - SpawnTODMode = TODModeType.Gametime; - break; - } - case (int)TODModeType.Realtime: - { - SpawnTODMode = TODModeType.Realtime; - break; - } - } + (int)TODModeType.Gametime => TODModeType.Gametime, + (int)TODModeType.Realtime => TODModeType.Realtime, + _ => SpawnTODMode + }; var SpawnKillReset = defKillReset; try { SpawnKillReset = int.Parse((string)dr["KillReset"]); } @@ -6156,7 +5810,7 @@ public class XmlSpawner : Item, ISpawner } // if this is a container held spawner, drop it in the container - if (found_container && spawn_container != null && !spawn_container.Deleted) + if (found_container && spawn_container?.Deleted == false) { TheSpawn.Location = new Point3D(ContainerX, ContainerY, ContainerZ); spawn_container.AddItem(TheSpawn); @@ -6196,7 +5850,7 @@ public class XmlSpawner : Item, ISpawner from?.SendMessage("Resolving spawner self references"); - if (ds.Tables[SpawnTablePointName] != null && ds.Tables[SpawnTablePointName].Rows.Count > 0) + if (ds.Tables[SpawnTablePointName]?.Rows.Count > 0) { foreach (DataRow dr in ds.Tables[SpawnTablePointName].Rows) { @@ -6249,7 +5903,7 @@ public class XmlSpawner : Item, ISpawner } } - if (found_spawner && OldSpawner != null && !OldSpawner.Deleted) + if (found_spawner && OldSpawner?.Deleted == false) { // resolve item name references since they may have referred to spawners that were just created string setObjectName = null; @@ -6594,7 +6248,7 @@ public class XmlSpawner : Item, ISpawner public override void Execute(CommandEventArgs e, object obj) { - if (e == null || e.Mobile == null || e.Arguments == null) + if (e?.Mobile == null || e.Arguments == null) { return; } @@ -6630,7 +6284,7 @@ public class XmlSpawner : Item, ISpawner string dirname; - if (Directory.Exists(XmlSpawnDir) && filename != null && !filename.StartsWith("/") && !filename.StartsWith("\\")) + if (Directory.Exists(XmlSpawnDir) && filename?.StartsWith("/") == false && !filename.StartsWith("\\")) { // put it in the defaults directory if it exists dirname = $"{XmlSpawnDir}/{filename}"; @@ -6652,7 +6306,7 @@ public class XmlSpawner : Item, ISpawner private static void SaveSpawns(CommandEventArgs e, bool SaveAllMaps, bool oldformat) { - if (e == null || e.Mobile == null || e.Arguments == null || e.Arguments.Length < 1) + if (e?.Mobile == null || e.Arguments == null || e.Arguments.Length < 1) { return; } @@ -6663,7 +6317,7 @@ public class XmlSpawner : Item, ISpawner return; } - if (e.Arguments != null && e.Arguments.Length < 1) + if (e.Arguments?.Length < 1) { e.Mobile.SendMessage($"Usage: {e.Command} [SpawnerPrefixFilter]"); return; @@ -6681,7 +6335,7 @@ public class XmlSpawner : Item, ISpawner var filename = e.Arguments[0]; string dirname; - if (Directory.Exists(XmlSpawnDir) && filename != null && !filename.StartsWith("/") && !filename.StartsWith("\\")) + if (Directory.Exists(XmlSpawnDir) && filename?.StartsWith("/") == false && !filename.StartsWith("\\")) { // put it in the defaults directory if it exists dirname = $"{XmlSpawnDir}/{filename}"; @@ -6713,7 +6367,7 @@ public class XmlSpawner : Item, ISpawner if (i is XmlSpawner spawner && !spawner.Deleted && (SaveAllMaps || spawner.Map == e.Mobile.Map) //check for mob carried spawners and ignore them && spawner.RootParent is not Mobile - && (SpawnerPrefix == null || SpawnerPrefix.Length == 0 || spawner.Name != null && spawner.Name.StartsWith(SpawnerPrefix))) + && (SpawnerPrefix == null || SpawnerPrefix.Length == 0 || spawner.Name?.StartsWith(SpawnerPrefix) == true)) { saveslist.Add(spawner); } @@ -6723,10 +6377,7 @@ public class XmlSpawner : Item, ISpawner _ = SaveSpawnList(e.Mobile, saveslist, dirname, oldformat, true); } - public static bool SaveSpawnList(List savelist, Stream stream) - { - return SaveSpawnList(null, savelist, null, stream, false, false); - } + public static bool SaveSpawnList(List savelist, Stream stream) => SaveSpawnList(null, savelist, null, stream, false, false); public static bool SaveSpawnList(Mobile from, List savelist, string dirname, bool oldformat, bool verbose) { @@ -6860,13 +6511,13 @@ public class XmlSpawner : Item, ISpawner // Add each spawn point to the new table foreach (var sp in savelist) { - if (sp == null || sp.Map == null || sp.Deleted) + if (sp?.Map == null || sp.Deleted) { continue; } - if (verbose && from != null) // Send a message to the client that the spawner is being saved + if (verbose && from != null) { from.SendMessage(68, $"Saving '{sp.Name}' in {sp.Map.Name} at {sp.Location}"); } @@ -6884,23 +6535,23 @@ public class XmlSpawner : Item, ISpawner dr["Map"] = sp.Map.Name; // Convert the xml map value to a real map object - if (string.Compare(sp.Map.Name, Map.Trammel.Name, true) == 0) + if (sp.Map.Name.InsensitiveEquals(Map.Trammel.Name)) { TrammelCount++; } - else if (string.Compare(sp.Map.Name, Map.Felucca.Name, true) == 0) + else if (sp.Map.Name.InsensitiveEquals(Map.Felucca.Name)) { FeluccaCount++; } - else if (string.Compare(sp.Map.Name, Map.Ilshenar.Name, true) == 0) + else if (sp.Map.Name.InsensitiveEquals(Map.Ilshenar.Name)) { IlshenarCount++; } - else if (string.Compare(sp.Map.Name, Map.Malas.Name, true) == 0) + else if (sp.Map.Name.InsensitiveEquals(Map.Malas.Name)) { MalasCount++; } - else if (string.Compare(sp.Map.Name, Map.Tokuno.Name, true) == 0) + else if (sp.Map.Name.InsensitiveEquals(Map.Tokuno.Name)) { TokunoCount++; } @@ -6970,7 +6621,7 @@ public class XmlSpawner : Item, ISpawner dr["ProximityRange"] = sp.m_ProximityRange; dr["ProximityTriggerSound"] = sp.ProximitySound; dr["ProximityTriggerMessage"] = sp.ProximityMsg; - if (sp.m_ObjectPropertyItem != null && !sp.m_ObjectPropertyItem.Deleted) + if (sp.m_ObjectPropertyItem?.Deleted == false) { dr["ObjectPropertyItemName"] = $"{sp.m_ObjectPropertyItem.Name},{sp.m_ObjectPropertyItem.GetType().Name}"; } @@ -6980,7 +6631,7 @@ public class XmlSpawner : Item, ISpawner } dr["ObjectPropertyName"] = sp.m_ObjectPropertyName; - if (sp.SetItem != null && !sp.SetItem.Deleted) + if (sp.SetItem?.Deleted == false) { dr["SetPropertyItemName"] = $"{sp.SetItem.Name},{sp.SetItem.GetType().Name}"; } @@ -7072,7 +6723,7 @@ public class XmlSpawner : Item, ISpawner private static void WipeSpawners(CommandEventArgs e, bool WipeAll) { - if (e == null || e.Mobile == null) + if (e?.Mobile == null) { return; } @@ -7083,7 +6734,7 @@ public class XmlSpawner : Item, ISpawner var SpawnerPrefix = string.Empty; // Check if there is an argument provided (delete criteria) - if (e.Arguments != null && e.Arguments.Length > 0) + if (e.Arguments?.Length > 0) { SpawnerPrefix = e.Arguments[0]; } @@ -7153,7 +6804,7 @@ public class XmlSpawner : Item, ISpawner private static void RespawnSpawners(CommandEventArgs e, bool RespawnAll) { - if (e == null || e.Mobile == null) + if (e?.Mobile == null) { return; } @@ -7164,7 +6815,7 @@ public class XmlSpawner : Item, ISpawner var SpawnerPrefix = string.Empty; // Check if there is an argument provided (respawn criteria) - if (e.Arguments != null && e.Arguments.Length > 0) + if (e.Arguments?.Length > 0) { SpawnerPrefix = e.Arguments[0]; } @@ -7188,7 +6839,7 @@ public class XmlSpawner : Item, ISpawner if (i is XmlSpawner && (RespawnAll || i.Map == e.Mobile.Map) && i.Deleted == false) { // Check if there is a respawn condition - if (SpawnerPrefix == null || SpawnerPrefix.Length == 0 || i.Name != null && i.Name.StartsWith(SpawnerPrefix)) + if (SpawnerPrefix == null || SpawnerPrefix.Length == 0 || i.Name?.StartsWith(SpawnerPrefix) == true) { ToRespawn.Add(i); Count++; @@ -7595,7 +7246,7 @@ public class XmlSpawner : Item, ISpawner { // Check if the creature has been tamed or previously tamed and released // and if it is, remove it from the list of spawns - if (creature.Controlled || creature.IsStabled || creature.Owners != null && creature.Owners.Count > 0) + if (creature.Controlled || creature.IsStabled || creature.Owners?.Count > 0) { _ = so.SpawnedObjects.Remove(mobile); x--; @@ -7684,7 +7335,7 @@ public class XmlSpawner : Item, ISpawner for (var x = ToDelete.Count - 1; x >= 0; --x) //BaseXmlSpawner.KeywordTag i in ToDelete) { var i = ToDelete[x]; - if (i != null && !i.Deleted) + if (i?.Deleted == false) { i.Delete(); } @@ -7724,7 +7375,7 @@ public class XmlSpawner : Item, ISpawner for (var x = ToDelete.Count - 1; x >= 0; --x) //each (BaseXmlSpawner.KeywordTag i in ToDelete) { var i = ToDelete[x]; - if (i != null && !i.Deleted) + if (i?.Deleted == false) { i.Delete(); } @@ -7774,7 +7425,7 @@ public class XmlSpawner : Item, ISpawner for (var x = ToDelete.Count - 1; x >= 0; --x) //BaseXmlSpawner.KeywordTag i in ToDelete) { var i = ToDelete[x]; - if (i != null && !i.Deleted) + if (i?.Deleted == false) { i.Delete(); } @@ -7818,7 +7469,7 @@ public class XmlSpawner : Item, ISpawner for (var x = ToDelete.Count - 1; x >= 0; --x) //BaseXmlSpawner.KeywordTag i in ToDelete) { var i = ToDelete[x]; - if (i != null && !i.Deleted) + if (i?.Deleted == false) { i.Delete(); } @@ -7852,11 +7503,9 @@ public class XmlSpawner : Item, ISpawner return nsub; } - private int RandomAvailableSpawnIndex() - { + private int RandomAvailableSpawnIndex() => // get spawn indices randomly from all available spawns independent of group - return RandomAvailableSpawnIndex(-1); - } + RandomAvailableSpawnIndex(-1); // get spawn indices randomly from all available spawns of a group private int RandomAvailableSpawnIndex(int sgroup) @@ -8346,16 +7995,13 @@ public class XmlSpawner : Item, ISpawner if (m_ProximityRange >= 0 && CanSpawn) { // check all nearby players - IPooledEnumerable eable = GetMobilesInRange(m_ProximityRange); - foreach (Mobile p in eable) + foreach (Mobile p in GetMobilesInRange(m_ProximityRange)) { if (ValidPlayerTrig(p)) { CheckTriggers(p, null, true); } } - - eable.Free(); } if (m_Group) @@ -8494,7 +8140,7 @@ public class XmlSpawner : Item, ISpawner // return false if it cannot spawn, e.g. there is nothing to spawn or it is a triggerable spawner and has not been triggered public bool Spawn(bool smartspawn, byte loops) { - if (m_SpawnObjects != null && m_SpawnObjects.Count > 0 && (m_proximityActivated || CanFreeSpawn) && TODInRange) + if (m_SpawnObjects?.Count > 0 && (m_proximityActivated || CanFreeSpawn) && TODInRange) { m_HoldSequence = false; @@ -8588,16 +8234,10 @@ public class XmlSpawner : Item, ISpawner } // spawn an individual entry by index up to count times - public bool Spawn(int index, bool smartspawn, int count, byte loops) - { - return Spawn(index, smartspawn, count, false, loops); - } + public bool Spawn(int index, bool smartspawn, int count, byte loops) => Spawn(index, smartspawn, count, false, loops); // spawn an individual entry by index up to count times - public bool Spawn(int index, bool smartspawn, int count, bool ignoreloopprotection, byte loops) - { - return Spawn(index, smartspawn, count, -1, Point3D.Zero, ignoreloopprotection, loops); - } + public bool Spawn(int index, bool smartspawn, int count, bool ignoreloopprotection, byte loops) => Spawn(index, smartspawn, count, -1, Point3D.Zero, ignoreloopprotection, loops); // spawn an individual entry by spawn object public void Spawn(string SpawnObjectTypeName, bool smartspawn, int packrange, Point3D packcoord, byte loops) @@ -8628,10 +8268,7 @@ public class XmlSpawner : Item, ISpawner } // spawn an individual entry by index - public bool Spawn(int index, bool smartspawn, int packrange, Point3D packcoord, byte loops) - { - return Spawn(index, smartspawn, packrange, packcoord, false, loops); - } + public bool Spawn(int index, bool smartspawn, int packrange, Point3D packcoord, byte loops) => Spawn(index, smartspawn, packrange, packcoord, false, loops); // spawn an individual entry by index public bool Spawn(int index, bool smartspawn, int packrange, Point3D packcoord, bool ignoreloopprotection, byte loops) @@ -8693,7 +8330,7 @@ public class XmlSpawner : Item, ISpawner var requiresurface = true; // parse the # function specification for the entry - while (substitutedtypeName.StartsWith("#")) + while (substitutedtypeName.StartsWith('#')) { var args = BaseXmlSpawner.ParseSemicolonArgs(substitutedtypeName, 2); @@ -8709,96 +8346,96 @@ public class XmlSpawner : Item, ISpawner switch (keyvalueargs[0]) { case "#NOITEMID": - { - spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.NoItemID, TriggerMob, keyvalueargs)); - break; - } + { + spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.NoItemID, TriggerMob, keyvalueargs)); + break; + } case "#ITEMID": - { - spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.ItemID, TriggerMob, keyvalueargs)); - break; - } + { + spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.ItemID, TriggerMob, keyvalueargs)); + break; + } case "#NOTILES": - { - spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.NoTiles, TriggerMob, keyvalueargs)); - break; - } + { + spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.NoTiles, TriggerMob, keyvalueargs)); + break; + } case "#TILES": - { - spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.Tiles, TriggerMob, keyvalueargs)); - break; - } + { + spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.Tiles, TriggerMob, keyvalueargs)); + break; + } case "#WET": - { - spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.Wet, TriggerMob, keyvalueargs)); - break; - } + { + spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.Wet, TriggerMob, keyvalueargs)); + break; + } case "#XFILL": - { - spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.RowFill, TriggerMob, keyvalueargs)); - break; - } + { + spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.RowFill, TriggerMob, keyvalueargs)); + break; + } case "#YFILL": - { - spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.ColFill, TriggerMob, keyvalueargs)); - break; - } + { + spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.ColFill, TriggerMob, keyvalueargs)); + break; + } case "#EDGE": - { - spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.Perimeter, TriggerMob, keyvalueargs)); - break; - } + { + spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.Perimeter, TriggerMob, keyvalueargs)); + break; + } case "#PLAYER": - { - spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.Player, TriggerMob, keyvalueargs)); - break; - } + { + spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.Player, TriggerMob, keyvalueargs)); + break; + } case "#WAYPOINT": - { - spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.Waypoint, TriggerMob, keyvalueargs)); - break; - } + { + spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.Waypoint, TriggerMob, keyvalueargs)); + break; + } case "#RELXY": - { - spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.RelXY, TriggerMob, keyvalueargs)); - break; - } + { + spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.RelXY, TriggerMob, keyvalueargs)); + break; + } case "#DXY": - { - spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.DeltaLocation, TriggerMob, keyvalueargs)); - break; - } + { + spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.DeltaLocation, TriggerMob, keyvalueargs)); + break; + } case "#XY": - { - spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.Location, TriggerMob, keyvalueargs)); - break; - } + { + spawnpositioning.Add(new SpawnPositionInfo(SpawnPositionType.Location, TriggerMob, keyvalueargs)); + break; + } case "#CONDITION": - { - // test the specified condition string - // syntax is #CONDITION,proptest - // reparse with only one arg after the comma, this allows property tests that use commas as well - var ckeyvalueargs = BaseXmlSpawner.ParseCommaArgs(args[0], 2); - if (ckeyvalueargs.Length > 1) { - // dont spawn if it fails the test - if (!BaseXmlSpawner.CheckPropertyString(this, this, ckeyvalueargs[1], out var status)) + // test the specified condition string + // syntax is #CONDITION,proptest + // reparse with only one arg after the comma, this allows property tests that use commas as well + var ckeyvalueargs = BaseXmlSpawner.ParseCommaArgs(args[0], 2); + if (ckeyvalueargs.Length > 1) { - status_str = status; - return false; + // dont spawn if it fails the test + if (!BaseXmlSpawner.CheckPropertyString(this, this, ckeyvalueargs[1], out var status)) + { + status_str = status; + return false; + } } + else + { + status_str = $"invalid #CONDITION specification: {args[0]}"; + } + break; } - else - { - status_str = $"invalid #CONDITION specification: {args[0]}"; - } - break; - } default: - { - status_str = $"invalid # specification: {args[0]}"; - break; - } + { + status_str = $"invalid # specification: {args[0]}"; + break; + } } } } @@ -8953,15 +8590,9 @@ public class XmlSpawner : Item, ISpawner return false; } - public bool SpawnSubGroup(int sgroup, byte loops) - { - return SpawnSubGroup(sgroup, false, loops); - } + public bool SpawnSubGroup(int sgroup, byte loops) => SpawnSubGroup(sgroup, false, loops); - public bool SpawnSubGroup(int sgroup, bool smartspawn, byte loops) - { - return SpawnSubGroup(sgroup, false, false, loops); - } + public bool SpawnSubGroup(int sgroup, bool smartspawn, byte loops) => SpawnSubGroup(sgroup, false, false, loops); public bool SpawnSubGroup(int sgroup, bool smartspawn, bool ignoreloopprotection, byte loops) { @@ -8979,7 +8610,7 @@ public class XmlSpawner : Item, ISpawner { var so = m_SpawnObjects[j]; - if (so != null && so.SubGroup == sgroup) + if (so?.SubGroup == sgroup) { // find the first subgroup spawn to determine the packspawning reference coordinates if (so.PackRange >= 0 && packcoord == Point3D.Zero) @@ -9017,7 +8648,7 @@ public class XmlSpawner : Item, ISpawner { var so = m_SpawnObjects[j]; - if (so != null && so.SubGroup == sgroup && so.SpawnedObjects.Count > 0 && so.PackRange >= 0) + if (so?.SubGroup == sgroup && so.SpawnedObjects.Count > 0 && so.PackRange >= 0) { // if pack spawning is enabled for this subgroup, then get the // the origin for pack spawning using the first existing pack spawn @@ -9287,7 +8918,7 @@ public class XmlSpawner : Item, ISpawner public static SpawnObject GetSpawnObject(XmlSpawner spawner, int sgroup) { - if (spawner == null || spawner.m_SpawnObjects == null) + if (spawner?.m_SpawnObjects == null) { return null; } @@ -9305,7 +8936,7 @@ public class XmlSpawner : Item, ISpawner public static object GetSpawned(XmlSpawner spawner, int sgroup) { - if (spawner == null || spawner.m_SpawnObjects == null) + if (spawner?.m_SpawnObjects == null) { return null; } @@ -9329,7 +8960,7 @@ public class XmlSpawner : Item, ISpawner { var newlist = new List(); - if (spawner == null || spawner.m_SpawnObjects == null) + if (spawner?.m_SpawnObjects == null) { return null; } @@ -9383,7 +9014,7 @@ public class XmlSpawner : Item, ISpawner public bool HasIndividualSpawnTimes() { - if (m_SpawnObjects != null && m_SpawnObjects.Count > 0) + if (m_SpawnObjects?.Count > 0) { for (var i = 0; i < m_SpawnObjects.Count; i++) { @@ -9401,7 +9032,7 @@ public class XmlSpawner : Item, ISpawner private void ResetNextSpawnTimes() { - if (m_SpawnObjects != null && m_SpawnObjects.Count > 0) + if (m_SpawnObjects?.Count > 0) { for (var i = 0; i < m_SpawnObjects.Count; i++) { @@ -9412,7 +9043,7 @@ public class XmlSpawner : Item, ISpawner } } - public void RefreshNextSpawnTime(SpawnObject so) + public static void RefreshNextSpawnTime(SpawnObject so) { if (so == null) { @@ -9486,7 +9117,7 @@ public class XmlSpawner : Item, ISpawner if (!string.IsNullOrEmpty(waypointstr)) { var wayargs = BaseXmlSpawner.ParseString(waypointstr, 2, ","); - if (wayargs != null && wayargs.Length > 0) + if (wayargs?.Length > 0) { // is this a SERIAL specification? if (wayargs[0] == "SERIAL") @@ -9530,19 +9161,10 @@ public class XmlSpawner : Item, ISpawner return false; } - var tiles = map.Tiles.GetStaticTiles(X, Y, true); - - if (tiles == null) - { - return false; - } - // go through the tiles and see if any are at the Z location - foreach (var o in tiles) + foreach (var staticTile in map.Tiles.GetStaticAndMultiTiles(X, Y)) { - var i = o; - - if (i.Z + i.Height == Z) + if (staticTile.Z + staticTile.Height == Z) { return true; } @@ -9551,7 +9173,7 @@ public class XmlSpawner : Item, ISpawner return false; } - private bool CheckHoldSmartSpawning(object o) + private static bool CheckHoldSmartSpawning(object o) { if (o == null) { @@ -9687,11 +9309,9 @@ public class XmlSpawner : Item, ISpawner Console.WriteLine("landtile at {0},{1},{2} wet={3} impassable={4} hassurface={5}", x, y, z, wet, impassable, hasSurface); } - var staticTiles = map.Tiles.GetStaticTiles(x, y, true); - - for (var i = 0; i < staticTiles.Length; ++i) + foreach (var staticTile in map.Tiles.GetStaticAndMultiTiles(x, y)) { - var id = TileData.ItemTable[staticTiles[i].ID & TileData.MaxItemValue]; + var id = TileData.ItemTable[staticTile.ID & TileData.MaxItemValue]; surface = id.Surface; impassable = id.Impassable; if (checkmob) @@ -9711,12 +9331,12 @@ public class XmlSpawner : Item, ISpawner } } - if ((surface || impassable) && staticTiles[i].Z + id.CalcHeight > z && z + height > staticTiles[i].Z) + if ((surface || impassable) && staticTile.Z + id.CalcHeight > z && z + height > staticTile.Z) { return false; } - if (surface && !impassable && z == staticTiles[i].Z + id.CalcHeight) + if (surface && !impassable && z == staticTile.Z + id.CalcHeight) { hasSurface = true; } @@ -9726,45 +9346,41 @@ public class XmlSpawner : Item, ISpawner Console.WriteLine("statics hassurface={0}", hasSurface); } - var sector = map.GetSector(x, y); - var items = sector.Items; - var mobs = sector.Mobiles; - - for (var i = 0; i < items.Count; ++i) + foreach (var item in map.GetItemsAt(x, y)) { - var item = items[i]; - - if (item.ItemID < 0x4000 && item.AtWorldPoint(x, y)) + if (item.ItemID >= 0x4000) { - var id = item.ItemData; - surface = id.Surface; - impassable = id.Impassable; - if (checkmob) - { - wet = (id.Flags & TileFlag.Wet) != 0; - // dont allow wateronly creatures on land - if (cantwalk && !wet) - { - impassable = true; - } + continue; + } - // allow water creatures on water - if (canswim && wet) - { - surface = true; - impassable = false; - } + var id = item.ItemData; + surface = id.Surface; + impassable = id.Impassable; + if (checkmob) + { + wet = (id.Flags & TileFlag.Wet) != 0; + // dont allow wateronly creatures on land + if (cantwalk && !wet) + { + impassable = true; } - if ((surface || impassable || checkBlocksFit && item.BlocksFit) && item.Z + id.CalcHeight > z && z + height > item.Z) + // allow water creatures on water + if (canswim && wet) { - return false; + surface = true; + impassable = false; } + } - if (surface && !impassable && !item.Movable && z == item.Z + id.CalcHeight) - { - hasSurface = true; - } + if ((surface || impassable || checkBlocksFit && item.BlocksFit) && item.Z + id.CalcHeight > z && z + height > item.Z) + { + return false; + } + + if (surface && !impassable && !item.Movable && z == item.Z + id.CalcHeight) + { + hasSurface = true; } } @@ -9775,16 +9391,11 @@ public class XmlSpawner : Item, ISpawner if (checkMobiles) { - for (var i = 0; i < mobs.Count; ++i) + foreach (var m in map.GetMobilesAt(x, y)) { - var m = mobs[i]; - - if (m.Location.X == x && m.Location.Y == y && (m.AccessLevel == AccessLevel.Player || !m.Hidden)) + if ((m.AccessLevel == AccessLevel.Player || !m.Hidden) && m.Z + 16 > z && z + height > m.Z) { - if (m.Z + 16 > z && z + height > m.Z) - { - return false; - } + return false; } } } @@ -9807,14 +9418,23 @@ public class XmlSpawner : Item, ISpawner return Region.Find(new Point3D(x, y, z), Map).AllowSpawn() && Map.CanFit(x, y, z, 16); } - public static bool HasRegionPoints(Region r) - { - return r != null && r.Area.Length > 0; - } + public static bool HasRegionPoints(Region r) => r?.Area.Length > 0; public Rectangle2D SpawnerBounds => new(m_X, m_Y, m_Width + 1, m_Height + 1); - private void FindTileLocations(ref List locations, Map map, int startx, int starty, int width, int height, List includetilelist, List excludetilelist, TileFlag tileflag, bool checkitems, int spawnerZ) + private static void FindTileLocations( + ref List locations, + Map map, + int startx, + int starty, + int width, + int height, + List includetilelist, + List excludetilelist, + TileFlag tileflag, + bool checkitems, + int spawnerZ + ) { if (width < 0 || height < 0 || map == null) { @@ -9823,9 +9443,6 @@ public class XmlSpawner : Item, ISpawner locations ??= new List(); - bool includetile; - bool excludetile; - for (var x = startx; x <= startx + width; x++) { for (var y = starty; y <= starty + height; y++) @@ -9837,7 +9454,8 @@ public class XmlSpawner : Item, ISpawner var lflags = TileData.LandTable[ltile.ID & TileData.MaxLandValue].Flags; // check the land tile - if (includetilelist != null && includetilelist.Count > 0) + bool includetile; + if (includetilelist?.Count > 0) { includetile = includetilelist.Contains(ltile.ID & TileData.MaxLandValue); } @@ -9847,7 +9465,8 @@ public class XmlSpawner : Item, ISpawner } // non-excluded tiles must also be passable - if (excludetilelist != null && excludetilelist.Count > 0) + bool excludetile; + if (excludetilelist?.Count > 0) { // also require the tile to be passable excludetile = (lflags & TileFlag.Impassable) != 0 || excludetilelist.Contains(ltile.ID & TileData.MaxLandValue); @@ -9863,15 +9482,12 @@ public class XmlSpawner : Item, ISpawner allok = true; } - var statictiles = map.Tiles.GetStaticTiles(x, y, true); - // check the static tiles - for (var i = 0; i < statictiles.Length; ++i) + foreach (var stile in map.Tiles.GetStaticAndMultiTiles(x, y)) { - var stile = statictiles[i]; var sflags = TileData.ItemTable[stile.ID & TileData.MaxItemValue].Flags; - if (includetilelist != null && includetilelist.Count > 0) + if (includetilelist?.Count > 0) { includetile = includetilelist.Contains(stile.ID & TileData.MaxItemValue); } @@ -9881,7 +9497,7 @@ public class XmlSpawner : Item, ISpawner } // non-excluded tiles must also be passable - if (excludetilelist != null && excludetilelist.Count > 0) + if (excludetilelist?.Count > 0) { excludetile = (sflags & TileFlag.Impassable) != 0 || excludetilelist.Contains(stile.ID & TileData.MaxItemValue); } @@ -9914,10 +9530,8 @@ public class XmlSpawner : Item, ISpawner if (checkitems) { - IPooledEnumerable itemslist = map.GetItemsInRange(new Point3D(x, y, 0), 0); - // check the itemsid - foreach (Item i in itemslist) + foreach (Item i in map.GetItemsAt(x, y)) { if (i.ItemData.Impassable) { @@ -9925,7 +9539,7 @@ public class XmlSpawner : Item, ISpawner } var iflags = TileData.ItemTable[i.ItemID & TileData.MaxItemValue].Flags; - if (includetilelist != null && includetilelist.Count > 0) + if (includetilelist?.Count > 0) { includetile = includetilelist.Contains(i.ItemID & TileData.MaxItemValue); } @@ -9934,7 +9548,7 @@ public class XmlSpawner : Item, ISpawner includetile = true; } - if (excludetilelist != null && excludetilelist.Count > 0) + if (excludetilelist?.Count > 0) { excludetile = excludetilelist.Contains(i.ItemID & TileData.MaxItemValue); } @@ -9949,8 +9563,6 @@ public class XmlSpawner : Item, ISpawner allok = true; } } - - itemslist.Free(); } if (allok && !excludetile) @@ -9963,7 +9575,7 @@ public class XmlSpawner : Item, ISpawner private void FindRegionTileLocations(ref List locations, Region r, List includetilelist, List excludetilelist, TileFlag tileflag, bool checkitems, int spawnerZ) { - if (r == null || r.Area == null) + if (r?.Area == null) { return; } @@ -10032,24 +9644,17 @@ public class XmlSpawner : Item, ISpawner return new Point2D(x, y); } - public Point3D GetSpawnPosition(ISpawnable spawned, Map map) - { - return GetSpawnPosition(true, spawned as Mobile); - } + public Point3D GetSpawnPosition(ISpawnable spawned, Map map) => GetSpawnPosition(true, spawned as Mobile); // used for getting non-mobile spawn positions - public Point3D GetSpawnPosition(bool requiresurface) - { + public Point3D GetSpawnPosition(bool requiresurface) => // no pack spawning - return GetSpawnPosition(requiresurface, -1, Point3D.Zero, null, null); - } + GetSpawnPosition(requiresurface, -1, Point3D.Zero, null, null); // used for getting mobile spawn positions - public Point3D GetSpawnPosition(bool requiresurface, Mobile mob) - { + public Point3D GetSpawnPosition(bool requiresurface, Mobile mob) => // no pack spawning - return GetSpawnPosition(requiresurface, -1, Point3D.Zero, null, mob); - } + GetSpawnPosition(requiresurface, -1, Point3D.Zero, null, mob); // used for getting non-mobile spawn positions public Point3D GetSpawnPosition( @@ -10057,10 +9662,8 @@ public class XmlSpawner : Item, ISpawner int packrange, Point3D packcoord, List spawnpositioning - ) - { - return GetSpawnPosition(requiresurface, packrange, packcoord, spawnpositioning, null); - } + ) => + GetSpawnPosition(requiresurface, packrange, packcoord, spawnpositioning, null); public Point3D GetSpawnPosition(bool requiresurface, int packrange, Point3D packcoord, List spawnpositioning, Mobile mob) { @@ -10104,205 +9707,206 @@ public class XmlSpawner : Item, ISpawner switch (s.positionType) { case SpawnPositionType.Wet: - { - // syntax Wet - // find all of the wet tiles - tileflag |= TileFlag.Wet; - requiresurface = false; - break; - } + { + // syntax Wet + // find all of the wet tiles + tileflag |= TileFlag.Wet; + requiresurface = false; + break; + } case SpawnPositionType.ItemID: - { - checkitems = true; - goto case SpawnPositionType.Tiles; - } + { + checkitems = true; + goto case SpawnPositionType.Tiles; + } case SpawnPositionType.NoItemID: - { - checkitems = true; - goto case SpawnPositionType.NoTiles; - } + + { + checkitems = true; + goto case SpawnPositionType.NoTiles; + } case SpawnPositionType.Tiles: - { - // syntax Tiles,start[,end] - // get the tiles in the range - requiresurface = false; - var start = -1; - var end = -1; - if (positionargs != null && positionargs.Length > 1) { - try + // syntax Tiles,start[,end] + // get the tiles in the range + requiresurface = false; + var start = -1; + var end = -1; + if (positionargs?.Length > 1) { - start = int.Parse(positionargs[1]); + try + { + start = int.Parse(positionargs[1]); + } + catch { } } - catch { } - } - if (positionargs != null && positionargs.Length > 2) - { - try + if (positionargs?.Length > 2) { - end = int.Parse(positionargs[2]); + try + { + end = int.Parse(positionargs[2]); + } + catch { } } - catch { } - } - includetilelist ??= new List(); + includetilelist ??= new List(); - // add the tiles to the list - if (start > -1 && end < 0) - { - includetilelist.Add(start); - } - else - if (start > -1 && end > -1) - { - for (var j = start; j <= end; j++) + // add the tiles to the list + if (start > -1 && end < 0) { - includetilelist.Add(j); + includetilelist.Add(start); } + else + if (start > -1 && end > -1) + { + for (var j = start; j <= end; j++) + { + includetilelist.Add(j); + } + } + break; } - break; - } case SpawnPositionType.NoTiles: - { - // syntax Tiles,start[,end] - // get the tiles in the range - requiresurface = false; - var start = -1; - var end = -1; - if (positionargs != null && positionargs.Length > 1) { - try + // syntax Tiles,start[,end] + // get the tiles in the range + requiresurface = false; + var start = -1; + var end = -1; + if (positionargs?.Length > 1) { - start = int.Parse(positionargs[1]); + try + { + start = int.Parse(positionargs[1]); + } + catch { } } - catch { } - } - if (positionargs != null && positionargs.Length > 2) - { - try + if (positionargs?.Length > 2) { - end = int.Parse(positionargs[2]); + try + { + end = int.Parse(positionargs[2]); + } + catch { } } - catch { } - } - excludetilelist ??= new List(); + excludetilelist ??= new List(); - // add the tiles to the list - if (start > -1 && end < 0) - { - excludetilelist.Add(start); - } - else - if (start > -1 && end > -1) - { - for (var j = start; j <= end; j++) + // add the tiles to the list + if (start > -1 && end < 0) { - excludetilelist.Add(j); + excludetilelist.Add(start); } + else + if (start > -1 && end > -1) + { + for (var j = start; j <= end; j++) + { + excludetilelist.Add(j); + } + } + break; } - break; - } case SpawnPositionType.RowFill: case SpawnPositionType.ColFill: case SpawnPositionType.Perimeter: - { - // syntax XFILL[,inc] - // syntax YFILL[,inc] - // syntax EDGE[,inc] - positioning = s.positionType; - if (positionargs != null && positionargs.Length > 1) { - try + // syntax XFILL[,inc] + // syntax YFILL[,inc] + // syntax EDGE[,inc] + positioning = s.positionType; + if (positionargs?.Length > 1) { - fillinc = int.Parse(positionargs[1]); + try + { + fillinc = int.Parse(positionargs[1]); + } + catch { } } - catch { } + break; } - break; - } case SpawnPositionType.RelXY: case SpawnPositionType.DeltaLocation: case SpawnPositionType.Location: - { - // syntax RELXY,xinc,yinc[,zinc] - // syntax XY,x,y[,z] - // syntax DXY,dx,dy[,dz] - positioning = s.positionType; - if (positionargs != null && positionargs.Length > 2) { - try + // syntax RELXY,xinc,yinc[,zinc] + // syntax XY,x,y[,z] + // syntax DXY,dx,dy[,dz] + positioning = s.positionType; + if (positionargs?.Length > 2) { - xinc = int.Parse(positionargs[1]); - yinc = int.Parse(positionargs[2]); - } - catch { } - } - if (positionargs != null && positionargs.Length > 3) - { - try - { - zinc = int.Parse(positionargs[3]); - } - catch { } - } - break; - } - case SpawnPositionType.Waypoint: - { - // syntax WAYPOINT,prefix[,range] - positioning = s.positionType; - if (positionargs != null && positionargs.Length > 1) - { - prefix = positionargs[1]; - } - - if (positionargs != null && positionargs.Length > 2) - { - try - { - positionrange = int.Parse(positionargs[2]); - } - catch { } - } - - // find a list of items that match the waypoint prefix - if (prefix != null) - { - // see if there is an existing hashtable for the waypoint lists - spawnPositionWayTable ??= new Dictionary>(); - - // no existing list so create a new one - if (!spawnPositionWayTable.TryGetValue(prefix, out WayList) || WayList == null) - { - WayList = new List(); - - foreach (var i in World.Items.Values) + try { - if (i is WayPoint && !string.IsNullOrEmpty(i.Name) && i.Map == Map && i.Name == prefix) - { - // add it to the list of items - WayList.Add(i); - } + xinc = int.Parse(positionargs[1]); + yinc = int.Parse(positionargs[2]); } - // add the new list to the local table - spawnPositionWayTable[prefix] = WayList; + catch { } } - } - break; - } - case SpawnPositionType.Player: - { - // syntax PLAYER[,range] - positioning = s.positionType; - if (positionargs != null && positionargs.Length > 1) - { - try + if (positionargs?.Length > 3) { - positionrange = int.Parse(positionargs[1]); + try + { + zinc = int.Parse(positionargs[3]); + } + catch { } } - catch { } + break; + } + case SpawnPositionType.Waypoint: + { + // syntax WAYPOINT,prefix[,range] + positioning = s.positionType; + if (positionargs?.Length > 1) + { + prefix = positionargs[1]; + } + + if (positionargs?.Length > 2) + { + try + { + positionrange = int.Parse(positionargs[2]); + } + catch { } + } + + // find a list of items that match the waypoint prefix + if (prefix != null) + { + // see if there is an existing hashtable for the waypoint lists + spawnPositionWayTable ??= new Dictionary>(); + + // no existing list so create a new one + if (!spawnPositionWayTable.TryGetValue(prefix, out WayList) || WayList == null) + { + WayList = new List(); + + foreach (var i in World.Items.Values) + { + if (i is WayPoint && !string.IsNullOrEmpty(i.Name) && i.Map == Map && i.Name == prefix) + { + // add it to the list of items + WayList.Add(i); + } + } + // add the new list to the local table + spawnPositionWayTable[prefix] = WayList; + } + } + break; + } + case SpawnPositionType.Player: + { + // syntax PLAYER[,range] + positioning = s.positionType; + if (positionargs?.Length > 1) + { + try + { + positionrange = int.Parse(positionargs[1]); + } + catch { } + } + break; } - break; - } } } } @@ -10347,7 +9951,7 @@ public class XmlSpawner : Item, ISpawner if (includetilelist != null || excludetilelist != null || tileflag != TileFlag.None) { // use the precalculated tile locations - if (locations != null && locations.Count > 0) + if (locations?.Count > 0) { var p = locations[Utility.Random(locations.Count)]; x = p.X; @@ -10367,208 +9971,205 @@ public class XmlSpawner : Item, ISpawner switch (positioning) { case SpawnPositionType.Random: - { - if (includetilelist != null || excludetilelist != null || tileflag != TileFlag.None) { - - if (locations != null && locations.Count > 0) + if (includetilelist != null || excludetilelist != null || tileflag != TileFlag.None) { - var p = locations[Utility.Random(locations.Count)]; - x = p.X; - y = p.Y; - defaultZ = p.Z; + + if (locations?.Count > 0) + { + var p = locations[Utility.Random(locations.Count)]; + x = p.X; + y = p.Y; + defaultZ = p.Z; + } } + else + { + + if (m_Width > 0) + { + x = m_X + Utility.Random(m_Width + 1); + } + + if (m_Height > 0) + { + y = m_Y + Utility.Random(m_Height + 1); + } + } + break; } - else - { - - if (m_Width > 0) - { - x = m_X + Utility.Random(m_Width + 1); - } - - if (m_Height > 0) - { - y = m_Y + Utility.Random(m_Height + 1); - } - } - break; - } case SpawnPositionType.RelXY: - { - x = mostRecentSpawnPosition.X + xinc; - y = mostRecentSpawnPosition.Y + yinc; - defaultZ = mostRecentSpawnPosition.Z + zinc; - break; - } + { + x = mostRecentSpawnPosition.X + xinc; + y = mostRecentSpawnPosition.Y + yinc; + defaultZ = mostRecentSpawnPosition.Z + zinc; + break; + } case SpawnPositionType.DeltaLocation: - { - x = X + xinc; - y = Y + yinc; - defaultZ = Z + zinc; - break; - } + { + x = X + xinc; + y = Y + yinc; + defaultZ = Z + zinc; + break; + } case SpawnPositionType.Location: - { - x = xinc; - y = yinc; - defaultZ = zinc; - break; - } + { + x = xinc; + y = yinc; + defaultZ = zinc; + break; + } case SpawnPositionType.RowFill: - { - x = mostRecentSpawnPosition.X + fillinc; - y = mostRecentSpawnPosition.Y; - - if (x < m_X) { - x = m_X; - } + x = mostRecentSpawnPosition.X + fillinc; + y = mostRecentSpawnPosition.Y; - if (y < m_Y) - { - y = m_Y; - } + if (x < m_X) + { + x = m_X; + } - if (x > m_X + m_Width) - { - x = m_X + (x - m_X - m_Width - 1); - y++; - } + if (y < m_Y) + { + y = m_Y; + } - if (y > m_Y + m_Height) - { - y = m_Y; - } + if (x > m_X + m_Width) + { + x = m_X + (x - m_X - m_Width - 1); + y++; + } - break; - } + if (y > m_Y + m_Height) + { + y = m_Y; + } + + break; + } case SpawnPositionType.ColFill: - { - x = mostRecentSpawnPosition.X; - y = mostRecentSpawnPosition.Y + fillinc; - - if (x < m_X) { - x = m_X; - } + x = mostRecentSpawnPosition.X; + y = mostRecentSpawnPosition.Y + fillinc; - if (y < m_Y) - { - y = m_Y; - } + if (x < m_X) + { + x = m_X; + } - if (y > m_Y + m_Height) - { - y = m_Y + (y - m_Y - m_Height - 1); - x++; - } + if (y < m_Y) + { + y = m_Y; + } - if (x > m_X + m_Width) - { - x = m_X; - } + if (y > m_Y + m_Height) + { + y = m_Y + (y - m_Y - m_Height - 1); + x++; + } - break; - } + if (x > m_X + m_Width) + { + x = m_X; + } + + break; + } case SpawnPositionType.Perimeter: - { - x = mostRecentSpawnPosition.X; - y = mostRecentSpawnPosition.Y; + { + x = mostRecentSpawnPosition.X; + y = mostRecentSpawnPosition.Y; - // if the point is not on the perimeter, reset it to the corner - if (x != m_X && x != m_X + m_Width && y != m_Y && y != m_Y + m_Height) - { - x = m_X; - y = m_Y; - } + // if the point is not on the perimeter, reset it to the corner + if (x != m_X && x != m_X + m_Width && y != m_Y && y != m_Y + m_Height) + { + x = m_X; + y = m_Y; + } - if (y == m_Y && x < m_X + m_Width) - { - x += fillinc; - } - else - if (y == m_Y + m_Height && x > m_X) - { - x -= fillinc; - } - else - if (x == m_X && y > m_Y) - { - y -= fillinc; - } - else - if (x == m_X + m_Width && y < m_Y + m_Height) - { - y += fillinc; - } + if (y == m_Y && x < m_X + m_Width) + { + x += fillinc; + } + else if (y == m_Y + m_Height && x > m_X) + { + x -= fillinc; + } + else if (x == m_X && y > m_Y) + { + y -= fillinc; + } + else if (x == m_X + m_Width && y < m_Y + m_Height) + { + y += fillinc; + } - if (x > m_X + m_Width) - { - x = m_X + m_Width; - } + if (x > m_X + m_Width) + { + x = m_X + m_Width; + } - if (y > m_Y + m_Height) - { - y = m_Y + m_Height; - } + if (y > m_Y + m_Height) + { + y = m_Y + m_Height; + } - if (x < m_X) - { - x = m_X; - } + if (x < m_X) + { + x = m_X; + } - if (y < m_Y) - { - y = m_Y; - } + if (y < m_Y) + { + y = m_Y; + } - break; - } + break; + } case SpawnPositionType.Player: - { - if (trigmob != null) { - x = trigmob.Location.X; - y = trigmob.Location.Y; - if (positionrange > 0) + if (trigmob != null) { - x += Utility.Random(positionrange * 2 + 1) - positionrange; - y += Utility.Random(positionrange * 2 + 1) - positionrange; - } - } - break; - } - - case SpawnPositionType.Waypoint: - { - // pick an item randomly from the waylist - if (WayList != null && WayList.Count > 0) - { - var index = Utility.Random(WayList.Count); - var waypoint = WayList[index]; - if (waypoint != null) - { - x = waypoint.Location.X; - y = waypoint.Location.Y; - defaultZ = waypoint.Location.Z; + x = trigmob.Location.X; + y = trigmob.Location.Y; if (positionrange > 0) { x += Utility.Random(positionrange * 2 + 1) - positionrange; y += Utility.Random(positionrange * 2 + 1) - positionrange; } } + break; } - break; - } + case SpawnPositionType.Waypoint: + { + // pick an item randomly from the waylist + if (WayList?.Count > 0) + { + var index = Utility.Random(WayList.Count); + var waypoint = WayList[index]; + if (waypoint != null) + { + x = waypoint.Location.X; + y = waypoint.Location.Y; + defaultZ = waypoint.Location.Z; + if (positionrange > 0) + { + x += Utility.Random(positionrange * 2 + 1) - positionrange; + y += Utility.Random(positionrange * 2 + 1) - positionrange; + } + } + } + + break; + } } mostRecentSpawnPosition = new Point3D(x, y, defaultZ); @@ -10611,13 +10212,7 @@ public class XmlSpawner : Item, ISpawner public int GetCreatureMax(int index) { Defrag(false); - - if (m_SpawnObjects == null) - { - return 0; - } - - return m_SpawnObjects[index].MaxCount; + return m_SpawnObjects?[index]?.MaxCount ?? 0; } private static void DeleteFromList(List list) where T : IEntity @@ -10868,7 +10463,7 @@ public class XmlSpawner : Item, ISpawner var deletelist = new List(); // Remove any spawns over the count - while (TheSpawn.SpawnedObjects != null && TheSpawn.SpawnedObjects.Count > 0 && TheSpawn.SpawnedObjects.Count > TheSpawn.MaxCount) + while (TheSpawn.SpawnedObjects?.Count > 0 && TheSpawn.SpawnedObjects.Count > TheSpawn.MaxCount) { var o = TheSpawn.SpawnedObjects[0]; @@ -10914,10 +10509,7 @@ public class XmlSpawner : Item, ISpawner } } - public static object CreateObject(Type type, string itemtypestring) - { - return CreateObject(type, itemtypestring, true); - } + public static object CreateObject(Type type, string itemtypestring) => CreateObject(type, itemtypestring, true); public static object CreateObject(Type type, string itemtypestring, bool requireConstructible) { @@ -11052,7 +10644,7 @@ public class XmlSpawner : Item, ISpawner foreach (var spawner in spawnerlist) { - if (spawner != null && !spawner.Deleted && spawner.Running && spawner.SmartSpawning && spawner.IsInactivated) + if (spawner?.Deleted == false && spawner.Running && spawner.SmartSpawning && spawner.IsInactivated) { spawner.SmartRespawn(); } @@ -11078,15 +10670,12 @@ public class XmlSpawner : Item, ISpawner { private readonly XmlSpawner m_Spawner; - public SectorTimer(XmlSpawner spawner, TimeSpan delay) : base(delay, delay) - { - m_Spawner = spawner; - } + public SectorTimer(XmlSpawner spawner, TimeSpan delay) : base(delay, delay) => m_Spawner = spawner; protected override void OnTick() { // check the sectors - if (m_Spawner != null && !m_Spawner.Deleted && m_Spawner.Running && m_Spawner.IsInactivated) + if (m_Spawner?.Deleted == false && m_Spawner.Running && m_Spawner.IsInactivated) { if (m_Spawner.SmartSpawning) { @@ -11224,14 +10813,11 @@ public class XmlSpawner : Item, ISpawner { private readonly XmlSpawner m_spawner; - public InternalTimer(XmlSpawner spawner, TimeSpan delay) : base(delay) - { - m_spawner = spawner; - } + public InternalTimer(XmlSpawner spawner, TimeSpan delay) : base(delay) => m_spawner = spawner; protected override void OnTick() { - if (m_spawner != null && !m_spawner.Deleted) + if (m_spawner?.Deleted == false) { m_spawner.RemoveSpawnObjects(); m_spawner.m_durActivated = false; @@ -11244,14 +10830,11 @@ public class XmlSpawner : Item, ISpawner { private readonly XmlSpawner m_Spawner; - public SpawnerTimer(XmlSpawner spawner, TimeSpan delay) : base(delay) - { - m_Spawner = spawner; - } + public SpawnerTimer(XmlSpawner spawner, TimeSpan delay) : base(delay) => m_Spawner = spawner; protected override void OnTick() { - if (m_Spawner != null && !m_Spawner.Deleted) + if (m_Spawner?.Deleted == false) { m_Spawner.OnTick(); } @@ -11263,14 +10846,11 @@ public class XmlSpawner : Item, ISpawner { private readonly XmlSpawner m_spawner; - public InternalTimer3(XmlSpawner spawner, TimeSpan delay) : base(delay) - { - m_spawner = spawner; - } + public InternalTimer3(XmlSpawner spawner, TimeSpan delay) : base(delay) => m_spawner = spawner; protected override void OnTick() { - if (m_spawner != null && !m_spawner.Deleted) + if (m_spawner?.Deleted == false) { // reenable triggering m_spawner.m_refractActivated = false; @@ -11347,7 +10927,7 @@ public class XmlSpawner : Item, ISpawner } } - if (m_ShowBoundsItems != null && m_ShowBoundsItems.Count > 0) + if (m_ShowBoundsItems?.Count > 0) { writer.Write(true); writer.Write(m_ShowBoundsItems); @@ -11588,461 +11168,442 @@ public class XmlSpawner : Item, ISpawner { case 32: case 31: - { - DisableGlobalAutoReset = reader.ReadBool(); - goto case 30; - } + { + DisableGlobalAutoReset = reader.ReadBool(); + goto case 30; + } case 30: - { - AllowNPCTrig = reader.ReadBool(); - goto case 29; - } + { + AllowNPCTrig = reader.ReadBool(); + goto case 29; + } case 29: - { - tmpSpawnListSize = reader.ReadInt(); - tmpSpawnsPer = new List(tmpSpawnListSize); - for (var i = 0; i < tmpSpawnListSize; ++i) { - var spawnsper = reader.ReadInt(); + tmpSpawnListSize = reader.ReadInt(); + tmpSpawnsPer = new List(tmpSpawnListSize); + for (var i = 0; i < tmpSpawnListSize; ++i) + { + var spawnsper = reader.ReadInt(); - tmpSpawnsPer.Add(spawnsper); + tmpSpawnsPer.Add(spawnsper); + } + goto case 28; } - goto case 28; - } case 28: - { - tmpPackRange = new List(tmpSpawnListSize); - for (var i = 0; i < tmpSpawnListSize; ++i) { - var packrange = reader.ReadInt(); + tmpPackRange = new List(tmpSpawnListSize); + for (var i = 0; i < tmpSpawnListSize; ++i) + { + var packrange = reader.ReadInt(); - tmpPackRange.Add(packrange); + tmpPackRange.Add(packrange); + } + goto case 27; } - goto case 27; - } case 27: - { - tmpDisableSpawn = new List(tmpSpawnListSize); - for (var i = 0; i < tmpSpawnListSize; ++i) { - var disablespawn = reader.ReadBool(); + tmpDisableSpawn = new List(tmpSpawnListSize); + for (var i = 0; i < tmpSpawnListSize; ++i) + { + var disablespawn = reader.ReadBool(); - tmpDisableSpawn.Add(disablespawn); + tmpDisableSpawn.Add(disablespawn); + } + goto case 26; } - goto case 26; - } case 26: - { - SpawnOnTrigger = reader.ReadBool(); - - if (version < 32) { - // Delete First & Last Modified - _ = reader.ReadDateTime(); - _ = reader.ReadDateTime(); + SpawnOnTrigger = reader.ReadBool(); + + if (version < 32) + { + // Delete First & Last Modified + _ = reader.ReadDateTime(); + _ = reader.ReadDateTime(); + } + goto case 25; } - goto case 25; - } case 25: - { - goto case 24; - } case 24: - { - tmpRestrictKillsToSubgroup = new List(tmpSpawnListSize); - tmpClearOnAdvance = new List(tmpSpawnListSize); - tmpMinDelay = new List(tmpSpawnListSize); - tmpMaxDelay = new List(tmpSpawnListSize); - tmpNextSpawn = new List(tmpSpawnListSize); - for (var i = 0; i < tmpSpawnListSize; ++i) { - var restrictkills = reader.ReadBool(); - var clearadvance = reader.ReadBool(); - var mind = reader.ReadDouble(); - var maxd = reader.ReadDouble(); - var nextspawn = reader.ReadDeltaTime(); + tmpRestrictKillsToSubgroup = new List(tmpSpawnListSize); + tmpClearOnAdvance = new List(tmpSpawnListSize); + tmpMinDelay = new List(tmpSpawnListSize); + tmpMaxDelay = new List(tmpSpawnListSize); + tmpNextSpawn = new List(tmpSpawnListSize); + for (var i = 0; i < tmpSpawnListSize; ++i) + { + var restrictkills = reader.ReadBool(); + var clearadvance = reader.ReadBool(); + var mind = reader.ReadDouble(); + var maxd = reader.ReadDouble(); + var nextspawn = reader.ReadDeltaTime(); - tmpRestrictKillsToSubgroup.Add(restrictkills); - tmpClearOnAdvance.Add(clearadvance); - tmpMinDelay.Add(mind); - tmpMaxDelay.Add(maxd); - tmpNextSpawn.Add(nextspawn); + tmpRestrictKillsToSubgroup.Add(restrictkills); + tmpClearOnAdvance.Add(clearadvance); + tmpMinDelay.Add(mind); + tmpMaxDelay.Add(maxd); + tmpNextSpawn.Add(nextspawn); + } + + var hasitems = reader.ReadBool(); + + if (hasitems) + { + m_ShowBoundsItems = reader.ReadEntityList(); + } + goto case 23; } - - var hasitems = reader.ReadBool(); - - if (hasitems) - { - m_ShowBoundsItems = reader.ReadEntityList(); - } - goto case 23; - } case 23: - { - IsInactivated = reader.ReadBool(); - SmartSpawning = reader.ReadBool(); + { + IsInactivated = reader.ReadBool(); + SmartSpawning = reader.ReadBool(); - goto case 22; - } + goto case 22; + } case 22: - { - SkillTrigger = reader.ReadString(); // note this will also register the skill - m_skill_that_triggered = (SkillName)reader.ReadInt(); - FreeRun = reader.ReadBool(); - TriggerMob = reader.ReadEntity(); - goto case 21; - } + { + SkillTrigger = reader.ReadString(); // note this will also register the skill + m_skill_that_triggered = (SkillName)reader.ReadInt(); + FreeRun = reader.ReadBool(); + TriggerMob = reader.ReadEntity(); + goto case 21; + } case 21: - { - DespawnTime = reader.ReadTimeSpan(); - goto case 20; - } + { + DespawnTime = reader.ReadTimeSpan(); + goto case 20; + } case 20: - { - tmpRequireSurface = new List(tmpSpawnListSize); - for (var i = 0; i < tmpSpawnListSize; ++i) { - var requiresurface = reader.ReadBool(); - tmpRequireSurface.Add(requiresurface); + tmpRequireSurface = new List(tmpSpawnListSize); + for (var i = 0; i < tmpSpawnListSize; ++i) + { + var requiresurface = reader.ReadBool(); + tmpRequireSurface.Add(requiresurface); + } + goto case 19; } - goto case 19; - } case 19: - { - ConfigFile = reader.ReadString(); - m_OnHold = reader.ReadBool(); - m_HoldSequence = reader.ReadBool(); - - if (version < 32) { - // // Delete First & Last Modified By - // // Delete First & Last Modified By - _ = reader.ReadString(); - _ = reader.ReadString(); - } + ConfigFile = reader.ReadString(); + m_OnHold = reader.ReadBool(); + m_HoldSequence = reader.ReadBool(); - // deserialize the keyword tag list - var tagcount = reader.ReadInt(); - m_KeywordTagList = new List(tagcount); - for (var i = 0; i < tagcount; i++) - { - var tag = new BaseXmlSpawner.KeywordTag(null, this); - tag.Deserialize(reader); + if (version < 32) + { + // // Delete First & Last Modified By + // // Delete First & Last Modified By + _ = reader.ReadString(); + _ = reader.ReadString(); + } + + // deserialize the keyword tag list + var tagcount = reader.ReadInt(); + m_KeywordTagList = new List(tagcount); + for (var i = 0; i < tagcount; i++) + { + var tag = new BaseXmlSpawner.KeywordTag(null, this); + tag.Deserialize(reader); + } + goto case 18; } - goto case 18; - } case 18: - { - AllowGhostTrig = reader.ReadBool(); - goto case 17; - } + { + AllowGhostTrig = reader.ReadBool(); + goto case 17; + } case 17: - { - goto case 16; - } case 16: - { - hasnewobjectinfo = true; - SequentialSpawn = reader.ReadInt(); - var seqdelay = reader.ReadTimeSpan(); - m_SeqEnd = Core.Now + seqdelay; - - tmpSubGroup = new List(tmpSpawnListSize); - tmpSequentialResetTime = new List(tmpSpawnListSize); - tmpSequentialResetTo = new List(tmpSpawnListSize); - tmpKillsNeeded = new List(tmpSpawnListSize); - for (var i = 0; i < tmpSpawnListSize; ++i) { - var subgroup = reader.ReadInt(); - var resettime = reader.ReadDouble(); - var resetto = reader.ReadInt(); - var killsneeded = reader.ReadInt(); - tmpSubGroup.Add(subgroup); - tmpSequentialResetTime.Add(resettime); - tmpSequentialResetTo.Add(resetto); - tmpKillsNeeded.Add(killsneeded); + hasnewobjectinfo = true; + SequentialSpawn = reader.ReadInt(); + var seqdelay = reader.ReadTimeSpan(); + m_SeqEnd = Core.Now + seqdelay; + + tmpSubGroup = new List(tmpSpawnListSize); + tmpSequentialResetTime = new List(tmpSpawnListSize); + tmpSequentialResetTo = new List(tmpSpawnListSize); + tmpKillsNeeded = new List(tmpSpawnListSize); + for (var i = 0; i < tmpSpawnListSize; ++i) + { + var subgroup = reader.ReadInt(); + var resettime = reader.ReadDouble(); + var resetto = reader.ReadInt(); + var killsneeded = reader.ReadInt(); + tmpSubGroup.Add(subgroup); + tmpSequentialResetTime.Add(resettime); + tmpSequentialResetTo.Add(resetto); + tmpKillsNeeded.Add(killsneeded); + } + m_RegionName = reader.ReadString(); + goto case 15; } - m_RegionName = reader.ReadString(); - goto case 15; - } case 15: - { - ExternalTriggering = reader.ReadBool(); - ExtTrigState = reader.ReadBool(); - goto case 14; - } + { + ExternalTriggering = reader.ReadBool(); + ExtTrigState = reader.ReadBool(); + goto case 14; + } case 14: - { - m_NoItemTriggerName = reader.ReadString(); - goto case 13; - } + { + m_NoItemTriggerName = reader.ReadString(); + goto case 13; + } case 13: - { - GumpState = reader.ReadString(); - goto case 12; - } + { + GumpState = reader.ReadString(); + goto case 12; + } case 12: - { - var todtype = reader.ReadInt(); - switch (todtype) { - case (int)TODModeType.Gametime: - { - TODMode = TODModeType.Gametime; - break; - } - case (int)TODModeType.Realtime: - { - TODMode = TODModeType.Realtime; - break; - } + TODMode = (TODModeType)reader.ReadInt(); + goto case 11; } - goto case 11; - } case 11: - { - KillReset = reader.ReadInt(); - m_skipped = reader.ReadBool(); - m_spawncheck = reader.ReadInt(); - goto case 10; - } + { + KillReset = reader.ReadInt(); + m_skipped = reader.ReadBool(); + m_spawncheck = reader.ReadInt(); + goto case 10; + } case 10: - { - SetItem = reader.ReadEntity(); - goto case 9; - } + { + SetItem = reader.ReadEntity(); + goto case 9; + } case 9: - { - TriggerProbability = reader.ReadDouble(); - goto case 8; - } + { + TriggerProbability = reader.ReadDouble(); + goto case 8; + } case 8: - { - MobTriggerProp = reader.ReadString(); - MobTriggerName = reader.ReadString(); - PlayerTriggerProp = reader.ReadString(); - goto case 7; - } + { + MobTriggerProp = reader.ReadString(); + MobTriggerName = reader.ReadString(); + PlayerTriggerProp = reader.ReadString(); + goto case 7; + } case 7: - { - SpeechTrigger = reader.ReadString(); - goto case 6; - } + { + SpeechTrigger = reader.ReadString(); + goto case 6; + } case 6: - { - m_ItemTriggerName = reader.ReadString(); - goto case 5; - } + { + m_ItemTriggerName = reader.ReadString(); + goto case 5; + } case 5: - { - ProximityMsg = reader.ReadString(); - m_ObjectPropertyItem = reader.ReadEntity(); - m_ObjectPropertyName = reader.ReadString(); - m_killcount = reader.ReadInt(); - goto case 4; - } + { + ProximityMsg = reader.ReadString(); + m_ObjectPropertyItem = reader.ReadEntity(); + m_ObjectPropertyName = reader.ReadString(); + m_killcount = reader.ReadInt(); + goto case 4; + } case 4: - { - haveproximityrange = true; - m_ProximityRange = reader.ReadInt(); - ProximitySound = reader.ReadInt(); - m_proximityActivated = reader.ReadBool(); - m_durActivated = reader.ReadBool(); - m_refractActivated = reader.ReadBool(); - StackAmount = reader.ReadInt(); - TODStart = reader.ReadTimeSpan(); - TODEnd = reader.ReadTimeSpan(); - RefractMin = reader.ReadTimeSpan(); - RefractMax = reader.ReadTimeSpan(); - if (m_refractActivated) { - var delay = reader.ReadTimeSpan(); - DoTimer3(delay); + haveproximityrange = true; + m_ProximityRange = reader.ReadInt(); + ProximitySound = reader.ReadInt(); + m_proximityActivated = reader.ReadBool(); + m_durActivated = reader.ReadBool(); + m_refractActivated = reader.ReadBool(); + StackAmount = reader.ReadInt(); + TODStart = reader.ReadTimeSpan(); + TODEnd = reader.ReadTimeSpan(); + RefractMin = reader.ReadTimeSpan(); + RefractMax = reader.ReadTimeSpan(); + if (m_refractActivated) + { + var delay = reader.ReadTimeSpan(); + DoTimer3(delay); + } + if (m_durActivated) + { + var delay = reader.ReadTimeSpan(); + DoTimer2(delay); + } + goto case 3; } - if (m_durActivated) - { - var delay = reader.ReadTimeSpan(); - DoTimer2(delay); - } - goto case 3; - } case 3: - { - m_ShowContainerStatic = reader.ReadEntity(); - goto case 2; - } + { + m_ShowContainerStatic = reader.ReadEntity(); + goto case 2; + } case 2: - { - m_Duration = reader.ReadTimeSpan(); - goto case 1; - } + { + m_Duration = reader.ReadTimeSpan(); + goto case 1; + } case 1: - { - UniqueId = reader.ReadString(); - HomeRangeIsRelative = reader.ReadBool(); - goto case 0; - } + { + UniqueId = reader.ReadString(); + HomeRangeIsRelative = reader.ReadBool(); + goto case 0; + } case 0: - { - m_Name = reader.ReadString(); - // backward compatibility with old name storage - if (!string.IsNullOrEmpty(m_Name)) { - Name = m_Name; - } - - m_X = reader.ReadInt(); - m_Y = reader.ReadInt(); - m_Width = reader.ReadInt(); - m_Height = reader.ReadInt(); - //we HAVE to check if the area is even or if coordinates point to the original spawner, otherwise it's custom area! - if (m_Width == m_Height && m_Width % 2 == 0 && m_X + m_Width / 2 == X && m_Y + m_Height / 2 == Y) - { - m_SpawnRange = m_Width / 2; - } - else - { - m_SpawnRange = -1; - } - - if (!haveproximityrange) - { - m_ProximityRange = -1; - } - WayPoint = reader.ReadEntity(); - m_Group = reader.ReadBool(); - m_MinDelay = reader.ReadTimeSpan(); - m_MaxDelay = reader.ReadTimeSpan(); - m_Count = reader.ReadInt(); - m_Team = reader.ReadInt(); - m_HomeRange = reader.ReadInt(); - m_Running = reader.ReadBool(); - - if (m_Running) - { - var delay = reader.ReadTimeSpan(); - DoTimer(delay); - } - - // Read in the size of the spawn object list - var SpawnListSize = reader.ReadInt(); - m_SpawnObjects = new List(SpawnListSize); - for (var i = 0; i < SpawnListSize; ++i) - { - var TypeName = reader.ReadString(); - var TypeMaxCount = reader.ReadInt(); - - var TheSpawnObject = new SpawnObject(TypeName, TypeMaxCount); - - m_SpawnObjects.Add(TheSpawnObject); - - var typeName = BaseXmlSpawner.ParseObjectType(TypeName); - - if (typeName == null || AssemblyHandler.FindTypeByName(typeName) == null && - !BaseXmlSpawner.IsTypeOrItemKeyword(typeName) && !typeName.Contains('{') && !typeName.StartsWith("*") && !typeName.StartsWith("#")) + m_Name = reader.ReadString(); + // backward compatibility with old name storage + if (!string.IsNullOrEmpty(m_Name)) { - m_WarnTimer ??= new WarnTimer2(); - - m_WarnTimer.Add(Location, Map, TypeName); - - status_str = $"invalid type: {typeName}"; + Name = m_Name; } - // Read in the number of spawns already - var SpawnedCount = reader.ReadInt(); - - TheSpawnObject.SpawnedObjects = new List(SpawnedCount); - - for (var x = 0; x < SpawnedCount; ++x) + m_X = reader.ReadInt(); + m_Y = reader.ReadInt(); + m_Width = reader.ReadInt(); + m_Height = reader.ReadInt(); + //we HAVE to check if the area is even or if coordinates point to the original spawner, otherwise it's custom area! + if (m_Width == m_Height && m_Width % 2 == 0 && m_X + m_Width / 2 == X && m_Y + m_Height / 2 == Y) { - var serial = reader.ReadInt(); - if (serial < -1) - { - // minusone is reserved for unknown types by default - // minustwo on is used for referencing keyword tags - var tagserial = -1 * (serial + 2); - // get the tag with that serial and add it - var t = BaseXmlSpawner.GetFromTagList(this, tagserial); - if (t != null) - { - TheSpawnObject.SpawnedObjects.Add(t); - } - } - else - { - var e = World.FindEntity((Serial)(uint)serial); - - if (e != null) - { - TheSpawnObject.SpawnedObjects.Add(e); - } - } + m_SpawnRange = m_Width / 2; } - } - // now have to reintegrate the later version spawnobject information into the earlier version desered objects - if (hasnewobjectinfo && tmpSpawnListSize == SpawnListSize) - { + else + { + m_SpawnRange = -1; + } + + if (!haveproximityrange) + { + m_ProximityRange = -1; + } + WayPoint = reader.ReadEntity(); + m_Group = reader.ReadBool(); + m_MinDelay = reader.ReadTimeSpan(); + m_MaxDelay = reader.ReadTimeSpan(); + m_Count = reader.ReadInt(); + m_Team = reader.ReadInt(); + m_HomeRange = reader.ReadInt(); + m_Running = reader.ReadBool(); + + if (m_Running) + { + var delay = reader.ReadTimeSpan(); + DoTimer(delay); + } + + // Read in the size of the spawn object list + var SpawnListSize = reader.ReadInt(); + m_SpawnObjects = new List(SpawnListSize); for (var i = 0; i < SpawnListSize; ++i) { - var so = m_SpawnObjects[i]; + var TypeName = reader.ReadString(); + var TypeMaxCount = reader.ReadInt(); - so.SubGroup = tmpSubGroup[i]; - so.SequentialResetTime = tmpSequentialResetTime[i]; - so.SequentialResetTo = tmpSequentialResetTo[i]; - so.KillsNeeded = tmpKillsNeeded[i]; - if (version > 19) + var TheSpawnObject = new SpawnObject(TypeName, TypeMaxCount); + + m_SpawnObjects.Add(TheSpawnObject); + + var typeName = BaseXmlSpawner.ParseObjectType(TypeName); + + if (typeName == null || AssemblyHandler.FindTypeByName(typeName) == null && + !BaseXmlSpawner.IsTypeOrItemKeyword(typeName) && !typeName.Contains('{') && !typeName.StartsWith("*") && !typeName.StartsWith("#")) { - so.RequireSurface = tmpRequireSurface[i]; + m_WarnTimer ??= new WarnTimer2(); + + m_WarnTimer.Add(Location, Map, TypeName); + + status_str = $"invalid type: {typeName}"; } - var restrictkills = false; - var clearadvance = true; - double mind = -1; - double maxd = -1; - var nextspawn = DateTime.MinValue; - if (version > 23) - { - restrictkills = tmpRestrictKillsToSubgroup[i]; - clearadvance = tmpClearOnAdvance[i]; - mind = tmpMinDelay[i]; - maxd = tmpMaxDelay[i]; - nextspawn = tmpNextSpawn[i]; - } - so.RestrictKillsToSubgroup = restrictkills; - so.ClearOnAdvance = clearadvance; - so.MinDelay = mind; - so.MaxDelay = maxd; - so.NextSpawn = nextspawn; + // Read in the number of spawns already + var SpawnedCount = reader.ReadInt(); - var disablespawn = false; - if (version > 26) - { - disablespawn = tmpDisableSpawn[i]; - } - so.Disabled = disablespawn; + TheSpawnObject.SpawnedObjects = new List(SpawnedCount); - var packrange = -1; - if (version > 27) + for (var x = 0; x < SpawnedCount; ++x) { - packrange = tmpPackRange[i]; - } - so.PackRange = packrange; + var serial = reader.ReadInt(); + if (serial < -1) + { + // minusone is reserved for unknown types by default + // minustwo on is used for referencing keyword tags + var tagserial = -1 * (serial + 2); + // get the tag with that serial and add it + var t = BaseXmlSpawner.GetFromTagList(this, tagserial); + if (t != null) + { + TheSpawnObject.SpawnedObjects.Add(t); + } + } + else + { + var e = World.FindEntity((Serial)(uint)serial); - var spawnsper = 1; - if (version > 28) - { - spawnsper = tmpSpawnsPer[i]; + if (e != null) + { + TheSpawnObject.SpawnedObjects.Add(e); + } + } } - so.SpawnsPerTick = spawnsper; - } - } + // now have to reintegrate the later version spawnobject information into the earlier version desered objects + if (hasnewobjectinfo && tmpSpawnListSize == SpawnListSize) + { + for (var i = 0; i < SpawnListSize; ++i) + { + var so = m_SpawnObjects[i]; - break; - } + so.SubGroup = tmpSubGroup[i]; + so.SequentialResetTime = tmpSequentialResetTime[i]; + so.SequentialResetTo = tmpSequentialResetTo[i]; + so.KillsNeeded = tmpKillsNeeded[i]; + if (version > 19) + { + so.RequireSurface = tmpRequireSurface[i]; + } + + var restrictkills = false; + var clearadvance = true; + double mind = -1; + double maxd = -1; + var nextspawn = DateTime.MinValue; + if (version > 23) + { + restrictkills = tmpRestrictKillsToSubgroup[i]; + clearadvance = tmpClearOnAdvance[i]; + mind = tmpMinDelay[i]; + maxd = tmpMaxDelay[i]; + nextspawn = tmpNextSpawn[i]; + } + so.RestrictKillsToSubgroup = restrictkills; + so.ClearOnAdvance = clearadvance; + so.MinDelay = mind; + so.MaxDelay = maxd; + so.NextSpawn = nextspawn; + + var disablespawn = false; + if (version > 26) + { + disablespawn = tmpDisableSpawn[i]; + } + so.Disabled = disablespawn; + + var packrange = -1; + if (version > 27) + { + packrange = tmpPackRange[i]; + } + so.PackRange = packrange; + + var spawnsper = 1; + if (version > 28) + { + spawnsper = tmpSpawnsPer[i]; + } + so.SpawnsPerTick = spawnsper; + + } + } + + break; + } } if (m_RegionName != null) { @@ -12084,9 +11645,9 @@ public class XmlSpawner : Item, ISpawner _ = sb.Append(":OBJ="); // Separates multiple object types } - _ = sb.AppendFormat("{0}:MX={1}:SB={2}:RT={3}:TO={4}:KL={5}:RK={6}:CA={7}:DN={8}:DX={9}:SP={10}:PR={11}", - so.TypeName, so.ActualMaxCount, so.SubGroup, so.SequentialResetTime, so.SequentialResetTo, so.KillsNeeded, - so.RestrictKillsToSubgroup ? 1 : 0, so.ClearOnAdvance ? 1 : 0, so.MinDelay, so.MaxDelay, so.SpawnsPerTick, so.PackRange); + _ = sb.Append( + $"{so.TypeName}:MX={so.ActualMaxCount}:SB={so.SubGroup}:RT={so.SequentialResetTime}:TO={so.SequentialResetTo}:KL={so.KillsNeeded}:RK={(so.RestrictKillsToSubgroup ? 1 : 0)}:CA={(so.ClearOnAdvance ? 1 : 0)}:DN={so.MinDelay}:DX={so.MaxDelay}:SP={so.SpawnsPerTick}:PR={so.PackRange}" + ); } return sb.ToString(); @@ -12111,15 +11672,7 @@ public class XmlSpawner : Item, ISpawner public int MaxCount { - get - { - if (Disabled) - { - return 0; - } - - return ActualMaxCount; - } + get => Disabled ? 0 : ActualMaxCount; set => ActualMaxCount = value; } public int ActualMaxCount { get; set; } @@ -12345,14 +11898,9 @@ public class XmlSpawner : Item, ISpawner // ClearOnAdvance parmstr = GetParm(s, ":CA="); - var clearAdvance = true; // if kills needed is zero, then set CA to false by default. This maintains consistency with the - // previous default behavior for old spawn specs that havent specified CA - if (killsNeeded == 0) - { - clearAdvance = false; - } - + // previous default behavior for old spawn specs that haven't specified CA + bool clearAdvance = killsNeeded != 0; if (parmstr != null) { try { clearAdvance = int.Parse(parmstr) == 1; } diff --git a/Projects/UOContent/Engines/XMLSpawner/XmlSpawnerGumps.cs b/Projects/UOContent/Engines/XMLSpawner/XmlSpawnerGumps.cs index a708f2c22..7669f1bb2 100644 --- a/Projects/UOContent/Engines/XMLSpawner/XmlSpawnerGumps.cs +++ b/Projects/UOContent/Engines/XMLSpawner/XmlSpawnerGumps.cs @@ -893,14 +893,14 @@ public class XmlSpawnerGump : Gump if (grpval != m_Spawner.SpawnObjects[i].MinDelay) { m_Spawner.SpawnObjects[i].MinDelay = grpval; - m_Spawner.RefreshNextSpawnTime(m_Spawner.SpawnObjects[i]); + XmlSpawner.RefreshNextSpawnTime(m_Spawner.SpawnObjects[i]); } } else { m_Spawner.SpawnObjects[i].MinDelay = -1; m_Spawner.SpawnObjects[i].MaxDelay = -1; - m_Spawner.RefreshNextSpawnTime(m_Spawner.SpawnObjects[i]); + XmlSpawner.RefreshNextSpawnTime(m_Spawner.SpawnObjects[i]); } } @@ -922,14 +922,14 @@ public class XmlSpawnerGump : Gump if (grpval != m_Spawner.SpawnObjects[i].MaxDelay) { m_Spawner.SpawnObjects[i].MaxDelay = grpval; - m_Spawner.RefreshNextSpawnTime(m_Spawner.SpawnObjects[i]); + XmlSpawner.RefreshNextSpawnTime(m_Spawner.SpawnObjects[i]); } } else { m_Spawner.SpawnObjects[i].MinDelay = -1; m_Spawner.SpawnObjects[i].MaxDelay = -1; - m_Spawner.RefreshNextSpawnTime(m_Spawner.SpawnObjects[i]); + XmlSpawner.RefreshNextSpawnTime(m_Spawner.SpawnObjects[i]); } } @@ -1031,7 +1031,7 @@ public class XmlSpawnerGump : Gump { m_Spawner.TryRespawn(); //m_Spawner.AdvanceSequential(); - m_Spawner.m_killcount = 0; + m_Spawner.KillCount = 0; break; } case 4: // Goto diff --git a/Projects/UOContent/Engines/XMLSpawner/XmlUtils/WriteMulti.cs b/Projects/UOContent/Engines/XMLSpawner/XmlUtils/WriteMulti.cs deleted file mode 100644 index ce083ed65..000000000 --- a/Projects/UOContent/Engines/XMLSpawner/XmlUtils/WriteMulti.cs +++ /dev/null @@ -1,461 +0,0 @@ -using System.IO; -using System.Collections; -using Server.Items; -using Server.Mobiles; - -namespace Server.Engines.XmlSpawner2; - -public class WriteMulti -{ - private class TileEntry - { - public int ID; - public int X; - public int Y; - public int Z; - - public TileEntry(int id, int x, int y, int z) - { - ID = id; - X = x; - Y = y; - Z = z; - } - } - - public static void Initialize() - { - - CommandSystem.Register("WriteMulti", XmlSpawner.DiskAccessLevel, WriteMulti_OnCommand); - } - - [Usage("WriteMulti [zmin zmax][-noitems][-nostatics][-nomultis][-noaddons][-invisible]")] - [Description("Creates a multi text file from the objects within the targeted area. The min/max z range can also be specified.")] - public static void WriteMulti_OnCommand(CommandEventArgs e) - { - if (e == null || e.Mobile == null) - { - return; - } - - if (e.Mobile.AccessLevel < XmlSpawner.DiskAccessLevel) - { - e.Mobile.SendMessage("You do not have rights to perform this command."); - return; - } - - if (e.Arguments != null && e.Arguments.Length < 1) - { - e.Mobile.SendMessage($"Usage: {e.Command} [zmin zmax][-noitems][-nostatics][-nomultis][-noaddons][-invisible]"); - return; - } - - string filename = e.Arguments[0]; - - int zmin = int.MinValue; - int zmax = int.MinValue; - bool includeitems = true; - bool includestatics = true; - bool includemultis = true; - bool includeaddons = true; - bool includeinvisible = false; - - if (e.Arguments.Length > 1) - { - int index = 1; - while (index < e.Arguments.Length) - { - if (e.Arguments[index] == "-noitems") - { - includeitems = false; - index++; - } - else if (e.Arguments[index] == "-nostatics") - { - includestatics = false; - index++; - } - else if (e.Arguments[index] == "-nomultis") - { - includemultis = false; - index++; - } - else if (e.Arguments[index] == "-noaddons") - { - includeaddons = false; - index++; - } - else if (e.Arguments[index] == "-invisible") - { - includeinvisible = true; - index++; - } - else - { - try - { - zmin = int.Parse(e.Arguments[index++]); - zmax = int.Parse(e.Arguments[index++]); - } - catch - { - e.Mobile.SendMessage($"{e.Command} : Invalid zmin zmax arguments"); - return; - } - } - } - } - - string dirname; - if (Directory.Exists(XmlSpawner.XmlSpawnDir) && filename != null && !filename.StartsWith("/") && !filename.StartsWith("\\")) - { - // put it in the defaults directory if it exists - dirname = $"{XmlSpawner.XmlSpawnDir}/{filename}"; - } - else - { - // otherwise just put it in the main installation dir - dirname = filename; - } - - // check to see if the file already exists and can be written to by the owner - if (File.Exists(dirname)) - { - - // check the file - try - { - StreamReader op = new StreamReader(dirname, false); - string line = op.ReadLine(); - - op.Close(); - - // check the first line - if (line != null && line.Length > 0) - { - - string[] args = line.Split(" ".ToCharArray(), 3); - if (args.Length < 3) - { - e.Mobile.SendMessage($"Cannot overwrite file {dirname} : not owner"); - return; - } - - if (args[2] != e.Mobile.Name) - { - e.Mobile.SendMessage($"Cannot overwrite file {dirname} : not owner"); - return; - } - } - else - { - e.Mobile.SendMessage($"Cannot overwrite file {dirname} : not owner"); - return; - } - - } - catch - { - e.Mobile.SendMessage($"Cannot overwrite file {dirname}"); - return; - } - - } - - DefineMultiArea(e.Mobile, dirname, zmin, zmax, includeitems, includestatics, includemultis, includeinvisible, includeaddons); - } - - public static void DefineMultiArea(Mobile m, string dirname, int zmin, int zmax, bool includeitems, bool includestatics, - bool includemultis, bool includeinvisible, bool includeaddons) - { - BoundingBoxPicker.Begin( - m, - (map, start, end) => DefineMultiArea_Callback( - m, - map, - start, - end, - dirname, - zmin, - zmax, - includeitems, - includestatics, - includemultis, - includeinvisible, - includeaddons - ) - ); - } - - private static void DefineMultiArea_Callback( - Mobile from, - Map map, - Point3D start, - Point3D end, - string dirname, - int zmin, - int zmax, - bool includeitems, - bool includestatics, - bool includemultis, - bool includeinvisible, - bool includeaddons - ) - { - if (from != null && map != null) - { - ArrayList itemlist = new ArrayList(); - ArrayList staticlist = new ArrayList(); - ArrayList tilelist = new ArrayList(); - - int sx = start.X > end.X ? end.X : start.X; - int sy = start.Y > end.Y ? end.Y : start.Y; - int ex = start.X < end.X ? end.X : start.X; - int ey = start.Y < end.Y ? end.Y : start.Y; - - // find all of the world-placed items within the specified area - if (includeitems) - { - // make the first pass for items only - IPooledEnumerable eable = map.GetItemsInBounds(new Rectangle2D(sx, sy, ex - sx + 1, ey - sy + 1)); - - foreach (Item item in eable) - { - // is it within the bounding area - if (item.Parent == null && (zmin == int.MinValue || item.Location.Z >= zmin && item.Location.Z <= zmax)) - { - // add the item - if ((includeinvisible || item.Visible) && item.ItemID <= 16383) - { - itemlist.Add(item); - } - } - } - - eable.Free(); - - int searchrange = 100; - - // make the second expanded pass to pick up addon components and multi components - eable = map.GetItemsInBounds(new Rectangle2D(sx - searchrange, sy - searchrange, ex - sy + searchrange * 2 + 1, - ey - sy + searchrange * 2 + 1)); - - foreach (Item item in eable) - { - // is it within the bounding area - if (item.Parent == null) - { - - if (item is BaseAddon addon && includeaddons) - { - // go through all of the addon components - foreach (AddonComponent c in addon.Components) - { - int x = c.X; - int y = c.Y; - int z = c.Z; - - if ((includeinvisible || addon.Visible) && (addon.ItemID <= 16383 || includemultis) && - x >= sx && x <= ex && y >= sy && y <= ey && (zmin == int.MinValue || z >= zmin && z <= zmax)) - { - itemlist.Add(c); - } - } - } - - if (item is BaseMulti multi && includemultis) - { - // go through all of the multi components - MultiComponentList mcl = multi.Components; - if (mcl != null && mcl.List != null) - { - for (int i = 0; i < mcl.List.Length; i++) - { - MultiTileEntry t = mcl.List[i]; - - int x = t.OffsetX + multi.X; - int y = t.OffsetY + multi.Y; - int z = t.OffsetZ + multi.Z; - int itemID = t.ItemId & 0x3FFF; - - if (x >= sx && x <= ex && y >= sy && y <= ey && (zmin == int.MinValue || z >= zmin && z <= zmax)) - { - tilelist.Add(new TileEntry(itemID, x, y, z)); - } - } - - } - } - } - } - - eable.Free(); - } - - // find all of the static tiles within the specified area - if (includestatics) - { - // count the statics - for (int x = sx; x < ex; x++) - { - for (int y = sy; y < ey; y++) - { - StaticTile[] statics = map.Tiles.GetStaticTiles(x, y, false); - - for (int j = 0; j < statics.Length; j++) - { - if (zmin == int.MinValue || statics[j].Z >= zmin && statics[j].Z <= zmax) - { - staticlist.Add(new TileEntry(statics[j].ID & 0x3FFF, x, y, statics[j].Z)); - } - } - } - } - } - - int nstatics = staticlist.Count; - int nitems = itemlist.Count; - int ntiles = tilelist.Count; - - int ntotal = nitems + nstatics + ntiles; - - int ninvisible = 0; - int nmultis = ntiles; - int naddons = 0; - - foreach (Item item in itemlist) - { - int x = item.X - from.X; - int y = item.Y - from.Y; - int z = item.Z - from.Z; - - if (item.ItemID > 16383) - { - nmultis++; - } - if (!item.Visible) - { - ninvisible++; - } - if (item is BaseAddon || item is AddonComponent) - { - naddons++; - } - } - - try - { - // open the file, overwrite any previous contents - StreamWriter op = new StreamWriter(dirname, false); - - if (op != null) - { - // write the header - op.WriteLine("1 version {0}", from.Name); - op.WriteLine("{0} num components", ntotal); - - // write out the items - foreach (Item item in itemlist) - { - - int x = item.X - from.X; - int y = item.Y - from.Y; - int z = item.Z - from.Z; - - if (item.Hue > 0) - { - // format is x y z visible hue - op.WriteLine("{0} {1} {2} {3} {4} {5}", item.ItemID, x, y, z, item.Visible ? 1 : 0, item.Hue); - } - else - { - // format is x y z visible - op.WriteLine("{0} {1} {2} {3} {4}", item.ItemID, x, y, z, item.Visible ? 1 : 0); - } - } - - if (includestatics) - { - foreach (TileEntry s in staticlist) - { - int x = s.X - from.X; - int y = s.Y - from.Y; - int z = s.Z - from.Z; - int ID = s.ID; - op.WriteLine("{0} {1} {2} {3} {4}", ID, x, y, z, 1); - } - } - - if (includemultis) - { - foreach (TileEntry s in tilelist) - { - int x = s.X - from.X; - int y = s.Y - from.Y; - int z = s.Z - from.Z; - int ID = s.ID; - op.WriteLine("{0} {1} {2} {3} {4}", ID, x, y, z, 1); - } - } - } - - op.Close(); - } - catch - { - from.SendMessage($"Error writing multi file {dirname}"); - return; - } - - from.SendMessage(66, "WriteMulti results:"); - - if (includeitems) - { - from.SendMessage(66, $"Included {nitems} items"); - - if (includemultis) - { - from.SendMessage($"{nmultis} multis"); - } - else - { - from.SendMessage(33, "Ignored multis"); - } - - if (includeinvisible) - { - from.SendMessage($"{ninvisible} invisible"); - } - else - { - from.SendMessage(33, "Ignored invisible"); - } - - if (includeaddons) - { - from.SendMessage($"{naddons} addons"); - } - else - { - from.SendMessage(33, "Ignored addons"); - } - - } - else - { - from.SendMessage(33, "Ignored items"); - } - - if (includestatics) - { - from.SendMessage(66, $"Included {nstatics} statics"); - } - else - { - from.SendMessage(33, "Ignored statics"); - } - - from.SendMessage(66, $"Saved {ntotal} components to {dirname}"); - } - } -} diff --git a/Projects/UOContent/Engines/XMLSpawner/XmlUtils/XmlFind.cs b/Projects/UOContent/Engines/XMLSpawner/XmlUtils/XmlFind.cs deleted file mode 100644 index 34ea93a2e..000000000 --- a/Projects/UOContent/Engines/XMLSpawner/XmlUtils/XmlFind.cs +++ /dev/null @@ -1,2366 +0,0 @@ -using Server.Accounting; -using Server.Commands; -using Server.Commands.Generic; -using Server.Gumps; -using Server.Items; -using Server.Multis; -using Server.Network; -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using Server.Engines.Spawners; - -namespace Server.Mobiles; - -public class XmlFindGump : Gump -{ - public class XmlFindThread - { - readonly SearchCriteria m_SearchCriteria; - readonly Mobile m_From; - readonly string m_commandstring; - - public XmlFindThread(Mobile from, SearchCriteria criteria, string commandstring) - { - m_SearchCriteria = criteria; - m_From = from; - m_commandstring = commandstring; - } - - public void XmlFindThreadMain() - { - if (m_From == null) - { - return; - } - - string status_str; - - ArrayList results = Search(m_SearchCriteria, out status_str); - - XmlFindGump gump = new XmlFindGump(m_From, m_From.Location, m_From.Map, true, true, false, - - m_SearchCriteria, - - results, -1, 0, null, m_commandstring, - false, false, false, false, false, false, 0, 0); - - // display the updated gump synched with the main server thread - Core.LoopContext.Post(() => GumpDisplayCallback(m_From, gump, status_str)); - - } - - public void GumpDisplayCallback(Mobile from, XmlFindGump gump, string status_str) - { - if (from != null && !from.Deleted) - { - from.SendGump(gump); - if (status_str != null) - { - from.SendMessage(33, $"XmlFind: {status_str}"); - } - } - } - } - - private const int MaxEntries = 18; - private const int MaxEntriesPerPage = 18; - - public class SearchEntry - { - public bool Selected; - public object Object; - - public SearchEntry(object o) => Object = o; - } - - public class SearchCriteria - { - public bool Dosearchtype; - public bool Dosearchname; - public bool Dosearchrange; - public bool Dosearchregion; - public bool Dosearchspawnentry; - public bool Dosearchspawntype; - public bool Dosearchcondition; - public bool Dosearchfel; - public bool Dosearchtram; - public bool Dosearchmal; - public bool Dosearchilsh; - public bool Dosearchtok; - public bool Dosearchter; - public bool Dosearchint; - public bool Dosearchnull; - public bool Dosearcherr; - public bool Dosearchage; - public bool Dohidevalidint; - public bool Searchagedirection; - public double Searchage; - public int Searchrange; - public string Searchregion; - public string Searchcondition; - public string Searchtype; - public string Searchname; - public string Searchspawnentry; - - public Map Currentmap; - public Point3D Currentloc; - - public SearchCriteria(bool dotype, bool doname, bool dorange, bool doregion, bool doentry, bool doentrytype, bool docondition, bool dofel, bool dotram, - bool domal, bool doilsh, bool dotok, bool doter, bool doint, bool donull, bool doerr, bool doage, bool dohidevalid, - bool agedirection, double age, int range, string region, string condition, string type, string name, string entry - ) - { - Dosearchtype = dotype; - Dosearchname = doname; - Dosearchrange = dorange; - Dosearchregion = doregion; - Dosearchspawnentry = doentry; - Dosearchspawntype = doentrytype; - Dosearchcondition = docondition; - Dosearchfel = dofel; - Dosearchtram = dotram; - Dosearchmal = domal; - Dosearchilsh = doilsh; - Dosearchtok = dotok; - Dosearchter = doter; - Dosearchint = doint; - Dosearchnull = donull; - Dosearcherr = doerr; - Dosearchage = doage; - Dohidevalidint = dohidevalid; - Searchagedirection = agedirection; - Searchage = age; - Searchrange = range; - Searchregion = region; - Searchcondition = condition; - Searchtype = type; - Searchname = name; - Searchspawnentry = entry; - } - - public SearchCriteria() - { - } - } - - private readonly SearchCriteria m_SearchCriteria; - private bool Sorttype; - private bool Sortrange; - private bool Sortname; - private bool Sortmap; - private bool Sortselect; - private readonly Mobile m_From; - private readonly Point3D StartingLoc; - private readonly Map StartingMap; - private bool m_ShowExtension; - private bool Descendingsort; - private int Selected; - private int DisplayFrom; - private string SaveFilename; - private string CommandString; - - private bool SelectAll; - - private ArrayList m_SearchList; - - public static void Initialize() - { - CommandSystem.Register("XmlFind", AccessLevel.GameMaster, XmlFind_OnCommand); - } - - private static bool TestRange(object o, int range, Map currentmap, Point3D currentloc) - { - if (range < 0) - { - return true; - } - - if (o is Item item) - { - if (item.Map != currentmap) - { - return false; - } - - // is the item in a container? - // if so, then check the range of the parent rather than the item - Point3D loc = item.Location; - if (item.Parent != null && item.RootParent != null) - { - if (item.RootParent is Mobile mobile) - { - loc = mobile.Location; - } - else - if (item.RootParent is Container container) - { - loc = container.Location; - } - - } - return Utility.InRange(currentloc, loc, range); - - } - if (o is Mobile mob) - { - if (mob.Map != currentmap) - { - return false; - } - - return Utility.InRange(currentloc, mob.Location, range); - - } - return false; - } - - private static bool TestRegion(object o, string regionname) - { - if (regionname == null) - { - return false; - } - - if (o is Item item) - { - // is the item in a container? - // if so, then check the region of the parent rather than the item - Point3D loc = item.Location; - if (item.Parent != null && item.RootParent != null) - { - if (item.RootParent is Mobile mobile) - { - loc = mobile.Location; - } - else - if (item.RootParent is Container container) - { - loc = container.Location; - } - } - - Region r = Region.Regions.FirstOrDefault(reg => reg.Map == item.Map && !string.IsNullOrEmpty(reg.Name) && string.Equals(reg.Name, regionname, StringComparison.CurrentCultureIgnoreCase)); - - if (r == null) - { - return false; - } - - return r.Contains(loc); - } - - if (o is Mobile mob) - { - Region r = Region.Regions.FirstOrDefault(reg => reg.Map == mob.Map && !string.IsNullOrEmpty(reg.Name) && string.Equals(reg.Name, regionname, StringComparison.CurrentCultureIgnoreCase)); - - if (r == null) - { - return false; - } - - return r.Contains(mob.Location); - - } - - return false; - } - - private static bool TestAge(object o, double age, bool direction) - { - if (age <= 0) - { - return true; - } - - if (o is Mobile mob) - { - if (direction) - { - // true means allow only mobs greater than the age - if (Core.Now - mob.Created > TimeSpan.FromHours(age)) - { - return true; - } - } - else - { - // false means allow only mobs less than the age - if (Core.Now - mob.Created < TimeSpan.FromHours(age)) - { - return true; - } - } - } - - return false; - } - - private static void IgnoreManagedInternal(object i, ref ArrayList ignoreList) - { - // ignore valid internalized commodity deed items - if (i is CommodityDeed deed && deed.Commodity != null && deed.Commodity.Map == Map.Internal) - { - ignoreList.Add(deed.Commodity); - } - - // ignore valid internalized keyring keys - if (i is KeyRing keyring && keyring.Keys != null) - { - foreach (Key k in keyring.Keys) - { - ignoreList.Add(k); - } - } - - // ignore valid internalized relocatable house items - if (i is BaseHouse house) - { - foreach (RelocatedEntity relEntity in house.RelocatedEntities) - { - if (relEntity.Entity is Item) - { - ignoreList.Add(relEntity.Entity); - } - } - - foreach (VendorInventory inventory in house.VendorInventories) - { - foreach (Item subItem in inventory.Items) - { - ignoreList.Add(subItem); - } - } - } - } - - // test for valid items/mobs on the internal map - private static bool TestValidInternal(object o) - { - if (o is Mobile m) - { - if (m.Map != Map.Internal || m.Account != null || - (m as IMount)?.Rider != null || - m is BaseCreature creature && creature.IsStabled || - m is PlayerVendor && BaseHouse.AllHouses.Any(x => x.InternalizedVendors.Contains(m))) - { - return true; - } - } - else if (o is Item i) - { - // note, in order to test for a vendors display container that contains valid internal map items - if (i.Map != Map.Internal || i.Parent != null || i is Fists or MountItem or EffectItem || i.HeldBy != null || - i is MovingCrate || i.GetType().DeclaringType == typeof(GenericBuyInfo)) - { - return true; - } - - // boat stuffs - if (i is Static && i.Name != null && (i.Name.ToLower() == "weapon pad" || i.Name.ToLower() == "deck")) - { - return true; - } - - // Ship/Vehicle parts - if (i is BaseDockedBoat or BaseBoat or Plank or TillerMan or Hold) - { - return true; - } - - // TODO: Ignores addons, persistence, and other items that are internalized while not in use - } - - return false; - } - - public static ArrayList Search(SearchCriteria criteria, out string status_str) - { - status_str = null; - ArrayList newarray = new ArrayList(); - ArrayList ignoreList = new ArrayList(); - - if (criteria == null) - { - status_str = "Empty search criteria"; - return newarray; - } - - Type targetType = null; - - Map tokunomap = null; - try - { - tokunomap = Map.Parse("Tokuno"); - } - catch (Exception e) { Diagnostics.ExceptionLogging.LogException(e); } - - // if the type is specified then get the search type - if (criteria.Dosearchtype && criteria.Searchtype != null) - { - targetType = AssemblyHandler.FindTypeByName(criteria.Searchtype); - if (targetType == null) - { - status_str = $"Invalid type: {criteria.Searchtype}"; - return newarray; - } - } - - // do the search through items - - // make a copy so that we dont get enumeration errors if World.Items.Values changes while searching - ArrayList itemarray = null; - - ICollection itemvalues = World.Items.Values; - - lock (itemvalues.SyncRoot) - { - try - { - itemarray = new ArrayList(itemvalues); - } - catch (SystemException e) { status_str = $"Unable to search World.Items: {e.Message}"; } - } - - if (itemarray != null) - { - foreach (Item i in itemarray) - { - bool hastype = false; - bool hasname = false; - bool hasentry = false; - bool hascondition = false; - bool hasrange = false; - bool hasregion = false; - bool hasmap = false; - bool hasspawnerr = false; - bool hasvalidhidden = false; - - if (i == null || i.Deleted) - { - continue; - } - - // this will deal with items that are not on the internal map but hold valid internal items - if (criteria.Dohidevalidint && i.Map != Map.Internal && i.Map != null) - { - IgnoreManagedInternal(i, ref ignoreList); - } - - // check for map - if (i.Map == Map.Felucca && criteria.Dosearchfel || i.Map == Map.Trammel && criteria.Dosearchtram || - i.Map == Map.Malas && criteria.Dosearchmal || i.Map == Map.Ilshenar && criteria.Dosearchilsh || - i.Map == Map.TerMur && criteria.Dosearchter || i.Map == Map.Internal && criteria.Dosearchint || - i.Map == null && criteria.Dosearchnull) - { - hasmap = true; - } - - if (tokunomap != null && i.Map == tokunomap && criteria.Dosearchtok) - { - hasmap = true; - } - - if (!hasmap) - { - continue; - } - - // check for type - if (criteria.Dosearchtype && (i.GetType().IsSubclassOf(targetType) || i.GetType() == targetType)) - { - hastype = true; - } - if (criteria.Dosearchtype && !hastype) - { - continue; - } - - // check for name - if (criteria.Dosearchname && i.Name != null && criteria.Searchname != null && i.Name.ToLower().IndexOf(criteria.Searchname.ToLower()) >= 0) - { - hasname = true; - } - - if (criteria.Dosearchname && !hasname) - { - continue; - } - - // check for valid internal map items - if (criteria.Dohidevalidint && TestValidInternal(i)) - { - hasvalidhidden = true; - - // this will deal with items that are on the internal map and hold valid internal items - IgnoreManagedInternal(i, ref ignoreList); - } - if (criteria.Dohidevalidint && hasvalidhidden) - { - continue; - } - - // check for range - if (criteria.Dosearchrange && TestRange(i, criteria.Searchrange, criteria.Currentmap, criteria.Currentloc)) - { - hasrange = true; - } - if (criteria.Dosearchrange && !hasrange) - { - continue; - } - - // check for region - if (criteria.Dosearchregion && TestRegion(i, criteria.Searchregion)) - { - hasregion = true; - } - if (criteria.Dosearchregion && !hasregion) - { - continue; - } - - // check for condition - if (criteria.Dosearchcondition && criteria.Searchcondition != null) - { - // check the property test - hascondition = BaseXmlSpawner.CheckPropertyString(null, i, criteria.Searchcondition, out status_str); - } - if (criteria.Dosearchcondition && !hascondition) - { - continue; - } - - // check for entry - if (criteria.Dosearchspawnentry) - { - Type targetentrytype = null; - - if (criteria.Dosearchspawntype) - { - targetentrytype = AssemblyHandler.FindTypeByName(criteria.Searchspawnentry.ToLower()); - } - - if (criteria.Searchspawnentry == null || targetentrytype == null && criteria.Dosearchspawntype) - { - hasentry = false; - } - else - { - // see what kind of spawner it is - if (i is XmlSpawner spawner) - { - // search the entries of the spawner - foreach (XmlSpawner.SpawnObject so in spawner.m_SpawnObjects) - { - if (criteria.Dosearchspawntype) - { - // search by entry type - Type type = null; - - if (so.TypeName != null) - { - string[] args = so.TypeName.Split('/'); - string typestr = null; - if (args != null && args.Length > 0) - { - typestr = args[0]; - } - - type = AssemblyHandler.FindTypeByName(typestr); - } - - if (type != null && (type == targetentrytype || type.IsSubclassOf(targetentrytype))) - { - hasentry = true; - break; - } - } - else - { - // search by entry string - if (so.TypeName != null && so.TypeName.ToLower().IndexOf(criteria.Searchspawnentry.ToLower()) >= 0) - { - hasentry = true; - break; - } - } - } - } - else if (i is Spawner spawner1) - { - // search the entries of the spawner - foreach (var entry in spawner1.Entries) - { - string so = entry.SpawnedName; - - if (criteria.Dosearchspawntype) - { - // search by entry type - Type type = null; - - if (so != null) - { - type = AssemblyHandler.FindTypeByName(so); - } - - if (type != null && (type == targetentrytype || type.IsSubclassOf(targetentrytype))) - { - hasentry = true; - break; - } - } - else - { - if (so != null && so.ToLower().IndexOf(criteria.Searchspawnentry.ToLower()) >= 0) - { - hasentry = true; - break; - } - } - } - } - else - { - hasentry = false; - } - } - } - - if (criteria.Dosearchspawnentry && !hasentry) - { - continue; - } - - if (criteria.Dosearcherr && i is XmlSpawner hasSpawn && hasSpawn.status_str != null) - { - hasspawnerr = true; - } - - if (criteria.Dosearcherr && !hasspawnerr) - { - continue; - } - - // satisfied all conditions so add it - newarray.Add(new SearchEntry(i)); - } - } - - // do the search through mobiles - if (!criteria.Dosearcherr) - { - // make a copy so that we dont get enumeration errors if World.Mobiles.Values changes while searching - ArrayList mobilearray = null; - ICollection mobilevalues = World.Mobiles.Values; - lock (mobilevalues.SyncRoot) - { - try - { - mobilearray = new ArrayList(mobilevalues); - } - catch (SystemException e) { status_str = $"Unable to search World.Mobiles: {e.Message}"; } - } - - if (mobilearray != null) - { - foreach (Mobile i in mobilearray) - { - bool hastype = false; - bool hasname = false; - bool hascondition = false; - bool hasrange = false; - bool hasregion = false; - bool hasmap = false; - bool hasage = false; - bool hasvalidhidden = false; - - if (i == null || i.Deleted) - { - continue; - } - - // check for map - if (i.Map == Map.Felucca && criteria.Dosearchfel || i.Map == Map.Trammel && criteria.Dosearchtram || - i.Map == Map.Malas && criteria.Dosearchmal || i.Map == Map.Ilshenar && criteria.Dosearchilsh || - i.Map == Map.TerMur && criteria.Dosearchter || i.Map == Map.Internal && criteria.Dosearchint || - i.Map == null && criteria.Dosearchnull) - { - hasmap = true; - } - - if (tokunomap != null && i.Map == tokunomap && criteria.Dosearchtok) - { - hasmap = true; - } - - if (!hasmap) - { - continue; - } - - // check for range - if (criteria.Dosearchrange && TestRange(i, criteria.Searchrange, criteria.Currentmap, criteria.Currentloc)) - { - hasrange = true; - } - if (criteria.Dosearchrange && !hasrange) - { - continue; - } - - // check for region - if (criteria.Dosearchregion && TestRegion(i, criteria.Searchregion)) - { - hasregion = true; - } - if (criteria.Dosearchregion && !hasregion) - { - continue; - } - - // check for valid internal map mobiles - if (criteria.Dohidevalidint && TestValidInternal(i)) - { - hasvalidhidden = true; - } - if (criteria.Dohidevalidint && hasvalidhidden) - { - continue; - } - - // check for age - if (criteria.Dosearchage && TestAge(i, criteria.Searchage, criteria.Searchagedirection)) - { - hasage = true; - } - if (criteria.Dosearchage && !hasage) - { - continue; - } - - // check for type - if (criteria.Dosearchtype && (i.GetType().IsSubclassOf(targetType) || i.GetType() == targetType)) - { - hastype = true; - } - if (criteria.Dosearchtype && !hastype) - { - continue; - } - - // check for name - if (criteria.Dosearchname && i.Name != null && criteria.Searchname != null && i.Name.ToLower().IndexOf(criteria.Searchname.ToLower()) >= 0) - { - hasname = true; - } - if (criteria.Dosearchname && !hasname) - { - continue; - } - - // check for condition - if (criteria.Dosearchcondition && criteria.Searchcondition != null) - { - // check the property test - hascondition = BaseXmlSpawner.CheckPropertyString(null, i, criteria.Searchcondition, out status_str); - } - if (criteria.Dosearchcondition && !hascondition) - { - continue; - } - - // passed all conditions so add it to the list - - newarray.Add(new SearchEntry(i)); - } - } - } - - ArrayList removelist = new ArrayList(); - for (int i = 0; i < ignoreList.Count; ++i) - { - foreach (SearchEntry se in newarray) - { - if (se.Object == ignoreList[i]) - { - removelist.Add(se); - break; - } - } - } - - foreach (SearchEntry se in removelist) - { - newarray.Remove(se); - } - - return newarray; - } - - [Usage("XmlFind [objecttype] [range]")] - [Description("Finds objects in the world")] - public static void XmlFind_OnCommand(CommandEventArgs e) - { - if (e?.Mobile == null) - { - return; - } - - Account acct = e.Mobile.Account as Account; - int x = 0; - int y = 0; - XmlSpawnerDefaults.DefaultEntry defs = null; - if (acct != null) - { - defs = XmlSpawnerDefaults.GetDefaults(acct.ToString(), e.Mobile.Name); - } - - if (defs != null) - { - x = defs.FindGumpX; - y = defs.FindGumpY; - } - - string typename = "Xmlspawner"; - int range = -1; - bool dorange = false; - - if (e.Arguments.Length > 0) - { - typename = e.Arguments[0]; - } - - if (e.Arguments.Length > 1) - { - dorange = true; - try - { - range = int.Parse(e.Arguments[1]); - } - catch - { - dorange = false; - e.Mobile.SendMessage($"Invalid range argument {e.Arguments[1]}"); - } - } - - e.Mobile.SendGump(new XmlFindGump(e.Mobile, e.Mobile.Location, e.Mobile.Map, typename, range, dorange, x, y)); - } - - public XmlFindGump(Mobile from, Point3D startloc, Map startmap, int x, int y) - : this(from, startloc, startmap, null, x, y) - { - } - - public XmlFindGump(Mobile from, Point3D startloc, Map startmap, string type, int x, int y) - : this(from, startloc, startmap, type, -1, false, x, y) - { - } - - public XmlFindGump(Mobile from, Point3D startloc, Map startmap, string type, int range, bool dorange, int x, int y) - : this(from, startloc, startmap, true, false, false, - - new SearchCriteria( - true, // dotype - false, // doname - dorange, // dorange - false, // doregion - false, // doentry - false, // doentrytype - false, // docondition - true, // dofel - true, // dotram - true, // domal - true, // doilsh - true, // dotok - true, // doter - false, // doint - false, // donull - false, // doerr - false, // doage - false, // dohidevalid - true, // agedirection - 0, // age - range, // range - null, // region - null, // condition - type, // type - null, // name - null // entry - ), - - null, -1, 0, null, null, - false, false, false, false, false, false, x, y) - { - } - - public XmlFindGump( - Mobile from, - Point3D startloc, - Map startmap, - bool firststart, - bool extension, - bool descend, - SearchCriteria criteria, - ArrayList searchlist, - int selected, - int displayfrom, - string savefilename, - string commandstring, - bool sorttype, - bool sortname, - bool sortrange, - bool sortmap, - bool sortselect, - bool selectall, - int X, - int Y - ) - : base(X, Y) - { - - StartingMap = startmap; - StartingLoc = startloc; - if (from != null && !from.Deleted) - { - m_From = from; - if (firststart) - { - StartingMap = from.Map; - StartingLoc = from.Location; - } - } - - SaveFilename = savefilename; - CommandString = commandstring; - SelectAll = selectall; - Sorttype = sorttype; - Sortname = sortname; - Sortrange = sortrange; - Sortmap = sortmap; - Sortselect = sortselect; - DisplayFrom = displayfrom; - Selected = selected; - m_ShowExtension = extension; - Descendingsort = descend; - - m_SearchCriteria = criteria ?? new SearchCriteria(); - - m_SearchList = searchlist; - - // prepare the page - const int height = 500; - - AddPage(0); - if (m_ShowExtension) - { - AddBackground(0, 0, 755, height, 5054); - AddAlphaRegion(0, 0, 755, height); - } - else - { - AddBackground(0, 0, 170, height, 5054); - AddAlphaRegion(0, 0, 170, height); - } - - // ---------------- - // SORT section - // ---------------- - int y = 5; - // add the Sort button - AddButton(5, y, 0xFAB, 0xFAD, 700); - AddLabel(38, y, 0x384, "Sort"); - - // add the sort direction button - if (Descendingsort) - { - AddButton(75, y + 3, 0x15E2, 0x15E6, 701); - AddLabel(95, y, 0x384, "descend"); - } - else - { - AddButton(75, y + 3, 0x15E0, 0x15E4, 701); - AddLabel(95, y, 0x384, "ascend"); - } - y += 22; - // add the Sort on type toggle - AddRadio(5, y, 0xD2, 0xD3, Sorttype, 0); - AddLabel(28, y, 0x384, "type"); - - // add the Sort on name toggle - AddRadio(75, y, 0xD2, 0xD3, Sortname, 1); - AddLabel(98, y, 0x384, "name"); - - y += 20; - // add the Sort on range toggle - AddRadio(5, y, 0xD2, 0xD3, Sortrange, 2); - AddLabel(28, y, 0x384, "range"); - - // add the Sort on map toggle - AddRadio(75, y, 0xD2, 0xD3, Sortmap, 4); - AddLabel(98, y, 0x384, "map"); - - y += 20; - // add the Sort on selected toggle - AddRadio(5, y, 0xD2, 0xD3, Sortselect, 5); - AddLabel(28, y, 0x384, "select"); - - // ---------------- - // SEARCH section - // ---------------- - y = 85; - // add the Search button - AddButton(5, y, 0xFA8, 0xFAA, 3); - AddLabel(38, y, 0x384, "Search"); - - y += 20; - // add the map buttons - AddCheck(5, y, 0xD2, 0xD3, m_SearchCriteria.Dosearchint, 312); - AddLabel(28, y, 0x384, "Int"); - AddCheck(75, y, 0xD2, 0xD3, m_SearchCriteria.Dosearchnull, 314); - AddLabel(98, y, 0x384, "Null"); - - y += 20; - AddCheck(5, y, 0xD2, 0xD3, m_SearchCriteria.Dosearchfel, 308); - AddLabel(28, y, 0x384, "Fel"); - AddCheck(75, y, 0xD2, 0xD3, m_SearchCriteria.Dosearchtram, 309); - AddLabel(98, y, 0x384, "Tram"); - - y += 20; - AddCheck(5, y, 0xD2, 0xD3, m_SearchCriteria.Dosearchmal, 310); - AddLabel(28, y, 0x384, "Mal"); - AddCheck(75, y, 0xD2, 0xD3, m_SearchCriteria.Dosearchilsh, 311); - AddLabel(98, y, 0x384, "Ilsh"); - - y += 20; - AddCheck(5, y, 0xD2, 0xD3, m_SearchCriteria.Dosearchtok, 318); - AddLabel(28, y, 0x384, "Tok"); - AddCheck(75, y, 0xD2, 0xD3, m_SearchCriteria.Dosearchter, 320); - AddLabel(98, y, 0x384, "Ter"); - - y += 20; - // add the hide valid internal map button - AddCheck(5, y, 0xD2, 0xD3, m_SearchCriteria.Dohidevalidint, 316); - AddLabel(28, y, 0x384, "Hide valid internal"); - - // ---------------- - // FILTER section - // ---------------- - y = height - 295; - - // add the search region entry - AddLabel(28, y, 0x384, "region"); - AddImageTiled(70, y, 68, 19, 0xBBC); - AddTextEntry(70, y, 250, 19, 0, 106, m_SearchCriteria.Searchregion); - // add the toggle to enable search region - AddCheck(5, y, 0xD2, 0xD3, m_SearchCriteria.Dosearchregion, 319); - - y += 20; - // add the search age entry - AddLabel(28, y, 0x384, "age"); - //AddImageTiled(80, 220, 50, 23, 0x52); - AddImageTiled(70, y, 45, 19, 0xBBC); - AddTextEntry(70, y, 45, 19, 0, 105, m_SearchCriteria.Searchage.ToString()); - AddLabel(117, y, 0x384, "Hrs"); - // add the toggle to enable search age - AddCheck(5, y, 0xD2, 0xD3, m_SearchCriteria.Dosearchage, 303); - // add the toggle to set the search age test direction - AddCheck(50, y + 2, 0x1467, 0x1468, m_SearchCriteria.Searchagedirection, 302); - - y += 20; - // add the search range entry - AddLabel(28, y, 0x384, "range"); - AddImageTiled(70, y, 45, 19, 0xBBC); - AddTextEntry(70, y, 45, 19, 0, 100, m_SearchCriteria.Searchrange.ToString()); - // add the toggle to enable search range - AddCheck(5, y, 0xD2, 0xD3, m_SearchCriteria.Dosearchrange, 304); - - y += 20; - // add the search type entry - AddLabel(28, y, 0x384, "type"); - // add the toggle to enable search by type - AddCheck(5, y, 0xD2, 0xD3, m_SearchCriteria.Dosearchtype, 305); - //AddImageTiled(5, 285, 135, 23, 0x52); - AddImageTiled(6, y + 20, 132, 19, 0xBBC); - AddTextEntry(6, y + 20, 250, 19, 0, 101, m_SearchCriteria.Searchtype); - - y += 41; - // add the search condition entry - AddLabel(28, y, 0x384, "property test"); - // add the toggle to enable search by condition - AddCheck(5, y, 0xD2, 0xD3, m_SearchCriteria.Dosearchcondition, 315); - //AddImageTiled(5, 285, 135, 23, 0x52); - AddImageTiled(6, y + 20, 132, 19, 0xBBC); - AddTextEntry(6, y + 20, 500, 19, 0, 104, m_SearchCriteria.Searchcondition); - - y += 41; - // add the search name entry - AddLabel(28, y, 0x384, "name"); - // add the toggle to enable search by name - AddCheck(5, y, 0xD2, 0xD3, m_SearchCriteria.Dosearchname, 306); - //AddImageTiled(5, 350, 135, 23, 0x52); - AddImageTiled(6, y + 20, 132, 19, 0xBBC); - AddTextEntry(6, y + 20, 250, 19, 0, 102, m_SearchCriteria.Searchname); - - y += 41; - // add the search spawner entries - AddLabel(28, y, 0x384, "entry"); - // add the toggle to enable search spawner entries - AddCheck(5, y, 0xD2, 0xD3, m_SearchCriteria.Dosearchspawnentry, 307); - - // add the search spawner entries by type - AddLabel(88, y, 0x384, "type"); - // add the toggle to enable search spawner entry types - AddCheck(65, y, 0xD2, 0xD3, m_SearchCriteria.Dosearchspawntype, 326); - - //AddImageTiled(5, 415, 135, 23, 0x52); - AddImageTiled(6, y + 20, 132, 19, 0xBBC); - AddTextEntry(6, y + 20, 250, 19, 0, 103, m_SearchCriteria.Searchspawnentry); - - // add the search spawner errors - AddLabel(140, y, 0x384, "err"); - // add the toggle to enable search spawner entries - AddCheck(117, y, 0xD2, 0xD3, m_SearchCriteria.Dosearcherr, 313); - - // add the Show Map button - //AddButton(5, 450, 0xFAB, 0xFAD, 150, GumpButtonType.Reply, 0); - //AddLabel(38, 450, 0x384, "Map"); - - // ---------------- - // CONTROL section - // ---------------- - - y = height - 25; - // add the Return button - AddButton(72, y, 0xFAE, 0xFAF, 155); - AddLabel(105, y, 0x384, "Return"); - - y = height - 25; - // add the Bring button - AddButton(5, y, 0xFAE, 0xFAF, 154); - AddLabel(38, y, 0x384, "Bring"); - - - // add gump extension button - if (m_ShowExtension) - { - AddButton(720, y + 5, 0x15E3, 0x15E7, 200); - } - else - { - AddButton(150, y + 5, 0x15E1, 0x15E5, 200); - } - - if (m_ShowExtension) - { - AddLabel(143, 5, 0x384, "Gump"); - AddLabel(178, 5, 0x384, "Prop"); - AddLabel(210, 5, 0x384, "Goto"); - AddLabel(250, 5, 0x384, "Name"); - AddLabel(365, 5, 0x384, "Type"); - AddLabel(460, 5, 0x384, "Location"); - AddLabel(578, 5, 0x384, "Map"); - AddLabel(650, 5, 0x384, "Owner"); - - // add the Delete button - AddButton(150, y, 0xFB1, 0xFB3, 156); - AddLabel(183, height - 25, 0x384, "Delete"); - - // add the Reset button - AddButton(230, y, 0xFA2, 0xFA3, 157); - AddLabel(263, y, 0x384, "Reset"); - - // add the Respawn button - AddButton(310, y, 0xFA8, 0xFAA, 158); - AddLabel(343, y, 0x384, "Respawn"); - - // add the xmlsave entry - AddButton(150, y - 25, 0xFA8, 0xFAA, 159); - AddLabel(183, y - 25, 0x384, "Save to file:"); - - AddImageTiled(270, y - 25, 180, 19, 0xBBC); - AddTextEntry(270, y - 25, 180, 19, 0, 300, SaveFilename); - - // add the commandstring entry - AddButton(470, y - 25, 0xFA8, 0xFAA, 160); - AddLabel(503, y - 25, 0x384, "Command:"); - - AddImageTiled(560, y - 25, 180, 19, 0xBBC); - AddTextEntry(560, y - 25, 180, 19, 0, 301, CommandString); - - - // add the page buttons - for (int i = 0; i < MaxEntries / MaxEntriesPerPage; i++) - { - //AddButton(38+i*30, 365, 2206, 2206, 0, GumpButtonType.Page, 1+i); - AddButton(418 + i * 25, height - 25, 0x8B1 + i, 0x8B1 + i, 0, GumpButtonType.Page, 1 + i); - } - - // add the advance pageblock buttons - AddButton(415 + 25 * (MaxEntries / MaxEntriesPerPage), height - 25, 0x15E1, 0x15E5, 201); // block forward - AddButton(395, height - 25, 0x15E3, 0x15E7, 202); // block backward - - // add the displayfrom entry - AddLabel(460, y, 0x384, "Display"); - AddImageTiled(500, y, 60, 21, 0xBBC); - AddTextEntry(501, y, 60, 21, 0, 400, DisplayFrom.ToString()); - AddButton(560, y, 0xFAB, 0xFAD, 9998); - - // display the item list - if (m_SearchList != null) - { - AddLabel(180, y - 50, 68, $"Found {m_SearchList.Count} items/mobiles"); - AddLabel(400, y - 50, 68, - $"Displaying {DisplayFrom}-{(DisplayFrom + MaxEntries < m_SearchList.Count ? DisplayFrom + MaxEntries : m_SearchList.Count)}" - ); - - // count the number of selected objects - int count = 0; - foreach (SearchEntry e in m_SearchList) - { - if (e.Selected) - { - count++; - } - } - AddLabel(600, y - 50, 33, $"Selected {count}"); - } - - // display the select-all-displayed toggle - AddButton(730, 5, 0xD2, 0xD3, 3999); - - AddLabel(610, y, 0x384, "Select All"); - // display the select-all toggle - AddButton(670, y, SelectAll ? 0xD3 : 0xD2, SelectAll ? 0xD2 : 0xD3, 3998); - - for (int i = 0; i < MaxEntries; i++) - { - int index = i + DisplayFrom; - if (m_SearchList == null || index >= m_SearchList.Count) - { - break; - } - - SearchEntry e = (SearchEntry)m_SearchList[index]; - - int page = i / MaxEntriesPerPage; - - if (i % MaxEntriesPerPage == 0) - { - AddPage(page + 1); - // add highlighted page button - //AddImageTiled(235+page*25, 448, 25, 25, 0xBBC); - //AddImage(238+page*25, 450, 0x8B1+page); - } - - // background for search results area - AddImageTiled(235, 22 * (i % MaxEntriesPerPage) + 30, 386, 23, 0x52); - AddImageTiled(236, 22 * (i % MaxEntriesPerPage) + 31, 384, 21, 0xBBC); - - // add the Goto button for each entry - AddButton(205, 22 * (i % MaxEntriesPerPage) + 30, 0xFAE, 0xFAF, 1000 + i); - - object o = e.Object; - - // add the Gump button for spawner entries - if (o is XmlSpawner || o is Spawner) - { - AddButton(145, 22 * (i % MaxEntriesPerPage) + 30, 0xFBD, 0xFBE, 2000 + i); - } - - // add the Props button for each entry - AddButton(175, 22 * (i % MaxEntriesPerPage) + 30, 0xFAB, 0xFAD, 3000 + i); - - string namestr = string.Empty; - string typestr = string.Empty; - string locstr = string.Empty; - string mapstr = string.Empty; - string ownstr = string.Empty; - int texthue = 0; - - if (o is Item) - { - Item item = (Item)e.Object; - // change the color if it is in a container - namestr = item.Name; - string str = item.GetType().ToString(); - if (str != null) - { - string[] arglist = str.Split('.'); - typestr = arglist[arglist.Length - 1]; - } - // check for in container - // if so then display parent loc - // change the color for container held items - if (item.Parent != null) - { - if (item.RootParent is Mobile m) - { - texthue = m.Player ? 44 : 24; - locstr = m.Location.ToString(); - ownstr = m.Name; - } - else if (item.RootParent is Container c) - { - texthue = 5; - locstr = c.Location.ToString(); - ownstr = c.Name ?? c.ItemData.Name; - } - } - else - { - locstr = item.Location.ToString(); - } - - if (item.Deleted) - { - mapstr = "Deleted"; - } - else - if (item.Map != null) - { - mapstr = item.Map.ToString(); - } - } - else if (o is Mobile) - { - Mobile mob = (Mobile)e.Object; - // change the color if it is in a container - namestr = mob.Name; - string str = mob.GetType().ToString(); - if (str != null) - { - string[] arglist = str.Split('.'); - typestr = arglist[arglist.Length - 1]; - } - locstr = mob.Location.ToString(); - if (mob.Deleted) - { - mapstr = "Deleted"; - } - else - if (mob.Map != null) - { - mapstr = mob.Map.ToString(); - } - } - - if (e.Selected) - { - texthue = 33; - } - - if (i == Selected) - { - texthue = 68; - } - - // display the name - AddLabelCropped(248, 22 * (i % MaxEntriesPerPage) + 31, 110, 21, texthue, namestr ?? string.Empty); - - // display the type - AddImageTiled(360, 22 * (i % MaxEntriesPerPage) + 31, 90, 21, 0xBBC); - AddLabelCropped(360, 22 * (i % MaxEntriesPerPage) + 31, 90, 21, texthue, typestr); - // display the loc - AddImageTiled(450, 22 * (i % MaxEntriesPerPage) + 31, 137, 21, 0xBBC); - AddLabel(450, 22 * (i % MaxEntriesPerPage) + 31, texthue, locstr); - // display the map - AddImageTiled(571, 22 * (i % MaxEntriesPerPage) + 31, 70, 21, 0xBBC); - AddLabel(571, 22 * (i % MaxEntriesPerPage) + 31, texthue, mapstr); - // display the owner - AddImageTiled(640, 22 * (i % MaxEntriesPerPage) + 31, 90, 21, 0xBBC); - AddLabelCropped(640, 22 * (i % MaxEntriesPerPage) + 31, 90, 21, texthue, ownstr); - - // display the selection button - - AddButton(730, 22 * (i % MaxEntriesPerPage) + 32, e.Selected ? 0xD3 : 0xD2, e.Selected ? 0xD2 : 0xD3, 4000 + i); - } - } - } - - private void DoGoTo(int index) - { - if (m_From == null || m_From.Deleted) - { - return; - } - - if (m_SearchList != null && index < m_SearchList.Count) - { - object o = ((SearchEntry)m_SearchList[index]).Object; - if (o is Item item) - { - Point3D itemloc; - if (item.Parent != null) - { - if (item.RootParent is Mobile mobile) - { - itemloc = mobile.Location; - } - else if (item.RootParent is Container container) - { - itemloc = container.Location; - } - else - { - return; - } - } - else - { - itemloc = item.Location; - } - if (item.Deleted || item.Map == null || item.Map == Map.Internal) - { - return; - } - - m_From.Location = itemloc; - m_From.Map = item.Map; - } - - else if (o is Mobile mob) - { - if (mob.Deleted || mob.Map == null || mob.Map == Map.Internal) - { - return; - } - - m_From.Location = mob.Location; - m_From.Map = mob.Map; - } - } - } - - private void DoShowGump(int index) - { - if (m_From == null || m_From.Deleted) - { - return; - } - - if (m_SearchList != null && index < m_SearchList.Count) - { - object o = ((SearchEntry)m_SearchList[index]).Object; - if (o is XmlSpawner x1) - { - // dont open anything with a null map null item or deleted - if (x1.Deleted || x1.Map == null || x1.Map == Map.Internal) - { - return; - } - - x1.OnDoubleClick(m_From); - } - else if (o is Spawner x2) - { - if (x2.Deleted || x2.Map == null || x2.Map == Map.Internal) - { - return; - } - - x2.OnDoubleClick(m_From); - } - } - } - - private void DoShowProps(int index) - { - if (m_From == null || m_From.Deleted) - { - return; - } - - if (m_SearchList != null && index < m_SearchList.Count) - { - object o = ((SearchEntry)m_SearchList[index]).Object; - if (o is Item x1) - { - if (x1.Deleted) - { - return; - } - - m_From.SendGump(new PropertiesGump(m_From, x1)); - } - else if (o is Mobile x2) - { - if (x2.Deleted) - { - return; - } - - m_From.SendGump(new PropertiesGump(m_From, x2)); - } - } - } - - private void SortFindList() - { - if (m_SearchList != null && m_SearchList.Count > 0) - { - if (Sorttype) - { - m_SearchList.Sort(new ListTypeSorter(Descendingsort)); - } - else if (Sortname) - { - m_SearchList.Sort(new ListNameSorter(Descendingsort)); - } - else if (Sortmap) - { - m_SearchList.Sort(new ListMapSorter(Descendingsort)); - } - else if (Sortrange) - { - m_SearchList.Sort(new ListRangeSorter(m_From, Descendingsort)); - } - else if (Sortselect) - { - m_SearchList.Sort(new ListSelectSorter(Descendingsort)); - } - } - } - - private class ListTypeSorter : IComparer - { - private readonly bool Dsort; - - public ListTypeSorter(bool descend) => Dsort = descend; - - public int Compare(object e1, object e2) - { - string xstr = (e1 as SearchEntry)?.Object?.GetType().Name; - string ystr = (e2 as SearchEntry)?.Object?.GetType().Name; - - if (Dsort) - { - return string.Compare(ystr, xstr, true); - } - - return string.Compare(xstr, ystr, true); - } - } - - private class ListNameSorter : IComparer - { - private readonly bool Dsort; - - public ListNameSorter(bool descend) => Dsort = descend; - - public int Compare(object e1, object e2) - { - string xstr = (e1 as SearchEntry)?.Object switch - { - Item item => item.Name, - Mobile mobile => mobile.Name, - _ => null - }; - - string ystr = (e2 as SearchEntry)?.Object switch - { - Item item => item.Name, - Mobile mobile => mobile.Name, - _ => null - }; - - if (Dsort) - { - return string.Compare(ystr, xstr, true); - } - - return string.Compare(xstr, ystr, true); - } - } - - private class ListMapSorter : IComparer - { - private readonly bool Dsort; - - public ListMapSorter(bool descend) => Dsort = descend; - - public int Compare(object e1, object e2) - { - string xstr = ((e1 as SearchEntry)?.Object as IEntity)?.Map.Name; - string ystr = ((e2 as SearchEntry)?.Object as IEntity)?.Map.Name; - - if (Dsort) - { - return string.Compare(ystr, xstr, true); - } - - return string.Compare(xstr, ystr, true); - } - } - - private class ListRangeSorter : IComparer - { - private readonly Mobile From; - private readonly bool Dsort; - - public ListRangeSorter(Mobile from, bool descend) - { - From = from; - Dsort = descend; - } - - public int Compare(object e1, object e2) - { - if (From == null || From.Deleted) - { - return 0; - } - - IEntity entity1 = (e1 as SearchEntry)?.Object as IEntity; - IEntity entity2 = (e2 as SearchEntry)?.Object as IEntity; - - if (entity1 == null && entity2 == null) - { - return 0; - } - - if (entity1 == null) - { - return Dsort ? 1 : -1; - } - if (entity2 == null) - { - return Dsort ? -1 : 1; - } - - if (entity1.Map != From.Map && entity2.Map != From.Map) - { - return 0; - } - - if (entity1.Map == From.Map && entity2.Map != From.Map) - { - return Dsort ? 1 : -1; - } - - if (entity1.Map != From.Map && entity2.Map == From.Map) - { - return Dsort ? -1 : 1; - } - - if (Dsort) - { - return From.GetDistanceToSqrt(entity2.Location).CompareTo(From.GetDistanceToSqrt(entity1.Location)); - } - - return From.GetDistanceToSqrt(entity1.Location).CompareTo(From.GetDistanceToSqrt(entity2.Location)); - } - } - - private class ListSelectSorter : IComparer - { - private readonly bool Dsort; - - public ListSelectSorter(bool descend) => Dsort = descend; - - public int Compare(object e1, object e2) - { - int x = 0; - int y = 0; - - if (e1 is SearchEntry entry) - { - x = entry.Selected ? 1 : 0; - } - - if (e2 is SearchEntry searchEntry) - { - y = searchEntry.Selected ? 1 : 0; - } - - if (Dsort) - { - return x - y; - } - - return y - x; - } - } - - private void Refresh(NetState state) - { - state.Mobile.SendGump(new XmlFindGump(m_From, StartingLoc, StartingMap, false, m_ShowExtension, Descendingsort, m_SearchCriteria, m_SearchList, Selected, DisplayFrom, SaveFilename, - CommandString, Sorttype, Sortname, Sortrange, - Sortmap, Sortselect, SelectAll, X, Y)); - } - - private void ResetList() - { - if (m_SearchList == null) - { - return; - } - - for (int i = 0; i < m_SearchList.Count; i++) - { - SearchEntry e = (SearchEntry)m_SearchList[i]; - - if (e.Selected) - { - object o = e.Object; - - if (o is XmlSpawner spawner) - { - spawner.DoReset = true; - } - } - } - } - - private void RespawnList() - { - if (m_SearchList == null) - { - return; - } - - for (int i = 0; i < m_SearchList.Count; i++) - { - SearchEntry e = (SearchEntry)m_SearchList[i]; - - if (e.Selected) - { - object o = e.Object; - - if (o is XmlSpawner spawner) - { - spawner.DoRespawn = true; - } - } - } - } - - private void SaveList(Mobile from, string filename) - { - if (m_SearchList == null) - { - return; - } - - string dirname; - if (System.IO.Directory.Exists(XmlSpawner.XmlSpawnDir) && filename != null && !filename.StartsWith("/") && !filename.StartsWith("\\")) - { - // put it in the defaults directory if it exists - dirname = $"{XmlSpawner.XmlSpawnDir}/{filename}"; - } - else - { - // otherwise just put it in the main installation dir - dirname = filename; - } - - List savelist = new List(); - - for (int i = 0; i < m_SearchList.Count; i++) - { - SearchEntry e = (SearchEntry)m_SearchList[i]; - - if (e.Selected) - { - object o = e.Object; - - if (o is XmlSpawner spawner) - { - // add it to the saves list - savelist.Add(spawner); - } - } - } - - // write out the spawners to a file - XmlSpawner.SaveSpawnList(from, savelist, dirname, false, true); - } - - private void ExecuteCommand(Mobile from, string command) - { - if (m_SearchList == null) - { - return; - } - - var executelist = new List(); - - for (int i = 0; i < m_SearchList.Count; i++) - { - SearchEntry e = (SearchEntry)m_SearchList[i]; - - if (e.Selected) - { - object o = e.Object; - - // add it to the execute list - executelist.Add(o); - - } - } - - // lookup the command - // and execute it - if (!string.IsNullOrEmpty(command)) - { - string[] args = command.Split(' '); - - if (args.Length > 1) - { - string[] cargs = new string[args.Length - 1]; - for (int i = 0; i < args.Length - 1; i++) - { - cargs[i] = args[i + 1]; - } - - CommandEventArgs e = new CommandEventArgs(from, args[0], command, cargs); - - foreach (BaseCommand c in TargetCommands.AllCommands) - { - // find the matching command - if (string.Equals(c.Commands[0], args[0], StringComparison.CurrentCultureIgnoreCase)) - { - bool flushToLog = false; - - // execute the command on the objects in the list - - if (executelist.Count > 20) - { - CommandLogging.Enabled = false; - } - - c.ExecuteList(e, executelist); - - if (executelist.Count > 20) - { - flushToLog = true; - CommandLogging.Enabled = true; - } - - c.Flush(from, flushToLog); - return; - } - } - from.SendMessage($"Invalid command: {args[0]}"); - } - } - } - - public override void OnResponse(NetState state, RelayInfo info) - { - if (info == null || state?.Mobile == null || m_SearchCriteria == null) - { - return; - } - - int radiostate = -1; - if (info.Switches.Length > 0) - { - radiostate = info.Switches[0]; - } - - // read the text entries for the search criteria - TextRelay tr = info.GetTextEntry(105); // range info - m_SearchCriteria.Searchage = 0; - if (tr?.Text != null && tr.Text.Length > 0) - { - try { m_SearchCriteria.Searchage = double.Parse(tr.Text); } - catch (Exception e) { Diagnostics.ExceptionLogging.LogException(e); } - } - - // read the text entries for the search criteria - tr = info.GetTextEntry(100); // range info - m_SearchCriteria.Searchrange = -1; - if (tr?.Text != null && tr.Text.Length > 0) - { - try { m_SearchCriteria.Searchrange = int.Parse(tr.Text); } - catch (Exception e) { Diagnostics.ExceptionLogging.LogException(e); } - } - - tr = info.GetTextEntry(101); // type info - if (tr != null) - { - m_SearchCriteria.Searchtype = tr.Text; - } - - tr = info.GetTextEntry(102); // name info - if (tr != null) - { - m_SearchCriteria.Searchname = tr.Text; - } - - tr = info.GetTextEntry(103); // entry info - if (tr != null) - { - m_SearchCriteria.Searchspawnentry = tr.Text; - } - - tr = info.GetTextEntry(104); // condition info - if (tr != null) - { - m_SearchCriteria.Searchcondition = tr.Text; - } - - tr = info.GetTextEntry(106); // region info - if (tr != null) - { - m_SearchCriteria.Searchregion = tr.Text; - } - - - tr = info.GetTextEntry(400); // displayfrom info - if (tr != null) - { - DisplayFrom = Utility.ToInt32(tr.Text); - } - - tr = info.GetTextEntry(300); // savefilename info - if (tr != null) - { - SaveFilename = tr.Text; - } - - tr = info.GetTextEntry(301); // commandstring info - if (tr != null) - { - CommandString = tr.Text; - } - - - // check all of the check boxes - m_SearchCriteria.Searchagedirection = info.IsSwitched(302); - m_SearchCriteria.Dosearchage = info.IsSwitched(303); - m_SearchCriteria.Dosearchrange = info.IsSwitched(304); - m_SearchCriteria.Dosearchtype = info.IsSwitched(305); - m_SearchCriteria.Dosearchname = info.IsSwitched(306); - m_SearchCriteria.Dosearchspawnentry = info.IsSwitched(307); - m_SearchCriteria.Dosearchspawntype = info.IsSwitched(326); - m_SearchCriteria.Dosearcherr = info.IsSwitched(313); - m_SearchCriteria.Dosearchcondition = info.IsSwitched(315); - - m_SearchCriteria.Dosearchint = info.IsSwitched(312); - m_SearchCriteria.Dosearchfel = info.IsSwitched(308); - m_SearchCriteria.Dosearchtram = info.IsSwitched(309); - m_SearchCriteria.Dosearchmal = info.IsSwitched(310); - m_SearchCriteria.Dosearchilsh = info.IsSwitched(311); - m_SearchCriteria.Dosearchtok = info.IsSwitched(318); - m_SearchCriteria.Dosearchter = info.IsSwitched(320); - m_SearchCriteria.Dosearchnull = info.IsSwitched(314); - - m_SearchCriteria.Dohidevalidint = info.IsSwitched(316); - m_SearchCriteria.Dosearchregion = info.IsSwitched(319); - - switch (info.ButtonID) - { - - case 0: // Close - { - return; - } - case 3: // Search - { - // clear any selection - Selected = -1; - - // reset displayfrom - DisplayFrom = 0; - - // do the search - m_SearchCriteria.Currentloc = state.Mobile.Location; - m_SearchCriteria.Currentmap = state.Mobile.Map; - - //m_SearchList = Search(m_SearchCriteria, out status_str); - XmlFindThread tobj = new XmlFindThread(state.Mobile, m_SearchCriteria, CommandString); - Thread find = new Thread(tobj.XmlFindThreadMain) - { - Name = "XmlFind Thread" - }; - find.Start(); - - // turn on gump extension - m_ShowExtension = true; - return; - } - case 4: // SubSearch - { - // do the search - m_SearchList = Search(m_SearchCriteria, out _); - break; - } - case 150: // Open the map gump - { - break; - } - case 154: // Bring all selected objects to the current location - { - Refresh(state); - - state.Mobile.SendGump(new XmlConfirmBringGump(m_SearchList)); - return; - } - case 155: // Return the player to the starting loc - { - m_From.Location = StartingLoc; - m_From.Map = StartingMap; - break; - } - case 156: // Delete selected items - { - Refresh(state); - - state.Mobile.SendGump(new XmlConfirmDeleteGump(m_SearchList)); - return; - } - case 157: // Reset selected items - { - ResetList(); - break; - } - case 158: // Respawn selected items - { - RespawnList(); - break; - } - case 159: // xmlsave selected spawners - { - SaveList(state.Mobile, SaveFilename); - break; - } - case 160: // execute the command on the selected items - { - ExecuteCommand(state.Mobile, CommandString); - break; - } - case 200: // gump extension - { - m_ShowExtension = !m_ShowExtension; - break; - } - case 201: // forward block - { - if (m_SearchList != null && DisplayFrom + MaxEntries < m_SearchList.Count) - { - DisplayFrom += MaxEntries; - // clear any selection - Selected = -1; - } - break; - } - case 202: // backward block - { - - DisplayFrom -= MaxEntries; - if (DisplayFrom < 0) - { - DisplayFrom = 0; - } - - // clear any selection - Selected = -1; - break; - } - - case 700: // Sort - { - // clear any selection - Selected = -1; - - Sorttype = false; - Sortname = false; - Sortrange = false; - Sortmap = false; - Sortselect = false; - // read the toggle switches that determine the sort - if (radiostate == 0) // sort by type - { - Sorttype = true; - } - else - if (radiostate == 1) // sort by name - { - Sortname = true; - } - else - if (radiostate == 2) // sort by range - { - Sortrange = true; - } - else - if (radiostate == 4) // sort by entry - { - Sortmap = true; - } - else - if (radiostate == 5) // sort by selected - { - Sortselect = true; - } - - SortFindList(); - break; - } - case 701: // descending sort - { - Descendingsort = !Descendingsort; - break; - } - case 9998: // refresh the gump - { - // clear any selection - Selected = -1; - break; - } - default: - { - - if (info.ButtonID >= 1000 && info.ButtonID < 1000 + MaxEntries) - { - // flag the entry selected - Selected = info.ButtonID - 1000; - // then go to it - DoGoTo(info.ButtonID - 1000 + DisplayFrom); - } - if (info.ButtonID >= 2000 && info.ButtonID < 2000 + MaxEntries) - { - // flag the entry selected - Selected = info.ButtonID - 2000; - // then open the gump - Refresh(state); - DoShowGump(info.ButtonID - 2000 + DisplayFrom); - return; - } - if (info.ButtonID >= 3000 && info.ButtonID < 3000 + MaxEntries) - { - Selected = info.ButtonID - 3000; - // Show the props window - Refresh(state); - DoShowProps(info.ButtonID - 3000 + DisplayFrom); - return; - } - if (info.ButtonID == 3998) - { - SelectAll = !SelectAll; - - if (m_SearchList != null) - { - foreach (SearchEntry e in m_SearchList) - { - e.Selected = SelectAll; - } - } - } - if (info.ButtonID == 3999) - { - // toggle selection of everything currently displayed - if (m_SearchList != null) - { - for (int i = 0; i < MaxEntries; i++) - { - if (i + DisplayFrom < m_SearchList.Count) - { - SearchEntry e = (SearchEntry)m_SearchList[i + DisplayFrom]; - - e.Selected = !e.Selected; - } - else - { - break; - } - } - } - } - if (info.ButtonID >= 4000 && info.ButtonID < 4000 + MaxEntries) - { - int i = info.ButtonID - 4000; - - if (m_SearchList != null && i >= 0 && m_SearchList.Count > i + DisplayFrom) - { - SearchEntry e = (SearchEntry)m_SearchList[i + DisplayFrom]; - - e.Selected = !e.Selected; - } - } - - break; - } - } - - Refresh(state); - } - - public class XmlConfirmBringGump : Gump - { - private readonly ArrayList SearchList; - - public XmlConfirmBringGump(ArrayList searchlist) - : base(0, 0) - { - SearchList = searchlist; - - Closable = false; - Draggable = true; - AddPage(0); - AddBackground(10, 200, 200, 130, 5054); - int count = 0; - - if (SearchList != null) - { - for (int i = 0; i < SearchList.Count; i++) - { - if (((SearchEntry)SearchList[i]).Selected) - { - count++; - } - } - } - - AddLabel(20, 225, 33, $"Bring {count} objects to you?"); - AddRadio(35, 255, 9721, 9724, false, 1); // accept/yes radio - AddRadio(135, 255, 9721, 9724, true, 2); // decline/no radio - AddHtmlLocalized(72, 255, 200, 30, 1049016, 0x7fff); // Yes - AddHtmlLocalized(172, 255, 200, 30, 1049017, 0x7fff); // No - AddButton(80, 289, 2130, 2129, 3); // Okay button - - } - public override void OnResponse(NetState state, RelayInfo info) - { - if (info == null || state?.Mobile == null) - { - return; - } - - int radiostate = -1; - - Point3D myloc = state.Mobile.Location; - Map mymap = state.Mobile.Map; - - if (info.Switches.Length > 0) - { - radiostate = info.Switches[0]; - } - switch (info.ButtonID) - { - default: - { - if (radiostate == 1 && SearchList != null) - { // accept - for (int i = 0; i < SearchList.Count; i++) - { - SearchEntry e = (SearchEntry)SearchList[i]; - - if (e.Selected) - { - object o = e.Object; - - if (o is Item item) - { - - item.MoveToWorld(myloc, mymap); - - } - else if (o is Mobile mobile) - { - - mobile.MoveToWorld(myloc, mymap); - - } - } - } - } - break; - } - } - } - } - - public class XmlConfirmDeleteGump : Gump - { - private readonly ArrayList SearchList; - - public XmlConfirmDeleteGump(ArrayList searchlist) - : base(0, 0) - { - SearchList = searchlist; - - Closable = false; - Draggable = true; - AddPage(0); - AddBackground(10, 200, 200, 130, 5054); - int count = 0; - - if (SearchList != null) - { - for (int i = 0; i < SearchList.Count; i++) - { - if (((SearchEntry)SearchList[i]).Selected) - { - count++; - } - } - } - - AddLabel(20, 225, 33, $"Delete {count} objects?"); - AddRadio(35, 255, 9721, 9724, false, 1); // accept/yes radio - AddRadio(135, 255, 9721, 9724, true, 2); // decline/no radio - AddHtmlLocalized(72, 255, 200, 30, 1049016, 0x7fff); // Yes - AddHtmlLocalized(172, 255, 200, 30, 1049017, 0x7fff); // No - AddButton(80, 289, 2130, 2129, 3); // Okay button - - } - public override void OnResponse(NetState state, RelayInfo info) - { - if (info == null || state?.Mobile == null) - { - return; - } - - int radiostate = -1; - if (info.Switches.Length > 0) - { - radiostate = info.Switches[0]; - } - switch (info.ButtonID) - { - - default: - { - if (radiostate == 1 && SearchList != null) - { // accept - for (int i = 0; i < SearchList.Count; i++) - { - SearchEntry e = (SearchEntry)SearchList[i]; - - if (e.Selected) - { - object o = e.Object; - - if (o is Item item) - { - // some objects may not delete gracefully (null map items are particularly error prone) so trap them - try - { - item.Delete(); - } - catch (Exception ex) { Diagnostics.ExceptionLogging.LogException(ex); } - } - else if (o is Mobile mobile && !mobile.Player) - { - try - { - mobile.Delete(); - } - catch (Exception ex) { Diagnostics.ExceptionLogging.LogException(ex); } - } - } - } - } - - break; - } - } - } - } -}