diff --git a/Projects/Server.Tests/Utility/ActivatorExtensionsTests.cs b/Projects/Server.Tests/Utility/ActivatorExtensionsTests.cs new file mode 100644 index 000000000..e4e5dddbd --- /dev/null +++ b/Projects/Server.Tests/Utility/ActivatorExtensionsTests.cs @@ -0,0 +1,95 @@ +using Server.Utilities; +using Xunit; + +namespace Server.Tests +{ + public class ActivatorExtensionsTests + { + [Fact] + public void TestZeroParamsActivator() + { + var result = typeof(TestZeroParamsClass).CreateInstance(); + Assert.IsType(result); + } + + [Fact] + public void TestZeroParamsNullActivator() + { + var result = typeof(TestZeroParamsClass).CreateInstance(null, null); + Assert.IsType(result); + } + + [Fact] + public void TestTwoParamsActivator() + { + var result = typeof(TestTwoParamsClass).CreateInstance(10, "ModernUO"); + Assert.IsType(result); + Assert.Equal(10, result.Amount); + Assert.Equal("ModernUO", result.Name); + } + + [Fact] + public void TestAllParamsOptionalActivator() + { + var result = typeof(TestTwoOptionalParamsClass).CreateInstance(); + Assert.IsType(result); + Assert.Equal(1, result.Amount); + Assert.Equal("Test ModernUO", result.Name); + } + + [Fact] + public void TestAllParamsNullOptionalActivator() + { + var result = typeof(TestTwoOptionalParamsClass).CreateInstance(null); + Assert.IsType(result); + Assert.Equal(1, result.Amount); + Assert.Equal("Test ModernUO", result.Name); + } + + [Fact] + public void TestLessParamsOptionalActivator() + { + var result = typeof(TestTwoOptionalParamsClass).CreateInstance(10); + Assert.IsType(result); + Assert.Equal(10, result.Amount); + Assert.Equal("Test ModernUO", result.Name); + } + + [Fact] + public void TestTwoParamsOptionalActivator() + { + var result = typeof(TestTwoOptionalParamsClass).CreateInstance(10, "Prod ModernUO"); + Assert.IsType(result); + Assert.Equal(10, result.Amount); + Assert.Equal("Prod ModernUO", result.Name); + } + + private class TestZeroParamsClass + { + } + + private class TestTwoParamsClass + { + public int Amount; + public string Name; + + public TestTwoParamsClass(int amount, string name) + { + Amount = amount; + Name = name; + } + } + + private class TestTwoOptionalParamsClass + { + public int Amount; + public string Name; + + public TestTwoOptionalParamsClass(int amount = 1, string name = "Test ModernUO") + { + Amount = amount; + Name = name; + } + } + } +} diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index a4cbef921..504e5fe9c 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -5738,7 +5738,7 @@ namespace Server Item item; try { - item = (Item)ActivatorUtil.CreateInstance(oldItem.GetType()); + item = oldItem.GetType().CreateInstance(); } catch { diff --git a/Projects/Server/Regions/RegionLoader.cs b/Projects/Server/Regions/RegionLoader.cs index e6266f5c5..74345b746 100644 --- a/Projects/Server/Regions/RegionLoader.cs +++ b/Projects/Server/Regions/RegionLoader.cs @@ -46,7 +46,7 @@ namespace Server continue; } - var region = ActivatorUtil.CreateInstance(type, json, JsonConfig.DefaultOptions) as Region; + var region = type.CreateInstance(json, JsonConfig.DefaultOptions); region?.Register(); count++; } diff --git a/Projects/Server/Utilities/ActivatorExtensions.cs b/Projects/Server/Utilities/ActivatorExtensions.cs new file mode 100644 index 000000000..287f7cdb5 --- /dev/null +++ b/Projects/Server/Utilities/ActivatorExtensions.cs @@ -0,0 +1,153 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2020 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: ActivatorExtensions.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using System; +using System.Reflection; + +namespace Server.Utilities +{ + public static class ActivatorExtensions + { + public static ConstructorInfo GetConstructor( + this Type type, + Predicate predicate = null, + Type[] args = null + ) => type.GetConstructor(predicate, args, out _); + + public static ConstructorInfo GetConstructor( + this Type type, + Predicate predicate, + Type[] args, + out int paramCount + ) + { + args ??= Array.Empty(); + var ctors = type.GetConstructors(); + + try + { + for (int i = 0; i < ctors.Length; i++) + { + ConstructorInfo info = ctors[i]; + + if (predicate?.Invoke(info) == false) + { + continue; + } + + var parameters = info.GetParameters(); + paramCount = parameters.Length; + + if (args.Length > parameters.Length) + { + continue; + } + + bool validated = true; + + // Check that all args match params + for (var j = 0; j < parameters.Length; j++) + { + ParameterInfo param = parameters[j]; + + // All extra parameters must be optional + if (j >= args.Length) + { + if (!param.IsOptional) + { + validated = false; + break; + } + + continue; + } + + var arg = args[j]; + if (arg == null && param.ParameterType.IsValueType) + { + validated = false; + break; + } + + if (arg != null && !param.ParameterType.IsAssignableFrom(arg)) + { + validated = false; + break; + } + } + + if (validated) + { + return info; + } + } + } + catch (Exception e) + { + Console.WriteLine(e); + } + + paramCount = 0; + return null; + } + + public static T CreateInstance( + this Type type, + params object[] args + ) where T : class => type.CreateInstance(null, args); + + public static T CreateInstance( + this Type type, + Predicate predicate, + object[] args = null + ) where T : class + { + var argLength = args?.Length ?? 0; + + var types = argLength > 0 ? new Type[argLength] : Array.Empty(); + for (int i = 0; i < types.Length; i++) + { + types[i] = args![i]?.GetType(); + } + + var ctor = type.GetConstructor(predicate, types, out var paramCount); + if (ctor == null) + { + Console.WriteLine("There is no constructor for {0} that matches the given predicate.", type); + return default; + } + + object[] paramArgs; + if (paramCount == 0) + { + paramArgs = Array.Empty(); + } + else if (argLength == paramCount) + { + paramArgs = args; + } + else + { + paramArgs = new object[paramCount]; + for (int i = 0; i < paramCount; i++) + { + paramArgs[i] = i < argLength ? args![i] : Type.Missing; + } + } + + return ctor.Invoke(paramArgs) as T; + } + } +} diff --git a/Projects/Server/Utilities/ActivatorUtil.cs b/Projects/Server/Utilities/ActivatorUtil.cs deleted file mode 100644 index eace380b5..000000000 --- a/Projects/Server/Utilities/ActivatorUtil.cs +++ /dev/null @@ -1,155 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2020 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: ActivatorUtil.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Linq; -using System.Reflection; - -namespace Server.Utilities -{ - public static class ActivatorUtil - { - public static ConstructorInfo GetConstructor(Type type, Predicate predicate = null) - { - var emptyCtor = type.GetConstructor(Type.EmptyTypes); - - if (emptyCtor != null && predicate?.Invoke(emptyCtor) != false) - { - return emptyCtor; - } - - var optionalCtor = type.GetConstructors() - .SingleOrDefault( - info => - predicate?.Invoke(info) != false && info.GetParameters().All(x => x.IsOptional) - ); - - if (optionalCtor != null) - { - return optionalCtor; - } - - throw new TypeInitializationException( - type.ToString(), - new Exception($"There is no empty/default constructor for {type} that matches predicate.") - ); - } - - public static ConstructorInfo GetConstructor(Type type, Predicate predicate, params Type[] args) - { - try - { - ConstructorInfo ctor; - - if (args.All(x => x != null)) - { - ctor = type.GetConstructor(args); - - if (ctor != null && predicate?.Invoke(ctor) != false) - { - return ctor; - } - } - else - { - ctor = type.GetConstructors() - .SingleOrDefault( - info => - { - if (predicate?.Invoke(info) == false) - { - return false; - } - - var paramList = info.GetParameters().ToList(); - - // If more args are given than parameters, skip. - if (args.Length > paramList.Count) - { - return false; - } - - // check all given args map to params. - for (var i = 0; i < args.Length; i++) - // if a null reference is passed, but the type is not nullable - { - if (args[i] == null && paramList[i].ParameterType.IsValueType - // or if an arg is not null and is not assignable to the parameter type, skip. - || !(args[i] == null || paramList[i].ParameterType.IsAssignableFrom(args[i]))) - { - return false; - } - } - - // If there are more parameters, check if they any are not optional, if any are not, skip. - // Otherwise all checks have passed. We have found a match - return args.Length <= paramList.Count || paramList - .GetRange(args.Length, paramList.Count - args.Length) - .All(x => x.IsOptional); - } - ); - - if (ctor != null) - { - return ctor; - } - } - - throw new Exception($"There is no empty/default constructor for {type} that matches predicate."); - } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } - } - - public static object CreateInstance(Type type, Predicate constructorPredicate = null) - { - var cctor = GetConstructor(type, constructorPredicate); - var args = cctor.GetParameters(); - - if (args.Length == 0) - { - return cctor.Invoke(Type.EmptyTypes); - } - - var argList = new object[args.Length]; - Array.Fill(argList, Type.Missing); - return cctor.Invoke(argList); - } - - public static object CreateInstance( - Type type, Predicate constructorPredicate = null, - params object[] args - ) - { - if (args == null || args.Length == 0) - { - return CreateInstance(type, constructorPredicate); - } - - var cctor = GetConstructor(type, constructorPredicate, args.Select(x => x?.GetType()).ToArray()); - return cctor.Invoke(args); - } - - public static object CreateInstance(Type type, params object[] args) => CreateInstance(type, null, args); - - public static T CreateInstance(Predicate constructorPredicate = null) => - (T)CreateInstance(typeof(T), constructorPredicate); - - public static T CreateInstance(params object[] args) => (T)CreateInstance(typeof(T), null, args); - } -} diff --git a/Projects/Server/Utilities/EntityActivatorExtensions.cs b/Projects/Server/Utilities/EntityActivatorExtensions.cs new file mode 100644 index 000000000..21afc6420 --- /dev/null +++ b/Projects/Server/Utilities/EntityActivatorExtensions.cs @@ -0,0 +1,46 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2020 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: EntityActivatorExtensions.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using System; +using System.Reflection; + +namespace Server.Utilities +{ + public static class EntityActivatorExtensions + { + public static T CreateEntityInstance( + this Type type, + params object[] args + ) where T : IEntity => type.CreateEntityInstance(null, args); + + public static T CreateEntityInstance( + this Type type, + Predicate predicate, + object[] args = null + ) where T : IEntity + { + var entity = type.CreateInstance(predicate, args); + + if (entity is T t) + { + return t; + } + + // Handles memory leaks by deleting the offending entity + entity?.Delete(); + return default; + } + } +} diff --git a/Projects/UOContent/Commands/Dupe.cs b/Projects/UOContent/Commands/Dupe.cs index 6e1a34026..d78e616c3 100644 --- a/Projects/UOContent/Commands/Dupe.cs +++ b/Projects/UOContent/Commands/Dupe.cs @@ -5,7 +5,7 @@ using Server.Utilities; namespace Server.Commands { - public class Dupe + public static class Dupe { public static void Initialize() { @@ -111,7 +111,7 @@ namespace Server.Commands pack = from.Backpack; } - var c = ActivatorUtil.GetConstructor(copy.GetType()); + var c = copy.GetType().GetConstructor(); if (c != null) { var paramList = c.GetParameters(); @@ -128,7 +128,7 @@ namespace Server.Commands { if (c.Invoke(args) is Item newItem) { - CopyProperties(newItem, copy); // copy.Dupe( item, copy.Amount ); + CopyProperties(newItem, copy); copy.OnAfterDuped(newItem); newItem.Parent = null; @@ -166,7 +166,7 @@ namespace Server.Commands if (!done) { - from.SendMessage("Unable to dupe. Item must have a 0 parameter constructor."); + from.SendMessage("Unable to dupe. Item must have a constructor with zero required parameters."); } } } diff --git a/Projects/UOContent/Commands/Generic/Extensions/Compilers/ConditionalCompiler.cs b/Projects/UOContent/Commands/Generic/Extensions/Compilers/ConditionalCompiler.cs index 25d9c3e5c..7061dc90f 100644 --- a/Projects/UOContent/Commands/Generic/Extensions/Compilers/ConditionalCompiler.cs +++ b/Projects/UOContent/Commands/Generic/Extensions/Compilers/ConditionalCompiler.cs @@ -563,7 +563,7 @@ namespace Server.Commands.Generic var conditionalType = typeBuilder.CreateType(); - return (IConditional)ActivatorUtil.CreateInstance(conditionalType); + return conditionalType.CreateInstance(); } } } diff --git a/Projects/UOContent/Commands/Generic/Extensions/Compilers/DistinctCompiler.cs b/Projects/UOContent/Commands/Generic/Extensions/Compilers/DistinctCompiler.cs index fade103e3..63c403d01 100644 --- a/Projects/UOContent/Commands/Generic/Extensions/Compilers/DistinctCompiler.cs +++ b/Projects/UOContent/Commands/Generic/Extensions/Compilers/DistinctCompiler.cs @@ -248,7 +248,7 @@ namespace Server.Commands.Generic var comparerType = typeBuilder.CreateType(); - return (IComparer)ActivatorUtil.CreateInstance(comparerType); + return comparerType.CreateInstance>(); } } } diff --git a/Projects/UOContent/Commands/Generic/Extensions/Compilers/SortCompiler.cs b/Projects/UOContent/Commands/Generic/Extensions/Compilers/SortCompiler.cs index da890e15d..bce1d53ae 100644 --- a/Projects/UOContent/Commands/Generic/Extensions/Compilers/SortCompiler.cs +++ b/Projects/UOContent/Commands/Generic/Extensions/Compilers/SortCompiler.cs @@ -161,7 +161,7 @@ namespace Server.Commands.Generic } var comparerType = typeBuilder.CreateType(); - return (IComparer)ActivatorUtil.CreateInstance(comparerType); + return comparerType.CreateInstance>(); } } } diff --git a/Projects/UOContent/Commands/Object Creation/Categorization.cs b/Projects/UOContent/Commands/Object Creation/Categorization.cs index e2cee8b2b..d5e55ad3f 100644 --- a/Projects/UOContent/Commands/Object Creation/Categorization.cs +++ b/Projects/UOContent/Commands/Object Creation/Categorization.cs @@ -300,7 +300,7 @@ namespace Server.Commands public CategoryTypeEntry(Type type) { Type = type; - Object = ActivatorUtil.CreateInstance(type); + Object = type.CreateInstance(); } public Type Type { get; } diff --git a/Projects/UOContent/Commands/Object Creation/Decorate.cs b/Projects/UOContent/Commands/Object Creation/Decorate.cs index a40bf0138..527f22ab8 100644 --- a/Projects/UOContent/Commands/Object Creation/Decorate.cs +++ b/Projects/UOContent/Commands/Object Creation/Decorate.cs @@ -405,11 +405,11 @@ namespace Server.Commands if (fill) { - item = (Item)ActivatorUtil.CreateInstance(m_Type, content); + item = m_Type.CreateInstance(content); } else { - item = (Item)ActivatorUtil.CreateInstance(m_Type); + item = m_Type.CreateInstance(); } } else if (m_Type.IsSubclassOf(typeofBaseDoor)) @@ -430,11 +430,11 @@ namespace Server.Commands } } - item = (Item)ActivatorUtil.CreateInstance(m_Type, facing); + item = m_Type.CreateInstance(facing); } else { - item = (Item)ActivatorUtil.CreateInstance(m_Type); + item = m_Type.CreateInstance(); } } catch (Exception e) diff --git a/Projects/UOContent/Commands/Object Creation/DecorateMag.cs b/Projects/UOContent/Commands/Object Creation/DecorateMag.cs index 5ae20aa2a..d38ee5f27 100644 --- a/Projects/UOContent/Commands/Object Creation/DecorateMag.cs +++ b/Projects/UOContent/Commands/Object Creation/DecorateMag.cs @@ -402,11 +402,11 @@ namespace Server.Commands if (fill) { - item = (Item)ActivatorUtil.CreateInstance(m_Type, content); + item = m_Type.CreateInstance(content); } else { - item = (Item)ActivatorUtil.CreateInstance(m_Type); + item = m_Type.CreateInstance(); } } else if (m_Type.IsSubclassOf(typeofBaseDoor)) @@ -427,11 +427,11 @@ namespace Server.Commands } } - item = (Item)ActivatorUtil.CreateInstance(m_Type, facing); + item = m_Type.CreateInstance(facing); } else { - item = (Item)ActivatorUtil.CreateInstance(m_Type); + item = m_Type.CreateInstance(); } } catch (Exception e) diff --git a/Projects/UOContent/Engines/CannedEvil/ChampionSpawn.cs b/Projects/UOContent/Engines/CannedEvil/ChampionSpawn.cs index 4a843ab3e..989a60834 100644 --- a/Projects/UOContent/Engines/CannedEvil/ChampionSpawn.cs +++ b/Projects/UOContent/Engines/CannedEvil/ChampionSpawn.cs @@ -395,10 +395,11 @@ namespace Server.Engines.CannedEvil { try { - prot.SendLocalizedMessage(1049368); // You have been rewarded for your dedication to Justice! + var scrollDupe = scroll.GetType().CreateEntityInstance(); - if (ActivatorUtil.CreateInstance(scroll.GetType()) is SpecialScroll scrollDupe) + if (scrollDupe != null) { + prot.SendLocalizedMessage(1049368); // You have been rewarded for your dedication to Justice! scrollDupe.Skill = scroll.Skill; scrollDupe.Value = scroll.Value; prot.AddToBackpack(scrollDupe); @@ -619,7 +620,7 @@ namespace Server.Engines.CannedEvil try { - Champion = ActivatorUtil.CreateInstance(ChampionSpawnInfo.GetInfo(m_Type).Champion) as Mobile; + Champion = ChampionSpawnInfo.GetInfo(m_Type).Champion.CreateInstance(); } catch { @@ -782,7 +783,7 @@ namespace Server.Engines.CannedEvil { try { - return ActivatorUtil.CreateInstance(types.RandomElement()) as Mobile; + return types.RandomElement().CreateInstance(); } catch { diff --git a/Projects/UOContent/Engines/Craft/Core/CraftItem.cs b/Projects/UOContent/Engines/Craft/Core/CraftItem.cs index 345c7f0ea..5b095e8ba 100644 --- a/Projects/UOContent/Engines/Craft/Core/CraftItem.cs +++ b/Projects/UOContent/Engines/Craft/Core/CraftItem.cs @@ -244,7 +244,7 @@ namespace Server.Engines.Craft try { - item = ActivatorUtil.CreateInstance(type) as Item; + item = type.CreateInstance(); } catch { @@ -1188,7 +1188,7 @@ namespace Server.Engines.Craft } else { - item = ActivatorUtil.CreateInstance(ItemType) as Item; + item = ItemType.CreateInstance(); } if (item != null) @@ -1428,27 +1428,22 @@ namespace Server.Engines.Craft if (typeof(CustomCraft).IsAssignableFrom(m_CraftItem.ItemType)) { - CustomCraft cc = null; - try { - cc = ActivatorUtil.CreateInstance( - m_CraftItem.ItemType, + m_CraftItem.ItemType.CreateInstance( m_From, m_CraftItem, m_CraftSystem, m_TypeRes, m_Tool, quality - ) as CustomCraft; + )?.EndCraftAction(); } - catch + catch (Exception e) { - // ignored + Console.WriteLine(e); } - cc?.EndCraftAction(); - return; } diff --git a/Projects/UOContent/Engines/Craft/Core/Resmelt.cs b/Projects/UOContent/Engines/Craft/Core/Resmelt.cs index b62d0c53b..33b5f7ac1 100644 --- a/Projects/UOContent/Engines/Craft/Core/Resmelt.cs +++ b/Projects/UOContent/Engines/Craft/Core/Resmelt.cs @@ -94,7 +94,7 @@ namespace Server.Engines.Craft } var resourceType = info.ResourceTypes[0]; - var ingot = (Item)ActivatorUtil.CreateInstance(resourceType); + var ingot = resourceType.CreateInstance(); if (item is DragonBardingDeed || item is BaseArmor armor && armor.PlayerConstructed || item is BaseWeapon weapon && weapon.PlayerConstructed || diff --git a/Projects/UOContent/Engines/Craft/DefInscription.cs b/Projects/UOContent/Engines/Craft/DefInscription.cs index ea74632a9..ef3e9a857 100644 --- a/Projects/UOContent/Engines/Craft/DefInscription.cs +++ b/Projects/UOContent/Engines/Craft/DefInscription.cs @@ -37,7 +37,7 @@ namespace Server.Engines.Craft public override int GumpTitleNumber => 1044009; - public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefInscription()); + public static CraftSystem CraftSystem => m_CraftSystem ??= new DefInscription(); public override double GetChanceAtMin(CraftItem item) => 0.0; @@ -55,9 +55,9 @@ namespace Server.Engines.Craft if (typeItem != null) { - var o = ActivatorUtil.CreateInstance(typeItem); + var scroll = typeItem.CreateEntityInstance(); - if (o is SpellScroll scroll) + if (scroll != null) { var hasSpell = Spellbook.Find(from, scroll.SpellID)?.HasSpell(scroll.SpellID) == true; @@ -65,11 +65,6 @@ namespace Server.Engines.Craft return hasSpell ? 0 : 1042404; // null : You don't have that spell! } - - if (o is Item item) - { - item.Delete(); - } } return 0; diff --git a/Projects/UOContent/Engines/Doom/GauntletSpawner.cs b/Projects/UOContent/Engines/Doom/GauntletSpawner.cs index 3b6729fce..60c19d90e 100644 --- a/Projects/UOContent/Engines/Doom/GauntletSpawner.cs +++ b/Projects/UOContent/Engines/Doom/GauntletSpawner.cs @@ -340,16 +340,11 @@ namespace Server.Engines.Doom return; } - var obj = ActivatorUtil.CreateInstance(type); + var mob = type.CreateEntityInstance(); - if (obj is Item item) - { - item.Delete(); - } - else if (obj is Mobile mob) + if (mob != null) { mob.MoveToWorld(GetWorldLocation(), Map); - Creatures.Add(mob); } } diff --git a/Projects/UOContent/Engines/Factions/Core/GuardList.cs b/Projects/UOContent/Engines/Factions/Core/GuardList.cs index 3ea41b8f4..b3845d241 100644 --- a/Projects/UOContent/Engines/Factions/Core/GuardList.cs +++ b/Projects/UOContent/Engines/Factions/Core/GuardList.cs @@ -19,7 +19,7 @@ namespace Server.Factions { try { - return ActivatorUtil.CreateInstance(Definition.Type) as BaseFactionGuard; + return Definition.Type.CreateInstance(); } catch { diff --git a/Projects/UOContent/Engines/Factions/Core/Reflector.cs b/Projects/UOContent/Engines/Factions/Core/Reflector.cs index 2e298b4e2..f2a3e0d33 100644 --- a/Projects/UOContent/Engines/Factions/Core/Reflector.cs +++ b/Projects/UOContent/Engines/Factions/Core/Reflector.cs @@ -41,7 +41,7 @@ namespace Server.Factions { try { - return ActivatorUtil.CreateInstance(type); + return type.CreateInstance(); } catch { diff --git a/Projects/UOContent/Engines/Factions/Core/VendorList.cs b/Projects/UOContent/Engines/Factions/Core/VendorList.cs index b94e84e5d..0c54f9f94 100644 --- a/Projects/UOContent/Engines/Factions/Core/VendorList.cs +++ b/Projects/UOContent/Engines/Factions/Core/VendorList.cs @@ -19,7 +19,7 @@ namespace Server.Factions { try { - return ActivatorUtil.CreateInstance(Definition.Type, town, faction) as BaseFactionVendor; + return Definition.Type.CreateInstance(town, faction); } catch { diff --git a/Projects/UOContent/Engines/Factions/Items/Power Faction Items/PowerFactionItem.cs b/Projects/UOContent/Engines/Factions/Items/Power Faction Items/PowerFactionItem.cs index f4350ff83..2a25143f8 100644 --- a/Projects/UOContent/Engines/Factions/Items/Power Faction Items/PowerFactionItem.cs +++ b/Projects/UOContent/Engines/Factions/Items/Power Faction Items/PowerFactionItem.cs @@ -55,7 +55,7 @@ namespace Server { if (weight < item.Weight) { - var obj = item.Construct(); + var obj = item.Type.CreateInstance(); if (obj != null) { @@ -188,8 +188,6 @@ namespace Server public int Weight { get; } public Type Type { get; } - - public Item Construct() => ActivatorUtil.CreateInstance(Type) as Item; } } } diff --git a/Projects/UOContent/Engines/Factions/Items/Traps/BaseFactionTrapDeed.cs b/Projects/UOContent/Engines/Factions/Items/Traps/BaseFactionTrapDeed.cs index 1617e7a95..cfdbb803e 100644 --- a/Projects/UOContent/Engines/Factions/Items/Traps/BaseFactionTrapDeed.cs +++ b/Projects/UOContent/Engines/Factions/Items/Traps/BaseFactionTrapDeed.cs @@ -51,7 +51,7 @@ namespace Server.Factions { try { - return ActivatorUtil.CreateInstance(TrapType, m_Faction, from) as BaseFactionTrap; + return TrapType.CreateInstance(m_Faction, from); } catch { diff --git a/Projects/UOContent/Engines/Factions/Mobiles/Guards/GuardAI.cs b/Projects/UOContent/Engines/Factions/Mobiles/Guards/GuardAI.cs index 13bb028df..60b702ee8 100644 --- a/Projects/UOContent/Engines/Factions/Mobiles/Guards/GuardAI.cs +++ b/Projects/UOContent/Engines/Factions/Mobiles/Guards/GuardAI.cs @@ -91,7 +91,7 @@ namespace Server.Factions if (entry.Chance > Utility.Random(100)) { releaseTime = DateTime.UtcNow + entry.Hold; - return (Spell)ActivatorUtil.CreateInstance(entry.Spell, mob, null); + return entry.Spell.CreateInstance(mob, null); } } @@ -406,9 +406,9 @@ namespace Server.Factions { if (m_Mobile.Target != null) m_Mobile.Target.Cancel( m_Mobile, TargetCancelType.Canceled ); - + new TeleportSpell( m_Mobile, null ).Cast(); - + m_Mobile.DebugSay( "I am stuck, I'm going to try teleporting away" ); } else*/ @@ -744,7 +744,7 @@ namespace Server.Factions } else if (types.Count == 1) { - spell = ActivatorUtil.CreateInstance(types[0], m_Guard, null) as Spell; + spell = types[0].CreateInstance(m_Guard, null); } } else if (types.Count > 0) @@ -796,7 +796,7 @@ namespace Server.Factions } else if (types.Count == 1) { - spell = (Spell)ActivatorUtil.CreateInstance(types[0], m_Guard, null); + spell = types[0].CreateInstance(m_Guard, null); } } } @@ -804,24 +804,14 @@ namespace Server.Factions if (spell != null && m_Guard.HitsMax - m_Guard.Hits + 10 > Utility.Random(100)) { - Type type = null; - - if (spell is GreaterHealSpell) + Type type = spell switch { - type = typeof(BaseHealPotion); - } - else if (spell is CureSpell) - { - type = typeof(BaseCurePotion); - } - else if (spell is StrengthSpell) - { - type = typeof(BaseStrengthPotion); - } - else if (spell is AgilitySpell) - { - type = typeof(BaseAgilityPotion); - } + GreaterHealSpell _ => typeof(BaseHealPotion), + CureSpell _ => typeof(BaseCurePotion), + StrengthSpell _ => typeof(BaseStrengthPotion), + AgilitySpell _ => typeof(BaseAgilityPotion), + _ => null + }; if (type == typeof(BaseHealPotion) && !m_Guard.CanBeginAction(type)) { diff --git a/Projects/UOContent/Engines/Harvest/Core/HarvestSystem.cs b/Projects/UOContent/Engines/Harvest/Core/HarvestSystem.cs index 574c94740..78fa7e8fe 100644 --- a/Projects/UOContent/Engines/Harvest/Core/HarvestSystem.cs +++ b/Projects/UOContent/Engines/Harvest/Core/HarvestSystem.cs @@ -268,7 +268,7 @@ namespace Server.Engines.Harvest { try { - return ActivatorUtil.CreateInstance(type) as Item; + return type.CreateInstance(); } catch { diff --git a/Projects/UOContent/Engines/Harvest/Mining.cs b/Projects/UOContent/Engines/Harvest/Mining.cs index 9ecc57ad5..2ee254f18 100644 --- a/Projects/UOContent/Engines/Harvest/Mining.cs +++ b/Projects/UOContent/Engines/Harvest/Mining.cs @@ -387,16 +387,17 @@ namespace Server.Engines.Harvest if (res == resource && res.Types.Length >= 3) { + var map = from.Map; + + if (map == null) + { + return; + } + try { - var map = from.Map; - - if (map == null) - { - return; - } - - if (ActivatorUtil.CreateInstance(res.Types[2], 25) is BaseCreature spawned) + var spawned = res.Types[2].CreateEntityInstance(25); + if (spawned != null) { var offset = Utility.Random(8) * 2; diff --git a/Projects/UOContent/Engines/MLQuests/MLQuestSystem.cs b/Projects/UOContent/Engines/MLQuests/MLQuestSystem.cs index 7888c66ce..90c4152cd 100644 --- a/Projects/UOContent/Engines/MLQuests/MLQuestSystem.cs +++ b/Projects/UOContent/Engines/MLQuests/MLQuestSystem.cs @@ -69,7 +69,7 @@ namespace Server.Engines.MLQuests try { - quest = ActivatorUtil.CreateInstance(type) as MLQuest; + quest = type.CreateInstance(); } catch { diff --git a/Projects/UOContent/Engines/MLQuests/Objectives/DeliverObjective.cs b/Projects/UOContent/Engines/MLQuests/Objectives/DeliverObjective.cs index 582954fe4..11d8922f0 100644 --- a/Projects/UOContent/Engines/MLQuests/Objectives/DeliverObjective.cs +++ b/Projects/UOContent/Engines/MLQuests/Objectives/DeliverObjective.cs @@ -49,17 +49,17 @@ namespace Server.Engines.MLQuests.Objectives for (var i = 0; i < Amount; ++i) { - if (!(ActivatorUtil.CreateInstance(Delivery) is Item item)) - { - continue; - } + var item = Delivery.CreateEntityInstance(); - delivery.Add(item); - - if (item.Stackable && Amount > 1) + if (item != null) { - item.Amount = Amount; - break; + delivery.Add(item); + + if (item.Stackable && Amount > 1) + { + item.Amount = Amount; + break; + } } } diff --git a/Projects/UOContent/Engines/MLQuests/Rewards/ItemReward.cs b/Projects/UOContent/Engines/MLQuests/Rewards/ItemReward.cs index 8823d9f74..e7c2e84c6 100644 --- a/Projects/UOContent/Engines/MLQuests/Rewards/ItemReward.cs +++ b/Projects/UOContent/Engines/MLQuests/Rewards/ItemReward.cs @@ -54,7 +54,7 @@ namespace Server.Engines.MLQuests.Rewards try { - spawnedItem = ActivatorUtil.CreateInstance(m_Type) as Item; + spawnedItem = m_Type.CreateInstance(); } catch (Exception e) { diff --git a/Projects/UOContent/Engines/Plants/MiscItems/GreenThorns.cs b/Projects/UOContent/Engines/Plants/MiscItems/GreenThorns.cs index bca402b98..02a8243ee 100644 --- a/Projects/UOContent/Engines/Plants/MiscItems/GreenThorns.cs +++ b/Projects/UOContent/Engines/Plants/MiscItems/GreenThorns.cs @@ -310,18 +310,12 @@ namespace Server.Items foreach (var taep in m_Table) { - var contains = false; - - for (var i = 0; !contains && i < taep.Tiles.Length; i += 2) + for (var i = 0; i < taep.Tiles.Length; i += 2) { - contains = tileID >= taep.Tiles[i] && tileID <= taep.Tiles[i + 1]; - } - - if (contains) - { - var effect = - (GreenThornsEffect)ActivatorUtil.CreateInstance(taep.Effect, land.Location, from.Map, from); - return effect; + if (tileID >= taep.Tiles[i] && tileID <= taep.Tiles[i + 1]) + { + return taep.Effect.CreateInstance(land.Location, from.Map, from); + } } } diff --git a/Projects/UOContent/Engines/Plants/PlantResources.cs b/Projects/UOContent/Engines/Plants/PlantResources.cs index 0b401b604..1bbff005c 100644 --- a/Projects/UOContent/Engines/Plants/PlantResources.cs +++ b/Projects/UOContent/Engines/Plants/PlantResources.cs @@ -45,6 +45,6 @@ namespace Server.Engines.Plants return null; } - public Item CreateResource() => (Item)ActivatorUtil.CreateInstance(ResourceType); + public Item CreateResource() => ResourceType.CreateInstance(); } } diff --git a/Projects/UOContent/Engines/Quests/Core/QuestSerializer.cs b/Projects/UOContent/Engines/Quests/Core/QuestSerializer.cs index d971e5f73..03b9a1862 100644 --- a/Projects/UOContent/Engines/Quests/Core/QuestSerializer.cs +++ b/Projects/UOContent/Engines/Quests/Core/QuestSerializer.cs @@ -3,13 +3,13 @@ using Server.Utilities; namespace Server.Engines.Quests { - public class QuestSerializer + public static class QuestSerializer { public static object Construct(Type type) { try { - return ActivatorUtil.CreateInstance(type); + return type.CreateInstance(); } catch { diff --git a/Projects/UOContent/Engines/Spawners/BaseSpawner.cs b/Projects/UOContent/Engines/Spawners/BaseSpawner.cs index d7c9ee9cf..428b6f7ec 100644 --- a/Projects/UOContent/Engines/Spawners/BaseSpawner.cs +++ b/Projects/UOContent/Engines/Spawners/BaseSpawner.cs @@ -563,153 +563,162 @@ namespace Server.Engines.Spawners var type = AssemblyHandler.FindFirstTypeForName(entry.SpawnedName); - if (type != null) + if (type == null) { - try + flags = EntryFlags.InvalidType; + return false; + } + + try + { + IEntity entity = null; + string[] paramargs; + string[] propargs; + + propargs = string.IsNullOrEmpty(entry.Properties) + ? Array.Empty() + : CommandSystem.Split(entry.Properties.Trim()); + + var props = FormatProperties(propargs); + + var realProps = GetTypeProperties(type, props); + + if (realProps == null) { - object o = null; - string[] paramargs; - string[] propargs; + flags = EntryFlags.InvalidProps; + return false; + } - propargs = string.IsNullOrEmpty(entry.Properties) - ? Array.Empty() - : CommandSystem.Split(entry.Properties.Trim()); + paramargs = string.IsNullOrEmpty(entry.Parameters) + ? Array.Empty() + : entry.Parameters.Trim().Split(' '); - var props = FormatProperties(propargs); + if (paramargs.Length == 0) + { + entity = type.CreateInstance( + ci => Add.IsConstructible(ci, AccessLevel.Developer) + ); + } + else + { + var ctors = type.GetConstructors(); - var realProps = GetTypeProperties(type, props); - - if (realProps == null) + for (var i = 0; i < ctors.Length; ++i) { - flags = EntryFlags.InvalidProps; - return false; - } + var ctor = ctors[i]; - paramargs = string.IsNullOrEmpty(entry.Parameters) - ? Array.Empty() - : entry.Parameters.Trim().Split(' '); - - if (paramargs.Length == 0) - { - o = ActivatorUtil.CreateInstance(type, ci => Add.IsConstructible(ci, AccessLevel.Developer)); - } - else - { - var ctors = type.GetConstructors(); - - for (var i = 0; i < ctors.Length; ++i) + if (Add.IsConstructible(ctor, AccessLevel.Developer)) { - var ctor = ctors[i]; + var paramList = ctor.GetParameters(); - if (Add.IsConstructible(ctor, AccessLevel.Developer)) + if (paramargs.Length == paramList.Length) { - var paramList = ctor.GetParameters(); + var paramValues = Add.ParseValues(paramList, paramargs); - if (paramargs.Length == paramList.Length) + if (paramValues != null) { - var paramValues = Add.ParseValues(paramList, paramargs); - - if (paramValues != null) - { - o = ctor.Invoke(paramValues); - break; - } + entity = ctor.Invoke(paramValues) as IEntity; + break; } } } } - - for (var i = 0; i < realProps.Length; i++) - { - if (realProps[i] != null) - { - object toSet = null; - var result = Properties.ConstructFromString( - realProps[i].PropertyType, - o, - props[i, 1], - ref toSet - ); - - if (result == null) - { - realProps[i].SetValue(o, toSet, null); - } - else - { - flags = EntryFlags.InvalidProps; - - (o as ISpawnable)?.Delete(); - - return false; - } - } - } - - if (o is Mobile m) - { - Spawned.Add(m, entry); - entry.Spawned.Add(m); - - var loc = m is BaseVendor ? Location : GetSpawnPosition(m, map); - - m.OnBeforeSpawn(loc, map); - InvalidateProperties(); - - m.MoveToWorld(loc, map); - - if (m is BaseCreature c) - { - var walkrange = GetWalkingRange(); - - c.RangeHome = walkrange >= 0 ? walkrange : m_HomeRange; - c.CurrentWayPoint = WayPoint; - - if (m_Team > 0) - { - c.Team = m_Team; - } - - c.Home = Location; - c.HomeMap = Map; - } - - m.Spawner = this; - m.OnAfterSpawn(); - } - else if (o is Item item) - { - Spawned.Add(item, entry); - entry.Spawned.Add(item); - - var loc = GetSpawnPosition(item, map); - - item.OnBeforeSpawn(loc, map); - - item.MoveToWorld(loc, map); - - item.Spawner = this; - item.OnAfterSpawn(); - } - else - { - flags = EntryFlags.InvalidType | EntryFlags.InvalidParams; - return false; - } } - catch (Exception e) + + if (entity == null) { - Console.WriteLine($"EXCEPTION CAUGHT: {Serial}"); - Console.WriteLine(e); + flags = EntryFlags.InvalidType | EntryFlags.InvalidParams; return false; } - InvalidateProperties(); - return true; + for (var i = 0; i < realProps.Length; i++) + { + if (realProps[i] != null) + { + object toSet = null; + var result = Properties.ConstructFromString( + realProps[i].PropertyType, + entity, + props[i, 1], + ref toSet + ); + + if (result == null) + { + realProps[i].SetValue(entity, toSet, null); + } + else + { + flags = EntryFlags.InvalidProps; + + (entity as ISpawnable)?.Delete(); + + return false; + } + } + } + + if (entity is Mobile m) + { + Spawned.Add(m, entry); + entry.Spawned.Add(m); + + var loc = m is BaseVendor ? Location : GetSpawnPosition(m, map); + + m.OnBeforeSpawn(loc, map); + InvalidateProperties(); + + m.MoveToWorld(loc, map); + + if (m is BaseCreature c) + { + var walkrange = GetWalkingRange(); + + c.RangeHome = walkrange >= 0 ? walkrange : m_HomeRange; + c.CurrentWayPoint = WayPoint; + + if (m_Team > 0) + { + c.Team = m_Team; + } + + c.Home = Location; + c.HomeMap = Map; + } + + m.Spawner = this; + m.OnAfterSpawn(); + } + else if (entity is Item item) + { + Spawned.Add(item, entry); + entry.Spawned.Add(item); + + var loc = GetSpawnPosition(item, map); + + item.OnBeforeSpawn(loc, map); + + item.MoveToWorld(loc, map); + + item.Spawner = this; + item.OnAfterSpawn(); + } + else + { + // Other IEntity types that might get created are simply not supported + flags = EntryFlags.InvalidType | EntryFlags.InvalidParams; + return false; + } + } + catch (Exception e) + { + Console.WriteLine($"EXCEPTION CAUGHT: {Serial}"); + Console.WriteLine(e); + return false; } - flags = EntryFlags.InvalidType; - return false; + InvalidateProperties(); + return true; } public virtual int GetWalkingRange() => m_WalkingRange; diff --git a/Projects/UOContent/Engines/Spawners/GenerateSpawners.cs b/Projects/UOContent/Engines/Spawners/GenerateSpawners.cs index 538b92961..5e57de968 100644 --- a/Projects/UOContent/Engines/Spawners/GenerateSpawners.cs +++ b/Projects/UOContent/Engines/Spawners/GenerateSpawners.cs @@ -96,7 +96,7 @@ namespace Server.Engines.Spawners try { - var spawner = ActivatorUtil.CreateInstance(type, json, options) as ISpawner; + var spawner = type.CreateInstance(json, options); spawner!.MoveToWorld(location, map); spawner!.Respawn(); diff --git a/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokuno.cs b/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokuno.cs index e5bb5f815..9ebba4993 100644 --- a/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokuno.cs +++ b/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokuno.cs @@ -157,47 +157,40 @@ namespace Server.Misc var chance = A * Math.Pow(10, B * x); - if (chance > Utility.RandomDouble()) + if (chance <= Utility.RandomDouble()) { - Item i = null; + return; + } - try + Item i; + + try + { + i = m_LesserArtifacts[(int)DropEra - 1].RandomElement().CreateInstance(); + } + catch + { + return; + } + + // For your valor in combating the fallen beast, a special artifact has been bestowed on you. + pm.SendLocalizedMessage(1062317); + + if (!pm.PlaceInBackpack(i)) + { + if (pm.BankBox?.TryDropItem(killer, i, false) == true) { - i = ActivatorUtil.CreateInstance( - m_LesserArtifacts[(int)DropEra - 1].RandomElement() - ) - as - Item; + pm.SendLocalizedMessage(1079730); // The item has been placed into your bank box. } - catch + else { - // ignored - } - - if (i != null) - { - pm.SendLocalizedMessage( - 1062317 - ); // For your valor in combating the fallen beast, a special artifact has been bestowed on you. - - if (!pm.PlaceInBackpack(i)) - { - if (pm.BankBox?.TryDropItem(killer, i, false) == true) - { - pm.SendLocalizedMessage(1079730); // The item has been placed into your bank box. - } - else - { - pm.SendLocalizedMessage( - 1072523 - ); // You find an artifact, but your backpack and bank are too full to hold it. - i.MoveToWorld(pm.Location, pm.Map); - } - } - - pm.ToTTotalMonsterFame = 0; + // You find an artifact, but your backpack and bank are too full to hold it. + pm.SendLocalizedMessage(1072523); + i.MoveToWorld(pm.Location, pm.Map); } } + + pm.ToTTotalMonsterFame = 0; } } } @@ -594,7 +587,7 @@ namespace Server.Gumps try { - item = (Item)ActivatorUtil.CreateInstance(t.Type); + item = t.Type.CreateInstance(); } catch { diff --git a/Projects/UOContent/Engines/VeteranRewards/RewardEntry.cs b/Projects/UOContent/Engines/VeteranRewards/RewardEntry.cs index 90124ac3a..7388c6fdb 100644 --- a/Projects/UOContent/Engines/VeteranRewards/RewardEntry.cs +++ b/Projects/UOContent/Engines/VeteranRewards/RewardEntry.cs @@ -69,7 +69,7 @@ namespace Server.Engines.VeteranRewards { try { - var item = ActivatorUtil.CreateInstance(ItemType, Args) as Item; + var item = ItemType.CreateInstance(Args); if (item is IRewardItem rewardItem) { diff --git a/Projects/UOContent/Gumps/ConfirmHeritageGump.cs b/Projects/UOContent/Gumps/ConfirmHeritageGump.cs index 0b1cd88d7..3ea29bb5f 100644 --- a/Projects/UOContent/Gumps/ConfirmHeritageGump.cs +++ b/Projects/UOContent/Gumps/ConfirmHeritageGump.cs @@ -45,7 +45,7 @@ namespace Server.Gumps { try { - item = ActivatorUtil.CreateInstance(type) as Item; + item = type.CreateInstance(); } catch (Exception ex) { diff --git a/Projects/UOContent/Holiday Stuff/Halloween/HolidaySettings.cs b/Projects/UOContent/Holiday Stuff/Halloween/HolidaySettings.cs index e7b08ea00..56e0f7701 100644 --- a/Projects/UOContent/Holiday Stuff/Halloween/HolidaySettings.cs +++ b/Projects/UOContent/Holiday Stuff/Halloween/HolidaySettings.cs @@ -36,8 +36,8 @@ namespace Server.Events.Halloween public static DateTime FinishHalloween => new DateTime(2012, 11, 15); public static Item RandomGMBeggerItem => - (Item)ActivatorUtil.CreateInstance(m_GMBeggarTreats.RandomElement()); + m_GMBeggarTreats.RandomElement().CreateInstance(); - public static Item RandomTreat => (Item)ActivatorUtil.CreateInstance(m_Treats.RandomElement()); + public static Item RandomTreat => m_Treats.RandomElement().CreateInstance(); } } diff --git a/Projects/UOContent/Items/Aquarium/Aquarium.cs b/Projects/UOContent/Items/Aquarium/Aquarium.cs index 9c223d69f..84140fec9 100644 --- a/Projects/UOContent/Items/Aquarium/Aquarium.cs +++ b/Projects/UOContent/Items/Aquarium/Aquarium.cs @@ -842,7 +842,7 @@ namespace Server.Items try { - item = ActivatorUtil.CreateInstance(m_Decorations[random]) as Item; + item = m_Decorations[random].CreateInstance(); } catch { diff --git a/Projects/UOContent/Items/Armor/BaseArmor.cs b/Projects/UOContent/Items/Armor/BaseArmor.cs index 50d01cc23..0e8e10cfe 100644 --- a/Projects/UOContent/Items/Armor/BaseArmor.cs +++ b/Projects/UOContent/Items/Armor/BaseArmor.cs @@ -594,7 +594,7 @@ namespace Server.Items { try { - var res = (Item)ActivatorUtil.CreateInstance(CraftResources.GetInfo(m_Resource).ResourceTypes[0]); + var res = CraftResources.GetInfo(m_Resource).ResourceTypes[0].CreateInstance(); ScissorHelper(from, res, PlayerConstructed ? item.Resources[0].Amount / 2 : 1); return true; diff --git a/Projects/UOContent/Items/Clothing/BaseClothing.cs b/Projects/UOContent/Items/Clothing/BaseClothing.cs index ef4e66eb6..cac92efd4 100644 --- a/Projects/UOContent/Items/Clothing/BaseClothing.cs +++ b/Projects/UOContent/Items/Clothing/BaseClothing.cs @@ -237,7 +237,7 @@ namespace Server.Items var resourceType = info.ResourceTypes?[0] ?? item.Resources[0].ItemType; - var res = (Item)ActivatorUtil.CreateInstance(resourceType); + var res = resourceType.CreateInstance(); ScissorHelper(from, res, PlayerConstructed ? item.Resources[0].Amount / 2 : 1); diff --git a/Projects/UOContent/Items/Containers/SalvageBag.cs b/Projects/UOContent/Items/Containers/SalvageBag.cs index c8f861ec1..da47e9740 100644 --- a/Projects/UOContent/Items/Containers/SalvageBag.cs +++ b/Projects/UOContent/Items/Containers/SalvageBag.cs @@ -88,8 +88,7 @@ namespace Server.Items _ => 0.0 }; - var resourceType = info.ResourceTypes[0]; - var ingot = (Item)ActivatorUtil.CreateInstance(resourceType); + var ingot = info.ResourceTypes[0].CreateInstance(); if (item is DragonBardingDeed || item is BaseArmor armor && armor.PlayerConstructed || item is BaseWeapon weapon && weapon.PlayerConstructed || diff --git a/Projects/UOContent/Items/Containers/TreasureMapChest.cs b/Projects/UOContent/Items/Containers/TreasureMapChest.cs index 86ce0f290..c68059693 100644 --- a/Projects/UOContent/Items/Containers/TreasureMapChest.cs +++ b/Projects/UOContent/Items/Containers/TreasureMapChest.cs @@ -304,7 +304,7 @@ namespace Server.Items if (level == 6 && Core.AOS) { - cont.DropItem((Item)ActivatorUtil.CreateInstance(Artifacts.RandomElement())); + cont.DropItem(Artifacts.RandomElement().CreateInstance()); } } diff --git a/Projects/UOContent/Items/Decoration Artifacts/StealableArtifactsSpawner.cs b/Projects/UOContent/Items/Decoration Artifacts/StealableArtifactsSpawner.cs index dc66b0fac..3414dfd17 100644 --- a/Projects/UOContent/Items/Decoration Artifacts/StealableArtifactsSpawner.cs +++ b/Projects/UOContent/Items/Decoration Artifacts/StealableArtifactsSpawner.cs @@ -346,7 +346,7 @@ namespace Server.Items public Item CreateInstance() { - var item = (Item)ActivatorUtil.CreateInstance(Type); + var item = Type.CreateInstance(); if (Hue > 0) { diff --git a/Projects/UOContent/Items/Maps/TreasureMap.cs b/Projects/UOContent/Items/Maps/TreasureMap.cs index d54ebb573..10ec0ed30 100644 --- a/Projects/UOContent/Items/Maps/TreasureMap.cs +++ b/Projects/UOContent/Items/Maps/TreasureMap.cs @@ -245,7 +245,7 @@ namespace Server.Items try { - bc = (BaseCreature)ActivatorUtil.CreateInstance(m_SpawnTypes[level].RandomElement()); + bc = m_SpawnTypes[level].RandomElement().CreateInstance(); } catch { diff --git a/Projects/UOContent/Items/Misc/DeceitBrazier.cs b/Projects/UOContent/Items/Misc/DeceitBrazier.cs index 4420be7cb..11e2557dd 100644 --- a/Projects/UOContent/Items/Misc/DeceitBrazier.cs +++ b/Projects/UOContent/Items/Misc/DeceitBrazier.cs @@ -174,8 +174,7 @@ namespace Server.Items if (NextSpawn < DateTime.UtcNow) { var map = Map; - var bc = - (BaseCreature)ActivatorUtil.CreateInstance(Creatures.RandomElement()); + var bc = Creatures.RandomElement().CreateInstance(); var spawnLoc = GetSpawnPosition(); diff --git a/Projects/UOContent/Items/Skill Items/Magical/Potions/BasePotion.cs b/Projects/UOContent/Items/Skill Items/Magical/Potions/BasePotion.cs index 3d3dab230..030a86745 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Potions/BasePotion.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Potions/BasePotion.cs @@ -72,8 +72,14 @@ namespace Server.Items bool ICommodity.IsDeedable => Core.ML; public int OnCraft( - int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, - CraftItem craftItem, int resHue + int quality, + bool makersMark, + Mobile from, + CraftSystem craftSystem, + Type typeRes, + BaseTool tool, + CraftItem craftItem, + int resHue ) { if (craftSystem is DefAlchemy) @@ -151,11 +157,11 @@ namespace Server.Items { if (this is BaseExplosionPotion && Amount > 1) { - var pot = (BasePotion)ActivatorUtil.CreateInstance(GetType()); + var pot = GetType().CreateInstance(); Amount--; - if (from.Backpack?.Deleted != false) + if (from.Backpack?.Deleted == false) { from.Backpack.DropItem(pot); } diff --git a/Projects/UOContent/Items/Skill Items/Ninjitsu/NinjaWeapons.cs b/Projects/UOContent/Items/Skill Items/Ninjitsu/NinjaWeapons.cs index 225c7ba6f..2c33deaa1 100644 --- a/Projects/UOContent/Items/Skill Items/Ninjitsu/NinjaWeapons.cs +++ b/Projects/UOContent/Items/Skill Items/Ninjitsu/NinjaWeapons.cs @@ -90,7 +90,7 @@ namespace Server.Items { if (weapon.UsesRemaining > 0) { - var ammo = ActivatorUtil.CreateInstance(weapon.AmmoType, weapon.UsesRemaining) as Item; + var ammo = weapon.AmmoType.CreateInstance(weapon.UsesRemaining); if (ammo is INinjaAmmo ninaAmmo) { diff --git a/Projects/UOContent/Items/Talismans/BaseTalisman.cs b/Projects/UOContent/Items/Talismans/BaseTalisman.cs index b4ae53147..74aeef2ac 100644 --- a/Projects/UOContent/Items/Talismans/BaseTalisman.cs +++ b/Projects/UOContent/Items/Talismans/BaseTalisman.cs @@ -451,18 +451,18 @@ namespace Server.Items if (type != null) { - object obj; + IEntity entity; try { - obj = ActivatorUtil.CreateInstance(type); + entity = type.CreateInstance(); } catch { - obj = null; + entity = null; } - if (obj is Item item) + if (entity is Item item) { var count = 1; @@ -492,7 +492,7 @@ namespace Server.Items if (i + 1 < count) { - item = ActivatorUtil.CreateInstance(type) as Item; + item = type.CreateInstance(); } } @@ -513,7 +513,7 @@ namespace Server.Items from.SendLocalizedMessage(1074853, m_Summoner.Name.ToString()); // You have been given ~1_name~ } } - else if (obj is BaseCreature mob) + else if (entity is BaseCreature mob) { if (m_Creature?.Deleted == false || from.Followers + mob.ControlSlots > from.FollowersMax) { @@ -536,6 +536,10 @@ namespace Server.Items m_Creature = mob; } + else + { + entity?.Delete(); + } OnAfterUse(from); } diff --git a/Projects/UOContent/Misc/Loot.cs b/Projects/UOContent/Misc/Loot.cs index bc2a6e734..1c42d05cd 100644 --- a/Projects/UOContent/Misc/Loot.cs +++ b/Projects/UOContent/Misc/Loot.cs @@ -780,7 +780,7 @@ namespace Server try { - return ActivatorUtil.CreateInstance(type) as Item; + return type.CreateInstance(); } catch { diff --git a/Projects/UOContent/Misc/LootPack.cs b/Projects/UOContent/Misc/LootPack.cs index 5fb39f601..1985eebb7 100644 --- a/Projects/UOContent/Misc/LootPack.cs +++ b/Projects/UOContent/Misc/LootPack.cs @@ -1066,7 +1066,7 @@ namespace Server } else { - item = ActivatorUtil.CreateInstance(Type) as Item; + item = Type.CreateInstance(); } return item; diff --git a/Projects/UOContent/Misc/MondainsLegacy.cs b/Projects/UOContent/Misc/MondainsLegacy.cs index 7047e8d1f..68a6a0e0e 100644 --- a/Projects/UOContent/Misc/MondainsLegacy.cs +++ b/Projects/UOContent/Misc/MondainsLegacy.cs @@ -29,7 +29,9 @@ namespace Server public static void GiveArtifactTo(Mobile m) { - if (!(ActivatorUtil.CreateInstance(Artifacts.RandomElement()) is Item item)) + var item = Artifacts.RandomElement().CreateInstance(); + + if (item == null) { return; } diff --git a/Projects/UOContent/Mobiles/BaseCreature.cs b/Projects/UOContent/Mobiles/BaseCreature.cs index 67a5db71b..2636a1c37 100644 --- a/Projects/UOContent/Mobiles/BaseCreature.cs +++ b/Projects/UOContent/Mobiles/BaseCreature.cs @@ -2820,17 +2820,9 @@ namespace Server.Mobiles m_SpellDefense.Add(type); } - public Spell GetAttackSpellRandom() - { - var type = m_SpellAttack.RandomElement(); - return type == null ? null : ActivatorUtil.CreateInstance(type, this, null) as Spell; - } + public Spell GetAttackSpellRandom() => m_SpellAttack.RandomElement()?.CreateInstance(this, null); - public Spell GetDefenseSpellRandom() - { - var type = m_SpellDefense.RandomElement(); - return type == null ? null : ActivatorUtil.CreateInstance(type, this, null) as Spell; - } + public Spell GetDefenseSpellRandom() => m_SpellDefense.RandomElement()?.CreateInstance(this, null); public Spell GetSpellSpecific(Type type) { @@ -2840,7 +2832,7 @@ namespace Server.Mobiles { if (m_SpellAttack[i] == type) { - return ActivatorUtil.CreateInstance(type, this, null) as Spell; + return type.CreateInstance(this, null); } } @@ -2848,7 +2840,7 @@ namespace Server.Mobiles { if (m_SpellDefense[i] == type) { - return ActivatorUtil.CreateInstance(type, this, null) as Spell; + return type.CreateInstance(this, null); } } diff --git a/Projects/UOContent/Mobiles/PlayerMobile.cs b/Projects/UOContent/Mobiles/PlayerMobile.cs index d37a3d1e2..56d5b14a5 100644 --- a/Projects/UOContent/Mobiles/PlayerMobile.cs +++ b/Projects/UOContent/Mobiles/PlayerMobile.cs @@ -3838,7 +3838,7 @@ namespace Server.Mobiles try { - ammo = ActivatorUtil.CreateInstance(kvp.Key) as Item; + ammo = kvp.Key.CreateInstance(); } catch { diff --git a/Projects/UOContent/Mobiles/Special/Paragon.cs b/Projects/UOContent/Mobiles/Special/Paragon.cs index 63330a26f..978e51524 100644 --- a/Projects/UOContent/Mobiles/Special/Paragon.cs +++ b/Projects/UOContent/Mobiles/Special/Paragon.cs @@ -215,7 +215,7 @@ namespace Server.Mobiles public static void GiveArtifactTo(Mobile m) { - var item = (Item)ActivatorUtil.CreateInstance(Artifacts.RandomElement()); + var item = Artifacts.RandomElement().CreateInstance(); if (m.AddToBackpack(item)) { diff --git a/Projects/UOContent/Mobiles/Vendors/BeverageBuy.cs b/Projects/UOContent/Mobiles/Vendors/BeverageBuy.cs index 90e882d65..f9bfb7ee0 100644 --- a/Projects/UOContent/Mobiles/Vendors/BeverageBuy.cs +++ b/Projects/UOContent/Mobiles/Vendors/BeverageBuy.cs @@ -41,6 +41,6 @@ namespace Server.Mobiles public override bool CanCacheDisplay => false; - public override IEntity GetEntity() => (IEntity)ActivatorUtil.CreateInstance(Type, m_Content); + public override IEntity GetEntity() => Type.CreateInstance(m_Content); } } diff --git a/Projects/UOContent/Mobiles/Vendors/GenericBuy.cs b/Projects/UOContent/Mobiles/Vendors/GenericBuy.cs index 603a140cf..850ebc8ff 100644 --- a/Projects/UOContent/Mobiles/Vendors/GenericBuy.cs +++ b/Projects/UOContent/Mobiles/Vendors/GenericBuy.cs @@ -97,16 +97,7 @@ namespace Server.Mobiles public int MaxAmount { get; set; } // get a new instance of an object (we just bought it) - public virtual IEntity GetEntity() - { - if (Args == null || Args.Length == 0) - { - return (IEntity)ActivatorUtil.CreateInstance(Type); - } - - return (IEntity)ActivatorUtil.CreateInstance(Type, Args); - // return (Item)ActivatorUtil.CreateInstance( m_Type ); - } + public virtual IEntity GetEntity() => Type.CreateInstance(Args); // Attempt to restock with item, (return true if restock successful) public bool Restock(Item item, int amount) => false; diff --git a/Projects/UOContent/Mobiles/Vendors/NPC/CustomHairstylist.cs b/Projects/UOContent/Mobiles/Vendors/NPC/CustomHairstylist.cs index 090266ad4..cc7ef962d 100644 --- a/Projects/UOContent/Mobiles/Vendors/NPC/CustomHairstylist.cs +++ b/Projects/UOContent/Mobiles/Vendors/NPC/CustomHairstylist.cs @@ -265,7 +265,7 @@ namespace Server.Mobiles } } - var g = ActivatorUtil.CreateInstance(buyInfo.GumpType, args) as Gump; + var g = buyInfo.GumpType.CreateInstance(args); m_From.SendGump(g); } diff --git a/Projects/UOContent/Multis/HousePlacementTool.cs b/Projects/UOContent/Multis/HousePlacementTool.cs index cee856cfa..685c23e1c 100644 --- a/Projects/UOContent/Multis/HousePlacementTool.cs +++ b/Projects/UOContent/Multis/HousePlacementTool.cs @@ -1971,7 +1971,7 @@ namespace Server.Items args = new object[] { from }; } - return ActivatorUtil.CreateInstance(Type, args) as BaseHouse; + return Type.CreateInstance(args); } catch { diff --git a/Projects/UOContent/Regions/GuardedRegion.cs b/Projects/UOContent/Regions/GuardedRegion.cs index 6ed3b244d..64bfc9c44 100644 --- a/Projects/UOContent/Regions/GuardedRegion.cs +++ b/Projects/UOContent/Regions/GuardedRegion.cs @@ -181,7 +181,7 @@ namespace Server.Regions try { - ActivatorUtil.CreateInstance(m_GuardType, m_GuardParams); + m_GuardType.CreateInstance(m_GuardParams); } catch { diff --git a/Projects/UOContent/Spells/Base/SpellRegistry.cs b/Projects/UOContent/Spells/Base/SpellRegistry.cs index 95ed5dbb5..dfba8fd76 100644 --- a/Projects/UOContent/Spells/Base/SpellRegistry.cs +++ b/Projects/UOContent/Spells/Base/SpellRegistry.cs @@ -91,7 +91,7 @@ namespace Server.Spells try { - spm = ActivatorUtil.CreateInstance(type) as SpecialMove; + spm = type.CreateInstance(); } catch { @@ -139,9 +139,9 @@ namespace Server.Spells try { - return (Spell)ActivatorUtil.CreateInstance(t, m_Params); + return t.CreateInstance(m_Params); } - catch (Exception e) + catch { // ignored } @@ -167,7 +167,7 @@ namespace Server.Spells try { - return (Spell)ActivatorUtil.CreateInstance(t, m_Params); + return t.CreateInstance(m_Params); } catch { diff --git a/Projects/UOContent/Spells/Fifth/SummonCreature.cs b/Projects/UOContent/Spells/Fifth/SummonCreature.cs index 83c21bc50..628eb3b49 100644 --- a/Projects/UOContent/Spells/Fifth/SummonCreature.cs +++ b/Projects/UOContent/Spells/Fifth/SummonCreature.cs @@ -68,7 +68,7 @@ namespace Server.Spells.Fifth { try { - var creature = (BaseCreature)ActivatorUtil.CreateInstance(m_Types.RandomElement()); + var creature = m_Types.RandomElement().CreateInstance(); // creature.ControlSlots = 2; diff --git a/Projects/UOContent/Spells/First/CreateFood.cs b/Projects/UOContent/Spells/First/CreateFood.cs index f41b54b13..373f21474 100644 --- a/Projects/UOContent/Spells/First/CreateFood.cs +++ b/Projects/UOContent/Spells/First/CreateFood.cs @@ -73,18 +73,16 @@ namespace Server.Spells.First public Item Create() { - Item item; - try { - item = (Item)ActivatorUtil.CreateInstance(Type); + return Type.CreateInstance(); } catch { - item = null; + // ignored } - return item; + return null; } } } diff --git a/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs b/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs index cc5190c7b..61c73edfe 100644 --- a/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs +++ b/Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs @@ -343,7 +343,7 @@ namespace Server.Spells.Necromancy try { - summoned = ActivatorUtil.CreateInstance(toSummon) as Mobile; + summoned = toSummon.CreateInstance(); } catch { diff --git a/Projects/UOContent/Spells/Necromancy/SummonFamiliar.cs b/Projects/UOContent/Spells/Necromancy/SummonFamiliar.cs index 7d71522e3..27b599dfa 100644 --- a/Projects/UOContent/Spells/Necromancy/SummonFamiliar.cs +++ b/Projects/UOContent/Spells/Necromancy/SummonFamiliar.cs @@ -181,7 +181,7 @@ namespace Server.Spells.Necromancy { try { - var bc = (BaseCreature)ActivatorUtil.CreateInstance(entry.Type); + var bc = entry.Type.CreateInstance(); // TODO: Is this right? bc.Skills.MagicResist.Base = m_From.Skills.MagicResist.Base; diff --git a/Projects/UOContent/Spells/Spellweaving/ArcaneSummon.cs b/Projects/UOContent/Spells/Spellweaving/ArcaneSummon.cs index 7d12aeafc..675234594 100644 --- a/Projects/UOContent/Spells/Spellweaving/ArcaneSummon.cs +++ b/Projects/UOContent/Spells/Spellweaving/ArcaneSummon.cs @@ -42,7 +42,7 @@ namespace Server.Spells.Spellweaving try { - bc = ActivatorUtil.CreateInstance(); + bc = typeof(T).CreateInstance(); } catch {