fix(core): Removes some uses of Linq (#421)

- [X] Removes some uses of linq
- [X] Creates struct based enumerator for Skills
- [X] Creates a struct based enumerator for TypeCache
- [X] Changes HarvestDefinition to an init array instead of List
- [X] Changes HeritageTokenGump Response from List to Array
This commit is contained in:
Kamron Batman 2021-01-18 21:05:11 -08:00 committed by GitHub
parent 52356866ed
commit b921c38879
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
50 changed files with 1006 additions and 507 deletions

View file

@ -14,6 +14,7 @@
*************************************************************************/ *************************************************************************/
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@ -89,40 +90,41 @@ namespace Server
return m_TypeCaches[asm] = new TypeCache(asm); return m_TypeCaches[asm] = new TypeCache(asm);
} }
public static Type FindFirstTypeForName(string name, bool ignoreCase = false, Func<Type, bool> predicate = null) private static bool IgnoreCaseTypeComparer(string name, Type type) =>
type.FullName.InsensitiveEquals(name) || type.Name.InsensitiveEquals(name);
private static bool CaseTypeComparer(string name, Type type) =>
type.FullName.EqualsOrdinal(name) || type.Name.EqualsOrdinal(name);
public static Type FindFirstTypeForName(string name, bool ignoreCase = false, Func<string, Type, bool> predicate = null)
{ {
if (string.IsNullOrWhiteSpace(name)) if (string.IsNullOrWhiteSpace(name))
{ {
return null; return null;
} }
var types = FindTypesByName(name, ignoreCase).ToList(); var types = FindTypesByName(name, ignoreCase);
if (types.Count == 0) if (types.Count == 0)
{ {
return null; return null;
} }
if (predicate != null)
{
return types.FirstOrDefault(predicate);
}
if (types.Count == 1)
{
return types[0];
}
// Try to find the closest match if there is no predicate. // Try to find the closest match if there is no predicate.
// Check for exact match of the FullName or Name // Check for exact match of the FullName or Name
// Then check for case-insensitive match of FullName or Name // Then check for case-insensitive match of FullName or Name
// Otherwise just return the first entry // Otherwise just return the first entry
var stringComparer = ignoreCase ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal; predicate ??= ignoreCase ? IgnoreCaseTypeComparer : CaseTypeComparer;
return types.FirstOrDefault( foreach (var type in types)
x => {
stringComparer.Equals(x.FullName, name) || stringComparer.Equals(x.Name, name) if (predicate(name, type))
) ?? {
types[0]; return type;
}
}
return null;
} }
public static List<Type> FindTypesByName(string name, bool ignoreCase = false) public static List<Type> FindTypesByName(string name, bool ignoreCase = false)
@ -136,12 +138,18 @@ namespace Server
for (var i = 0; i < Assemblies.Length; i++) for (var i = 0; i < Assemblies.Length; i++)
{ {
types.AddRange(GetTypeCache(Assemblies[i])[name]); foreach (var type in GetTypeCache(Assemblies[i])[name])
{
types.Add(type);
}
} }
if (types.Count == 0) if (types.Count == 0)
{ {
types.AddRange(GetTypeCache(Core.Assembly)[name]); foreach(var type in GetTypeCache(Core.Assembly)[name])
{
types.Add(type);
}
} }
return types; return types;
@ -159,11 +167,10 @@ namespace Server
public class TypeCache public class TypeCache
{ {
private readonly Dictionary<string, int[]> m_NameMap = new(); private readonly Dictionary<string, int[]> m_NameMap = new();
private readonly Type[] m_Types;
public TypeCache(Assembly asm) public TypeCache(Assembly asm)
{ {
m_Types = asm?.GetTypes() ?? Type.EmptyTypes; Types = asm?.GetTypes() ?? Type.EmptyTypes;
var nameMap = new Dictionary<string, HashSet<int>>(); var nameMap = new Dictionary<string, HashSet<int>>();
HashSet<int> refs; HashSet<int> refs;
@ -181,9 +188,9 @@ namespace Server
}; };
var aliasType = typeof(TypeAliasAttribute); var aliasType = typeof(TypeAliasAttribute);
for (var i = 0; i < m_Types.Length; i++) for (var i = 0; i < Types.Length; i++)
{ {
var current = m_Types[i]; var current = Types[i];
addToRefs(i, current.Name); addToRefs(i, current.Name);
addToRefs(i, current.Name.ToLower()); addToRefs(i, current.Name.ToLower());
addToRefs(i, current.FullName); addToRefs(i, current.FullName);
@ -204,10 +211,70 @@ namespace Server
} }
} }
public IEnumerable<Type> Types => m_Types; public Enumerator this[string name] => new(name, this);
public IEnumerable<string> Names => m_NameMap.Keys;
public IEnumerable<Type> this[string name] => public Type[] Types { get; }
m_NameMap.TryGetValue(name, out var value) ? value.Select(x => m_Types[x]) : Array.Empty<Type>();
public struct Enumerator : IEnumerable<Type>, IEnumerator<Type>
{
private readonly TypeCache _cache;
private readonly int[] _values;
private int _index;
private Type _current;
internal Enumerator(string name, TypeCache cache)
{
_cache = cache;
_values = !cache.m_NameMap.TryGetValue(name, out var values) ? Array.Empty<int>() : values;
_index = 0;
_current = default;
}
public void Dispose()
{
}
public bool MoveNext()
{
int[] localList = _values;
while ((uint)_index < (uint)localList.Length)
{
_current = _cache.Types[_values[_index++]];
if (_current != null)
{
return true;
}
}
return false;
}
public Type Current => _current!;
object IEnumerator.Current
{
get
{
if (_index == 0 || _index == _values.Length + 1)
{
throw new InvalidOperationException(nameof(_index));
}
return Current;
}
}
void IEnumerator.Reset()
{
_index = 0;
_current = default;
}
public IEnumerator<Type> GetEnumerator() => this;
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
} }
} }

View file

@ -1,5 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace Server.ContextMenus namespace Server.ContextMenus
{ {
@ -64,7 +63,21 @@ namespace Server.ContextMenus
/// <summary> /// <summary>
/// Returns true if this ContextMenu requires packet version 2. /// Returns true if this ContextMenu requires packet version 2.
/// </summary> /// </summary>
public bool RequiresNewPacket => public bool RequiresNewPacket
Entries.Any(t => t.Number < 3000000 || t.Number > 3032767); {
get
{
for (var i = 0; i < Entries.Length; ++i)
{
var number = Entries[i].Number;
if (number < 3000000 || number > 3032767)
{
return true;
}
}
return false;
}
}
} }
} }

View file

