Implement IGameSaveTraitData on BotModules.
This commit is contained in:
@@ -125,7 +125,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public override object Create(ActorInitializer init) { return new BaseBuilderBotModule(init.Self, this); }
|
||||
}
|
||||
|
||||
public class BaseBuilderBotModule : ConditionalTrait<BaseBuilderBotModuleInfo>, IBotTick, IBotPositionsUpdated, IBotRespondToAttack, IBotRequestPauseUnitProduction
|
||||
public class BaseBuilderBotModule : ConditionalTrait<BaseBuilderBotModuleInfo>, IGameSaveTraitData,
|
||||
IBotTick, IBotPositionsUpdated, IBotRespondToAttack, IBotRequestPauseUnitProduction
|
||||
{
|
||||
public CPos GetRandomBaseCenter()
|
||||
{
|
||||
@@ -268,5 +269,31 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return AIUtils.CountBuildingByCommonName(Info.BarracksTypes, player) > 0 ? 2 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
List<MiniYamlNode> IGameSaveTraitData.IssueTraitData(Actor self)
|
||||
{
|
||||
if (IsTraitDisabled)
|
||||
return null;
|
||||
|
||||
return new List<MiniYamlNode>()
|
||||
{
|
||||
new MiniYamlNode("InitialBaseCenter", FieldSaver.FormatValue(initialBaseCenter)),
|
||||
new MiniYamlNode("DefenseCenter", FieldSaver.FormatValue(defenseCenter))
|
||||
};
|
||||
}
|
||||
|
||||
void IGameSaveTraitData.ResolveTraitData(Actor self, List<MiniYamlNode> data)
|
||||
{
|
||||
if (self.World.IsReplay)
|
||||
return;
|
||||
|
||||
var initialBaseCenterNode = data.FirstOrDefault(n => n.Key == "InitialBaseCenter");
|
||||
if (initialBaseCenterNode != null)
|
||||
initialBaseCenter = FieldLoader.GetValue<CPos>("InitialBaseCenter", initialBaseCenterNode.Value.Value);
|
||||
|
||||
var defenseCenterNode = data.FirstOrDefault(n => n.Key == "DefenseCenter");
|
||||
if (defenseCenterNode != null)
|
||||
defenseCenter = FieldLoader.GetValue<CPos>("DefenseCenter", defenseCenterNode.Value.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public override object Create(ActorInitializer init) { return new McvManagerBotModule(init.Self, this); }
|
||||
}
|
||||
|
||||
public class McvManagerBotModule : ConditionalTrait<McvManagerBotModuleInfo>, IBotTick, IBotPositionsUpdated
|
||||
public class McvManagerBotModule : ConditionalTrait<McvManagerBotModuleInfo>, IBotTick, IBotPositionsUpdated, IGameSaveTraitData
|
||||
{
|
||||
public CPos GetRandomBaseCenter()
|
||||
{
|
||||
@@ -220,5 +220,35 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return findPos(baseCenter, baseCenter, Info.MinBaseRadius,
|
||||
distanceToBaseIsImportant ? Info.MaxBaseRadius : world.Map.Grid.MaximumTileSearchRange);
|
||||
}
|
||||
|
||||
List<MiniYamlNode> IGameSaveTraitData.IssueTraitData(Actor self)
|
||||
{
|
||||
if (IsTraitDisabled)
|
||||
return null;
|
||||
|
||||
return new List<MiniYamlNode>()
|
||||
{
|
||||
new MiniYamlNode("InitialBaseCenter", FieldSaver.FormatValue(initialBaseCenter)),
|
||||
new MiniYamlNode("ActiveMCVs", FieldSaver.FormatValue(activeMCVs.Select(a => a.ActorID).ToArray()))
|
||||
};
|
||||
}
|
||||
|
||||
void IGameSaveTraitData.ResolveTraitData(Actor self, List<MiniYamlNode> data)
|
||||
{
|
||||
if (self.World.IsReplay)
|
||||
return;
|
||||
|
||||
var initialBaseCenterNode = data.FirstOrDefault(n => n.Key == "InitialBaseCenter");
|
||||
if (initialBaseCenterNode != null)
|
||||
initialBaseCenter = FieldLoader.GetValue<CPos>("InitialBaseCenter", initialBaseCenterNode.Value.Value);
|
||||
|
||||
var activeMCVsNode = data.FirstOrDefault(n => n.Key == "ActiveMCVs");
|
||||
if (activeMCVsNode != null)
|
||||
{
|
||||
activeMCVs.Clear();
|
||||
activeMCVs.AddRange(FieldLoader.GetValue<uint[]>("ActiveMCVs", activeMCVsNode.Value.Value)
|
||||
.Select(a => world.GetActorById(a)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public override object Create(ActorInitializer init) { return new SquadManagerBotModule(init.Self, this); }
|
||||
}
|
||||
|
||||
public class SquadManagerBotModule : ConditionalTrait<SquadManagerBotModuleInfo>, IBotTick, IBotRespondToAttack, IBotPositionsUpdated
|
||||
public class SquadManagerBotModule : ConditionalTrait<SquadManagerBotModuleInfo>, IBotEnabled, IBotTick, IBotRespondToAttack, IBotPositionsUpdated, IGameSaveTraitData
|
||||
{
|
||||
public CPos GetRandomBaseCenter()
|
||||
{
|
||||
@@ -95,6 +95,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public List<Squad> Squads = new List<Squad>();
|
||||
|
||||
IBot bot;
|
||||
IBotPositionsUpdated[] notifyPositionsUpdated;
|
||||
IBotNotifyIdleBaseUnits[] notifyIdleBaseUnits;
|
||||
|
||||
@@ -140,6 +141,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
minAttackForceDelayTicks = World.LocalRandom.Next(0, Info.MinimumAttackForceDelay);
|
||||
}
|
||||
|
||||
void IBotEnabled.BotEnabled(IBot bot)
|
||||
{
|
||||
this.bot = bot;
|
||||
}
|
||||
|
||||
void IBotTick.BotTick(IBot bot)
|
||||
{
|
||||
AssignRolesToIdleUnits(bot);
|
||||
@@ -341,5 +347,73 @@ namespace OpenRA.Mods.Common.Traits
|
||||
ProtectOwn(bot, e.Attacker);
|
||||
}
|
||||
}
|
||||
|
||||
List<MiniYamlNode> IGameSaveTraitData.IssueTraitData(Actor self)
|
||||
{
|
||||
if (IsTraitDisabled)
|
||||
return null;
|
||||
|
||||
return new List<MiniYamlNode>()
|
||||
{
|
||||
new MiniYamlNode("Squads", "", Squads.Select(s => new MiniYamlNode("Squad", s.Serialize())).ToList()),
|
||||
new MiniYamlNode("InitialBaseCenter", FieldSaver.FormatValue(initialBaseCenter)),
|
||||
new MiniYamlNode("UnitsHangingAroundTheBase", FieldSaver.FormatValue(unitsHangingAroundTheBase.Select(a => a.ActorID).ToArray())),
|
||||
new MiniYamlNode("ActiveUnits", FieldSaver.FormatValue(activeUnits.Select(a => a.ActorID).ToArray())),
|
||||
new MiniYamlNode("RushTicks", FieldSaver.FormatValue(rushTicks)),
|
||||
new MiniYamlNode("AssignRolesTicks", FieldSaver.FormatValue(assignRolesTicks)),
|
||||
new MiniYamlNode("AttackForceTicks", FieldSaver.FormatValue(attackForceTicks)),
|
||||
new MiniYamlNode("MinAttackForceDelayTicks", FieldSaver.FormatValue(minAttackForceDelayTicks)),
|
||||
};
|
||||
}
|
||||
|
||||
void IGameSaveTraitData.ResolveTraitData(Actor self, List<MiniYamlNode> data)
|
||||
{
|
||||
if (self.World.IsReplay)
|
||||
return;
|
||||
|
||||
var initialBaseCenterNode = data.FirstOrDefault(n => n.Key == "InitialBaseCenter");
|
||||
if (initialBaseCenterNode != null)
|
||||
initialBaseCenter = FieldLoader.GetValue<CPos>("InitialBaseCenter", initialBaseCenterNode.Value.Value);
|
||||
|
||||
var unitsHangingAroundTheBaseNode = data.FirstOrDefault(n => n.Key == "UnitsHangingAroundTheBase");
|
||||
if (unitsHangingAroundTheBaseNode != null)
|
||||
{
|
||||
unitsHangingAroundTheBase.Clear();
|
||||
unitsHangingAroundTheBase.AddRange(FieldLoader.GetValue<uint[]>("UnitsHangingAroundTheBase", unitsHangingAroundTheBaseNode.Value.Value)
|
||||
.Select(a => self.World.GetActorById(a)));
|
||||
}
|
||||
|
||||
var activeUnitsNode = data.FirstOrDefault(n => n.Key == "ActiveUnits");
|
||||
if (activeUnitsNode != null)
|
||||
{
|
||||
activeUnits.Clear();
|
||||
activeUnits.AddRange(FieldLoader.GetValue<uint[]>("ActiveUnits", activeUnitsNode.Value.Value)
|
||||
.Select(a => self.World.GetActorById(a)));
|
||||
}
|
||||
|
||||
var rushTicksNode = data.FirstOrDefault(n => n.Key == "RushTicks");
|
||||
if (rushTicksNode != null)
|
||||
rushTicks = FieldLoader.GetValue<int>("RushTicks", rushTicksNode.Value.Value);
|
||||
|
||||
var assignRolesTicksNode = data.FirstOrDefault(n => n.Key == "AssignRolesTicks");
|
||||
if (assignRolesTicksNode != null)
|
||||
assignRolesTicks = FieldLoader.GetValue<int>("AssignRolesTicks", assignRolesTicksNode.Value.Value);
|
||||
|
||||
var attackForceTicksNode = data.FirstOrDefault(n => n.Key == "AttackForceTicks");
|
||||
if (attackForceTicksNode != null)
|
||||
attackForceTicks = FieldLoader.GetValue<int>("AttackForceTicks", attackForceTicksNode.Value.Value);
|
||||
|
||||
var minAttackForceDelayTicksNode = data.FirstOrDefault(n => n.Key == "MinAttackForceDelayTicks");
|
||||
if (minAttackForceDelayTicksNode != null)
|
||||
minAttackForceDelayTicks = FieldLoader.GetValue<int>("MinAttackForceDelayTicks", minAttackForceDelayTicksNode.Value.Value);
|
||||
|
||||
var squadsNode = data.FirstOrDefault(n => n.Key == "Squads");
|
||||
if (squadsNode != null)
|
||||
{
|
||||
Squads.Clear();
|
||||
foreach (var n in squadsNode.Value.Nodes)
|
||||
Squads.Add(Squad.Deserialize(bot, this, n.Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,5 +86,42 @@ namespace OpenRA.Mods.Common.Traits.BotModules.Squads
|
||||
}
|
||||
|
||||
public WPos CenterPosition { get { return Units.Select(u => u.CenterPosition).Average(); } }
|
||||
|
||||
public MiniYaml Serialize()
|
||||
{
|
||||
var nodes = new MiniYaml("", new List<MiniYamlNode>()
|
||||
{
|
||||
new MiniYamlNode("Type", FieldSaver.FormatValue(Type)),
|
||||
new MiniYamlNode("Units", FieldSaver.FormatValue(Units.Select(a => a.ActorID).ToArray())),
|
||||
});
|
||||
|
||||
if (Target.Type == TargetType.Actor)
|
||||
nodes.Nodes.Add(new MiniYamlNode("Target", FieldSaver.FormatValue(Target.Actor.ActorID)));
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
public static Squad Deserialize(IBot bot, SquadManagerBotModule squadManager, MiniYaml yaml)
|
||||
{
|
||||
var type = SquadType.Rush;
|
||||
Actor targetActor = null;
|
||||
|
||||
var typeNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Type");
|
||||
if (typeNode != null)
|
||||
type = FieldLoader.GetValue<SquadType>("Type", typeNode.Value.Value);
|
||||
|
||||
var targetNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Target");
|
||||
if (targetNode != null)
|
||||
targetActor = squadManager.World.GetActorById(FieldLoader.GetValue<uint>("ActiveUnits", targetNode.Value.Value));
|
||||
|
||||
var squad = new Squad(bot, squadManager, type, targetActor);
|
||||
|
||||
var unitsNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Units");
|
||||
if (unitsNode != null)
|
||||
squad.Units.AddRange(FieldLoader.GetValue<uint[]>("Units", unitsNode.Value.Value)
|
||||
.Select(a => squadManager.World.GetActorById(a)));
|
||||
|
||||
return squad;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public override object Create(ActorInitializer init) { return new SupportPowerBotModule(init.Self, this); }
|
||||
}
|
||||
|
||||
public class SupportPowerBotModule : ConditionalTrait<SupportPowerBotModuleInfo>, IBotTick
|
||||
public class SupportPowerBotModule : ConditionalTrait<SupportPowerBotModuleInfo>, IBotTick, IGameSaveTraitData
|
||||
{
|
||||
readonly World world;
|
||||
readonly Player player;
|
||||
@@ -185,5 +185,31 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
return bestLocation;
|
||||
}
|
||||
|
||||
List<MiniYamlNode> IGameSaveTraitData.IssueTraitData(Actor self)
|
||||
{
|
||||
if (IsTraitDisabled)
|
||||
return null;
|
||||
|
||||
var waitingPowersNodes = waitingPowers
|
||||
.Select(kv => new MiniYamlNode(kv.Key.Key, FieldSaver.FormatValue(kv.Value)))
|
||||
.ToList();
|
||||
|
||||
return new List<MiniYamlNode>()
|
||||
{
|
||||
new MiniYamlNode("WaitingPowers", "", waitingPowersNodes)
|
||||
};
|
||||
}
|
||||
|
||||
void IGameSaveTraitData.ResolveTraitData(Actor self, List<MiniYamlNode> data)
|
||||
{
|
||||
if (self.World.IsReplay)
|
||||
return;
|
||||
|
||||
var waitingPowersNode = data.FirstOrDefault(n => n.Key == "WaitingPowers");
|
||||
if (waitingPowersNode != null)
|
||||
foreach (var n in waitingPowersNode.Value.Nodes)
|
||||
waitingPowers[supportPowerManager.Powers[n.Key]] = FieldLoader.GetValue<int>("WaitingPowers", n.Value.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public override object Create(ActorInitializer init) { return new UnitBuilderBotModule(init.Self, this); }
|
||||
}
|
||||
|
||||
public class UnitBuilderBotModule : ConditionalTrait<UnitBuilderBotModuleInfo>, IBotTick, IBotNotifyIdleBaseUnits, IBotRequestUnitProduction
|
||||
public class UnitBuilderBotModule : ConditionalTrait<UnitBuilderBotModuleInfo>, IBotTick, IBotNotifyIdleBaseUnits, IBotRequestUnitProduction, IGameSaveTraitData
|
||||
{
|
||||
public const int FeedbackTime = 30; // ticks; = a bit over 1s. must be >= netlag.
|
||||
|
||||
@@ -209,5 +209,38 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
List<MiniYamlNode> IGameSaveTraitData.IssueTraitData(Actor self)
|
||||
{
|
||||
if (IsTraitDisabled)
|
||||
return null;
|
||||
|
||||
return new List<MiniYamlNode>()
|
||||
{
|
||||
new MiniYamlNode("QueuedBuildRequests", FieldSaver.FormatValue(queuedBuildRequests.ToArray())),
|
||||
new MiniYamlNode("IdleUnits", FieldSaver.FormatValue(idleUnits.Select(a => a.ActorID).ToArray()))
|
||||
};
|
||||
}
|
||||
|
||||
void IGameSaveTraitData.ResolveTraitData(Actor self, List<MiniYamlNode> data)
|
||||
{
|
||||
if (self.World.IsReplay)
|
||||
return;
|
||||
|
||||
var queuedBuildRequestsNode = data.FirstOrDefault(n => n.Key == "QueuedBuildRequests");
|
||||
if (queuedBuildRequestsNode != null)
|
||||
{
|
||||
queuedBuildRequests.Clear();
|
||||
queuedBuildRequests.AddRange(FieldLoader.GetValue<string[]>("QueuedBuildRequests", queuedBuildRequestsNode.Value.Value));
|
||||
}
|
||||
|
||||
var idleUnitsNode = data.FirstOrDefault(n => n.Key == "IdleUnits");
|
||||
if (idleUnitsNode != null)
|
||||
{
|
||||
idleUnits.Clear();
|
||||
idleUnits.AddRange(FieldLoader.GetValue<uint[]>("IdleUnits", idleUnitsNode.Value.Value)
|
||||
.Select(a => world.GetActorById(a)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user