diff --git a/src/Perpetuum.ExportedTypes/CategoryFlags.cs b/src/Perpetuum.ExportedTypes/CategoryFlags.cs index 6d3e1d20b..a67d1b043 100644 --- a/src/Perpetuum.ExportedTypes/CategoryFlags.cs +++ b/src/Perpetuum.ExportedTypes/CategoryFlags.cs @@ -53,6 +53,12 @@ public enum CategoryFlags : long cf_command_robots = 0x0000000000001001, cf_combat_command_robots = 0x0000000000011001, + cf_drones = 0x0000000000001101, + cf_assault_drones = 0x0000000000011101, + cf_industrial_drones = 0x0000000000021101, + cf_support_drones = 0x0000000000031101, + cf_attack_drones = 0x0000000000041101, + cf_ammo = 0x000000000000000A, cf_railgun_ammo = 0x000000000000010A, cf_small_railgun_ammo = 0x000000000001010A, @@ -193,6 +199,7 @@ public enum CategoryFlags : long cf_energy_warfare_upgrades = 0x00000000000D030F, cf_reactor_sealings = 0x00000000000E030F, cf_landmine_detectors = 0x00000000000F030F, + cf_jumpers = 0x000000000010030F, cf_electronics_equipment = 0x000000000000040F, cf_sensor_boosters = 0x000000000001040F, cf_remote_sensor_boosters = 0x000000000002040F, @@ -611,10 +618,6 @@ public enum CategoryFlags : long cf_mining_turrets = 0x0000000000000E92, cf_harvesting_turrets = 0x0000000000000F92, cf_combat_drones = 0x0000000000001092, - cf_assault_drones = 0x0000000000001192, - cf_industrial_drones = 0x0000000000001292, - cf_support_drones = 0x0000000000001392, - cf_attack_drones = 0x0000000000001492, cf_production_items = 0x0000000000000094, cf_research_kits = 0x0000000000000194, diff --git a/src/Perpetuum.RequestHandlers/EquipModule.cs b/src/Perpetuum.RequestHandlers/EquipModule.cs index a78354ffd..6511ebcda 100644 --- a/src/Perpetuum.RequestHandlers/EquipModule.cs +++ b/src/Perpetuum.RequestHandlers/EquipModule.cs @@ -1,5 +1,3 @@ -using System.Collections.Generic; -using System.Transactions; using Perpetuum.Containers; using Perpetuum.Data; using Perpetuum.EntityFramework; @@ -7,6 +5,8 @@ using Perpetuum.Items; using Perpetuum.Modules; using Perpetuum.Robots; +using System.Collections.Generic; +using System.Transactions; namespace Perpetuum.RequestHandlers { @@ -15,7 +15,7 @@ public class EquipModule : IRequestHandler private readonly IEntityRepository _entityRepository; private readonly RobotHelper _robotHelper; - public EquipModule(IEntityRepository entityRepository,RobotHelper robotHelper) + public EquipModule(IEntityRepository entityRepository, RobotHelper robotHelper) { _entityRepository = entityRepository; _robotHelper = robotHelper; @@ -23,27 +23,27 @@ public EquipModule(IEntityRepository entityRepository,RobotHelper robotHelper) public void HandleRequest(IRequest request) { - using (var scope = Db.CreateTransaction()) + using (TransactionScope scope = Db.CreateTransaction()) { - var character = request.Session.Character; + Accounting.Characters.Character character = request.Session.Character; character.IsDocked.ThrowIfFalse(ErrorCodes.CharacterHasToBeDocked); - var containerEid = request.Data.GetOrDefault(k.containerEID); - var container = Container.GetWithItems(containerEid, character).ThrowIfNull(ErrorCodes.ContainerNotFound); + long containerEid = request.Data.GetOrDefault(k.containerEID); + Container container = Container.GetWithItems(containerEid, character).ThrowIfNull(ErrorCodes.ContainerNotFound); container.ThrowIfType(ErrorCodes.AccessDenied); - var robotEid = request.Data.GetOrDefault(k.robotEID); - var robot = _robotHelper.LoadRobotOrThrow(robotEid); + long robotEid = request.Data.GetOrDefault(k.robotEID); + Robot robot = _robotHelper.LoadRobotOrThrow(robotEid); robot.IsSingleAndUnpacked.ThrowIfFalse(ErrorCodes.RobotMustbeSingleAndNonRepacked); robot.Initialize(character); - var slot = request.Data.GetOrDefault(k.slot); - var componentType = request.Data.GetOrDefault(k.robotComponent).ToEnum(); - var component = robot.GetRobotComponentOrThrow(componentType); + int slot = request.Data.GetOrDefault(k.slot); + RobotComponentType componentType = request.Data.GetOrDefault(k.robotComponent).ToEnum(); + RobotComponent component = robot.GetRobotComponentOrThrow(componentType); component.MakeSlotFree(slot, container); - var moduleEid = request.Data.GetOrDefault(k.moduleEID); - var module = (Module)container.GetItemOrThrow(moduleEid).Unstack(1); - component.EquipModuleOrThrow(module, slot); + long moduleEid = request.Data.GetOrDefault(k.moduleEID); + Module module = (Module)container.GetItemOrThrow(moduleEid).Unstack(1); + component.EquipModuleOrThrow(module, slot, robot.Definition); robot.Initialize(character); robot.Save(); @@ -51,14 +51,14 @@ public void HandleRequest(IRequest request) Transaction.Current.OnCompleted(completed => { - var result = new Dictionary + Dictionary result = new Dictionary { - {k.robot, robot.ToDictionary()}, + {k.robot, robot.ToDictionary()}, {k.container, container.ToDictionary()} }; Message.Builder.FromRequest(request).WithData(result).WrapToResult().Send(); }); - + scope.Complete(); } } diff --git a/src/Perpetuum.RequestHandlers/FittingPreset/FittingPresetApply.cs b/src/Perpetuum.RequestHandlers/FittingPreset/FittingPresetApply.cs index 3811a9c3d..6436133b9 100644 --- a/src/Perpetuum.RequestHandlers/FittingPreset/FittingPresetApply.cs +++ b/src/Perpetuum.RequestHandlers/FittingPreset/FittingPresetApply.cs @@ -1,5 +1,3 @@ -using System.Collections.Generic; -using System.Linq; using Perpetuum.Containers; using Perpetuum.Data; using Perpetuum.EntityFramework; @@ -8,6 +6,8 @@ using Perpetuum.Items.Ammos; using Perpetuum.Modules; using Perpetuum.Robots; +using System.Collections.Generic; +using System.Linq; namespace Perpetuum.RequestHandlers.FittingPreset { @@ -16,7 +16,7 @@ public class FittingPresetApply : FittingPresetRequestHandler private readonly IEntityRepository _entityRepository; private readonly RobotHelper _robotHelper; - public FittingPresetApply(IEntityRepository entityRepository,RobotHelper robotHelper) + public FittingPresetApply(IEntityRepository entityRepository, RobotHelper robotHelper) { _entityRepository = entityRepository; _robotHelper = robotHelper; @@ -24,43 +24,47 @@ public FittingPresetApply(IEntityRepository entityRepository,RobotHelper robotHe public override void HandleRequest(IRequest request) { - using (var scope = Db.CreateTransaction()) + using (System.Transactions.TransactionScope scope = Db.CreateTransaction()) { - var id = request.Data.GetOrDefault(k.ID); - var robotEid = request.Data.GetOrDefault(k.robotEID); - var containerEid = request.Data.GetOrDefault(k.containerEID); - var forCorporation = request.Data.GetOrDefault(k.forCorporation).ToBool(); + int id = request.Data.GetOrDefault(k.ID); + long robotEid = request.Data.GetOrDefault(k.robotEID); + long containerEid = request.Data.GetOrDefault(k.containerEID); + bool forCorporation = request.Data.GetOrDefault(k.forCorporation).ToBool(); - var character = request.Session.Character; - var repo = GetFittingPresetRepository(character, forCorporation); - var preset = repo.Get(id); - var robot = _robotHelper.LoadRobotForCharacter(robotEid, character); + Accounting.Characters.Character character = request.Session.Character; + Robots.Fitting.IFittingPresetRepository repo = GetFittingPresetRepository(character, forCorporation); + Robots.Fitting.FittingPreset preset = repo.Get(id); + Robot robot = _robotHelper.LoadRobotForCharacter(robotEid, character); robot.ED.ThrowIfNotEqual(preset.Robot, ErrorCodes.WTFErrorMedicalAttentionSuggested); - var container = Container.GetWithItems(containerEid, character); + Container container = Container.GetWithItems(containerEid, character); robot.EmptyRobot(character, container, false); robot.Initialize(character); - foreach (var moduleInfos in preset.Modules.GroupBy(i => i.Component)) + foreach (IGrouping moduleInfos in preset.Modules.GroupBy(i => i.Component)) { - var component = robot.GetRobotComponent((RobotComponentType) moduleInfos.Key).ThrowIfNull(ErrorCodes.ItemNotFound); + RobotComponent component = robot.GetRobotComponent(moduleInfos.Key).ThrowIfNull(ErrorCodes.ItemNotFound); - foreach (var moduleInfo in moduleInfos) + foreach (Robots.Fitting.FittingPreset.ModuleInfo moduleInfo in moduleInfos) { - var module = container.GetItems().OfType().FirstOrDefault(m => m.ED == moduleInfo.Module); + Module module = container.GetItems().OfType().FirstOrDefault(m => m.ED == moduleInfo.Module); if (module == null) + { continue; + } module = (Module)module.Unstack(1); if (module is ActiveModule activeModule && moduleInfo.Ammo != EntityDefault.None) { - var ammo = (Ammo)container.GetAndRemoveItemByDefinition(moduleInfo.Ammo.Definition, activeModule.AmmoCapacity); + Ammo ammo = (Ammo)container.GetAndRemoveItemByDefinition(moduleInfo.Ammo.Definition, activeModule.AmmoCapacity); if (ammo != null) + { activeModule.SetAmmo(ammo); + } } - component.EquipModuleOrThrow(module, moduleInfo.Slot); + component.EquipModuleOrThrow(module, moduleInfo.Slot, robot.Definition); } } @@ -69,13 +73,13 @@ public override void HandleRequest(IRequest request) robot.Save(); container.Save(); - var result = new Dictionary + Dictionary result = new Dictionary { {k.robot, robot.ToDictionary()}, {k.container, container.ToDictionary()} }; Message.Builder.FromRequest(request).WithData(result).Send(); - + scope.Complete(); } } diff --git a/src/Perpetuum.RequestHandlers/Zone/Containers/EquipModule.cs b/src/Perpetuum.RequestHandlers/Zone/Containers/EquipModule.cs index d0eaefcb3..3ee529d58 100644 --- a/src/Perpetuum.RequestHandlers/Zone/Containers/EquipModule.cs +++ b/src/Perpetuum.RequestHandlers/Zone/Containers/EquipModule.cs @@ -11,20 +11,22 @@ public class EquipModule : ZoneChangeModule { public override void DoChange(IZoneRequest request, Player player, Container container) { - var componentType = request.Data.GetOrDefault(k.robotComponent).ToEnum(); - var component = player.GetRobotComponentOrThrow(componentType); - var slot = request.Data.GetOrDefault(k.slot); + RobotComponentType componentType = request.Data.GetOrDefault(k.robotComponent).ToEnum(); + RobotComponent component = player.GetRobotComponentOrThrow(componentType); + int slot = request.Data.GetOrDefault(k.slot); component.GetModule(slot).ThrowIfNotNull(ErrorCodes.UsedSlot); //OPP: explicitly prohibit this to make this simpler // component.MakeSlotFree(slot, container); // Big nope - var moduleEid = request.Data.GetOrDefault(k.moduleEID); - var module = (Module)container.GetItemOrThrow(moduleEid).Unstack(1); + long moduleEid = request.Data.GetOrDefault(k.moduleEID); + Module module = (Module)container.GetItemOrThrow(moduleEid).Unstack(1); module.CheckEnablerExtensionsAndThrowIfFailed(player.Character); //Perform pre-fit check for fitting legality player.CheckEnergySystemAndThrowIfFailed(module); - component.EquipModuleOrThrow(module, slot); + Robot robot = player; + + component.EquipModuleOrThrow(module, slot, robot.Definition); } } } \ No newline at end of file diff --git a/src/Perpetuum/EntityFramework/EntityDefaultOptions.cs b/src/Perpetuum/EntityFramework/EntityDefaultOptions.cs index ad71cecd8..20aeff02a 100644 --- a/src/Perpetuum/EntityFramework/EntityDefaultOptions.cs +++ b/src/Perpetuum/EntityFramework/EntityDefaultOptions.cs @@ -162,6 +162,17 @@ public Faction Faction } } + public int[] AllowedBots + { + get + { + int[] ids = _dictionary.GetOrDefault(k.AllowedBots, Array.Empty()); + Debug.Assert(ids.Length > 0); + + return ids; + } + } + public int PlasmaDefinition => _dictionary.GetOrDefault(k.PlasmaDefinition); public int PlasmaConsumption => _dictionary.GetOrDefault(k.PlasmaConsumption); diff --git a/src/Perpetuum/ErrorCodes.cs b/src/Perpetuum/ErrorCodes.cs index 5335ea05d..8d5324cf1 100644 --- a/src/Perpetuum/ErrorCodes.cs +++ b/src/Perpetuum/ErrorCodes.cs @@ -717,5 +717,6 @@ public enum ErrorCodes NoxTeleportForbidden, PlasmaNotFound, Overheat, + NotAllowedOnThisBot, } } diff --git a/src/Perpetuum/Keywords.cs b/src/Perpetuum/Keywords.cs index bbe4fecf4..10ec1a5ec 100644 --- a/src/Perpetuum/Keywords.cs +++ b/src/Perpetuum/Keywords.cs @@ -1228,5 +1228,8 @@ public class k // Plasma-based modules public const string PlasmaDefinition = "plasmaDefinition"; public const string PlasmaConsumption = "plasmaConsumption"; + + // Allowed bots for this equipment + public const string AllowedBots = "allowedBots"; } } \ No newline at end of file diff --git a/src/Perpetuum/Robots/Robot.cs b/src/Perpetuum/Robots/Robot.cs index e64e84224..76ed6fe0b 100644 --- a/src/Perpetuum/Robots/Robot.cs +++ b/src/Perpetuum/Robots/Robot.cs @@ -403,12 +403,25 @@ protected override void OnBeforeRemovedFromZone(IZone zone) base.OnBeforeRemovedFromZone(zone); } + //TODO: review if it's still has to be Lazy private void InitComponents() { + //Peanuts Plague components = new Lazy>(() => Children.OfType().ToArray()); + _ = components.Value; // force evaluation robotComponents = new Lazy>(() => Components.OfType().ToArray()); - modules = new Lazy>(() => RobotComponents.SelectMany(c => c.Modules).ToArray()); + _ = robotComponents.Value; // force evaluation + modules = new Lazy>(() => RobotComponents + .SelectMany(c => + { + c.Initialize(); + + return c.Modules; + }) + .ToArray()); + _ = modules.Value; // force evaluation activeModules = new Lazy>(() => Modules.OfType().ToArray()); + _ = activeModules.Value; // force evaluation } protected override void OnEnterZone(IZone zone, ZoneEnterType enterType) diff --git a/src/Perpetuum/Robots/RobotComponent.cs b/src/Perpetuum/Robots/RobotComponent.cs index dad5fbdce..4bae73873 100644 --- a/src/Perpetuum/Robots/RobotComponent.cs +++ b/src/Perpetuum/Robots/RobotComponent.cs @@ -45,8 +45,10 @@ public override void Initialize() private void InitModules() { - modules = new Lazy>(() => Children.OfType().ToArray()); - activeModules = new Lazy>(() => Modules.OfType().ToArray()); + modules = new Lazy>(() => Children.OfType().ToArray(), isThreadSafe: true); + _ = modules.Value; + activeModules = new Lazy>(() => Modules.OfType().ToArray(), isThreadSafe: true); + _ = activeModules.Value; } public override void AcceptVisitor(IEntityVisitor visitor) @@ -129,24 +131,31 @@ public bool IsValidSlotTo(Module module, int slot) (!specializedSlot || specializedModule); } - public ErrorCodes CanEquipModule(Module module, int slot) + public ErrorCodes CanEquipModule(Module module, int slot, int robotDefinition = 0) { - return IsUsedSlot(slot) - ? ErrorCodes.UsedSlot - : !IsValidSlotTo(module, slot) - ? ErrorCodes.InvalidSlot - : module.Quantity <= 0 - ? ErrorCodes.WTFErrorMedicalAttentionSuggested - : module.IsDamaged - ? ErrorCodes.ItemHasToBeRepaired - : !CheckUniqueModule(module) - ? ErrorCodes.OnlyOnePerCategoryPerRobotAllowed - : ErrorCodes.NoError; + return IsRobotAllowed(module, robotDefinition) + ? ErrorCodes.NotAllowedOnThisBot + : IsUsedSlot(slot) + ? ErrorCodes.UsedSlot + : !IsValidSlotTo(module, slot) + ? ErrorCodes.InvalidSlot + : module.Quantity <= 0 + ? ErrorCodes.WTFErrorMedicalAttentionSuggested + : module.IsDamaged + ? ErrorCodes.ItemHasToBeRepaired + : !CheckUniqueModule(module) + ? ErrorCodes.OnlyOnePerCategoryPerRobotAllowed + : ErrorCodes.NoError; } - public void EquipModuleOrThrow(Module module, int slot) + private bool IsRobotAllowed(Module module, int robotDefinition = 0) { - _ = CanEquipModule(module, slot).ThrowIfError(); + return module.ED.Options.AllowedBots.Length > 0 && !module.ED.Options.AllowedBots.Contains(robotDefinition); + } + + public void EquipModuleOrThrow(Module module, int slot, int robotDefinition = 0) + { + _ = CanEquipModule(module, slot, robotDefinition).ThrowIfError(); EquipModule(module, slot); } diff --git a/src/Perpetuum/Zones/LandMines/LandMine.cs b/src/Perpetuum/Zones/LandMines/LandMine.cs index 693c9c509..be742e5a0 100644 --- a/src/Perpetuum/Zones/LandMines/LandMine.cs +++ b/src/Perpetuum/Zones/LandMines/LandMine.cs @@ -113,10 +113,6 @@ public override void AcceptVisitor(IEntityVisitor visitor) } } - public override void OnUnitsFound(List unitsFound) - { - } - protected override ProximityDeviceBase GetThis() { return this; diff --git a/src/Perpetuum/Zones/ProximityProbes/ProximityDevice.cs b/src/Perpetuum/Zones/ProximityProbes/ProximityDevice.cs index de46dd763..5539bcac4 100644 --- a/src/Perpetuum/Zones/ProximityProbes/ProximityDevice.cs +++ b/src/Perpetuum/Zones/ProximityProbes/ProximityDevice.cs @@ -158,8 +158,6 @@ public virtual void OnDeviceCreated() public abstract void OnUnitsFound(List unitsFound); - - public abstract void OnUnitsFound(List unitsFound); #endregion protected override void OnDead(Unit killer) diff --git a/src/Perpetuum/Zones/ProximityProbes/ProximityProbe.cs b/src/Perpetuum/Zones/ProximityProbes/ProximityProbe.cs index 822a00bdc..2f8a32874 100644 --- a/src/Perpetuum/Zones/ProximityProbes/ProximityProbe.cs +++ b/src/Perpetuum/Zones/ProximityProbes/ProximityProbe.cs @@ -79,11 +79,11 @@ public Dictionary CreateInfoDictionaryForProximityProbe(List unitsFound) + public override void OnUnitsFound(List unitsFound) { - //itt lehet mindenfele, pl most kuldunk egy kommandot amire a kliens terkepet frissit + List playersFound = unitsFound.Cast().ToList(); - if (unitsFound.Count <= 0) + if (playersFound.Count <= 0) { return; } @@ -95,15 +95,11 @@ public override void OnUnitsFound(List unitsFound) return; } - Dictionary infoDict = CreateInfoDictionaryForProximityProbe(unitsFound); + Dictionary infoDict = CreateInfoDictionaryForProximityProbe(playersFound); Message.Builder.SetCommand(Commands.ProximityProbeInfo).WithData(infoDict).ToCharacters(registerdCharacters).Send(); } - public override void OnUnitsFound(List unitsFound) - { - } - protected override ProximityDeviceBase GetThis() { return this;