@ -1,5 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace Server.Guilds namespace Server.Guilds
{ {
@ -43,11 +42,31 @@ namespace Server.Guilds
public abstract void Deserialize(IGenericReader reader); public abstract void Deserialize(IGenericReader reader);
public abstract void OnDelete(Mobile mob); public abstract void OnDelete(Mobile mob);
public static BaseGuild FindByName(string name) => public static BaseGuild FindByName(string name)
World.Guilds.Values.FirstOrDefault(g => g.Name == name); {
foreach (var g in World.Guilds.Values)
{
if (g.Name == name)
{
return g;
}
}
public static BaseGuild FindByAbbrev(string abbr) => return null;
World.Guilds.Values.FirstOrDefault(g => g.Abbreviation == abbr); }
public static BaseGuild FindByAbbrev(string abbr)
{
foreach (var g in World.Guilds.Values)
{
if (g.Abbreviation == abbr)
{
return g;
}
}
return null;
}
public static HashSet<BaseGuild> Search(string find) public static HashSet<BaseGuild> Search(string find)
{ {

View file

@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using Server.Network; using Server.Network;
using Server.Utilities; using Server.Utilities;
using QueuePool = Server.Utilities.RefPool<Server.Utilities.QueueRef<Server.Items.Container>>; using QueuePool = Server.Utilities.RefPool<Server.Utilities.QueueRef<Server.Items.Container>>;
@ -1457,7 +1456,11 @@ namespace Server.Items
for (var j = 0; j < groups.Count; ++j) for (var j = 0; j < groups.Count; ++j)
{ {
var items = groups[j].ToArray(); var items = groups[j].ToArray();
var total = items.Sum(t => t.Amount); var total = 0;
foreach (var item in items)
{
total += item.Amount;
}
if (total >= best) if (total >= best)
{ {
@ -1531,9 +1534,27 @@ namespace Server.Items
return best; return best;
} }
public int GetAmount(Type type, bool recurse = true) => FindItemsByType(type, recurse).Sum(t => t.Amount); public int GetAmount(Type type, bool recurse = true)
{
var total = 0;
foreach (var item in FindItemsByType(type, recurse))
{
total += item.Amount;
}
public int GetAmount(Type[] types, bool recurse = true) => FindItemsByType(types, recurse).Sum(t => t.Amount); return total;
}
public int GetAmount(Type[] types, bool recurse = true)
{
var total = 0;
foreach (var item in FindItemsByType(types, recurse))
{
total += item.Amount;
}
return total;
}
public Item[] FindItemsByType(Type type, bool recurse = true) public Item[] FindItemsByType(Type type, bool recurse = true)
{ {

View file

@ -2,7 +2,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using Server.ContextMenus; using Server.ContextMenus;
using Server.Items; using Server.Items;
@ -3619,28 +3618,27 @@ namespace Server
var eable = map.GetItemsInRange(p, 0); var eable = map.GetItemsInRange(p, 0);
var items = eable.Where( var items = new List<Item>();
item => foreach (var item in eable)
{
if (item is BaseMulti || item.ItemID > TileData.MaxItemValue)
{ {
if (item is BaseMulti || item.ItemID > TileData.MaxItemValue) continue;
{
return false;
}
var id = item.ItemData;
if (id.Surface)
{
var top = item.Z + id.CalcHeight;
if (top <= maxZ && top >= z)
{
z = top;
}
}
return true;
} }
).ToList();
var id = item.ItemData;
if (id.Surface)
{
var top = item.Z + id.CalcHeight;
if (top <= maxZ && top >= z)
{
z = top;
}
}
items.Add(item);
}
eable.Free(); eable.Free();

View file

@ -17,7 +17,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime; using System.Runtime;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -38,7 +37,9 @@ namespace Server
private static bool m_Profiling; private static bool m_Profiling;
private static DateTime m_ProfileStart; private static DateTime m_ProfileStart;
private static TimeSpan m_ProfileTime; private static TimeSpan m_ProfileTime;
private static bool? m_IsRunningFromXUnit; #nullable enable
private static bool? _isRunningFromXUnit;
#nullable disable
private static long m_CycleIndex; private static long m_CycleIndex;
private static readonly float[] m_CyclesPerSecond = new float[127]; // Divisible by long.MaxValue private static readonly float[] m_CyclesPerSecond = new float[127]; // Divisible by long.MaxValue
@ -58,11 +59,31 @@ namespace Server
private const string assembliesConfiguration = "Data/assemblies.json"; private const string assembliesConfiguration = "Data/assemblies.json";
public static bool IsRunningFromXUnit => #nullable enable
m_IsRunningFromXUnit ??= AppDomain.CurrentDomain.GetAssemblies() // TODO: Find a way to get rid of this
.Any( public static bool IsRunningFromXUnit
a => a.FullName.InsensitiveStartsWith("XUNIT") {
); get
{
if (_isRunningFromXUnit != null)
{
return _isRunningFromXUnit.Value;
}
foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
{
if (a.FullName.InsensitiveStartsWith("xunit"))
{
_isRunningFromXUnit = true;
return true;
}
}
_isRunningFromXUnit = false;
return false;
}
}
#nullable disable
public static bool Profiling public static bool Profiling
{ {
@ -440,9 +461,11 @@ namespace Server
var assemblyPath = Path.Join(BaseDirectory, assembliesConfiguration); var assemblyPath = Path.Join(BaseDirectory, assembliesConfiguration);
// Load UOContent.dll // Load UOContent.dll
var assemblyFiles = JsonConfig.Deserialize<List<string>>(assemblyPath) var assemblyFiles = JsonConfig.Deserialize<List<string>>(assemblyPath).ToArray();
.Select(t => Path.Join(BaseDirectory, "Assemblies", t)) for (var i = 0; i < assemblyFiles.Length; i++)
.ToArray(); {
assemblyFiles[i] = Path.Join(BaseDirectory, "Assemblies", assemblyFiles[i]);
}
AssemblyHandler.LoadScripts(assemblyFiles); AssemblyHandler.LoadScripts(assemblyFiles);

View file

@ -2,7 +2,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using Microsoft.Toolkit.HighPerformance.Extensions; using Microsoft.Toolkit.HighPerformance.Extensions;
@ -6012,7 +6011,15 @@ namespace Server
de.Responsible = list = new List<DamageEntry>(); de.Responsible = list = new List<DamageEntry>();
} }
var resp = list.FirstOrDefault(check => check.Damager == master); DamageEntry resp = null;
foreach (var check in list)
{
if (check.Damager == master)
{
resp = check;
break;
}
}
if (resp == null) if (resp == null)
{ {

View file

@ -1,7 +1,6 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Server.Network; using Server.Network;
namespace Server namespace Server
@ -806,15 +805,9 @@ namespace Server
[CommandProperty(AccessLevel.Counselor)] [CommandProperty(AccessLevel.Counselor)]
public Skill Throwing => this[SkillName.Throwing]; public Skill Throwing => this[SkillName.Throwing];
public IEnumerator<Skill> GetEnumerator() public Enumerator GetEnumerator() => new(this);
{ IEnumerator<Skill> IEnumerable<Skill>.GetEnumerator() => new Enumerator(this);
return m_Skills.Where(s => s != null).GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => new Enumerator(this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return m_Skills.Where(s => s != null).GetEnumerator();
}
public override string ToString() => "..."; public override string ToString() => "...";
@ -902,5 +895,60 @@ namespace Server
Owner.OnSkillInvalidated(skill); Owner.OnSkillInvalidated(skill);
Owner.NetState.SendSkillChange(skill); Owner.NetState.SendSkillChange(skill);
} }
public struct Enumerator : IEnumerator<Skill>
{
private readonly Skills _skills;
private int _index;
private Skill _current;
internal Enumerator(Skills skills)
{
_skills = skills;
_index = 0;
_current = default;
}
public void Dispose()
{
}
public bool MoveNext()
{
Skills localList = _skills;
while ((uint)_index < (uint)localList.Length)
{
_current = localList.m_Skills[_index++];
if (_current != null)
{
return true;
}
}
return false;
}
public Skill Current => _current!;
object IEnumerator.Current
{
get
{
if (_index == 0 || _index == _skills.Length + 1)
{
throw new InvalidOperationException(nameof(_index));
}
return Current;
}
}
void IEnumerator.Reset()
{
_index = 0;
_current = default;
}
}
} }
} }

View file

@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -224,16 +223,11 @@ namespace Server
var any = false; var any = false;
m_TilesList.AddRange( foreach (StaticTile[] multiTiles in eable)
eable.SelectMany( {
t => any = true;
{ m_TilesList.AddRange(multiTiles);
any = true; }
return t;
}
)
.ToArray()
);
eable.Free(); eable.Free();

View file

@ -3,7 +3,6 @@ using System.Buffers.Binary;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@ -742,7 +741,12 @@ namespace Server
var byteIndex = 0; var byteIndex = 0;
var length = mems.Sum(mem => mem.Length); var length = 0;
for (var i = 0; i < mems.Length; i++)
{
length += mems[i].Length;
}
var position = 0; var position = 0;
var memIndex = 0; var memIndex = 0;
var span = mems[memIndex].Span; var span = mems[memIndex].Span;
@ -1386,5 +1390,7 @@ namespace Server
i = (i & 0x3333333333333333UL) + ((i >> 2) & 0x3333333333333333UL); i = (i & 0x3333333333333333UL) + ((i >> 2) & 0x3333333333333333UL);
return (int)(unchecked(((i + (i >> 4)) & 0xF0F0F0F0F0F0F0FUL) * 0x101010101010101UL) >> 56); return (int)(unchecked(((i + (i >> 4)) & 0xF0F0F0F0F0F0F0FUL) * 0x101010101010101UL) >> 56);
} }
} }
} }

View file

