From 0ecaba17271d50dd5fee1e57cbea2e95b3dee994 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Wed, 8 Jul 2020 02:56:38 +1000 Subject: [PATCH] Minor AI system fixes (#1292) * Add test to check all LogicNames in prototypes * Change CreateProcessor to AiLogicProcessor (I thought I'd already done this as I remember PJB telling me to do this but apparently I'm an idiot) * Temporarily remove invalid AiControllers Co-authored-by: Metal Gear Sloth --- .../Tests/AI/AiControllerTest.cs | 67 +++++++++++++++++++ .../GameObjects/EntitySystems/AI/AiSystem.cs | 13 ++-- .../Prototypes/Entities/Buildings/turret.yml | 6 -- 3 files changed, 72 insertions(+), 14 deletions(-) create mode 100644 Content.IntegrationTests/Tests/AI/AiControllerTest.cs diff --git a/Content.IntegrationTests/Tests/AI/AiControllerTest.cs b/Content.IntegrationTests/Tests/AI/AiControllerTest.cs new file mode 100644 index 0000000000..7c2b1b3371 --- /dev/null +++ b/Content.IntegrationTests/Tests/AI/AiControllerTest.cs @@ -0,0 +1,67 @@ +using NUnit.Framework; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Interfaces.Map; +using Robust.Shared.Map; +using Robust.Shared.Prototypes; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Content.Server.GameObjects.Components.Movement; +using Content.Shared.VendingMachines; +using Robust.Server.AI; +using Robust.Shared.Log; +using Robust.Server.Interfaces.Maps; +using Robust.Server.Interfaces.Timing; +using Robust.Shared.Interfaces.Reflection; +using Robust.Shared.IoC; +using Robust.Shared.Maths; + +namespace Content.IntegrationTests.Tests +{ + [TestFixture] + [TestOf(typeof(AiControllerTest))] + public class AiControllerTest : ContentIntegrationTest + { + [Test] + public async Task AiProcessorNamesValidTest() + { + var server = StartServerDummyTicker(); + + server.Assert(() => + { + var entityManager = IoCManager.Resolve(); + var prototypeManager = IoCManager.Resolve(); + var reflectionManager = IoCManager.Resolve(); + var mapManager = IoCManager.Resolve(); + + mapManager.CreateMap(new MapId(1)); + var grid = mapManager.CreateGrid(new MapId(1)); + + var processorNames = new List(); + + // Verify they all have the required attribute + foreach (var processor in reflectionManager.GetAllChildren(typeof(AiLogicProcessor))) + { + var attrib = (AiLogicProcessorAttribute) Attribute.GetCustomAttribute(processor, typeof(AiLogicProcessorAttribute)); + Assert.That(attrib != null, $"No AiLogicProcessorAttribute found on {processor.Name}"); + processorNames.Add(attrib.SerializeName); + } + + foreach (var entity in prototypeManager.EnumeratePrototypes()) + { + var comps = entity.Components; + + if (!comps.ContainsKey("AiController")) continue; + + var aiEntity = entityManager.SpawnEntity(entity.ID, new GridCoordinates(new Vector2(0, 0), grid.Index)); + var aiController = aiEntity.GetComponent(); + Assert.That(processorNames.Contains(aiController.LogicName), $"Could not find valid processor named {aiController.LogicName} on entity {entity.ID}"); + } + }); + + await server.WaitIdleAsync(); + } + + } +} diff --git a/Content.Server/GameObjects/EntitySystems/AI/AiSystem.cs b/Content.Server/GameObjects/EntitySystems/AI/AiSystem.cs index ad5c232c9c..0c1a8d1c68 100644 --- a/Content.Server/GameObjects/EntitySystems/AI/AiSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/AI/AiSystem.cs @@ -40,17 +40,15 @@ namespace Content.Server.GameObjects.EntitySystems.AI foreach (var processor in processors) { var att = (AiLogicProcessorAttribute)Attribute.GetCustomAttribute(processor, typeof(AiLogicProcessorAttribute)); - if (att != null) - { - _processorTypes.Add(att.SerializeName, processor); - } + // Tests should pick this up + DebugTools.AssertNotNull(att); + _processorTypes.Add(att.SerializeName, processor); } } /// public override void Update(float frameTime) { - var entities = EntityManager.GetEntities(EntityQuery); foreach (var entity in entities) { @@ -77,15 +75,14 @@ namespace Content.Server.GameObjects.EntitySystems.AI if (controller.Processor != null) return; controller.Processor = CreateProcessor(controller.LogicName); controller.Processor.SelfEntity = controller.Owner; - controller.Processor.VisionRadius = controller.VisionRadius; controller.Processor.Setup(); } - private UtilityAi CreateProcessor(string name) + private AiLogicProcessor CreateProcessor(string name) { if (_processorTypes.TryGetValue(name, out var type)) { - return (UtilityAi)_typeFactory.CreateInstance(type); + return (AiLogicProcessor)_typeFactory.CreateInstance(type); } // processor needs to inherit AiLogicProcessor, and needs an AiLogicProcessorAttribute to define the YAML name diff --git a/Resources/Prototypes/Entities/Buildings/turret.yml b/Resources/Prototypes/Entities/Buildings/turret.yml index 2077f7f18b..a778418bfa 100644 --- a/Resources/Prototypes/Entities/Buildings/turret.yml +++ b/Resources/Prototypes/Entities/Buildings/turret.yml @@ -19,9 +19,6 @@ drawdepth: WallMountedItems texture: Buildings/TurrTop.png directional: false - - type: AiController - logic: AimShootLife - vision: 6.0 - type: entity id: TurretTopLight @@ -34,9 +31,6 @@ drawdepth: WallMountedItems texture: Buildings/TurrLamp.png directional: false - - type: AiController - logic: AimShootLife - vision: 6.0 - type: PointLight radius: 512 mask: flashlight_mask