1 #region Copyright & License Information 2 /* 3 * Copyright 2007-2020 The OpenRA Developers (see AUTHORS) 4 * This file is part of OpenRA, which is free software. It is made 5 * available to you under the terms of the GNU General Public License 6 * as published by the Free Software Foundation, either version 3 of 7 * the License, or (at your option) any later version. For more 8 * information, see COPYING. 9 */ 10 #endregion 11 12 using System.Collections.Generic; 13 using System.Linq; 14 using OpenRA.Support; 15 using OpenRA.Traits; 16 17 namespace OpenRA.Mods.Common.Traits.BotModules.Squads 18 { 19 public enum SquadType { Assault, Air, Rush, Protection, Naval } 20 21 public class Squad 22 { 23 public List<Actor> Units = new List<Actor>(); 24 public SquadType Type; 25 26 internal IBot Bot; 27 internal World World; 28 internal SquadManagerBotModule SquadManager; 29 internal MersenneTwister Random; 30 31 internal Target Target; 32 internal StateMachine FuzzyStateMachine; 33 Squad(IBot bot, SquadManagerBotModule squadManager, SquadType type)34 public Squad(IBot bot, SquadManagerBotModule squadManager, SquadType type) 35 : this(bot, squadManager, type, null) { } 36 Squad(IBot bot, SquadManagerBotModule squadManager, SquadType type, Actor target)37 public Squad(IBot bot, SquadManagerBotModule squadManager, SquadType type, Actor target) 38 { 39 Bot = bot; 40 SquadManager = squadManager; 41 World = bot.Player.PlayerActor.World; 42 Random = World.LocalRandom; 43 Type = type; 44 Target = Target.FromActor(target); 45 FuzzyStateMachine = new StateMachine(); 46 47 switch (type) 48 { 49 case SquadType.Assault: 50 case SquadType.Rush: 51 FuzzyStateMachine.ChangeState(this, new GroundUnitsIdleState(), true); 52 break; 53 case SquadType.Air: 54 FuzzyStateMachine.ChangeState(this, new AirIdleState(), true); 55 break; 56 case SquadType.Protection: 57 FuzzyStateMachine.ChangeState(this, new UnitsForProtectionIdleState(), true); 58 break; 59 case SquadType.Naval: 60 FuzzyStateMachine.ChangeState(this, new NavyUnitsIdleState(), true); 61 break; 62 } 63 } 64 Update()65 public void Update() 66 { 67 if (IsValid) 68 FuzzyStateMachine.Update(this); 69 } 70 71 public bool IsValid { get { return Units.Any(); } } 72 73 public Actor TargetActor 74 { 75 get { return Target.Actor; } 76 set { Target = Target.FromActor(value); } 77 } 78 79 public bool IsTargetValid 80 { 81 get { return Target.IsValidFor(Units.FirstOrDefault()) && !Target.Actor.Info.HasTraitInfo<HuskInfo>(); } 82 } 83 84 public bool IsTargetVisible 85 { 86 get { return TargetActor.CanBeViewedByPlayer(Bot.Player); } 87 } 88 89 public WPos CenterPosition { get { return Units.Select(u => u.CenterPosition).Average(); } } 90 Serialize()91 public MiniYaml Serialize() 92 { 93 var nodes = new MiniYaml("", new List<MiniYamlNode>() 94 { 95 new MiniYamlNode("Type", FieldSaver.FormatValue(Type)), 96 new MiniYamlNode("Units", FieldSaver.FormatValue(Units.Select(a => a.ActorID).ToArray())), 97 }); 98 99 if (Target.Type == TargetType.Actor) 100 nodes.Nodes.Add(new MiniYamlNode("Target", FieldSaver.FormatValue(Target.Actor.ActorID))); 101 102 return nodes; 103 } 104 Deserialize(IBot bot, SquadManagerBotModule squadManager, MiniYaml yaml)105 public static Squad Deserialize(IBot bot, SquadManagerBotModule squadManager, MiniYaml yaml) 106 { 107 var type = SquadType.Rush; 108 Actor targetActor = null; 109 110 var typeNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Type"); 111 if (typeNode != null) 112 type = FieldLoader.GetValue<SquadType>("Type", typeNode.Value.Value); 113 114 var targetNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Target"); 115 if (targetNode != null) 116 targetActor = squadManager.World.GetActorById(FieldLoader.GetValue<uint>("ActiveUnits", targetNode.Value.Value)); 117 118 var squad = new Squad(bot, squadManager, type, targetActor); 119 120 var unitsNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Units"); 121 if (unitsNode != null) 122 squad.Units.AddRange(FieldLoader.GetValue<uint[]>("Units", unitsNode.Value.Value) 123 .Select(a => squadManager.World.GetActorById(a))); 124 125 return squad; 126 } 127 } 128 } 129