@ -1,4 +1,3 @@
using System.Linq;
using System.Net; using System.Net;
using Server.Network; using Server.Network;
@ -22,7 +21,16 @@ namespace Server.Misc
MaxAddresses = ServerConfiguration.GetOrUpdateSetting("ipLimiter.maxConnectionsPerIP", 10); MaxAddresses = ServerConfiguration.GetOrUpdateSetting("ipLimiter.maxConnectionsPerIP", 10);
} }
public static bool IsExempt(IPAddress ip) => Exemptions.Contains(ip); public static bool IsExempt(IPAddress ip)
{
for (int i = 0; i < Exemptions.Length; i++)
{
if (ip.Equals(Exemptions[i]))
return true;
}
return false;
}
public static bool Verify(IPAddress ourAddress) public static bool Verify(IPAddress ourAddress)
{ {

View file

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using Server.Items; using Server.Items;
@ -230,7 +229,14 @@ namespace Server.Commands
// Handle optional constructors // Handle optional constructors
var paramList = ctor.GetParameters(); var paramList = ctor.GetParameters();
var totalParams = paramList.Count(t => !t.HasDefaultValue); var totalParams = 0;
for (var j = 0; j < paramList.Length; j++)
{
if (!paramList[j].HasDefaultValue)
{
totalParams++;
}
}
if (args.Length >= totalParams && args.Length <= paramList.Length) if (args.Length >= totalParams && args.Length <= paramList.Length)
{ {

View file

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Server.Network; using Server.Network;
using Server.Targeting; using Server.Targeting;
@ -160,11 +159,11 @@ namespace Server.Gumps
for (var i = 0; i < asms.Length; ++i) for (var i = 0; i < asms.Length; ++i)
{ {
types = AssemblyHandler.GetTypeCache(asms[i]).Types.ToArray(); types = AssemblyHandler.GetTypeCache(asms[i]).Types;
Match(match, types, results); Match(match, types, results);
} }
types = AssemblyHandler.GetTypeCache(Core.Assembly).Types.ToArray(); types = AssemblyHandler.GetTypeCache(Core.Assembly).Types;
Match(match, types, results); Match(match, types, results);
results.Sort(new TypeNameComparer()); results.Sort(new TypeNameComparer());

View file

@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Reflection; using System.Reflection;
using Server.Items; using Server.Items;
using Server.Json; using Server.Json;
@ -79,67 +78,69 @@ namespace Server.Commands
if (ce.Matched.Count > 0) if (ce.Matched.Count > 0)
{ {
var objects = new CAGObject[ce.Matched.Count];
for (var i = 0; i < ce.Matched.Count; i++)
{
var cte = ce.Matched[i];
if (cte.Object is Item item)
{
var itemID = item.ItemID;
if (item is BaseAddon addon && addon.Components.Count == 1)
{
itemID = addon.Components[0].ItemID;
}
if (itemID > TileData.MaxItemValue)
{
itemID = 1;
}
int? hue = item.Hue & 0x7FFF;
if ((hue & 0x4000) != 0)
{
hue = 0;
}
objects[i] = new CAGObject
{
Type = cte.Type,
ItemID = itemID,
Hue = hue == 0 ? null : hue
};
}
if (cte.Object is Mobile m)
{
var itemID = ShrinkTable.Lookup(m, 1);
int? hue = m.Hue & 0x7FFF;
if ((hue & 0x4000) != 0)
{
hue = 0;
}
objects[i] = new CAGObject
{
Type = cte.Type,
ItemID = itemID,
Hue = hue == 0 ? null : hue
};
}
throw new InvalidCastException(
$"Categorization Type Entry: {cte.Type.Name} is not a valid type."
);
}
list.Add( list.Add(
new CAGJson new CAGJson
{ {
Category = category, Category = category,
Objects = ce.Matched.Select( Objects = objects
cte =>
{
if (cte.Object is Item item)
{
var itemID = item.ItemID;
if (item is BaseAddon addon && addon.Components.Count == 1)
{
itemID = addon.Components[0].ItemID;
}
if (itemID > TileData.MaxItemValue)
{
itemID = 1;
}
int? hue = item.Hue & 0x7FFF;
if ((hue & 0x4000) != 0)
{
hue = 0;
}
return new CAGObject
{
Type = cte.Type,
ItemID = itemID,
Hue = hue == 0 ? null : hue
};
}
if (cte.Object is Mobile m)
{
var itemID = ShrinkTable.Lookup(m, 1);
int? hue = m.Hue & 0x7FFF;
if ((hue & 0x4000) != 0)
{
hue = 0;
}
return new CAGObject
{
Type = cte.Type,
ItemID = itemID,
Hue = hue == 0 ? null : hue
};
}
throw new InvalidCastException(
$"Categorization Type Entry: {cte.Type.Name} is not a valid type."
);
}
)
.ToArray()
} }
); );
} }

View file

@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using Server.Engines.Quests.Haven; using Server.Engines.Quests.Haven;
using Server.Engines.Quests.Necro; using Server.Engines.Quests.Necro;
using Server.Engines.Spawners; using Server.Engines.Spawners;
@ -1130,10 +1129,13 @@ namespace Server.Commands
{ {
eable = map.GetItemsInRange(new Point3D(x, y, z), 0); eable = map.GetItemsInRange(new Point3D(x, y, z), 0);
if (eable.Any(item => item.Z == z && item.ItemID == itemID)) foreach (var item in eable)
{ {
eable.Free(); if (item.Z == z && item.ItemID == itemID)
return true; {
eable.Free();
return true;
}
} }
} }

View file

@ -2,7 +2,6 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using Server.Engines.Quests.Haven; using Server.Engines.Quests.Haven;
using Server.Engines.Quests.Necro; using Server.Engines.Quests.Necro;
using Server.Engines.Spawners; using Server.Engines.Spawners;
@ -1127,10 +1126,13 @@ namespace Server.Commands
{ {
eable = map.GetItemsInRange(new Point3D(x, y, z), 0); eable = map.GetItemsInRange(new Point3D(x, y, z), 0);
if (eable.Any(item => item.Z == z && item.ItemID == itemID)) foreach (var item in eable)
{ {
eable.Free(); if (item.Z == z && item.ItemID == itemID)
return true; {
eable.Free();
return true;
}
} }
} }

View file

@ -1,7 +1,6 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Server.Engines.PartySystem; using Server.Engines.PartySystem;
using Server.Factions; using Server.Factions;
using Server.Gumps; using Server.Gumps;
@ -1295,9 +1294,26 @@ namespace Server.Engines.ConPVP
} }
} }
public static bool CheckCombat(Mobile m) => public static bool CheckCombat(Mobile m)
m.Aggressed.Any(info => info.Defender.Player && DateTime.UtcNow - info.LastCombatTime < CombatDelay) || {
m.Aggressors.Any(info => info.Attacker.Player && DateTime.UtcNow - info.LastCombatTime < CombatDelay); foreach (var info in m.Aggressed)
{
if (info.Defender.Player && DateTime.UtcNow - info.LastCombatTime < CombatDelay)
{
return true;
}
}
foreach (var info in m.Aggressors)
{
if (info.Attacker.Player && DateTime.UtcNow - info.LastCombatTime < CombatDelay)
{
return true;
}
}
return false;
}
private static void EventSink_Login(Mobile m) private static void EventSink_Login(Mobile m)
{ {

View file

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Server.Commands; using Server.Commands;
using Server.Factions; using Server.Factions;
using Server.Items; using Server.Items;
@ -404,12 +403,13 @@ namespace Server.Engines.Craft
} }
var eable = map.GetItemsInRange(from.Location, 2); var eable = map.GetItemsInRange(from.Location, 2);
var found = eable.Any(item => item.Z + 16 > item.Z && item.Z + 16 > item.Z && Find(item.ItemID, itemIDs)); foreach (var item in eable)
eable.Free();
if (found)
{ {
return true; if (item.Z + 16 > item.Z && item.Z + 16 > item.Z && Find(item.ItemID, itemIDs))
{
eable.Free();
return true;
}
} }
for (var x = -2; x <= 2; ++x) for (var x = -2; x <= 2; ++x)
@ -449,8 +449,23 @@ namespace Server.Engines.Craft
return contains; return contains;
} }
public bool IsQuantityType(Type[][] types) => public bool IsQuantityType(Type[][] types)
types.Any(check => check.Any(t => typeof(IHasQuantity).IsAssignableFrom(t))); {
for (int i = 0; i < types.Length; ++i)
{
Type[] check = types[i];
for (int j = 0; j < check.Length; ++j)
{
if (typeof(IHasQuantity).IsAssignableFrom(check[j]))
{
return true;
}
}
}
return false;
}
public int ConsumeQuantity(Container cont, Type[][] types, int[] amounts) public int ConsumeQuantity(Container cont, Type[][] types, int[] amounts)
{ {
@ -861,8 +876,7 @@ namespace Server.Engines.Craft
} }
public bool CheckSkills( public bool CheckSkills(
Mobile from, Type typeRes, CraftSystem craftSystem, ref int quality, Mobile from, Type typeRes, CraftSystem craftSystem, ref int quality, ref bool allRequiredSkills
ref bool allRequiredSkills
) => ) =>
CheckSkills(from, typeRes, craftSystem, ref quality, out allRequiredSkills, true); CheckSkills(from, typeRes, craftSystem, ref quality, out allRequiredSkills, true);

View file

@ -17,7 +17,7 @@ namespace Server.Engines.Craft
public override int GumpTitleNumber => 1044001; public override int GumpTitleNumber => 1044001;
public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefAlchemy()); public static CraftSystem CraftSystem => m_CraftSystem ??= new DefAlchemy();
public override double GetChanceAtMin(CraftItem item) => 0.0; public override double GetChanceAtMin(CraftItem item) => 0.0;

View file

@ -30,7 +30,7 @@ namespace Server.Engines.Craft
public override int GumpTitleNumber => 1044002; public override int GumpTitleNumber => 1044002;
public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefBlacksmithy()); public static CraftSystem CraftSystem => m_CraftSystem ??= new DefBlacksmithy();
public override CraftECA ECA => CraftECA.ChanceMinusSixtyToFourtyFive; public override CraftECA ECA => CraftECA.ChanceMinusSixtyToFourtyFive;

View file

@ -15,7 +15,7 @@ namespace Server.Engines.Craft
public override int GumpTitleNumber => 1044006; public override int GumpTitleNumber => 1044006;
public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefBowFletching()); public static CraftSystem CraftSystem => m_CraftSystem ??= new DefBowFletching();
public override CraftECA ECA => CraftECA.FiftyPercentChanceMinusTenPercent; public override CraftECA ECA => CraftECA.FiftyPercentChanceMinusTenPercent;

View file

@ -15,7 +15,7 @@ namespace Server.Engines.Craft
public override int GumpTitleNumber => 1044004; public override int GumpTitleNumber => 1044004;
public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefCarpentry()); public static CraftSystem CraftSystem => m_CraftSystem ??= new DefCarpentry();
public override double GetChanceAtMin(CraftItem item) => 0.5; public override double GetChanceAtMin(CraftItem item) => 0.5;

View file

@ -15,7 +15,7 @@ namespace Server.Engines.Craft
public override int GumpTitleNumber => 1044008; public override int GumpTitleNumber => 1044008;
public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefCartography()); public static CraftSystem CraftSystem => m_CraftSystem ??= new DefCartography();
public override double GetChanceAtMin(CraftItem item) => 0.0; public override double GetChanceAtMin(CraftItem item) => 0.0;

View file

@ -15,7 +15,7 @@ namespace Server.Engines.Craft
public override int GumpTitleNumber => 1044003; public override int GumpTitleNumber => 1044003;
public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefCooking()); public static CraftSystem CraftSystem => m_CraftSystem ??= new DefCooking();
public override CraftECA ECA => CraftECA.ChanceMinusSixtyToFourtyFive; public override CraftECA ECA => CraftECA.ChanceMinusSixtyToFourtyFive;

View file

@ -16,7 +16,7 @@ namespace Server.Engines.Craft
public override int GumpTitleNumber => 1044622; public override int GumpTitleNumber => 1044622;
public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefGlassblowing()); public static CraftSystem CraftSystem => m_CraftSystem ??= new DefGlassblowing();
public override double GetChanceAtMin(CraftItem item) => item.ItemType == typeof(HollowPrism) ? 0.5 : 0.0; public override double GetChanceAtMin(CraftItem item) => item.ItemType == typeof(HollowPrism) ? 0.5 : 0.0;

View file

@ -16,7 +16,7 @@ namespace Server.Engines.Craft
public override int GumpTitleNumber => 1044500; public override int GumpTitleNumber => 1044500;
public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefMasonry()); public static CraftSystem CraftSystem => m_CraftSystem ??= new DefMasonry();
public override double GetChanceAtMin(CraftItem item) => 0.0; public override double GetChanceAtMin(CraftItem item) => 0.0;

View file

@ -23,7 +23,7 @@ namespace Server.Engines.Craft
public override int GumpTitleNumber => 1044005; public override int GumpTitleNumber => 1044005;
public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefTailoring()); public static CraftSystem CraftSystem => m_CraftSystem ??= new DefTailoring();
public override CraftECA ECA => CraftECA.ChanceMinusSixtyToFourtyFive; public override CraftECA ECA => CraftECA.ChanceMinusSixtyToFourtyFive;

View file

@ -31,7 +31,7 @@ namespace Server.Engines.Craft
public override int GumpTitleNumber => 1044007; public override int GumpTitleNumber => 1044007;
public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefTinkering()); public static CraftSystem CraftSystem => m_CraftSystem ??= new DefTinkering();
public override double GetChanceAtMin(CraftItem item) public override double GetChanceAtMin(CraftItem item)
{ {

View file

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Server.Mobiles; using Server.Mobiles;
using Server.Network; using Server.Network;
using Server.Spells; using Server.Spells;
@ -192,12 +191,20 @@ namespace Server.Engines.Doom
[Usage("GenLeverPuzzle"), Description("Generates lamp room and lever puzzle in doom.")] [Usage("GenLeverPuzzle"), Description("Generates lamp room and lever puzzle in doom.")]
public static void GenLampPuzzle_OnCommand(CommandEventArgs e) public static void GenLampPuzzle_OnCommand(CommandEventArgs e)
{ {
if (Map.Malas.GetItemsInRange(lp_Center, 0).OfType<LeverPuzzleController>().Any()) var eable = Map.Malas.GetItemsInRange(lp_Center, 0);
foreach (var item in eable)
{ {
e.Mobile.SendMessage("Lamp room puzzle already exists: please delete the existing controller first ..."); if (item is LeverPuzzleController)
return; {
eable.Free();
e.Mobile.SendMessage("Lamp room puzzle already exists: please delete the existing controller first ...");
return;
}
} }
eable.Free();
e.Mobile.SendMessage("Generating Lamp Room puzzle..."); e.Mobile.SendMessage("Generating Lamp Room puzzle...");
new LeverPuzzleController().MoveToWorld(lp_Center, Map.Malas); new LeverPuzzleController().MoveToWorld(lp_Center, Map.Malas);
@ -634,7 +641,10 @@ namespace Server.Engines.Doom
{ {
IEntity m_IEntity = new Entity(Serial.Zero, RandomPointIn(m_Player.Location, 10), m_Player.Map); IEntity m_IEntity = new Entity(Serial.Zero, RandomPointIn(m_Player.Location, 10), m_Player.Map);
var mobiles = m_IEntity.Map.GetMobilesInRange(m_IEntity.Location, 2).ToList(); var eable = m_IEntity.Map.GetMobilesInRange(m_IEntity.Location, 2);
var mobiles = new List<Mobile>();
mobiles.AddRange(eable);
eable.Free();
for (var k = 0; k < mobiles.Count; k++) for (var k = 0; k < mobiles.Count; k++)
{ {

View file

@ -1,4 +1,3 @@
using System.Linq;
using Server.Ethics.Evil; using Server.Ethics.Evil;
using Server.Ethics.Hero; using Server.Ethics.Hero;
using Server.Items; using Server.Items;
@ -156,7 +155,21 @@ namespace Server.Ethics
continue; continue;
} }
if (!e.Mobile.GetItemsInRange(2).Any(item => item is AnkhNorth || item is AnkhWest)) var eable = e.Mobile.GetItemsInRange(2);
var found = false;
foreach (var item in eable)
{
if (item is AnkhNorth || item is AnkhWest)
{
found = true;
break;
}
}
eable.Free();
if (!found)
{ {
continue; continue;
} }

View file

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Server.Accounting; using Server.Accounting;
using Server.Commands.Generic; using Server.Commands.Generic;
using Server.Engines.ConPVP; using Server.Engines.ConPVP;
@ -275,18 +274,37 @@ namespace Server.Factions
} }
var eable = mob.Map.GetObjectsInRange(mob.Location, range, items, mobs); var eable = mob.Map.GetObjectsInRange(mob.Location, range, items, mobs);
var isInstance = eable.Any(type.IsInstanceOfType); foreach (var obj in eable)
{
if (type.IsInstanceOfType(obj))
{
eable.Free();
return true;
}
}
eable.Free(); eable.Free();
return isInstance; return false;
} }
public static bool IsNearType(Mobile mob, Type[] types, int range) public static bool IsNearType(Mobile mob, Type[] types, int range)
{ {
var eable = mob.GetObjectsInRange(range); var eable = mob.GetObjectsInRange(range);
var found = eable.Any(obj => types.Any(t => t.IsInstanceOfType(obj))); foreach (var obj in eable)
{
for (int i = 0; i < types.Length; i++)
{
if (types[i].IsInstanceOfType(obj))
{
eable.Free();
return true;
}
}
}
eable.Free(); eable.Free();
return found; return false;
} }
public void RemovePlayerState(PlayerState pl) public void RemovePlayerState(PlayerState pl)

View file

@ -1,5 +1,4 @@
using System; using System;
using System.Linq;
namespace Server.Factions namespace Server.Factions
{ {
@ -77,7 +76,20 @@ namespace Server.Factions
} }
} }
private static bool CheckExistence(Point3D loc, Map facet, Type type) => private static bool CheckExistence(Point3D loc, Map facet, Type type)
facet.GetItemsInRange(loc, 0).Any(type.IsInstanceOfType); {
var eable = facet.GetItemsInRange(loc, 0);
foreach (var item in eable)
{
if (type.IsInstanceOfType(item))
{
eable.Free();
return true;
}
}
eable.Free();
return false;
}
} }
} }

View file

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Server.Utilities; using Server.Utilities;
namespace Server.Factions namespace Server.Factions
@ -60,7 +59,7 @@ namespace Server.Factions
{ {
var asm = asms[i]; var asm = asms[i];
var tc = AssemblyHandler.GetTypeCache(asm); var tc = AssemblyHandler.GetTypeCache(asm);
var types = tc.Types.ToArray(); var types = tc.Types;
for (var j = 0; j < types.Length; ++j) for (var j = 0; j < types.Length; ++j)
{ {

View file

@ -1,5 +1,5 @@
using System; using System;
using System.Linq; using System.Collections.Generic;
using Server.Factions; using Server.Factions;
using Server.Spells; using Server.Spells;
using Server.Targeting; using Server.Targeting;
@ -90,13 +90,19 @@ namespace Server
private static void OnHit(Mobile from, Point3D origin, Map facet) private static void OnHit(Mobile from, Point3D origin, Map facet)
{ {
var targets = facet.GetMobilesInRange(origin, 12) var eable = facet.GetMobilesInRange(origin, 12);
.Where( var targets = new List<Mobile>();
mob => foreach (var m in eable)
from.CanBeHarmful(mob, false) && mob.InLOS(new Point3D(origin, origin.Z + 1)) && {
Faction.Find(mob) != null if (from.CanBeHarmful(m, false) &&
) m.InLOS(new Point3D(origin, origin.Z + 1)) &&
.ToList(); Faction.Find(m) != null)
{
targets.Add(from);
}
}
eable.Free();
foreach (var mob in targets) foreach (var mob in targets)
{ {

View file

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Server.Random; using Server.Random;
namespace Server.Engines.Harvest namespace Server.Engines.Harvest
@ -66,7 +65,13 @@ namespace Server.Engines.Harvest
set set
{ {
m_Veins = value; m_Veins = value;
VeinWeights = m_Veins.Aggregate<HarvestVein, uint>(0, (current, t) => current + t.VeinChance); var totalWeight = 0u;
for (var i = 0; i < m_Veins.Length; i++)
{
totalWeight += m_Veins[i].VeinChance;
}
VeinWeights = totalWeight;
} }
} }

View file

@ -1,6 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using Server.Items; using Server.Items;
using Server.Targeting; using Server.Targeting;
using Server.Utilities; using Server.Utilities;
@ -9,9 +7,7 @@ namespace Server.Engines.Harvest
{ {
public abstract class HarvestSystem public abstract class HarvestSystem
{ {
public HarvestSystem() => Definitions = new List<HarvestDefinition>(); public HarvestDefinition[] Definitions { get; init; }
public List<HarvestDefinition> Definitions { get; }
public virtual bool CheckTool(Mobile from, Item tool) public virtual bool CheckTool(Mobile from, Item tool)
{ {
@ -311,11 +307,18 @@ namespace Server.Engines.Harvest
return false; return false;
} }
if (m.GetItemsInRange(0).Any(t => t.StackWith(m, item, false))) var eable = m.GetItemsInRange(0);
foreach (var i in eable)
{ {
return true; if (i.StackWith(m, i, false))
{
eable.Free();
return true;
}
} }
eable.Free();
item.MoveToWorld(m.Location, map); item.MoveToWorld(m.Location, map);
return true; return true;
} }
@ -418,10 +421,22 @@ namespace Server.Engines.Harvest
} }
} }
public virtual HarvestDefinition GetDefinition() => Definitions.First(); public virtual HarvestDefinition GetDefinition() => Definitions[0];
public virtual HarvestDefinition GetDefinition(int tileID) => public virtual HarvestDefinition GetDefinition(int tileID)
Definitions.FirstOrDefault(check => check.Validate(tileID)); {
for (var i = 0; i < Definitions.Length; i++)
{
var check = Definitions[i];
if (check.Validate(tileID))
{
return check;
}
}
return null;
}
public virtual void StartHarvesting(Mobile from, Item tool, object toHarvest) public virtual void StartHarvesting(Mobile from, Item tool, object toHarvest)
{ {

View file

@ -93,7 +93,7 @@ namespace Server.Engines.Harvest
}; };
} }
Definitions.Add(fish); Definitions = new[] { fish };
} }
public static Fishing System => m_System ?? (m_System = new Fishing()); public static Fishing System => m_System ?? (m_System = new Fishing());

View file

@ -117,10 +117,10 @@ namespace Server.Engines.Harvest
lumber.RaceBonus = Core.ML; lumber.RaceBonus = Core.ML;
lumber.RandomizeVeins = Core.ML; lumber.RandomizeVeins = Core.ML;
Definitions.Add(lumber); Definitions = new[] { lumber };
} }
public static Lumberjacking System => m_System ?? (m_System = new Lumberjacking()); public static Lumberjacking System => m_System ??= new Lumberjacking();
public override bool CheckHarvest(Mobile from, Item tool) public override bool CheckHarvest(Mobile from, Item tool)
{ {

View file

@ -225,8 +225,6 @@ namespace Server.Engines.Harvest
OreAndStone.RaceBonus = Core.ML; OreAndStone.RaceBonus = Core.ML;
OreAndStone.RandomizeVeins = Core.ML; OreAndStone.RandomizeVeins = Core.ML;
Definitions.Add(OreAndStone);
Sand = new HarvestDefinition Sand = new HarvestDefinition
{ {
BankWidth = 8, BankWidth = 8,
@ -267,7 +265,7 @@ namespace Server.Engines.Harvest
Sand.Resources = res; Sand.Resources = res;
Sand.Veins = veins; Sand.Veins = veins;
Definitions.Add(Sand); Definitions = new[] { OreAndStone, Sand };
} }
public static Mining System => m_System ?? (m_System = new Mining()); public static Mining System => m_System ?? (m_System = new Mining());

View file

@ -1,5 +1,4 @@
using System; using System;
using System.Linq;
using Server.Engines.ConPVP; using Server.Engines.ConPVP;
using Server.Factions; using Server.Factions;
using Server.Gumps; using Server.Gumps;
@ -294,9 +293,12 @@ namespace Server.Engines.Help
private static void EventSink_HelpRequest(Mobile m) private static void EventSink_HelpRequest(Mobile m)
{ {
if (m.NetState.Gumps.OfType<HelpGump>().Any()) foreach (var gump in m.NetState.Gumps)
{ {
return; if (gump is HelpGump)
{
return;
}
} }
if (!PageQueue.CheckAllowedToPage(m)) if (!PageQueue.CheckAllowedToPage(m))

View file

@ -1,5 +1,4 @@
using System; using System;
using System.Collections.Generic;
using Server.Items; using Server.Items;
using Server.Network; using Server.Network;
@ -278,303 +277,441 @@ namespace Server.Gumps
return; return;
} }
var types = new List<Type>(); Type[] types;
var cliloc = 0; int cliloc;
switch (info.ButtonID) switch (info.ButtonID)
{ {
default:
{
types = null;
cliloc = 0;
break;
}
// 7th anniversary // 7th anniversary
case 0x64: case 0x64:
types.Add(typeof(LeggingsOfEmbers)); {
cliloc = 1078147; types = new [] { typeof(LeggingsOfEmbers) };
break; cliloc = 1078147;
break;
}
case 0x65: case 0x65:
types.Add(typeof(RoseOfTrinsic)); {
cliloc = 1062913; types = new [] { typeof(RoseOfTrinsic) };
break; cliloc = 1062913;
break;
}
case 0x66: case 0x66:
types.Add(typeof(ShaminoCrossbow)); {
cliloc = 1062915; types = new [] { typeof(ShaminoCrossbow) };
break; cliloc = 1062915;
break;
}
case 0x67: case 0x67:
types.Add(typeof(TapestryOfSosaria)); {
cliloc = 1062917; types = new [] { typeof(TapestryOfSosaria) };
break; cliloc = 1062917;
break;
}
case 0x68: case 0x68:
types.Add(typeof(HearthOfHomeFireDeed)); {
cliloc = 1062919; types = new [] { typeof(HearthOfHomeFireDeed) };
break; cliloc = 1062919;
break;
}
case 0x69: case 0x69:
types.Add(typeof(HolySword)); {
cliloc = 1062921; types = new [] { typeof(HolySword) };
break; cliloc = 1062921;
break;
}
case 0x6A: case 0x6A:
types.Add(typeof(SamuraiHelm)); {
cliloc = 1062923; types = new [] { typeof(SamuraiHelm) };
break; cliloc = 1062923;
break;
}
// 8th anniversary // 8th anniversary
/*case 0x6B: types.Add( typeof( SpiritualityHelm ) ); cliloc = 1075188; break; /*case 0x6B: types = new [] { typeof( SpiritualityHelm ) }; cliloc = 1075188; break;
case 0x6C: types.Add( typeof( ValorGauntlets ) ); cliloc = 1075192; break;*/ case 0x6C: types = new [] { typeof( ValorGauntlets ) }; cliloc = 1075192; break;*/
case 0x6D: case 0x6D:
types.Add(typeof(DupresShield)); {
cliloc = 1075196; types = new [] { typeof(DupresShield) };
break; cliloc = 1075196;
break;
}
case 0x6E: case 0x6E:
types.Add(typeof(FountainOfLifeDeed)); {
cliloc = 1075197; types = new [] { typeof(FountainOfLifeDeed) };
break; cliloc = 1075197;
break;
}
case 0x6F: case 0x6F:
types.Add(typeof(DawnsMusicBox)); {
cliloc = 1075198; types = new [] { typeof(DawnsMusicBox) };
break; cliloc = 1075198;
break;
}
case 0x70: case 0x70:
types.Add(typeof(OssianGrimoire)); {
cliloc = 1078148; types = new [] { typeof(OssianGrimoire) };
break; cliloc = 1078148;
break;
}
case 0x71: case 0x71:
types.Add(typeof(FerretFormTalisman)); {
cliloc = 1078142; types = new [] { typeof(FerretFormTalisman) };
break; cliloc = 1078142;
break;
}
case 0x72: case 0x72:
types.Add(typeof(SquirrelFormTalisman)); {
cliloc = 1078143; types = new [] { typeof(SquirrelFormTalisman) };
break; cliloc = 1078143;
break;
}
case 0x73: case 0x73:
types.Add(typeof(CuSidheFormTalisman)); {
cliloc = 1078144; types = new [] { typeof(CuSidheFormTalisman) };
break; cliloc = 1078144;
break;
}
case 0x74: case 0x74:
types.Add(typeof(ReptalonFormTalisman)); {
cliloc = 1078145; types = new [] { typeof(ReptalonFormTalisman) };
break; cliloc = 1078145;
break;
}
case 0x75: case 0x75:
types.Add(typeof(QuiverOfInfinity)); {
cliloc = 1075201; types = new [] { typeof(QuiverOfInfinity) };
break; cliloc = 1075201;
break;
}
// evil home decor // evil home decor
case 0x76: case 0x76:
types.Add(typeof(BoneThroneDeed)); {
types.Add(typeof(BoneCouchDeed)); types = new [] { typeof(BoneThroneDeed), typeof(BoneCouchDeed), typeof(BoneTableDeed) };
types.Add(typeof(BoneTableDeed)); cliloc = 1074797;
cliloc = 1074797; break;
break; }
case 0x77: case 0x77:
types.Add(typeof(CreepyPortraitDeed)); {
types.Add(typeof(DisturbingPortraitDeed)); types = new []
types.Add(typeof(UnsettlingPortraitDeed)); {
cliloc = 1078146; typeof(CreepyPortraitDeed),
break; typeof(DisturbingPortraitDeed),
typeof(UnsettlingPortraitDeed)
};
cliloc = 1078146;
break;
}
case 0x78: case 0x78:
types.Add(typeof(MountedPixieBlueDeed)); {
types.Add(typeof(MountedPixieGreenDeed)); types = new []
types.Add(typeof(MountedPixieLimeDeed)); {
types.Add(typeof(MountedPixieOrangeDeed)); typeof(MountedPixieBlueDeed),
types.Add(typeof(MountedPixieWhiteDeed)); typeof(MountedPixieGreenDeed),
cliloc = 1074799; typeof(MountedPixieLimeDeed),
break; typeof(MountedPixieOrangeDeed),
typeof(MountedPixieWhiteDeed)
};
cliloc = 1074799;
break;
}
case 0x79: case 0x79:
types.Add(typeof(HaunterMirrorDeed)); {
cliloc = 1074800; types = new [] { typeof(HaunterMirrorDeed) };
break; cliloc = 1074800;
break;
}
case 0x7A: case 0x7A:
types.Add(typeof(BedOfNailsDeed)); {
cliloc = 1074801; types = new [] { typeof(BedOfNailsDeed) };
break; cliloc = 1074801;
break;
}
case 0x7B: case 0x7B:
types.Add(typeof(SacrificialAltarDeed)); {
cliloc = 1074818; types = new [] { typeof(SacrificialAltarDeed) };
break; cliloc = 1074818;
break;
}
// broken furniture // broken furniture
case 0x7C: case 0x7C:
types.Add(typeof(BrokenCoveredChairDeed)); {
cliloc = 1076257; types = new [] { typeof(BrokenCoveredChairDeed) };
break; cliloc = 1076257;
break;
}
case 0x7D: case 0x7D:
types.Add(typeof(BrokenBookcaseDeed)); {
cliloc = 1076258; types = new [] { typeof(BrokenBookcaseDeed) };
break; cliloc = 1076258;
break;
}
case 0x7E: case 0x7E:
types.Add(typeof(StandingBrokenChairDeed)); {
cliloc = 1076259; types = new [] { typeof(StandingBrokenChairDeed) };
break; cliloc = 1076259;
break;
}
case 0x7F: case 0x7F:
types.Add(typeof(BrokenVanityDeed)); {
cliloc = 1076260; types = new [] { typeof(BrokenVanityDeed) };
break; cliloc = 1076260;
break;
}
case 0x80: case 0x80:
types.Add(typeof(BrokenChestOfDrawersDeed)); {
cliloc = 1076261; types = new [] { typeof(BrokenChestOfDrawersDeed) };
break; cliloc = 1076261;
break;
}
case 0x81: case 0x81:
types.Add(typeof(BrokenArmoireDeed)); {
cliloc = 1076262; types = new [] { typeof(BrokenArmoireDeed) };
break; cliloc = 1076262;
break;
}
case 0x82: case 0x82:
types.Add(typeof(BrokenBedDeed)); {
cliloc = 1076263; types = new [] { typeof(BrokenBedDeed) };
break; cliloc = 1076263;
break;
}
case 0x83: case 0x83:
types.Add(typeof(BrokenFallenChairDeed)); {
cliloc = 1076264; types = new [] { typeof(BrokenFallenChairDeed) };
break; cliloc = 1076264;
break;
}
// other // other
case 0x84: case 0x84:
types.Add(typeof(SuitOfGoldArmorDeed)); {
cliloc = 1076265; types = new [] { typeof(SuitOfGoldArmorDeed) };
break; cliloc = 1076265;
break;
}
case 0x85: case 0x85:
types.Add(typeof(SuitOfSilverArmorDeed)); {
cliloc = 1076266; types = new [] { typeof(SuitOfSilverArmorDeed) };
break; cliloc = 1076266;
break;
}
case 0x86: case 0x86:
types.Add(typeof(BoilingCauldronDeed)); {
cliloc = 1076267; types = new [] { typeof(BoilingCauldronDeed) };
break; cliloc = 1076267;
break;
}
case 0x87: case 0x87:
types.Add(typeof(GuillotineDeed)); {
cliloc = 1024656; types = new [] { typeof(GuillotineDeed) };
break; cliloc = 1024656;
break;
}
case 0x88: case 0x88:
types.Add(typeof(CherryBlossomTreeDeed)); {
cliloc = 1076268; types = new [] { typeof(CherryBlossomTreeDeed) };
break; cliloc = 1076268;
break;
}
case 0x89: case 0x89:
types.Add(typeof(AppleTreeDeed)); {
cliloc = 1076269; types = new [] { typeof(AppleTreeDeed) };
break; cliloc = 1076269;
break;
}
case 0x8A: case 0x8A:
types.Add(typeof(PeachTreeDeed)); {
cliloc = 1076270; types = new [] { typeof(PeachTreeDeed) };
break; cliloc = 1076270;
break;
}
case 0x8B: case 0x8B:
types.Add(typeof(HangingAxesDeed)); {
cliloc = 1076271; types = new [] { typeof(HangingAxesDeed) };
break; cliloc = 1076271;
break;
}
case 0x8C: case 0x8C:
types.Add(typeof(HangingSwordsDeed)); {
cliloc = 1076272; types = new [] { typeof(HangingSwordsDeed) };
break; cliloc = 1076272;
break;
}
case 0x8D: case 0x8D:
types.Add(typeof(BlueFancyRugDeed)); {
cliloc = 1076273; types = new [] { typeof(BlueFancyRugDeed) };
break; cliloc = 1076273;
break;
}
case 0x8E: case 0x8E:
types.Add(typeof(WoodenCoffinDeed)); {
cliloc = 1076274; types = new [] { typeof(WoodenCoffinDeed) };
break; cliloc = 1076274;
break;
}
case 0x8F: case 0x8F:
types.Add(typeof(VanityDeed)); {
cliloc = 1074027; types = new [] { typeof(VanityDeed) };
break; cliloc = 1074027;
break;
}
case 0x90: case 0x90:
types.Add(typeof(TableWithPurpleClothDeed)); {
cliloc = 1076635; types = new [] { typeof(TableWithPurpleClothDeed) };
break; cliloc = 1076635;
break;
}
case 0x91: case 0x91:
types.Add(typeof(TableWithBlueClothDeed)); {
cliloc = 1076636; types = new [] { typeof(TableWithBlueClothDeed) };
break; cliloc = 1076636;
break;
}
case 0x92: case 0x92:
types.Add(typeof(TableWithRedClothDeed)); {
cliloc = 1076637; types = new [] { typeof(TableWithRedClothDeed) };
break; cliloc = 1076637;
break;
}
case 0x93: case 0x93:
types.Add(typeof(TableWithOrangeClothDeed)); {
cliloc = 1076638; types = new [] { typeof(TableWithOrangeClothDeed) };
break; cliloc = 1076638;
break;
}
case 0x94: case 0x94:
types.Add(typeof(UnmadeBedDeed)); {
cliloc = 1076279; types = new [] { typeof(UnmadeBedDeed) };
break; cliloc = 1076279;
break;
}
case 0x95: case 0x95:
types.Add(typeof(CurtainsDeed)); {
cliloc = 1076280; types = new [] { typeof(CurtainsDeed) };
break; cliloc = 1076280;
break;
}
case 0x96: case 0x96:
types.Add(typeof(ScarecrowDeed)); {
cliloc = 1076281; types = new [] { typeof(ScarecrowDeed) };
break; cliloc = 1076281;
break;
}
case 0x97: case 0x97:
types.Add(typeof(WallTorchDeed)); {
cliloc = 1076282; types = new [] { typeof(WallTorchDeed) };
break; cliloc = 1076282;
break;
}
case 0x98: case 0x98:
types.Add(typeof(FountainDeed)); {
cliloc = 1076283; types = new [] { typeof(FountainDeed) };
break; cliloc = 1076283;
break;
}
case 0x99: case 0x99:
types.Add(typeof(StoneStatueDeed)); {
cliloc = 1076284; types = new [] { typeof(StoneStatueDeed) };
break; cliloc = 1076284;
break;
}
case 0x9A: case 0x9A:
types.Add(typeof(LargeFishingNetDeed)); {
cliloc = 1076285; types = new [] { typeof(LargeFishingNetDeed) };
break; cliloc = 1076285;
break;
}
case 0x9B: case 0x9B:
types.Add(typeof(SmallFishingNetDeed)); {
cliloc = 1076286; types = new [] { typeof(SmallFishingNetDeed) };
break; cliloc = 1076286;
break;
}
case 0x9C: case 0x9C:
types.Add(typeof(HouseLadderDeed)); {
cliloc = 1076287; types = new [] { typeof(HouseLadderDeed) };
break; cliloc = 1076287;
break;
}
case 0x9D: case 0x9D:
types.Add(typeof(IronMaidenDeed)); {
cliloc = 1076288; types = new [] { typeof(IronMaidenDeed) };
break; cliloc = 1076288;
break;
}
case 0x9E: case 0x9E:
types.Add(typeof(BluePlainRugDeed)); {
cliloc = 1076585; types = new [] { typeof(BluePlainRugDeed) };
break; cliloc = 1076585;
break;
}
case 0x9F: case 0x9F:
types.Add(typeof(GoldenDecorativeRugDeed)); {
cliloc = 1076586; types = new [] { typeof(GoldenDecorativeRugDeed) };
break; cliloc = 1076586;
break;
}
case 0xA0: case 0xA0:
types.Add(typeof(CinnamonFancyRugDeed)); {
cliloc = 1076587; types = new [] { typeof(CinnamonFancyRugDeed) };
break; cliloc = 1076587;
break;
}
case 0xA1: case 0xA1:
types.Add(typeof(RedPlainRugDeed)); {
cliloc = 1076588; types = new [] { typeof(RedPlainRugDeed) };
break; cliloc = 1076588;
break;
}
case 0xA2: case 0xA2:
types.Add(typeof(BlueDecorativeRugDeed)); {
cliloc = 1076589; types = new [] { typeof(BlueDecorativeRugDeed) };
break; cliloc = 1076589;
break;
}
case 0xA3: case 0xA3:
types.Add(typeof(PinkFancyRugDeed)); {
cliloc = 1076590; types = new [] { typeof(PinkFancyRugDeed) };
break; cliloc = 1076590;
break;
}
case 0xA4: case 0xA4:
types.Add(typeof(CherryBlossomTrunkDeed)); {
cliloc = 1076784; types = new [] { typeof(CherryBlossomTrunkDeed) };
break; cliloc = 1076784;
break;
}
case 0xA5: case 0xA5:
types.Add(typeof(AppleTrunkDeed)); {
cliloc = 1076785; types = new [] { typeof(AppleTrunkDeed) };
break; cliloc = 1076785;
break;
}
case 0xA6: case 0xA6:
types.Add(typeof(PeachTrunkDeed)); {
cliloc = 1076786; types = new [] { typeof(PeachTrunkDeed) };
break; cliloc = 1076786;
break;
}
} }
if (types.Count > 0 && cliloc > 0) if (types?.Length > 0 && cliloc > 0)
{ {
sender.Mobile.CloseGump<ConfirmHeritageGump>(); sender.Mobile.CloseGump<ConfirmHeritageGump>();
sender.Mobile.SendGump(new ConfirmHeritageGump(m_Token, types.ToArray(), cliloc)); sender.Mobile.SendGump(new ConfirmHeritageGump(m_Token, types, cliloc));
} }
else else
{ {
sender.Mobile // This option is currently disabled, while we evaluate it for game balance.
.SendLocalizedMessage( sender.Mobile.SendLocalizedMessage(501311);
501311
); // This option is currently disabled, while we evaluate it for game balance.
} }
} }
} }

View file

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Server.Accounting; using Server.Accounting;
using Server.ContextMenus; using Server.ContextMenus;
using Server.Engines.BulkOrders; using Server.Engines.BulkOrders;
@ -1049,13 +1048,22 @@ namespace Server.Mobiles
public static void EquipMacro(Mobile m, List<Serial> list) public static void EquipMacro(Mobile m, List<Serial> list)
{ {
if (m is PlayerMobile pm && pm.Backpack != null && pm.Alive) if (m is PlayerMobile { Alive: true } pm && pm.Backpack != null)
{ {
var pack = pm.Backpack; var pack = pm.Backpack;
foreach (var serial in list) foreach (var serial in list)
{ {
var item = pack.Items.FirstOrDefault(i => i.Serial == serial); Item item = null;
foreach (var i in pack.Items)
{
if (i.Serial == serial)
{
item = i;
break;
}
}
if (item == null) if (item == null)
{ {
continue; continue;
@ -3275,12 +3283,20 @@ namespace Server.Mobiles
public override void Serialize(IGenericWriter writer) public override void Serialize(IGenericWriter writer)
{ {
var toRemove = new List<object>();
// cleanup our anti-macro table // cleanup our anti-macro table
foreach (var t in m_AntiMacroTable.Values) foreach (var t in m_AntiMacroTable.Values)
{ {
var toRemove = t.Where(kvp => kvp.Value.TimeStamp + SkillCheck.AntiMacroExpire <= DateTime.UtcNow) toRemove.Clear();
.Select(kvp => kvp.Key)
.ToList(); foreach (var (k, v) in t)
{
if (v.TimeStamp + SkillCheck.AntiMacroExpire <= DateTime.UtcNow)
{
toRemove.Add(k);
}
}
foreach (var key in toRemove) foreach (var key in toRemove)
{ {

View file

@ -1,5 +1,4 @@
using System; using System;
using System.Linq;
using Server.Engines.CannedEvil; using Server.Engines.CannedEvil;
using Server.Items; using Server.Items;
using Server.Spells.Fifth; using Server.Spells.Fifth;
@ -142,14 +141,23 @@ namespace Server.Mobiles
} }
var eable = GetMobilesInRange<BaseCreature>(10); var eable = GetMobilesInRange<BaseCreature>(10);
var rats = eable.Aggregate(0, (c, m) => c + (m is Ratman || m is RatmanArcher || m is RatmanMage ? 1 : 0)); var rats = 0;
eable.Free();
if (rats >= 16) foreach (var m in eable)
{ {
return; if (m is Ratman || m is RatmanArcher || m is RatmanMage)
{
rats++;
if (rats >= 16)
{
eable.Free();
return;
}
}
} }
eable.Free();
PlaySound(0x3D); PlaySound(0x3D);
rats = Utility.RandomMinMax(3, 6); rats = Utility.RandomMinMax(3, 6);

View file

@ -1,5 +1,4 @@
using System; using System;
using System.Linq;
using Server.Items; using Server.Items;
namespace Server.Spells.Chivalry namespace Server.Spells.Chivalry
@ -55,14 +54,14 @@ namespace Server.Spells.Chivalry
0 0
); );
var targets = Caster.GetMobilesInRange(3) foreach (var m in Caster.GetMobilesInRange(3))
.Where(
m => Caster != m && SpellHelper.ValidIndirectTarget(Caster, m) && Caster.CanBeHarmful(m, false) &&
(!Core.AOS || Caster.InLOS(m))
);
foreach (var m in targets)
{ {
if (Caster == m || !SpellHelper.ValidIndirectTarget(Caster, m) || !Caster.CanBeHarmful(m, false) ||
Core.AOS && !Caster.InLOS(m))
{
continue;
}
var damage = Math.Clamp(ComputePowerValue(10) + Utility.RandomMinMax(0, 2), 8, 24); var damage = Math.Clamp(ComputePowerValue(10) + Utility.RandomMinMax(0, 2), 8, 24);
Caster.DoHarmful(m); Caster.DoHarmful(m);

View file

@ -1,5 +1,4 @@
using System; using System;
using System.Linq;
using Server.Engines.CannedEvil; using Server.Engines.CannedEvil;
using Server.Engines.PartySystem; using Server.Engines.PartySystem;
using Server.Factions; using Server.Factions;
@ -95,12 +94,13 @@ namespace Server.Spells.Necromancy
if (map != null) if (map != null)
{ {
var targets = r.ChampionSpawn.GetMobilesInRange(Range).Where(IsValidTarget); // Surprisingly, no sparkle type effects
foreach (var m in r.ChampionSpawn.GetMobilesInRange(Range))
foreach (var m in targets)
// Surprisingly, no sparkle type effects
{ {
m.Location = GetNearestShrine(m); if (IsValidTarget(m))
{
m.Location = GetNearestShrine(m);
}
} }
} }
} }

View file

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Server.Items; using Server.Items;
using Server.Mobiles; using Server.Mobiles;
using Server.Targeting; using Server.Targeting;
@ -84,13 +83,20 @@ namespace Server.Spells.Necromancy
targets.Add(m); targets.Add(m);
} }
targets.AddRange( var eable = m.GetMobilesInRange(2);
m.GetMobilesInRange(2)
.Where( foreach (Mobile targ in eable)
targ => !(Caster is BaseCreature && targ is BaseCreature && targ != Caster && m != targ && {
SpellHelper.ValidIndirectTarget(Caster, targ) && Caster.CanBeHarmful(targ, false)) if (!(Caster is BaseCreature && targ is BaseCreature) &&
) targ != Caster && m != targ &&
); SpellHelper.ValidIndirectTarget(Caster, targ) &&
Caster.CanBeHarmful(targ, false))
{
targets.Add(targ);
}
}
eable.Free();
for (var i = 0; i < targets.Count; ++i) for (var i = 0; i < targets.Count; ++i)
{ {

View file

@ -1,5 +1,4 @@
using System; using System;
using System.Linq;
using Server.Factions; using Server.Factions;
using Server.Items; using Server.Items;
using Server.Misc; using Server.Misc;
@ -127,10 +126,16 @@ namespace Server.Spells.Seventh
private bool GateExistsAt(Map map, Point3D loc) private bool GateExistsAt(Map map, Point3D loc)
{ {
var eable = map.GetItemsInRange(loc, 0); var eable = map.GetItemsInRange(loc, 0);
var gateFound = eable.Any(item => item is Moongate || item is PublicMoongate);
eable.Free();
return gateFound; foreach (var item in eable)
{
if (item is Moongate || item is PublicMoongate)
{
return true;
}
}
return false;
} }
[DispellableField] [DispellableField]

View file

@ -79,9 +79,7 @@ namespace Server.Spells.Seventh
targets = new List<Mobile>(); targets = new List<Mobile>();
} }
double damage; double damage = Core.AOS
damage = Core.AOS
? GetNewAosDamage(51, 1, 5, playerVsPlayer) ? GetNewAosDamage(51, 1, 5, playerVsPlayer)
: Utility.Random(27, 22); : Utility.Random(27, 22);

View file

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Server.Items; using Server.Items;
using Server.Mobiles; using Server.Mobiles;
@ -105,14 +104,17 @@ namespace Server.Spells.Spellweaving
var eable = map.GetItemsInRange(location, 0); var eable = map.GetItemsInRange(location, 0);
var found = eable.Any( foreach (var item in eable)
item => {
item.Z + item.ItemData.CalcHeight == location.Z && IsValidTile(item.ItemID) if (item.Z + item.ItemData.CalcHeight == location.Z && IsValidTile(item.ItemID))
); {
return true;
}
}
eable.Free(); eable.Free();
return found; return false;
} }
public static bool IsValidTile(int itemID) => public static bool IsValidTile(int itemID) =>
@ -126,13 +128,19 @@ namespace Server.Spells.Spellweaving
// OSI Verified: Even enemies/combatants count // OSI Verified: Even enemies/combatants count
// Everyone gets the Arcane Focus, power capped elsewhere // Everyone gets the Arcane Focus, power capped elsewhere
weavers.AddRange(
Caster.GetMobilesInRange(1) var eable = Caster.GetMobilesInRange(1);
.Where(
m => m != Caster && m is PlayerMobile && Caster.CanBeBeneficial(m, false) && foreach (var m in eable)
Math.Abs(Caster.Skills.Spellweaving.Value - m.Skills.Spellweaving.Value) <= 20 {
) if (m != Caster && m is PlayerMobile && Caster.CanBeBeneficial(m, false) &&
); Math.Abs(Caster.Skills.Spellweaving.Value - m.Skills.Spellweaving.Value) <= 20)
{
weavers.Add(m);
}
}
eable.Free();
return weavers; return weavers;
} }

View file

@ -72,7 +72,7 @@ namespace Server.Targets
} }
HarvestSystem system = Lumberjacking.System; HarvestSystem system = Lumberjacking.System;
var def = Lumberjacking.System.GetDefinition(); var def = system.GetDefinition();
if (!system.GetHarvestDetails(from, m_Item, targeted, out var tileID, out var map, out var loc)) if (!system.GetHarvestDetails(from, m_Item, targeted, out var tileID, out var map, out var loc))
{ {