diff --git a/OpenRA.Game/Widgets/ButtonWidget.cs b/OpenRA.Game/Widgets/ButtonWidget.cs index 4fc4e832cb..4bc60a33b3 100644 --- a/OpenRA.Game/Widgets/ButtonWidget.cs +++ b/OpenRA.Game/Widgets/ButtonWidget.cs @@ -23,8 +23,10 @@ namespace OpenRA.Widgets public int VisualHeight = ChromeMetrics.Get("ButtonDepth"); public string Font = ChromeMetrics.Get("ButtonFont"); public bool Disabled = false; + public bool Highlighted = false; public Func GetText; public Func IsDisabled; + public Func IsHighlighted; public Action OnMouseDown = _ => {}; public Action OnMouseUp = _ => {}; @@ -39,6 +41,7 @@ namespace OpenRA.Widgets OnMouseUp = _ => OnClick(); OnKeyPress = _ => OnClick(); IsDisabled = () => Disabled; + IsHighlighted = () => Highlighted; } protected ButtonWidget(ButtonWidget widget) @@ -52,6 +55,8 @@ namespace OpenRA.Widgets OnMouseDown = widget.OnMouseDown; Disabled = widget.Disabled; IsDisabled = widget.IsDisabled; + Highlighted = widget.Highlighted; + IsHighlighted = widget.IsHighlighted; OnMouseUp = mi => OnClick(); OnKeyPress = _ => OnClick(); @@ -124,13 +129,14 @@ namespace OpenRA.Widgets { var rb = RenderBounds; var disabled = IsDisabled(); + var highlighted = IsHighlighted(); var font = Game.Renderer.Fonts[Font]; var text = GetText(); var s = font.Measure(text); var stateOffset = (Depressed) ? new int2(VisualHeight, VisualHeight) : new int2(0, 0); - DrawBackground(rb, disabled, Depressed, Ui.MouseOverWidget == this); + DrawBackground(rb, disabled, Depressed, Ui.MouseOverWidget == this, highlighted); font.DrawText(text, new int2(rb.X + (UsableWidth - s.X)/ 2, rb.Y + (Bounds.Height - s.Y) / 2) + stateOffset, disabled ? Color.Gray : Color.White); } @@ -138,17 +144,19 @@ namespace OpenRA.Widgets public override Widget Clone() { return new ButtonWidget(this); } public virtual int UsableWidth { get { return Bounds.Width; } } - public virtual void DrawBackground(Rectangle rect, bool disabled, bool pressed, bool hover) + public virtual void DrawBackground(Rectangle rect, bool disabled, bool pressed, bool hover, bool highlighted) { - ButtonWidget.DrawBackground("button", rect, disabled, pressed, hover); + ButtonWidget.DrawBackground("button", rect, disabled, pressed, hover, highlighted); } - public static void DrawBackground(string baseName, Rectangle rect, bool disabled, bool pressed, bool hover) + public static void DrawBackground(string baseName, Rectangle rect, bool disabled, bool pressed, bool hover, bool highlighted) { var state = disabled ? "-disabled" : pressed ? "-pressed" : hover ? "-hover" : ""; + if (highlighted) + state += "-highlighted"; WidgetUtils.DrawPanel(baseName + state, rect); } diff --git a/OpenRA.Game/Widgets/ScrollPanelWidget.cs b/OpenRA.Game/Widgets/ScrollPanelWidget.cs index c896775306..365670a007 100644 --- a/OpenRA.Game/Widgets/ScrollPanelWidget.cs +++ b/OpenRA.Game/Widgets/ScrollPanelWidget.cs @@ -79,11 +79,11 @@ namespace OpenRA.Widgets var thumbHover = Ui.MouseOverWidget == this && thumbRect.Contains(Viewport.LastMousePos); WidgetUtils.DrawPanel(Background, backgroundRect); WidgetUtils.DrawPanel("scrollpanel-bg", scrollbarRect); - ButtonWidget.DrawBackground("button", upButtonRect, upDisabled, UpPressed, upHover); - ButtonWidget.DrawBackground("button", downButtonRect, downDisabled, DownPressed, downHover); + ButtonWidget.DrawBackground("button", upButtonRect, upDisabled, UpPressed, upHover, false); + ButtonWidget.DrawBackground("button", downButtonRect, downDisabled, DownPressed, downHover, false); if (thumbHeight > 0) - ButtonWidget.DrawBackground("scrollthumb", thumbRect, false, Focused && thumbHover, thumbHover); + ButtonWidget.DrawBackground("scrollthumb", thumbRect, false, Focused && thumbHover, thumbHover, false); var upOffset = !UpPressed || upDisabled ? 4 : 4 + ButtonDepth; var downOffset = !DownPressed || downDisabled ? 4 : 4 + ButtonDepth; diff --git a/OpenRA.Game/Widgets/SliderWidget.cs b/OpenRA.Game/Widgets/SliderWidget.cs index e94a04f00a..a1cf26e6be 100755 --- a/OpenRA.Game/Widgets/SliderWidget.cs +++ b/OpenRA.Game/Widgets/SliderWidget.cs @@ -118,7 +118,7 @@ namespace OpenRA.Widgets // Thumb var thumbHover = Ui.MouseOverWidget == this && tr.Contains(Viewport.LastMousePos); - ButtonWidget.DrawBackground("scrollthumb", tr, IsDisabled(), isMoving, thumbHover); + ButtonWidget.DrawBackground("scrollthumb", tr, IsDisabled(), isMoving, thumbHover, false); } } } diff --git a/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs b/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs index 3e585f4fe5..95f31484ba 100755 --- a/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs +++ b/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs @@ -138,8 +138,8 @@ namespace OpenRA.Mods.Cnc.Widgets var rightHover = Ui.MouseOverWidget == this && rightButtonRect.Contains(Viewport.LastMousePos); WidgetUtils.DrawPanel("panel-black", rb); - ButtonWidget.DrawBackground("button", leftButtonRect, leftDisabled, leftPressed, leftHover); - ButtonWidget.DrawBackground("button", rightButtonRect, rightDisabled, rightPressed, rightHover); + ButtonWidget.DrawBackground("button", leftButtonRect, leftDisabled, leftPressed, leftHover, false); + ButtonWidget.DrawBackground("button", rightButtonRect, rightDisabled, rightPressed, rightHover, false); WidgetUtils.DrawRGBA(ChromeProvider.GetImage("scrollbar", leftPressed || leftDisabled ? "left_pressed" : "left_arrow"), new float2(leftButtonRect.Left + 2, leftButtonRect.Top + 2)); @@ -157,7 +157,7 @@ namespace OpenRA.Mods.Cnc.Widgets var rect = new Rectangle(origin.X + ContentWidth, origin.Y, TabWidth, rb.Height); var hover = !leftHover && !rightHover && Ui.MouseOverWidget == this && rect.Contains(Viewport.LastMousePos); var baseName = tab.Queue == CurrentQueue ? "button-toggled" : "button"; - ButtonWidget.DrawBackground(baseName, rect, false, false, hover); + ButtonWidget.DrawBackground(baseName, rect, false, false, hover, false); ContentWidth += TabWidth - 1; int2 textSize = font.Measure(tab.Name); diff --git a/OpenRA.Mods.Cnc/Widgets/ToggleButtonWidget.cs b/OpenRA.Mods.Cnc/Widgets/ToggleButtonWidget.cs index 4b46a67956..a55a807814 100644 --- a/OpenRA.Mods.Cnc/Widgets/ToggleButtonWidget.cs +++ b/OpenRA.Mods.Cnc/Widgets/ToggleButtonWidget.cs @@ -53,10 +53,10 @@ namespace OpenRA.Mods.Cnc.Widgets tooltipContainer.Value.RemoveTooltip(); } - public override void DrawBackground(Rectangle rect, bool disabled, bool pressed, bool hover) + public override void DrawBackground(Rectangle rect, bool disabled, bool pressed, bool hover, bool highlighted) { var baseName = IsToggled() ? "button-toggled" : "button"; - ButtonWidget.DrawBackground(baseName, rect, disabled, pressed, hover); + ButtonWidget.DrawBackground(baseName, rect, disabled, pressed, hover, highlighted); } } -} \ No newline at end of file +} diff --git a/OpenRA.Mods.RA/ContainsCrate.cs b/OpenRA.Mods.RA/ContainsCrate.cs new file mode 100644 index 0000000000..694f94ccdb --- /dev/null +++ b/OpenRA.Mods.RA/ContainsCrate.cs @@ -0,0 +1,29 @@ +#region Copyright & License Information +/* + * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using OpenRA.FileFormats; +using OpenRA.Traits; + +namespace OpenRA.Mods.RA +{ + public class ContainsCrateInfo : TraitInfo { } + + public class ContainsCrate : INotifyKilled + { + public void Killed(Actor self, AttackInfo e) + { + self.World.AddFrameEndTask(w => w.CreateActor("crate", new TypeDictionary + { + new LocationInit(self.Location), + new OwnerInit(self.World.WorldActor.Owner), + })); + } + } +} diff --git a/OpenRA.Mods.RA/Crates/HealUnitsCrateAction.cs b/OpenRA.Mods.RA/Crates/HealUnitsCrateAction.cs new file mode 100644 index 0000000000..fd96a9ae80 --- /dev/null +++ b/OpenRA.Mods.RA/Crates/HealUnitsCrateAction.cs @@ -0,0 +1,39 @@ +#region Copyright & License Information +/* + * Copyright 2007-2012 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System.Linq; +using OpenRA.Traits; + +namespace OpenRA.Mods.RA.Crates +{ + class HealUnitsCrateActionInfo : CrateActionInfo + { + public override object Create(ActorInitializer init) { return new HealUnitsCrateAction(init.self, this); } + } + + class HealUnitsCrateAction : CrateAction + { + public HealUnitsCrateAction(Actor self, HealUnitsCrateActionInfo info) + : base(self, info) { } + + public override void Activate(Actor collector) + { + base.Activate(collector); + foreach (var unit in collector.World.Actors.Where(a => a.Owner == collector.Owner)) + { + var health = unit.TraitOrDefault(); + if (health != null && !health.IsDead) + { + health.InflictDamage(unit, unit, -(health.MaxHP - health.HP), null, true); + } + } + } + } +} diff --git a/OpenRA.Mods.RA/Missions/Allies01Script.cs b/OpenRA.Mods.RA/Missions/Allies01Script.cs index 4186d0934f..f28919d5f9 100644 --- a/OpenRA.Mods.RA/Missions/Allies01Script.cs +++ b/OpenRA.Mods.RA/Missions/Allies01Script.cs @@ -8,12 +8,14 @@ */ #endregion +using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using OpenRA.FileFormats; using OpenRA.Mods.RA.Activities; using OpenRA.Mods.RA.Air; +using OpenRA.Mods.RA.Move; using OpenRA.Network; using OpenRA.Scripting; using OpenRA.Traits; @@ -22,15 +24,23 @@ namespace OpenRA.Mods.RA.Missions { class Allies01ScriptInfo : TraitInfo, Requires { } - class Allies01Script : IWorldLoaded, ITick + class Allies01Script : IHasObjectives, IWorldLoaded, ITick { - static readonly string[] Objectives = + public event ObjectivesUpdatedEventHandler OnObjectivesUpdated; + + public IEnumerable Objectives { get { return objectives.Values; } } + + Dictionary objectives = new Dictionary { - "Find Einstein. Tanya and Einstein must survive.", - "Wait for the helicopter and extract Einstein. Tanya and Einstein must survive." + { FindEinsteinID, new Objective(ObjectiveType.Primary, FindEinstein, ObjectiveStatus.InProgress) }, + { ExtractEinsteinID, new Objective(ObjectiveType.Primary, ExtractEinstein, ObjectiveStatus.Inactive) } }; - int currentObjective; + const int FindEinsteinID = 0; + const int ExtractEinsteinID = 1; + + const string FindEinstein = "Find Einstein. Tanya and Einstein must survive."; + const string ExtractEinstein = "Wait for the helicopter and extract Einstein. Tanya and Einstein must survive."; Player allies; Player soviets; @@ -65,15 +75,8 @@ namespace OpenRA.Mods.RA.Missions const int LabClearRange = 5; const string EinsteinName = "einstein"; const string TanyaName = "e7"; - const string ChinookName = "tran"; const string SignalFlareName = "flare"; - void DisplayObjective() - { - Game.AddChatLine(Color.LimeGreen, "Objective", Objectives[currentObjective]); - Sound.Play("bleep6.aud"); - } - void MissionFailed(string text) { if (allies.WinState != WinState.Undefined) @@ -106,18 +109,11 @@ namespace OpenRA.Mods.RA.Missions { return; } - // display current objective every so often - if (world.FrameNumber % 1500 == 1) - { - DisplayObjective(); - } - // taunt every so often if (world.FrameNumber % 1000 == 0) { Sound.Play(Taunts[world.SharedRandom.Next(Taunts.Length)]); } - // objectives - if (currentObjective == 0) + if (objectives[FindEinsteinID].Status == ObjectiveStatus.InProgress) { if (AlliesControlLab()) { @@ -125,40 +121,48 @@ namespace OpenRA.Mods.RA.Missions Sound.Play("flaren1.aud"); SpawnEinsteinAtLab(); SendShips(); - currentObjective++; - DisplayObjective(); + objectives[FindEinsteinID].Status = ObjectiveStatus.Completed; + objectives[ExtractEinsteinID].Status = ObjectiveStatus.InProgress; + OnObjectivesUpdated(true); currentAttackWaveFrameNumber = world.FrameNumber; } if (lab.Destroyed) { + objectives[FindEinsteinID].Status = ObjectiveStatus.Failed; + OnObjectivesUpdated(true); MissionFailed("Einstein was killed."); } } - else if (currentObjective == 1) + if (objectives[ExtractEinsteinID].Status == ObjectiveStatus.InProgress) { + SendAttackWave(); if (world.FrameNumber >= currentAttackWaveFrameNumber + 600) { Sound.Play("enmyapp1.aud"); - SendAttackWave(AttackWave); + SpawnAttackWave(AttackWave); currentAttackWave++; currentAttackWaveFrameNumber = world.FrameNumber; if (currentAttackWave >= EinsteinChinookAttackWave) { - SendAttackWave(LastAttackWaveAddition); + SpawnAttackWave(LastAttackWaveAddition); } if (currentAttackWave == EinsteinChinookAttackWave) { - FlyEinsteinFromExtractionLZ(); + ExtractEinsteinAtLZ(); } } if (einsteinChinook != null) { if (einsteinChinook.Destroyed) { + objectives[ExtractEinsteinID].Status = ObjectiveStatus.Failed; + OnObjectivesUpdated(true); MissionFailed("The extraction helicopter was destroyed."); } else if (!world.Map.IsInMap(einsteinChinook.Location) && einsteinChinook.Trait().Passengers.Contains(einstein)) { + objectives[ExtractEinsteinID].Status = ObjectiveStatus.Completed; + OnObjectivesUpdated(true); MissionAccomplished("Einstein was rescued."); } } @@ -186,22 +190,47 @@ namespace OpenRA.Mods.RA.Missions world.CreateActor(SignalFlareName, new TypeDictionary { new OwnerInit(allies), new LocationInit(extractionLZ.Location) }); } - void SendAttackWave(IEnumerable wave) + void SpawnAttackWave(IEnumerable wave) { foreach (var unit in wave) { var spawnActor = world.SharedRandom.Next(2) == 0 ? attackEntryPoint1 : attackEntryPoint2; var actor = world.CreateActor(unit, new TypeDictionary { new OwnerInit(soviets), new LocationInit(spawnActor.Location) }); + } + } + + void SendAttackWave() + { + foreach (var unit in world.Actors.Where( + a => a != world.WorldActor + && a.IsInWorld + && a.Owner == soviets + && !a.IsDead() + && a.IsIdle + && a.HasTrait() + && a.HasTrait())) + { Activity innerActivity; - if (einstein != null && einstein.IsInWorld) + if (einstein != null) { - innerActivity = new Attack(Target.FromActor(einstein), 3); + if (einstein.IsInWorld) + { + innerActivity = new Attack(Target.FromActor(einstein), 3); + } + else + { + var container = world.UnitContaining(einstein); + if (container != null && !container.HasTrait() && container.HasTrait()) + { + innerActivity = new Attack(Target.FromActor(container), 3); + } + else + { + innerActivity = new Move.Move(extractionLZ.Location, 3); + } + } + unit.QueueActivity(new AttackMove.AttackMoveActivity(unit, innerActivity)); } - else - { - innerActivity = new Move.Move(extractionLZ.Location, 3); - } - actor.QueueActivity(new AttackMove.AttackMoveActivity(actor, innerActivity)); } } @@ -214,16 +243,9 @@ namespace OpenRA.Mods.RA.Missions } } - IEnumerable UnitsNearActor(Actor actor, int range) - { - return world.FindUnitsInCircle(actor.CenterLocation, Game.CellSize * range) - .Where(a => a.IsInWorld && a != world.WorldActor && !a.Destroyed && a.HasTrait() && !a.Owner.NonCombatant); - } - bool AlliesControlLab() { - var units = UnitsNearActor(lab, LabClearRange); - return units.Any() && units.All(a => a.Owner == allies); + return MissionUtils.AreaSecuredWithUnits(world, allies, lab.CenterLocation, LabClearRange); } void SpawnEinsteinAtLab() @@ -242,32 +264,31 @@ namespace OpenRA.Mods.RA.Missions } } - void FlyEinsteinFromExtractionLZ() + void ExtractEinsteinAtLZ() { - einsteinChinook = world.CreateActor(ChinookName, new TypeDictionary { new OwnerInit(allies), new LocationInit(extractionLZEntryPoint.Location) }); - einsteinChinook.QueueActivity(new HeliFly(extractionLZ.CenterLocation)); - einsteinChinook.QueueActivity(new Turn(0)); - einsteinChinook.QueueActivity(new HeliLand(true, 0)); - einsteinChinook.QueueActivity(new WaitFor(() => einsteinChinook.Trait().Passengers.Contains(einstein))); - einsteinChinook.QueueActivity(new Wait(150)); - einsteinChinook.QueueActivity(new HeliFly(chinookExitPoint.CenterLocation)); - einsteinChinook.QueueActivity(new RemoveSelf()); + einsteinChinook = MissionUtils.ExtractUnitWithChinook( + world, + allies, + einstein, + extractionLZEntryPoint.Location, + extractionLZ.Location, + chinookExitPoint.Location); } - void FlyTanyaToInsertionLZ() + void InsertTanyaAtLZ() { - tanya = world.CreateActor(false, TanyaName, new TypeDictionary { new OwnerInit(allies) }); - var chinook = world.CreateActor(ChinookName, new TypeDictionary { new OwnerInit(allies), new LocationInit(insertionLZEntryPoint.Location) }); - chinook.Trait().Load(chinook, tanya); - chinook.QueueActivity(new HeliFly(insertionLZ.CenterLocation)); - chinook.QueueActivity(new Turn(0)); - chinook.QueueActivity(new HeliLand(true, 0)); - chinook.QueueActivity(new UnloadCargo(true)); - chinook.QueueActivity(new CallFunc(() => Sound.Play("laugh1.aud"))); - chinook.QueueActivity(new CallFunc(() => tanya.QueueActivity(new Move.Move(insertionLZ.Location - new CVec(1, 0))))); - chinook.QueueActivity(new Wait(150)); - chinook.QueueActivity(new HeliFly(chinookExitPoint.CenterLocation)); - chinook.QueueActivity(new RemoveSelf()); + tanya = MissionUtils.InsertUnitWithChinook( + world, + allies, + TanyaName, + insertionLZEntryPoint.Location, + insertionLZ.Location, + chinookExitPoint.Location, + unit => + { + Sound.Play("laugh1.aud"); + unit.QueueActivity(new Move.Move(insertionLZ.Location - new CVec(1, 0))); + }).Second; } void SetAlliedUnitsToDefensiveStance() @@ -310,7 +331,7 @@ namespace OpenRA.Mods.RA.Missions { Media.PlayFMVFullscreen(w, "landing.vqa", () => { - FlyTanyaToInsertionLZ(); + InsertTanyaAtLZ(); SendPatrol(); PlayMusic(); }); diff --git a/OpenRA.Mods.RA/Missions/Allies02Script.cs b/OpenRA.Mods.RA/Missions/Allies02Script.cs index 88200fbfe4..33d7bd8853 100644 --- a/OpenRA.Mods.RA/Missions/Allies02Script.cs +++ b/OpenRA.Mods.RA/Missions/Allies02Script.cs @@ -16,6 +16,8 @@ using OpenRA.FileFormats; using OpenRA.Mods.RA.Activities; using OpenRA.Mods.RA.Air; using OpenRA.Mods.RA.Buildings; +using OpenRA.Mods.RA.Effects; +using OpenRA.Mods.RA.Move; using OpenRA.Network; using OpenRA.Traits; using OpenRA.Widgets; @@ -24,15 +26,34 @@ namespace OpenRA.Mods.RA.Missions { class Allies02ScriptInfo : TraitInfo, Requires { } - class Allies02Script : IWorldLoaded, ITick + class Allies02Script : IHasObjectives, IWorldLoaded, ITick { - static readonly string[] Objectives = + public event ObjectivesUpdatedEventHandler OnObjectivesUpdated; + + public IEnumerable Objectives { get { return objectives.Values; } } + + Dictionary objectives = new Dictionary() { - "Hold off the Soviet forces and destroy the SAM sites. Tanya and Einstein must survive.", - "Wait for the helicopter and extract Einstein. Tanya and Einstein must survive." + { FindEinsteinID, new Objective(ObjectiveType.Primary, FindEinstein, ObjectiveStatus.InProgress) }, + { DestroySamSitesID, new Objective(ObjectiveType.Primary, DestroySamSites, ObjectiveStatus.InProgress) }, + { ExtractEinsteinID, new Objective(ObjectiveType.Primary, ExtractEinstein, ObjectiveStatus.Inactive) }, + { MaintainPresenceID, new Objective(ObjectiveType.Primary, MaintainPresence, ObjectiveStatus.InProgress) }, + { FewDeathsID, new Objective(ObjectiveType.Secondary, "", ObjectiveStatus.InProgress) } }; - int currentObjective; + const int FindEinsteinID = 0; + const int DestroySamSitesID = 1; + const int ExtractEinsteinID = 2; + const int MaintainPresenceID = 3; + const int FewDeathsID = 4; + + const string FindEinstein = "Find Einstein's crashed helicopter. Tanya must survive."; + const string DestroySamSites = "Destroy the SAM sites. Tanya must survive."; + const string ExtractEinstein = "Wait for the helicopter and extract Einstein. Tanya and Einstein must survive."; + const string MaintainPresence = "Maintain an Allied presence in the area. Reinforcements will arrive soon."; + const string FewDeathsTemplate = "Lose fewer than {0}/{1} units."; + + const int DeathsThreshold = 100; Actor sam1; Actor sam2; @@ -42,17 +63,29 @@ namespace OpenRA.Mods.RA.Missions Actor einstein; Actor engineer; - Actor engineerMiss; - Actor chinookHusk; Actor allies2BasePoint; Actor reinforcementsEntryPoint; Actor extractionLZEntryPoint; Actor extractionLZ; - Actor badgerEntryPoint; - Actor badgerDropPoint; + Actor badgerEntryPoint1; + Actor badgerEntryPoint2; + Actor badgerDropPoint1; + Actor badgerDropPoint2; + Actor badgerDropPoint3; + Actor parabombPoint1; + Actor parabombPoint2; Actor sovietRallyPoint; Actor flamersEntryPoint; + Actor tanksEntryPoint; + Actor townPoint; + Actor sovietTownAttackPoint1; + Actor sovietTownAttackPoint2; + Actor yakEntryPoint; + Actor yakAttackPoint; + Actor yak; + Actor sovietReinforcementsEntryPoint1; + Actor sovietReinforcementsEntryPoint2; Actor einsteinChinook; @@ -67,36 +100,56 @@ namespace OpenRA.Mods.RA.Missions CountdownTimer reinforcementsTimer; CountdownTimerWidget reinforcementsTimerWidget; + List sovietReinforcementsUnits = new List(); + const string InfantryQueueName = "Infantry"; const string VehicleQueueName = "Vehicle"; - readonly List sovietInfantry = new List { "e1", "e2", "e3" }; - readonly List sovietVehicles = new List { "3tnk" }; - static readonly string[] SovietVehicleAdditions = { "v2rl" }; - const int SovietGroupSize = 5; - const int SovietVehicleAdditionsTicks = 1500 * 4; + static readonly string[] SovietInfantry = { "e1", "e2", "e3" }; + static readonly string[] SovietVehicles1 = { "3tnk" }; + static readonly string[] SovietVehicles2 = { "3tnk", "v2rl" }; + const int SovietVehiclesUpgradeTicks = 1500 * 4; + const int SovietGroupSize = 8; + const int SovietHelperCash = 2000; const int ReinforcementsTicks = 1500 * 12; - static readonly string[] Reinforcements = { "2tnk", "2tnk", "2tnk", "2tnk", "2tnk", "2tnk", "1tnk", "1tnk", "jeep", "e1", "e1", "e1", "e1", "e3", "e3", "mcv" }; - const int ReinforcementsCash = 2000; + static readonly string[] Reinforcements = + { + "2tnk", "2tnk", "2tnk", "2tnk", "2tnk", "2tnk", + "1tnk", "1tnk", + "jeep", + "e1", "e1", "e1", "e1", + "e3", "e3", + "mcv", + "truk", "truk", "truk", "truk", "truk", "truk" + }; + const int SovietReinforcementsTicks = 1500 * 16; + static readonly string[] SovietReinforcements = + { + "3tnk", "3tnk", "3tnk", "3tnk", "3tnk", "3tnk", "3tnk", "3tnk", "3tnk", "3tnk", "3tnk", "3tnk", + "v2rl", "v2rl", "v2rl", "v2rl", + "ftrk", "ftrk" + }; - const int ParatroopersTicks = 1500 * 10; - static readonly string[] Paratroopers = { "e1", "e1", "e1", "e2", "3tnk" }; - const string BadgerName = "badr"; + const int ParabombTicks = 750; - const int FlamersTicks = 1500 * 7; + const int FlamersTicks = 1500 * 2; static readonly string[] Flamers = { "e4", "e4", "e4", "e4", "e4" }; const string ApcName = "apc"; - const string ChinookName = "tran"; - const string SignalFlareName = "flare"; - const string EngineerName = "e6"; - const int EngineerMissClearRange = 5; + const int ParatroopersTicks = 1500 * 5; + static readonly string[] Badger1Passengers = { "e1", "e1", "e1", "e2", "3tnk" }; + static readonly string[] Badger2Passengers = { "e1", "e1", "e1", "e2", "e2" }; + static readonly string[] Badger3Passengers = { "e1", "e1", "e1", "e2", "e2" }; - void DisplayObjective() - { - Game.AddChatLine(Color.LimeGreen, "Objective", Objectives[currentObjective]); - Sound.Play("bleep6.aud"); - } + const int TanksTicks = 1500 * 11; + static readonly string[] Tanks = { "3tnk", "3tnk", "3tnk", "3tnk", "3tnk", "3tnk", "3tnk", "3tnk" }; + + const string SignalFlareName = "flare"; + const string YakName = "yak"; + + const int AlliedTownTransferRange = 15; + const int SovietTownAttackGroupRange = 5; + const int SovietTownMoveNearEnough = 3; void MissionFailed(string text) { @@ -138,9 +191,9 @@ namespace OpenRA.Mods.RA.Missions { return; } - if (world.FrameNumber % 3500 == 1) + if (world.FrameNumber % 50 == 1 && chinookHusk.IsInWorld) { - DisplayObjective(); + world.Add(new Smoke(world, chinookHusk.CenterLocation, "smoke_m")); } if (world.FrameNumber == 1) { @@ -150,15 +203,35 @@ namespace OpenRA.Mods.RA.Missions reinforcementsTimer.Tick(); if (world.FrameNumber == ParatroopersTicks) { - ParadropSovietUnits(); + MissionUtils.Paradrop(world, soviets, Badger1Passengers, badgerEntryPoint1.Location, badgerDropPoint1.Location); + MissionUtils.Paradrop(world, soviets, Badger2Passengers, badgerEntryPoint1.Location + new CVec(3, 0), badgerDropPoint2.Location); + MissionUtils.Paradrop(world, soviets, Badger3Passengers, badgerEntryPoint1.Location + new CVec(6, 0), badgerDropPoint3.Location); } if (world.FrameNumber == FlamersTicks) { RushSovietFlamers(); } - if (world.FrameNumber == SovietVehicleAdditionsTicks) + if (world.FrameNumber == TanksTicks) { - sovietVehicles.AddRange(SovietVehicleAdditions); + RushSovietUnits(); + } + if (world.FrameNumber == ParabombTicks) + { + MissionUtils.Parabomb(world, soviets, badgerEntryPoint2.Location, parabombPoint1.Location); + MissionUtils.Parabomb(world, soviets, badgerEntryPoint2.Location + new CVec(0, 3), parabombPoint2.Location); + } + if (world.FrameNumber == SovietReinforcementsTicks) + { + SendSovietReinforcements(); + } + if (yak == null || (yak != null && !yak.IsDead() && (yak.GetCurrentActivity() is FlyCircle || yak.IsIdle))) + { + var alliedUnitsNearYakPoint = world.FindAliveCombatantActorsInCircle(yakAttackPoint.CenterLocation, 10) + .Where(a => a.Owner != soviets && a.HasTrait() && a != tanya && a != einstein && a != engineer); + if (alliedUnitsNearYakPoint.Any()) + { + YakStrafe(alliedUnitsNearYakPoint); + } } if (world.FrameNumber % 25 == 0) { @@ -166,30 +239,47 @@ namespace OpenRA.Mods.RA.Missions BuildSovietUnits(); ManageSovietUnits(); } - if (!engineerMiss.Destroyed && engineer == null && AlliesControlMiss()) + UpdateDeaths(); + if (objectives[FindEinsteinID].Status == ObjectiveStatus.InProgress) { - SpawnEngineerAtMiss(); - engineerMiss.QueueActivity(new Demolish(engineerMiss, 0)); + if (AlliesNearTown()) + { + objectives[FindEinsteinID].Status = ObjectiveStatus.Completed; + OnObjectivesUpdated(true); + TransferTownUnitsToAllies(); + SovietsAttackTown(); + } } - if (currentObjective == 0) + if (objectives[DestroySamSitesID].Status == ObjectiveStatus.InProgress) { if (sam1.Destroyed && sam2.Destroyed && sam3.Destroyed && sam4.Destroyed) { - currentObjective++; - DisplayObjective(); + objectives[DestroySamSitesID].Status = ObjectiveStatus.Completed; + objectives[ExtractEinsteinID].Status = ObjectiveStatus.InProgress; + OnObjectivesUpdated(true); SpawnSignalFlare(); Sound.Play("flaren1.aud"); - SendChinook(); + ExtractEinsteinAtLZ(); } } - else if (currentObjective == 1 && einsteinChinook != null) + if (objectives[ExtractEinsteinID].Status == ObjectiveStatus.InProgress && einsteinChinook != null) { if (einsteinChinook.Destroyed) { + objectives[ExtractEinsteinID].Status = ObjectiveStatus.Failed; + objectives[MaintainPresenceID].Status = ObjectiveStatus.Failed; + OnObjectivesUpdated(true); MissionFailed("The extraction helicopter was destroyed."); } else if (!world.Map.IsInMap(einsteinChinook.Location) && einsteinChinook.Trait().Passengers.Contains(einstein)) { + objectives[ExtractEinsteinID].Status = ObjectiveStatus.Completed; + objectives[MaintainPresenceID].Status = ObjectiveStatus.Completed; + if (objectives[FewDeathsID].Status == ObjectiveStatus.InProgress) + { + objectives[FewDeathsID].Status = ObjectiveStatus.Completed; + } + OnObjectivesUpdated(true); MissionAccomplished("Einstein was rescued."); } } @@ -201,18 +291,58 @@ namespace OpenRA.Mods.RA.Missions { MissionFailed("Einstein was killed."); } - else if (!world.Actors.Any(a => a.IsInWorld && a.HasTrait() && !a.HasTrait() && a.Owner == allies2)) + world.AddFrameEndTask(w => { - MissionFailed("The Allied reinforcements have been defeated."); + if (!world.FindAliveCombatantActorsInCircle(allies2BasePoint.CenterLocation, 20).Any(a => a.HasTrait() && !a.HasTrait() && a.Owner == allies2)) + { + objectives[MaintainPresenceID].Status = ObjectiveStatus.Failed; + OnObjectivesUpdated(true); + MissionFailed("The Allied reinforcements have been defeated."); + } + }); + } + + void UpdateDeaths() + { + var unitDeaths = allies1.Deaths + allies2.Deaths; + objectives[FewDeathsID].Text = FewDeathsTemplate.F(unitDeaths, DeathsThreshold); + OnObjectivesUpdated(false); + if (unitDeaths >= DeathsThreshold && objectives[FewDeathsID].Status == ObjectiveStatus.InProgress) + { + objectives[FewDeathsID].Status = ObjectiveStatus.Failed; + OnObjectivesUpdated(true); + } + } + + void YakStrafe(IEnumerable candidates) + { + if (yak == null) + { + yak = world.CreateActor(YakName, new TypeDictionary + { + new LocationInit(yakEntryPoint.Location), + new OwnerInit(soviets), + new FacingInit(Util.GetFacing(yakAttackPoint.Location - yakEntryPoint.Location, 0)), + new AltitudeInit(Rules.Info[YakName].Traits.Get().CruiseAltitude), + }); + } + if (yak.Trait().HasAmmo()) + { + yak.QueueActivity(new FlyAttack(Target.FromActor(candidates.Random(world.SharedRandom)))); + } + else + { + yak.QueueActivity(new FlyOffMap()); + yak.QueueActivity(new RemoveSelf()); } } void AddSovietCashIfRequired() { var resources = soviets.PlayerActor.Trait(); - if (resources.Cash < ReinforcementsCash) + if (resources.Cash < SovietHelperCash) { - resources.GiveCash(ReinforcementsCash); + resources.GiveCash(SovietHelperCash); } } @@ -225,66 +355,75 @@ namespace OpenRA.Mods.RA.Missions } if (!sovietBarracks.Destroyed) { - BuildSovietUnit(InfantryQueueName, sovietInfantry.Random(world.SharedRandom)); + BuildSovietUnit(InfantryQueueName, SovietInfantry.Random(world.SharedRandom)); } if (!sovietWarFactory.Destroyed) { - BuildSovietUnit(VehicleQueueName, sovietVehicles.Random(world.SharedRandom)); + var vehicles = world.FrameNumber >= SovietVehiclesUpgradeTicks ? SovietVehicles2 : SovietVehicles1; + BuildSovietUnit(VehicleQueueName, vehicles.Random(world.SharedRandom)); } } void ManageSovietUnits() { - var idleSovietUnits = ForcesNearActor(allies2BasePoint, 10).Where(a => a.Owner == soviets && a.IsIdle); - var idleSovietUnitsAtRP = ForcesNearActor(sovietRallyPoint, 5).Where(a => a.Owner == soviets && a.IsIdle); + var idleSovietUnitsAtRP = world.FindAliveCombatantActorsInCircle(sovietRallyPoint.CenterLocation, 3).Where(a => a.Owner == soviets && a.IsIdle && a.HasTrait()); if (idleSovietUnitsAtRP.Count() >= SovietGroupSize) { - idleSovietUnits = idleSovietUnits.Union(idleSovietUnitsAtRP); + var firstUnit = idleSovietUnitsAtRP.FirstOrDefault(); + if (firstUnit != null) + { + var closestAlliedBuilding = ClosestAlliedBuilding(firstUnit, 40); + if (closestAlliedBuilding != null) + { + foreach (var unit in idleSovietUnitsAtRP) + { + unit.Trait().Nudge(unit, unit, true); + unit.QueueActivity(new AttackMove.AttackMoveActivity(unit, new Attack(Target.FromActor(closestAlliedBuilding), 3))); + } + } + } } + var idleSovietUnits = world.FindAliveCombatantActorsInCircle(allies2BasePoint.CenterLocation, 20).Where(a => a.Owner == soviets && a.IsIdle && a.HasTrait()); foreach (var unit in idleSovietUnits) { - var closestAlliedBuilding = ClosestAlliedBuilding(unit, 20); + var closestAlliedBuilding = ClosestAlliedBuilding(unit, 40); if (closestAlliedBuilding != null) { - unit.QueueActivity(new AttackMove.AttackMoveActivity(unit, new Move.Move(closestAlliedBuilding.Location, 3))); + unit.QueueActivity(new AttackMove.AttackMoveActivity(unit, new Attack(Target.FromActor(closestAlliedBuilding), 3))); } } } Actor ClosestAlliedBuilding(Actor actor, int range) { - return BuildingsNearActor(actor, range) - .Where(a => a.Owner == allies2) - .OrderBy(a => (actor.Location - a.Location).LengthSquared) - .FirstOrDefault(); + return MissionUtils.ClosestPlayerBuilding(world, allies2, actor.CenterLocation, range); + } + + IEnumerable ClosestAlliedBuildings(Actor actor, int range) + { + return MissionUtils.ClosestPlayerBuildings(world, allies2, actor.CenterLocation, range); } void InitializeSovietFactories() { - sovietBarracks.Trait().rallyPoint = sovietRallyPoint.Location; - sovietWarFactory.Trait().rallyPoint = sovietRallyPoint.Location; + var sbrp = sovietBarracks.Trait(); + var swrp = sovietWarFactory.Trait(); + sbrp.rallyPoint = swrp.rallyPoint = sovietRallyPoint.Location; + sbrp.nearEnough = swrp.nearEnough = 3; sovietBarracks.Trait().SetPrimaryProducer(sovietBarracks, true); sovietWarFactory.Trait().SetPrimaryProducer(sovietWarFactory, true); } - IEnumerable FindQueues(Player player, string category) - { - return world.ActorsWithTrait() - .Where(a => a.Actor.Owner == player && a.Trait.Info.Type == category) - .Select(a => a.Trait); - } - void BuildSovietUnit(string category, string unit) { - var queue = FindQueues(soviets, category).FirstOrDefault(q => q.CurrentItem() == null); + var queue = MissionUtils.FindQueues(world, soviets, category).FirstOrDefault(q => q.CurrentItem() == null); if (queue == null) { return; } - var order = Order.StartProduction(queue.self, unit, 1); if (Game.IsHost) { - world.IssueOrder(order); + world.IssueOrder(Order.StartProduction(queue.self, unit, 1)); } } @@ -296,32 +435,76 @@ namespace OpenRA.Mods.RA.Missions void StartReinforcementsTimer() { Sound.Play("timergo1.aud"); - reinforcementsTimer = new CountdownTimer(ReinforcementsTicks, ReinforcementsTimerExpired); - reinforcementsTimerWidget = new CountdownTimerWidget(reinforcementsTimer, "Reinforcements arrive in", new float2(128, 96)); + reinforcementsTimer = new CountdownTimer(ReinforcementsTicks, ReinforcementsTimerExpired, true); + reinforcementsTimerWidget = new CountdownTimerWidget( + reinforcementsTimer, + "Allied reinforcements arrive in: {0}", + new float2(Game.viewport.Width * 0.35f, Game.viewport.Height * 0.9f)); Ui.Root.AddChild(reinforcementsTimerWidget); } - void ParadropSovietUnits() + void SendSovietReinforcements() { - var badger = world.CreateActor(BadgerName, new TypeDictionary + foreach (var entryPoint in new[] { sovietReinforcementsEntryPoint1, sovietReinforcementsEntryPoint2 }) { - new LocationInit(badgerEntryPoint.Location), - new OwnerInit(soviets), - new FacingInit(Util.GetFacing(badgerDropPoint.Location - badgerEntryPoint.Location, 0)), - new AltitudeInit(Rules.Info[BadgerName].Traits.Get().CruiseAltitude), - }); - badger.QueueActivity(new FlyAttack(Target.FromCell(badgerDropPoint.Location))); - badger.Trait().SetLZ(badgerDropPoint.Location); - var cargo = badger.Trait(); - foreach (var unit in Paratroopers) + foreach (var unit in SovietReinforcements) + { + var u = world.CreateActor(unit, new TypeDictionary + { + new LocationInit(entryPoint.Location), + new FacingInit(Util.GetFacing(allies2BasePoint.Location - entryPoint.Location, 0)), + new OwnerInit(soviets) + }); + u.QueueActivity(new Move.Move(sovietRallyPoint.Location, 3)); + } + } + } + + void ReinforcementsTimerExpired(CountdownTimer countdownTimer) + { + reinforcementsTimerWidget.Visible = false; + SendReinforcements(); + Sound.Play("aarrivs1.aud"); + } + + void SendReinforcements() + { + foreach (var unit in Reinforcements) { - cargo.Load(badger, world.CreateActor(false, unit, new TypeDictionary { new OwnerInit(soviets) })); + var u = world.CreateActor(unit, new TypeDictionary + { + new LocationInit(reinforcementsEntryPoint.Location), + new FacingInit(0), + new OwnerInit(allies2) + }); + u.QueueActivity(new Move.Move(allies2BasePoint.Location)); + } + } + + void RushSovietUnits() + { + var closestAlliedBuildings = ClosestAlliedBuildings(badgerDropPoint1, 40); + if (!closestAlliedBuildings.Any()) + { + return; + } + foreach (var tank in Tanks) + { + var unit = world.CreateActor(tank, new TypeDictionary + { + new OwnerInit(soviets), + new LocationInit(tanksEntryPoint.Location) + }); + foreach (var building in closestAlliedBuildings) + { + unit.QueueActivity(new Attack(Target.FromActor(building), 3)); + } } } void RushSovietFlamers() { - var closestAlliedBuilding = ClosestAlliedBuilding(badgerDropPoint, 10); + var closestAlliedBuilding = ClosestAlliedBuilding(badgerDropPoint1, 40); if (closestAlliedBuilding == null) { return; @@ -336,67 +519,41 @@ namespace OpenRA.Mods.RA.Missions apc.QueueActivity(new UnloadCargo(true)); } - void ReinforcementsTimerExpired(CountdownTimer countdownTimer) + void ExtractEinsteinAtLZ() { - reinforcementsTimerWidget.Visible = false; - SendReinforcements(); + einsteinChinook = MissionUtils.ExtractUnitWithChinook( + world, + allies1, + einstein, + extractionLZEntryPoint.Location, + extractionLZ.Location, + extractionLZEntryPoint.Location); } - void SendReinforcements() + bool AlliesNearTown() { - Sound.Play("reinfor1.aud"); - var resources = allies2.PlayerActor.Trait(); - resources.GiveCash(2000); - foreach (var unit in Reinforcements) + return world.FindAliveCombatantActorsInCircle(townPoint.CenterLocation, AlliedTownTransferRange) + .Any(a => a.Owner == allies1 && a.HasTrait()); + } + + void TransferTownUnitsToAllies() + { + foreach (var unit in world.FindAliveNonCombatantActorsInCircle(townPoint.CenterLocation, AlliedTownTransferRange).Where(a => a.HasTrait())) { - var actor = world.CreateActor(unit, new TypeDictionary - { - new LocationInit(reinforcementsEntryPoint.Location), - new FacingInit(0), - new OwnerInit(allies2) - }); - actor.QueueActivity(new Move.Move(allies2BasePoint.Location)); + unit.ChangeOwner(allies1); } } - void SendChinook() + void SovietsAttackTown() { - einsteinChinook = world.CreateActor(ChinookName, new TypeDictionary { new OwnerInit(allies1), new LocationInit(extractionLZEntryPoint.Location) }); - einsteinChinook.QueueActivity(new HeliFly(extractionLZ.CenterLocation)); - einsteinChinook.QueueActivity(new Turn(0)); - einsteinChinook.QueueActivity(new HeliLand(true, 0)); - einsteinChinook.QueueActivity(new WaitFor(() => einsteinChinook.Trait().Passengers.Contains(einstein))); - einsteinChinook.QueueActivity(new Wait(150)); - einsteinChinook.QueueActivity(new HeliFly(extractionLZEntryPoint.CenterLocation)); - einsteinChinook.QueueActivity(new RemoveSelf()); - } - - IEnumerable UnitsNearActor(Actor actor, int range) - { - return world.FindUnitsInCircle(actor.CenterLocation, Game.CellSize * range) - .Where(a => a.IsInWorld && a != world.WorldActor && !a.Destroyed && !a.Owner.NonCombatant); - } - - IEnumerable BuildingsNearActor(Actor actor, int range) - { - return UnitsNearActor(actor, range).Where(a => a.HasTrait() && !a.HasTrait()); - } - - IEnumerable ForcesNearActor(Actor actor, int range) - { - return UnitsNearActor(actor, range).Where(a => a.HasTrait()); - } - - bool AlliesControlMiss() - { - var units = ForcesNearActor(engineerMiss, EngineerMissClearRange); - return units.Any() && units.All(a => a.Owner == allies1); - } - - void SpawnEngineerAtMiss() - { - engineer = world.CreateActor(EngineerName, new TypeDictionary { new OwnerInit(allies1), new LocationInit(engineerMiss.Location) }); - engineer.QueueActivity(new Move.Move(engineerMiss.Location + new CVec(5, 0))); + var sovietAttackUnits = world.FindAliveCombatantActorsInCircle(sovietTownAttackPoint1.CenterLocation, SovietTownAttackGroupRange) + .Union(world.FindAliveCombatantActorsInCircle(sovietTownAttackPoint2.CenterLocation, SovietTownAttackGroupRange)) + .Union(world.FindAliveCombatantActorsInCircle(townPoint.CenterLocation, AlliedTownTransferRange)) + .Where(a => a.HasTrait() && a.Owner == soviets); + foreach (var unit in sovietAttackUnits) + { + unit.QueueActivity(new AttackMove.AttackMoveActivity(unit, new Move.Move(townPoint.Location, SovietTownMoveNearEnough))); + } } public void WorldLoaded(World w) @@ -412,18 +569,31 @@ namespace OpenRA.Mods.RA.Missions sam4 = actors["SAM4"]; tanya = actors["Tanya"]; einstein = actors["Einstein"]; + engineer = actors["Engineer"]; chinookHusk = actors["ChinookHusk"]; allies2BasePoint = actors["Allies2BasePoint"]; reinforcementsEntryPoint = actors["ReinforcementsEntryPoint"]; extractionLZ = actors["ExtractionLZ"]; extractionLZEntryPoint = actors["ExtractionLZEntryPoint"]; - badgerEntryPoint = actors["BadgerEntryPoint"]; - badgerDropPoint = actors["BadgerDropPoint"]; - engineerMiss = actors["EngineerMiss"]; + badgerEntryPoint1 = actors["BadgerEntryPoint1"]; + badgerEntryPoint2 = actors["BadgerEntryPoint2"]; + badgerDropPoint1 = actors["BadgerDropPoint1"]; + badgerDropPoint2 = actors["BadgerDropPoint2"]; + badgerDropPoint3 = actors["BadgerDropPoint3"]; + parabombPoint1 = actors["ParabombPoint1"]; + parabombPoint2 = actors["ParabombPoint2"]; sovietBarracks = actors["SovietBarracks"]; sovietWarFactory = actors["SovietWarFactory"]; sovietRallyPoint = actors["SovietRallyPoint"]; flamersEntryPoint = actors["FlamersEntryPoint"]; + tanksEntryPoint = actors["TanksEntryPoint"]; + townPoint = actors["TownPoint"]; + sovietTownAttackPoint1 = actors["SovietTownAttackPoint1"]; + sovietTownAttackPoint2 = actors["SovietTownAttackPoint2"]; + yakEntryPoint = actors["YakEntryPoint"]; + yakAttackPoint = actors["YakAttackPoint"]; + sovietReinforcementsEntryPoint1 = actors["SovietReinforcementsEntryPoint1"]; + sovietReinforcementsEntryPoint2 = actors["SovietReinforcementsEntryPoint2"]; var shroud = w.WorldActor.Trait(); shroud.Explore(w, sam1.Location, 2); shroud.Explore(w, sam2.Location, 2); @@ -460,81 +630,4 @@ namespace OpenRA.Mods.RA.Missions } } } - - public class CountdownTimer - { - public int TicksLeft { get; set; } - - public Action OnExpired { get; set; } - public Action OnOneMinuteRemaining { get; set; } - public Action OnTwoMinutesRemaining { get; set; } - public Action OnThreeMinutesRemaining { get; set; } - public Action OnFourMinutesRemaining { get; set; } - public Action OnFiveMinutesRemaining { get; set; } - public Action OnTenMinutesRemaining { get; set; } - public Action OnTwentyMinutesRemaining { get; set; } - public Action OnThirtyMinutesRemaining { get; set; } - public Action OnFortyMinutesRemaining { get; set; } - - public CountdownTimer(int ticksLeft, Action onExpired) - { - TicksLeft = ticksLeft; - OnExpired = onExpired; - OnOneMinuteRemaining = t => Sound.Play("1minr.aud"); - OnTwoMinutesRemaining = t => Sound.Play("2minr.aud"); - OnThreeMinutesRemaining = t => Sound.Play("3minr.aud"); - OnFourMinutesRemaining = t => Sound.Play("4minr.aud"); - OnFiveMinutesRemaining = t => Sound.Play("5minr.aud"); - OnTenMinutesRemaining = t => Sound.Play("10minr.aud"); - OnTwentyMinutesRemaining = t => Sound.Play("20minr.aud"); - OnThirtyMinutesRemaining = t => Sound.Play("30minr.aud"); - OnFortyMinutesRemaining = t => Sound.Play("40minr.aud"); - } - - public void Tick() - { - if (TicksLeft > 0) - { - TicksLeft--; - switch (TicksLeft) - { - case 1500 * 00: OnExpired(this); break; - case 1500 * 01: OnOneMinuteRemaining(this); break; - case 1500 * 02: OnTwoMinutesRemaining(this); break; - case 1500 * 03: OnThreeMinutesRemaining(this); break; - case 1500 * 04: OnFourMinutesRemaining(this); break; - case 1500 * 05: OnFiveMinutesRemaining(this); break; - case 1500 * 10: OnTenMinutesRemaining(this); break; - case 1500 * 20: OnTwentyMinutesRemaining(this); break; - case 1500 * 30: OnThirtyMinutesRemaining(this); break; - case 1500 * 40: OnFortyMinutesRemaining(this); break; - } - } - } - } - - public class CountdownTimerWidget : Widget - { - public CountdownTimer CountdownTimer { get; set; } - public string Header { get; set; } - public float2 Position { get; set; } - - public CountdownTimerWidget(CountdownTimer countdownTimer, string header, float2 position) - { - CountdownTimer = countdownTimer; - Header = header; - Position = position; - } - - public override void Draw() - { - if (!IsVisible()) - { - return; - } - var font = Game.Renderer.Fonts["Bold"]; - var text = "{0}: {1}".F(Header, WidgetUtils.FormatTime(CountdownTimer.TicksLeft)); - font.DrawTextWithContrast(text, Position, CountdownTimer.TicksLeft == 0 && Game.LocalTick % 60 >= 30 ? Color.Red : Color.White, Color.Black, 1); - } - } } diff --git a/OpenRA.Mods.RA/Missions/CountdownTimer.cs b/OpenRA.Mods.RA/Missions/CountdownTimer.cs new file mode 100644 index 0000000000..5da6165707 --- /dev/null +++ b/OpenRA.Mods.RA/Missions/CountdownTimer.cs @@ -0,0 +1,96 @@ +#region Copyright & License Information +/* + * Copyright 2007-2012 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.Drawing; +using OpenRA.Widgets; + +namespace OpenRA.Mods.RA.Missions +{ + public class CountdownTimer + { + public int TicksLeft { get; set; } + + public event Action OnExpired = t => { }; + public event Action OnOneMinuteRemaining = t => { }; + public event Action OnTwoMinutesRemaining = t => { }; + public event Action OnThreeMinutesRemaining = t => { }; + public event Action OnFourMinutesRemaining = t => { }; + public event Action OnFiveMinutesRemaining = t => { }; + public event Action OnTenMinutesRemaining = t => { }; + public event Action OnTwentyMinutesRemaining = t => { }; + public event Action OnThirtyMinutesRemaining = t => { }; + public event Action OnFortyMinutesRemaining = t => { }; + + public CountdownTimer(int ticksLeft, Action onExpired, bool withNotifications) + { + TicksLeft = ticksLeft; + OnExpired += onExpired; + if (withNotifications) + { + OnOneMinuteRemaining += t => Sound.Play("1minr.aud"); + OnTwoMinutesRemaining += t => Sound.Play("2minr.aud"); + OnThreeMinutesRemaining += t => Sound.Play("3minr.aud"); + OnFourMinutesRemaining += t => Sound.Play("4minr.aud"); + OnFiveMinutesRemaining += t => Sound.Play("5minr.aud"); + OnTenMinutesRemaining += t => Sound.Play("10minr.aud"); + OnTwentyMinutesRemaining += t => Sound.Play("20minr.aud"); + OnThirtyMinutesRemaining += t => Sound.Play("30minr.aud"); + OnFortyMinutesRemaining += t => Sound.Play("40minr.aud"); + } + } + + public void Tick() + { + if (TicksLeft > 0) + { + TicksLeft--; + switch (TicksLeft) + { + case 1500 * 00: OnExpired(this); break; + case 1500 * 01: OnOneMinuteRemaining(this); break; + case 1500 * 02: OnTwoMinutesRemaining(this); break; + case 1500 * 03: OnThreeMinutesRemaining(this); break; + case 1500 * 04: OnFourMinutesRemaining(this); break; + case 1500 * 05: OnFiveMinutesRemaining(this); break; + case 1500 * 10: OnTenMinutesRemaining(this); break; + case 1500 * 20: OnTwentyMinutesRemaining(this); break; + case 1500 * 30: OnThirtyMinutesRemaining(this); break; + case 1500 * 40: OnFortyMinutesRemaining(this); break; + } + } + } + } + + public class CountdownTimerWidget : Widget + { + public CountdownTimer Timer { get; set; } + public string Format { get; set; } + public float2 Position { get; set; } + + public CountdownTimerWidget(CountdownTimer timer, string format, float2 position) + { + Timer = timer; + Format = format; + Position = position; + } + + public override void Draw() + { + if (!IsVisible()) + { + return; + } + var font = Game.Renderer.Fonts["Bold"]; + var text = Format.F(WidgetUtils.FormatTime(Timer.TicksLeft)); + font.DrawTextWithContrast(text, Position, Timer.TicksLeft <= 25 * 10 && Game.LocalTick % 50 < 25 ? Color.Red : Color.White, Color.Black, 1); + } + } +} diff --git a/OpenRA.Mods.RA/Missions/MissionUtils.cs b/OpenRA.Mods.RA/Missions/MissionUtils.cs new file mode 100644 index 0000000000..76e81d8fcc --- /dev/null +++ b/OpenRA.Mods.RA/Missions/MissionUtils.cs @@ -0,0 +1,140 @@ +#region Copyright & License Information +/* + * Copyright 2007-2012 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using OpenRA.FileFormats; +using OpenRA.Mods.RA.Activities; +using OpenRA.Mods.RA.Air; +using OpenRA.Mods.RA.Buildings; +using OpenRA.Traits; + +namespace OpenRA.Mods.RA.Missions +{ + public static class MissionUtils + { + public static IEnumerable FindAliveCombatantActorsInCircle(this World world, PPos location, int range) + { + return world.FindUnitsInCircle(location, Game.CellSize * range) + .Where(a => a.IsInWorld && a != world.WorldActor && !a.IsDead() && !a.Owner.NonCombatant); + } + + public static IEnumerable FindAliveNonCombatantActorsInCircle(this World world, PPos location, int range) + { + return world.FindUnitsInCircle(location, Game.CellSize * range) + .Where(a => a.IsInWorld && a != world.WorldActor && !a.IsDead() && a.Owner.NonCombatant); + } + + public static Actor ExtractUnitWithChinook(World world, Player owner, Actor unit, CPos entry, CPos lz, CPos exit) + { + var chinook = world.CreateActor("tran", new TypeDictionary { new OwnerInit(owner), new LocationInit(entry) }); + chinook.QueueActivity(new HeliFly(Util.CenterOfCell(lz))); + chinook.QueueActivity(new Turn(0)); + chinook.QueueActivity(new HeliLand(true, 0)); + chinook.QueueActivity(new WaitFor(() => chinook.Trait().Passengers.Contains(unit))); + chinook.QueueActivity(new Wait(150)); + chinook.QueueActivity(new HeliFly(Util.CenterOfCell(exit))); + chinook.QueueActivity(new RemoveSelf()); + return chinook; + } + + public static Pair InsertUnitWithChinook(World world, Player owner, string unitName, CPos entry, CPos lz, CPos exit, Action afterUnload) + { + var unit = world.CreateActor(false, unitName, new TypeDictionary { new OwnerInit(owner) }); + var chinook = world.CreateActor("tran", new TypeDictionary { new OwnerInit(owner), new LocationInit(entry) }); + chinook.Trait().Load(chinook, unit); + chinook.QueueActivity(new HeliFly(Util.CenterOfCell(lz))); + chinook.QueueActivity(new Turn(0)); + chinook.QueueActivity(new HeliLand(true, 0)); + chinook.QueueActivity(new UnloadCargo(true)); + chinook.QueueActivity(new CallFunc(() => afterUnload(unit))); + chinook.QueueActivity(new Wait(150)); + chinook.QueueActivity(new HeliFly(Util.CenterOfCell(exit))); + chinook.QueueActivity(new RemoveSelf()); + return Pair.New(chinook, unit); + } + + public static void Paradrop(World world, Player owner, IEnumerable units, CPos entry, CPos location) + { + var badger = world.CreateActor("badr", new TypeDictionary + { + new LocationInit(entry), + new OwnerInit(owner), + new FacingInit(Util.GetFacing(location - entry, 0)), + new AltitudeInit(Rules.Info["badr"].Traits.Get().CruiseAltitude), + }); + badger.QueueActivity(new FlyAttack(Target.FromCell(location))); + badger.Trait().SetLZ(location); + var cargo = badger.Trait(); + foreach (var unit in units) + { + cargo.Load(badger, world.CreateActor(false, unit, new TypeDictionary { new OwnerInit(owner) })); + } + } + + public static void Parabomb(World world, Player owner, CPos entry, CPos location) + { + var badger = world.CreateActor("badr.bomber", new TypeDictionary + { + new LocationInit(entry), + new OwnerInit(owner), + new FacingInit(Util.GetFacing(location - entry, 0)), + new AltitudeInit(Rules.Info["badr.bomber"].Traits.Get().CruiseAltitude), + }); + badger.Trait().SetTarget(location); + badger.QueueActivity(Fly.ToCell(location)); + badger.QueueActivity(new FlyOffMap()); + badger.QueueActivity(new RemoveSelf()); + } + + public static bool AreaSecuredWithUnits(World world, Player player, PPos location, int range) + { + var units = world.FindAliveCombatantActorsInCircle(location, range).Where(a => a.HasTrait()); + return units.Any() && units.All(a => a.Owner == player); + } + + public static Actor ClosestPlayerUnit(World world, Player player, PPos location, int range) + { + return ClosestPlayerUnits(world, player, location, range).FirstOrDefault(); + } + + public static IEnumerable ClosestPlayerUnits(World world, Player player, PPos location, int range) + { + return world.FindAliveCombatantActorsInCircle(location, range) + .Where(a => a.Owner == player && a.HasTrait()) + .OrderBy(a => (location - a.CenterLocation).LengthSquared); + } + + public static Actor ClosestPlayerBuilding(World world, Player player, PPos location, int range) + { + return ClosestPlayerBuildings(world, player, location, range).FirstOrDefault(); + } + + public static IEnumerable ClosestPlayerBuildings(World world, Player player, PPos location, int range) + { + return world.FindAliveCombatantActorsInCircle(location, range) + .Where(a => a.Owner == player && a.HasTrait() && !a.HasTrait()) + .OrderBy(a => (location - a.CenterLocation).LengthSquared); + } + + public static IEnumerable FindQueues(World world, Player player, string category) + { + return world.ActorsWithTrait() + .Where(a => a.Actor.Owner == player && a.Trait.Info.Type == category) + .Select(a => a.Trait); + } + + public static Actor UnitContaining(this World world, Actor actor) + { + return world.Actors.FirstOrDefault(a => a.HasTrait() && a.Trait().Passengers.Contains(actor)); + } + } +} diff --git a/OpenRA.Mods.RA/Missions/Objective.cs b/OpenRA.Mods.RA/Missions/Objective.cs new file mode 100644 index 0000000000..5a1fe70128 --- /dev/null +++ b/OpenRA.Mods.RA/Missions/Objective.cs @@ -0,0 +1,54 @@ +#region Copyright & License Information +/* + * Copyright 2007-2012 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.Collections.Generic; +using OpenRA.Traits; + +namespace OpenRA.Mods.RA.Missions +{ + public class Objective + { + public ObjectiveType Type { get; set; } + public string Text { get; set; } + public ObjectiveStatus Status { get; set; } + + public Objective(ObjectiveType type, string text, ObjectiveStatus status) + { + Type = type; + Text = text; + Status = status; + } + } + + public enum ObjectiveType { Primary, Secondary } + public enum ObjectiveStatus { Inactive, InProgress, Completed, Failed } + + public delegate void ObjectivesUpdatedEventHandler(bool notify); + + public interface IHasObjectives + { + event ObjectivesUpdatedEventHandler OnObjectivesUpdated; + IEnumerable Objectives { get; } + } + + public class MissionObjectivesPanelInfo : ITraitInfo + { + public string ObjectivesPanel = null; + public object Create(ActorInitializer init) { return new MissionObjectivesPanel(this); } + } + + public class MissionObjectivesPanel : IObjectivesPanel + { + MissionObjectivesPanelInfo info; + public MissionObjectivesPanel(MissionObjectivesPanelInfo info) { this.info = info; } + public string ObjectivesPanel { get { return info.ObjectivesPanel; } } + } +} diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index bddb801f01..6a336d29a1 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -172,6 +172,7 @@ + @@ -181,6 +182,7 @@ + @@ -238,7 +240,10 @@ + + + @@ -361,6 +366,7 @@ + @@ -434,4 +440,4 @@ copy "$(TargetPath)" "$(SolutionDir)mods/ra/" cd "$(SolutionDir)" - \ No newline at end of file + diff --git a/OpenRA.Mods.RA/Production.cs b/OpenRA.Mods.RA/Production.cs index 07ba7015a9..16325451a0 100755 --- a/OpenRA.Mods.RA/Production.cs +++ b/OpenRA.Mods.RA/Production.cs @@ -91,7 +91,7 @@ namespace OpenRA.Mods.RA if (mobile != null) { newUnit.QueueActivity(new AttackMove.AttackMoveActivity( - newUnit, mobile.MoveTo(rp.rallyPoint, 1))); + newUnit, mobile.MoveTo(rp.rallyPoint, rp.nearEnough))); return rp.rallyPoint; } diff --git a/OpenRA.Mods.RA/RallyPoint.cs b/OpenRA.Mods.RA/RallyPoint.cs index 961646e572..ba1c410200 100755 --- a/OpenRA.Mods.RA/RallyPoint.cs +++ b/OpenRA.Mods.RA/RallyPoint.cs @@ -1,4 +1,4 @@ -#region Copyright & License Information +#region Copyright & License Information /* * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made @@ -24,6 +24,7 @@ namespace OpenRA.Mods.RA public class RallyPoint : IIssueOrder, IResolveOrder, ISync { [Sync] public CPos rallyPoint; + public int nearEnough = 1; public RallyPoint(Actor self) { diff --git a/OpenRA.Mods.RA/Widgets/Logic/IngameChromeLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/IngameChromeLogic.cs index c54ba06f9a..4f1cd7a0c2 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/IngameChromeLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/IngameChromeLogic.cs @@ -9,6 +9,7 @@ #endregion using OpenRA.Traits; +using System.Linq; using OpenRA.Widgets; using System.Drawing; @@ -38,6 +39,16 @@ namespace OpenRA.Mods.RA.Widgets.Logic }; cheatsButton.IsVisible = () => world.LocalPlayer != null && world.LobbyInfo.GlobalSettings.AllowCheats; + var iop = world.WorldActor.TraitsImplementing().FirstOrDefault(); + if (iop != null && iop.ObjectivesPanel != null) + { + var objectivesButton = gameRoot.Get("OBJECTIVES_BUTTON"); + var objectivesWidget = Game.LoadWidget(world, iop.ObjectivesPanel, Ui.Root, new WidgetArgs()); + objectivesWidget.Visible = false; + objectivesButton.OnClick += () => objectivesWidget.Visible = !objectivesWidget.Visible; + objectivesButton.IsVisible = () => world.LocalPlayer != null; + } + optionsBG.Get("DISCONNECT").OnClick = () => LeaveGame(optionsBG, world); optionsBG.Get("SETTINGS").OnClick = () => Ui.OpenWindow("SETTINGS_MENU"); diff --git a/OpenRA.Mods.RA/Widgets/Logic/MissionObjectivesLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/MissionObjectivesLogic.cs new file mode 100644 index 0000000000..e011256c46 --- /dev/null +++ b/OpenRA.Mods.RA/Widgets/Logic/MissionObjectivesLogic.cs @@ -0,0 +1,95 @@ +#region Copyright & License Information +/* + * Copyright 2007-2012 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System.Linq; +using OpenRA.Mods.RA.Missions; +using OpenRA.Network; +using OpenRA.Widgets; + +namespace OpenRA.Mods.RA.Widgets.Logic +{ + public class MissionObjectivesLogic + { + IHasObjectives objectives; + Widget primaryPanel; + Widget secondaryPanel; + Widget primaryTemplate; + Widget secondaryTemplate; + ButtonWidget objectivesButton; + + [ObjectCreator.UseCtor] + public MissionObjectivesLogic(World world, Widget widget) + { + var gameRoot = Ui.Root.Get("INGAME_ROOT"); + primaryPanel = widget.Get("PRIMARY_OBJECTIVES"); + secondaryPanel = widget.Get("SECONDARY_OBJECTIVES"); + primaryTemplate = primaryPanel.Get("PRIMARY_OBJECTIVE_TEMPLATE"); + secondaryTemplate = secondaryPanel.Get("SECONDARY_OBJECTIVE_TEMPLATE"); + + objectives = world.WorldActor.TraitsImplementing().First(); + + objectivesButton = gameRoot.Get("OBJECTIVES_BUTTON"); + objectivesButton.IsHighlighted = () => Game.LocalTick % 50 < 25 && objectivesButton.Highlighted; + objectivesButton.OnClick += () => objectivesButton.Highlighted = false; + + objectives.OnObjectivesUpdated += UpdateObjectives; + UpdateObjectives(true); + Game.ConnectionStateChanged += RemoveHandlers; + } + + public void RemoveHandlers(OrderManager orderManager) + { + if (!orderManager.GameStarted) + { + Game.ConnectionStateChanged -= RemoveHandlers; + objectives.OnObjectivesUpdated -= UpdateObjectives; + } + } + + public void UpdateObjectives(bool notify) + { + if (notify) + { + objectivesButton.Highlighted = true; + } + primaryPanel.RemoveChildren(); + secondaryPanel.RemoveChildren(); + foreach (var o in objectives.Objectives.Where(o => o.Status != ObjectiveStatus.Inactive)) + { + var objective = o; + if (objective.Type == ObjectiveType.Secondary) + { + var template = secondaryTemplate.Clone(); + template.Get("SECONDARY_OBJECTIVE").GetText = () => objective.Text; + template.Get("SECONDARY_STATUS").GetText = () => GetObjectiveStatusText(objective.Status); + secondaryPanel.AddChild(template); + } + else + { + var template = primaryTemplate.Clone(); + template.Get("PRIMARY_OBJECTIVE").GetText = () => objective.Text; + template.Get("PRIMARY_STATUS").GetText = () => GetObjectiveStatusText(objective.Status); + primaryPanel.AddChild(template); + } + } + } + + static string GetObjectiveStatusText(ObjectiveStatus status) + { + switch (status) + { + case ObjectiveStatus.InProgress: return "In Progress"; + case ObjectiveStatus.Completed: return "Completed"; + case ObjectiveStatus.Failed: return "Failed"; + default: return ""; + } + } + } +} diff --git a/mods/ra/bits/invun.shp b/mods/ra/bits/invun.shp new file mode 100644 index 0000000000..4796747898 Binary files /dev/null and b/mods/ra/bits/invun.shp differ diff --git a/mods/ra/chrome.yaml b/mods/ra/chrome.yaml index 2bd7854ad6..91be2c8e9a 100644 --- a/mods/ra/chrome.yaml +++ b/mods/ra/chrome.yaml @@ -249,6 +249,17 @@ button: dialog.png corner-bl: 512,82,1,1 corner-br: 594,82,1,1 +button-highlighted: dialog.png + background: 513,145,126,126 + border-r: 639,145,1,126 + border-l: 512,145,1,126 + border-b: 513,271,126,1 + border-t: 513,144,126,1 + corner-tl: 512,144,1,1 + corner-tr: 594,144,1,1 + corner-bl: 512,271,1,1 + corner-br: 594,271,1,1 + # A copy of dialog2 button-hover: dialog.png background: 513,1,126,126 @@ -261,6 +272,17 @@ button-hover: dialog.png corner-bl: 512,82,1,1 corner-br: 594,82,1,1 +button-hover-highlighted: dialog.png + background: 513,145,126,126 + border-r: 639,145,1,126 + border-l: 512,145,1,126 + border-b: 513,271,126,1 + border-t: 513,144,126,1 + corner-tl: 512,144,1,1 + corner-tr: 594,144,1,1 + corner-bl: 512,271,1,1 + corner-br: 594,271,1,1 + # A copy of dialog2 button-disabled: dialog.png background: 513,1,126,126 @@ -273,6 +295,17 @@ button-disabled: dialog.png corner-bl: 512,82,1,1 corner-br: 594,82,1,1 +button-disabled-highlighted: dialog.png + background: 513,145,126,126 + border-r: 639,145,1,126 + border-l: 512,145,1,126 + border-b: 513,271,126,1 + border-t: 513,144,126,1 + corner-tl: 512,144,1,1 + corner-tr: 594,144,1,1 + corner-bl: 512,271,1,1 + corner-br: 594,271,1,1 + # A copy of dialog3 button-pressed: dialog.png background: 641,1,126,126 @@ -284,7 +317,18 @@ button-pressed: dialog.png corner-tr: 722,0,1,1 corner-bl: 640,82,1,1 corner-br: 722,82,1,1 - + +button-pressed-highlighted: dialog.png + background: 641,145,126,126 + border-r: 767,145,1,126 + border-l: 640,145,1,126 + border-b: 641,271,126,1 + border-t: 641,144,126,1 + corner-tl: 640,144,1,1 + corner-tr: 722,144,1,1 + corner-bl: 640,271,1,1 + corner-br: 722,271,1,1 + scrollthumb: dialog.png background: 513,1,126,126 border-r: 639,1,1,126 diff --git a/mods/ra/chrome/ingame.yaml b/mods/ra/chrome/ingame.yaml index 7202106cee..fcfb2fb387 100644 --- a/mods/ra/chrome/ingame.yaml +++ b/mods/ra/chrome/ingame.yaml @@ -81,6 +81,14 @@ Container@INGAME_ROOT: Text:Cheats Visible:false Font:Bold + Button@OBJECTIVES_BUTTON: + X:486 + Y:0 + Width:160 + Height:25 + Text:Objectives + Visible:false + Font:Bold RadarBin@INGAME_RADAR_BIN: WorldInteractionController:INTERACTION_CONTROLLER PowerBin@INGAME_POWER_BIN: diff --git a/mods/ra/chrome/objectives.yaml b/mods/ra/chrome/objectives.yaml new file mode 100644 index 0000000000..3da3275072 --- /dev/null +++ b/mods/ra/chrome/objectives.yaml @@ -0,0 +1,102 @@ +Container@MISSION_OBJECTIVES: + Logic:MissionObjectivesLogic + X:25 + Y:50 + Width:512 + Height:530 + Children: + Background@BACKGROUND: + Width:512 + Height:530 + Background:dialog + Children: + Label@TITLE: + X:0 + Y:15 + Width:PARENT_RIGHT + Height:25 + Font:Bold + Align:Center + Text:Objectives + Label@PRIMARY_OBJECTIVE_HEADER: + X:40 + Y:40 + Width:300 + Height:25 + Font:Bold + Text:Primary Objectives + Label@PRIMARY_STATUS_HEADER: + X:350 + Y:40 + Width:122 + Height:25 + Font:Bold + Text:Status + ScrollPanel@PRIMARY_OBJECTIVES: + X:25 + Y:70 + Width:PARENT_RIGHT-50 + Height:200 + ItemSpacing:5 + Children: + Container@PRIMARY_OBJECTIVE_TEMPLATE: + X:15 + Y:0-15 + Width:PARENT_RIGHT + Height:60 + Children: + Label@PRIMARY_OBJECTIVE: + X:0 + Y:0 + Width:300 + Height:PARENT_BOTTOM + Font:Regular + WordWrap:True + Label@PRIMARY_STATUS: + X:310 + Y:0 + Width:122 + Height:PARENT_BOTTOM + Font:Bold + WordWrap:True + Label@SECONDARY_OBJECTIVE_HEADER: + X:40 + Y:275 + Width:300 + Height:25 + Font:Bold + Text:Secondary Objectives + Label@SECONDARY_STATUS_HEADER: + X:350 + Y:275 + Width:122 + Height:25 + Font:Bold + Text:Status + ScrollPanel@SECONDARY_OBJECTIVES: + X:25 + Y:305 + Width:PARENT_RIGHT-50 + Height:200 + ItemSpacing:5 + Children: + Container@SECONDARY_OBJECTIVE_TEMPLATE: + X:15 + Y:0-15 + Width:PARENT_RIGHT + Height:60 + Children: + Label@SECONDARY_OBJECTIVE: + X:0 + Y:0 + Width:300 + Height:PARENT_BOTTOM + Font:Regular + WordWrap:True + Label@SECONDARY_STATUS: + X:310 + Y:0 + Width:122 + Height:PARENT_BOTTOM + Font:Bold + WordWrap:True \ No newline at end of file diff --git a/mods/ra/maps/allies-01.oramap b/mods/ra/maps/allies-01.oramap deleted file mode 100644 index 9fa253b64c..0000000000 Binary files a/mods/ra/maps/allies-01.oramap and /dev/null differ diff --git a/mods/ra/maps/allies-01/map.bin b/mods/ra/maps/allies-01/map.bin new file mode 100644 index 0000000000..36c11cce4b Binary files /dev/null and b/mods/ra/maps/allies-01/map.bin differ diff --git a/mods/ra/maps/allies-01/map.yaml b/mods/ra/maps/allies-01/map.yaml new file mode 100644 index 0000000000..70646c23ea --- /dev/null +++ b/mods/ra/maps/allies-01/map.yaml @@ -0,0 +1,403 @@ +Selectable: True + +MapFormat: 5 + +RequiresMod: ra + +Title: Allies 01 + +Description: Allies' first mission + +Author: Scott_NZ + +Tileset: SNOW + +MapSize: 48,64 + +Bounds: 8,8,32,38 + +UseAsShellmap: False + +Type: Mission + +Players: + PlayerReference@Neutral: + Name: Neutral + OwnsWorld: True + NonCombatant: True + Race: allies + PlayerReference@Creeps: + Name: Creeps + NonCombatant: True + Race: allies + PlayerReference@Allies: + Name: Allies + Playable: True + AllowBots: False + LockRace: True + Race: allies + LockColor: True + ColorRamp: 153,240,130,10 + LockSpawn: True + LockTeam: True + Allies: Creeps + Enemies: Soviets + PlayerReference@Soviets: + Name: Soviets + Race: soviet + ColorRamp: 0,255,128,10 + Enemies: Allies,Creeps + +Actors: + Actor1: tc01 + Location: 13,9 + Owner: Neutral + Actor10: oilb + Location: 17,19 + Owner: Soviets + Actor3: t13 + Location: 17,13 + Owner: Neutral + Actor5: t16 + Location: 25,9 + Owner: Neutral + Actor4: t17 + Location: 17,10 + Owner: Neutral + Actor8: brl3 + Location: 19,21 + Owner: Soviets + Actor7: barl + Location: 19,20 + Owner: Soviets + Actor2: brl3 + Location: 19,19 + Owner: Soviets + Actor6: brl3 + Location: 20,19 + Owner: Soviets + Actor71: t01 + Location: 33,31 + Owner: Neutral + Actor11: powr + Location: 20,20 + Owner: Soviets + Actor12: powr + Location: 24,20 + Owner: Soviets + Actor13: powr + Location: 26,20 + Owner: Soviets + Actor14: t08 + Location: 25,13 + Owner: Neutral + Actor15: fenc + Location: 27,18 + Owner: Soviets + Actor16: fenc + Location: 28,18 + Owner: Soviets + Actor17: fenc + Location: 27,17 + Owner: Soviets + Actor18: jeep + Location: 21,13 + Owner: Allies + Actor19: jeep + Location: 22,13 + Owner: Allies + Actor20: jeep + Location: 23,13 + Owner: Allies + Actor22: e2 + Location: 21,19 + Owner: Soviets + Actor23: e1 + Location: 17,23 + Owner: Soviets + Actor28: e1 + Location: 23,12 + Owner: Allies + Actor26: e1 + Location: 22,12 + Owner: Allies + Actor25: e1 + Location: 21,12 + Owner: Allies + Actor65: fenc + Location: 33,33 + Owner: Soviets + Actor31: mine + Location: 33,14 + Owner: Neutral + Actor32: tc03 + Location: 28,13 + Owner: Neutral + Actor33: v04 + Location: 35,8 + Owner: Neutral + Actor34: tsla + Location: 30,22 + Owner: Soviets + Actor35: proc + Location: 32,21 + Owner: Soviets + Actor37: e1 + Location: 23,24 + Owner: Soviets + Actor0: e2 + Location: 22,27 + Owner: Soviets + Actor21: e2 + Location: 20,27 + Owner: Soviets + Actor40: weap + Location: 24,25 + Owner: Soviets + Actor41: fact + Location: 28,25 + Owner: Soviets + Actor42: barr + Location: 20,28 + Owner: Soviets + Actor43: silo + Location: 18,28 + Owner: Soviets + Actor44: dome + Location: 26,28 + Owner: Soviets + Actor45: t12 + Location: 15,19 + Owner: Neutral + Actor46: t12 + Location: 15,25 + Owner: Neutral + Actor47: fenc + Location: 14,27 + Owner: Soviets + Actor48: fenc + Location: 14,28 + Owner: Soviets + Actor49: fenc + Location: 14,29 + Owner: Soviets + Actor50: fenc + Location: 14,30 + Owner: Soviets + Actor51: tsla + Location: 19,30 + Owner: Soviets + Actor52: tsla + Location: 26,30 + Owner: Soviets + Actor53: fenc + Location: 14,31 + Owner: Soviets + Actor54: fenc + Location: 15,31 + Owner: Soviets + Actor55: fenc + Location: 16,31 + Owner: Soviets + Actor56: fenc + Location: 17,31 + Owner: Soviets + Actor57: fenc + Location: 17,32 + Owner: Soviets + Actor70: fenc + Location: 35,33 + Owner: Soviets + Actor59: e1 + Location: 23,31 + Owner: Soviets + Actor60: e1 + Location: 21,31 + Owner: Soviets + Actor61: powr + Location: 34,30 + Owner: Soviets + Actor58: powr + Location: 36,27 + Owner: Soviets + Actor64: t05 + Location: 32,27 + Owner: Neutral + Actor62: powr + Location: 36,30 + Owner: Soviets + Actor63: fenc + Location: 32,33 + Owner: Soviets + Actor30: powr + Location: 34,27 + Owner: Soviets + Actor67: fenc + Location: 34,33 + Owner: Soviets + Actor68: c1 + Location: 28,16 + Owner: Creeps + Actor69: c2 + Location: 30,17 + Owner: Creeps + Actor72: e1 + Location: 35,29 + Owner: Soviets + Actor66: e1 + Location: 31,29 + Owner: Soviets + Actor9: barl + Location: 18,21 + Owner: Soviets + Actor74: tc02 + Location: 11,23 + Owner: Neutral + Actor73: tc03 + Location: 37,22 + Owner: Neutral + Actor75: t02 + Location: 29,31 + Owner: Neutral + Actor76: t02 + Location: 12,34 + Owner: Neutral + Actor79: fenc + Location: 14,21 + Owner: Soviets + Actor78: fenc + Location: 14,22 + Owner: Soviets + Actor77: fenc + Location: 14,23 + Owner: Soviets + Actor85: 3tnk + Location: 17,25 + Owner: Soviets + Facing: 0 + Actor92: wood + Location: 34,9 + Owner: Neutral + Actor94: c1 + Location: 19,24 + Owner: Soviets + Actor95: c2 + Location: 31,23 + Owner: Soviets + InsertionLZ: waypoint + Location: 22,10 + Owner: Neutral + Lab: stek + Location: 20,24 + Owner: Soviets + Actor24: e2 + Location: 27,24 + Owner: Soviets + ShipSpawnPoint: waypoint + Location: 23,45 + Owner: Neutral + ShipMovePoint: waypoint + Location: 23,40 + Owner: Neutral + InsertionLZEntryPoint: waypoint + Location: 22,4 + Owner: Neutral + Actor27: e2 + Location: 27,27 + Owner: Soviets + ChinookExitPoint: waypoint + Location: 55,11 + Owner: Neutral + ExtractionLZEntryPoint: waypoint + Location: 31,48 + Owner: Neutral + SovietAttackEntryPoint2: waypoint + Location: 39,11 + Owner: Neutral + ExtractionLZ: waypoint + Location: 13,12 + Owner: Neutral + Actor36: e1 + Location: 20,12 + Owner: Allies + Actor38: e1 + Location: 24,12 + Owner: Allies + Actor39: e3 + Location: 21,11 + Owner: Allies + Actor80: e3 + Location: 22,11 + Owner: Allies + Actor81: e3 + Location: 23,11 + Owner: Allies + SovietAttackEntryPoint1: waypoint + Location: 8,30 + Owner: Neutral + Actor29: kenn + Location: 23,28 + Owner: Soviets + +Smudges: + +Rules: + Player: + -ConquestVictoryConditions: + World: + -CrateDrop: + -SpawnMPUnits: + -MPStartLocations: + Allies01Script: + MissionObjectivesPanel: + ObjectivesPanel: MISSION_OBJECTIVES + TRAN: + -Selectable: + RevealsShroud: + Range: 0 + E7: + AutoTarget: + InitialStance: ReturnFire + Passenger: + Weight: 0 + EINSTEIN: + Passenger: + Weight: 0 + JEEP: + Cargo: + MaxWeight: 0 + PipCount: 0 + +Sequences: + +Weapons: + 8Inch: + ROF: 200 + Range: 25 + Burst: 2 + Report: TURRET1 + Projectile: Bullet + Speed: 30 + High: true + Angle: .1 + Inaccuracy: 100 + Image: 120MM + ContrailLength: 10 + Warhead: + Spread: 5 + Versus: + None: 60% + Wood: 75% + Light: 60% + Heavy: 25% + Explosion: large_explosion + WaterExplosion: large_splash + InfDeath: 2 + SmudgeType: Crater + Damage: 500 + ImpactSound: kaboom12 + WaterImpactSound: splash9 + +Voices: + +Notifications: diff --git a/mods/ra/maps/allies-02.oramap b/mods/ra/maps/allies-02.oramap deleted file mode 100644 index 3c38bdf8dd..0000000000 Binary files a/mods/ra/maps/allies-02.oramap and /dev/null differ diff --git a/mods/ra/maps/allies-02/map.bin b/mods/ra/maps/allies-02/map.bin new file mode 100644 index 0000000000..2fcc7d8c2f Binary files /dev/null and b/mods/ra/maps/allies-02/map.bin differ diff --git a/mods/ra/maps/allies-02/map.yaml b/mods/ra/maps/allies-02/map.yaml new file mode 100644 index 0000000000..0f079b48e1 --- /dev/null +++ b/mods/ra/maps/allies-02/map.yaml @@ -0,0 +1,3050 @@ +Selectable: True + +MapFormat: 5 + +RequiresMod: ra + +Title: Allies 02 + +Description: Allies' second mission + +Author: Scott_NZ + +Tileset: SNOW + +MapSize: 128,128 + +Bounds: 16,16,96,96 + +UseAsShellmap: False + +Type: Mission + +Players: + PlayerReference@Neutral: + Name: Neutral + OwnsWorld: True + NonCombatant: True + Race: allies + PlayerReference@Allies1: + Name: Allies1 + Playable: True + AllowBots: False + LockRace: True + Race: allies + LockColor: True + ColorRamp: 153,240,130,10 + LockSpawn: True + LockTeam: True + Allies: Allies2 + Enemies: Soviets + PlayerReference@Allies2: + Name: Allies2 + Playable: True + AllowBots: False + LockRace: True + Race: allies + LockColor: True + ColorRamp: 80,240,130,10 + LockSpawn: True + LockTeam: True + Allies: Allies1 + Enemies: Soviets + PlayerReference@Soviets: + Name: Soviets + Race: soviet + ColorRamp: 0,255,128,10 + Enemies: Allies1,Allies2 + +Actors: + Actor1: v07 + Location: 71,91 + Owner: Neutral + Actor2: v04 + Location: 77,90 + Owner: Neutral + Actor3: v03 + Location: 66,90 + Owner: Neutral + Actor4: v02 + Location: 73,94 + Owner: Neutral + Actor5: v01 + Location: 77,94 + Owner: Neutral + Actor6: v07 + Location: 77,87 + Owner: Neutral + Actor7: v09 + Location: 61,95 + Owner: Neutral + Actor8: v08 + Location: 60,91 + Owner: Neutral + Actor15: t16 + Location: 60,104 + Owner: Neutral + Actor33: t06 + Location: 59,95 + Owner: Neutral + Actor11: wood + Location: 68,100 + Owner: Neutral + Actor12: v05 + Location: 72,87 + Owner: Neutral + Actor20: t05 + Location: 74,76 + Owner: Neutral + Actor10: tc03 + Location: 60,99 + Owner: Neutral + Actor16: wood + Location: 67,100 + Owner: Neutral + Actor17: wood + Location: 66,100 + Owner: Neutral + Actor18: wood + Location: 66,99 + Owner: Neutral + Actor19: wood + Location: 66,98 + Owner: Neutral + Actor29: wood + Location: 65,96 + Owner: Neutral + Actor13: t06 + Location: 65,82 + Owner: Neutral + Actor22: v08 + Location: 83,94 + Owner: Neutral + Actor23: v04 + Location: 64,93 + Owner: Neutral + Actor24: v04 + Location: 83,91 + Owner: Neutral + Actor25: tc04 + Location: 93,86 + Owner: Neutral + Actor26: v12 + Location: 79,91 + Owner: Neutral + Actor31: wood + Location: 63,96 + Owner: Neutral + Actor30: wood + Location: 64,96 + Owner: Neutral + Actor194: sbag + Location: 94,50 + Owner: Soviets + Actor27: wood + Location: 66,97 + Owner: Neutral + Actor14: tc05 + Location: 59,101 + Owner: Neutral + Actor28: wood + Location: 66,96 + Owner: Neutral + Actor9: t12 + Location: 59,98 + Owner: Neutral + Actor34: t14 + Location: 68,98 + Owner: Neutral + Actor35: t11 + Location: 71,89 + Owner: Neutral + Actor36: t15 + Location: 83,95 + Owner: Neutral + Actor115: fenc + Location: 100,99 + Owner: Soviets + Actor38: t14 + Location: 89,97 + Owner: Neutral + Actor39: t15 + Location: 84,108 + Owner: Neutral + Engineer: e6 + Location: 68,86 + Owner: Neutral + Actor41: t01 + Location: 71,80 + Owner: Neutral + Actor43: t02 + Location: 79,102 + Owner: Neutral + Actor132: fenc + Location: 100,100 + Owner: Soviets + Actor45: tc04 + Location: 64,108 + Owner: Neutral + Actor46: tc01 + Location: 64,105 + Owner: Neutral + Actor47: t07 + Location: 77,107 + Owner: Neutral + Actor48: t05 + Location: 92,80 + Owner: Neutral + Actor49: t03 + Location: 87,88 + Owner: Neutral + Actor50: t06 + Location: 96,82 + Owner: Neutral + Actor669: fenc + Location: 95,79 + Owner: Soviets + Actor135: tc05 + Location: 106,109 + Owner: Neutral + Actor58: t06 + Location: 85,105 + Owner: Neutral + Actor125: e2 + Location: 99,86 + Owner: Soviets + Actor599: tc01 + Location: 70,32 + Owner: Neutral + Actor62: t12 + Location: 96,79 + Owner: Neutral + Actor66: t17 + Location: 85,71 + Owner: Neutral + Actor65: t14 + Location: 89,70 + Owner: Neutral + Actor87: t03 + Location: 69,34 + Owner: Neutral + Actor598: t08 + Location: 71,31 + Owner: Neutral + Actor82: e2 + Location: 73,109 + Owner: Soviets + Actor81: e2 + Location: 70,109 + Owner: Soviets + Actor86: e2 + Location: 74,110 + Owner: Soviets + Actor154: e1 + Location: 105,95 + Owner: Soviets + Actor149: sbag + Location: 92,50 + Owner: Soviets + Actor99: e1 + Location: 82,72 + Owner: Soviets + Actor75: t06 + Location: 73,64 + Owner: Neutral + Actor76: t14 + Location: 71,71 + Owner: Neutral + Actor77: tc04 + Location: 93,96 + Owner: Neutral + ChinookHusk: tran.husk2 + Location: 108,87 + Owner: Allies1 + Actor95: fenc + Location: 83,71 + Owner: Soviets + Actor642: t10 + Location: 66,29 + Owner: Neutral + Actor603: fenc + Location: 84,71 + Owner: Soviets + Actor417: brik + Location: 20,67 + Owner: Soviets + Einstein: einstein + Location: 66,85 + Owner: Neutral + Actor85: medi + Location: 110,86 + Owner: Allies1 + SAM1: sam + Location: 105,97 + Owner: Soviets + Tanya: e7 + Location: 106,86 + Owner: Allies1 + Actor60: e2 + Location: 77,96 + Owner: Soviets + Actor59: e2 + Location: 74,92 + Owner: Soviets + Actor89: e1 + Location: 71,99 + Owner: Soviets + Actor88: t07 + Location: 93,80 + Owner: Neutral + Actor469: e2 + Location: 97,20 + Owner: Soviets + Actor438: fenc + Location: 88,19 + Owner: Soviets + Actor56: e1 + Location: 78,74 + Owner: Soviets + Actor549: t16 + Location: 111,50 + Owner: Neutral + Actor242: fenc + Location: 88,50 + Owner: Soviets + Actor104: t10 + Location: 107,46 + Owner: Neutral + Actor163: e2 + Location: 109,96 + Owner: Soviets + Actor90: t02 + Location: 90,72 + Owner: Neutral + Actor106: fenc + Location: 111,94 + Owner: Soviets + Actor590: e1 + Location: 102,97 + Owner: Soviets + Actor64: e1 + Location: 96,93 + Owner: Soviets + Actor207: e1 + Location: 45,22 + Owner: Soviets + Actor264: ftur + Location: 58,55 + Owner: Soviets + Actor209: brik + Location: 58,49 + Owner: Soviets + Actor122: e1 + Location: 89,66 + Owner: Soviets + Actor137: t01 + Location: 111,92 + Owner: Neutral + Actor410: brik + Location: 28,66 + Owner: Soviets + Actor233: fcom + Location: 47,58 + Owner: Soviets + Actor327: brik + Location: 42,67 + Owner: Soviets + Actor98: fenc + Location: 109,93 + Owner: Soviets + Actor105: fenc + Location: 110,94 + Owner: Soviets + Actor146: t16 + Location: 62,85 + Owner: Neutral + Actor159: brl3 + Location: 93,64 + Owner: Soviets + Actor160: tc05 + Location: 15,108 + Owner: Neutral + Actor155: t05 + Location: 110,40 + Owner: Neutral + Actor157: tc05 + Location: 91,36 + Owner: Neutral + Actor330: oilb + Location: 65,31 + Owner: Neutral + Actor360: t16 + Location: 21,81 + Owner: Neutral + Actor114: fenc + Location: 100,98 + Owner: Soviets + Actor136: t15 + Location: 110,103 + Owner: Neutral + Actor226: fenc + Location: 97,39 + Owner: Soviets + Actor113: fenc + Location: 100,97 + Owner: Soviets + Actor110: fenc + Location: 98,97 + Owner: Soviets + Actor152: t01 + Location: 109,39 + Owner: Neutral + Actor439: fenc + Location: 88,18 + Owner: Soviets + Actor127: fenc + Location: 109,101 + Owner: Soviets + Actor153: t08 + Location: 108,58 + Owner: Neutral + Actor130: e1 + Location: 100,77 + Owner: Soviets + Actor118: fenc + Location: 109,102 + Owner: Soviets + Actor158: t07 + Location: 110,48 + Owner: Neutral + Actor126: t03 + Location: 107,79 + Owner: Neutral + Actor143: dome + Location: 102,74 + Owner: Soviets + Actor156: e1 + Location: 98,72 + Owner: Soviets + Actor142: e2 + Location: 101,69 + Owner: Soviets + Actor184: 3tnk + Location: 31,45 + Owner: Soviets + Actor185: tc02 + Location: 17,57 + Owner: Neutral + Actor61: tc05 + Location: 87,109 + Owner: Neutral + Actor381: brik + Location: 28,67 + Owner: Soviets + Actor174: t06 + Location: 51,78 + Owner: Neutral + Actor711: e1 + Location: 74,36 + Owner: Soviets + Actor178: brik + Location: 21,67 + Owner: Soviets + SovietWarFactory: weap + Location: 33,42 + Owner: Soviets + Actor73: e1 + Location: 72,109 + Owner: Soviets + Actor361: tc03 + Location: 27,80 + Owner: Neutral + Actor387: brik + Location: 16,43 + Owner: Soviets + Actor134: tc03 + Location: 110,107 + Owner: Neutral + Actor215: tc01 + Location: 16,62 + Owner: Neutral + Actor186: t06 + Location: 26,39 + Owner: Neutral + Actor187: brik + Location: 31,38 + Owner: Soviets + Actor188: t02 + Location: 55,24 + Owner: Neutral + Actor412: brik + Location: 16,51 + Owner: Soviets + Actor315: brik + Location: 49,67 + Owner: Soviets + Actor37: fenc + Location: 99,97 + Owner: Soviets + Actor195: tc03 + Location: 16,16 + Owner: Neutral + Actor196: t17 + Location: 21,15 + Owner: Neutral + Actor198: tc03 + Location: 18,106 + Owner: Neutral + Actor200: tc01 + Location: 19,110 + Owner: Neutral + Actor423: brik + Location: 18,67 + Owner: Soviets + Actor203: t11 + Location: 45,91 + Owner: Neutral + Actor474: t01 + Location: 26,91 + Owner: Neutral + Actor147: mine + Location: 20,98 + Owner: Neutral + Actor459: tc01 + Location: 41,99 + Owner: Neutral + Actor404: brik + Location: 16,50 + Owner: Soviets + Actor212: dog + Location: 56,50 + Owner: Soviets + Actor552: e3 + Location: 27,66 + Owner: Soviets + Actor176: tc05 + Location: 17,60 + Owner: Neutral + Actor216: t05 + Location: 26,31 + Owner: Neutral + Actor217: t07 + Location: 49,32 + Owner: Neutral + Actor218: t16 + Location: 55,34 + Owner: Neutral + Actor53: e1 + Location: 109,89 + Owner: Allies1 + Actor896: e1 + Location: 25,80 + Owner: Soviets + Actor182: tc02 + Location: 53,35 + Owner: Neutral + Actor52: e1 + Location: 106,88 + Owner: Allies1 + Actor238: t06 + Location: 16,35 + Owner: Neutral + Actor239: t06 + Location: 48,75 + Owner: Neutral + Actor241: tc05 + Location: 24,69 + Owner: Neutral + Actor479: e1 + Location: 29,57 + Owner: Soviets + Actor71: e1 + Location: 86,102 + Owner: Soviets + Actor80: e1 + Location: 70,110 + Owner: Soviets + Actor44: t16 + Location: 87,105 + Owner: Neutral + Actor133: v04 + Location: 83,101 + Owner: Neutral + Actor259: tc01 + Location: 110,109 + Owner: Neutral + Actor140: t11 + Location: 110,82 + Owner: Neutral + Actor610: e2 + Location: 101,79 + Owner: Soviets + Actor109: fenc + Location: 111,95 + Owner: Soviets + Actor70: dog + Location: 87,99 + Owner: Soviets + Actor322: brik + Location: 46,67 + Owner: Soviets + Actor141: t13 + Location: 104,85 + Owner: Neutral + Actor236: 3tnk + Location: 91,45 + Owner: Soviets + Actor254: tc02 + Location: 89,34 + Owner: Neutral + Actor138: tc01 + Location: 104,82 + Owner: Neutral + Actor282: tsla + Location: 31,54 + Owner: Soviets + Actor164: e1 + Location: 107,99 + Owner: Soviets + Actor121: brik + Location: 57,42 + Owner: Soviets + Actor103: brik + Location: 51,40 + Owner: Soviets + Actor292: 3tnk + Location: 37,45 + Owner: Soviets + Actor252: brik + Location: 58,41 + Owner: Soviets + Actor247: brik + Location: 58,42 + Owner: Soviets + Actor396: e1 + Location: 24,59 + Owner: Soviets + Actor251: tsla + Location: 44,36 + Owner: Soviets + Actor271: brik + Location: 50,41 + Owner: Soviets + Actor272: brik + Location: 51,41 + Owner: Soviets + Actor273: brik + Location: 52,41 + Owner: Soviets + Actor274: brik + Location: 53,41 + Owner: Soviets + Actor275: brik + Location: 54,41 + Owner: Soviets + Actor276: brik + Location: 55,41 + Owner: Soviets + Actor277: brik + Location: 56,41 + Owner: Soviets + Actor278: brik + Location: 57,41 + Owner: Soviets + Actor442: e2 + Location: 91,19 + Owner: Soviets + Actor300: 3tnk + Location: 47,43 + Owner: Soviets + Actor503: brik + Location: 57,67 + Owner: Soviets + Actor145: brik + Location: 58,43 + Owner: Soviets + Actor323: brik + Location: 44,67 + Owner: Soviets + Actor362: e2 + Location: 26,26 + Owner: Soviets + Actor324: brik + Location: 42,66 + Owner: Soviets + Actor321: brik + Location: 45,67 + Owner: Soviets + Actor752: stek + Location: 36,57 + Owner: Soviets + Actor325: brik + Location: 43,66 + Owner: Soviets + Actor316: brik + Location: 48,67 + Owner: Soviets + Actor408: t16 + Location: 31,17 + Owner: Neutral + Actor364: brik + Location: 16,42 + Owner: Soviets + Actor263: brik + Location: 58,46 + Owner: Soviets + Actor329: 3tnk + Location: 37,60 + Owner: Soviets + Actor165: brik + Location: 58,45 + Owner: Soviets + Actor197: fenc + Location: 30,27 + Owner: Soviets + Actor257: fenc + Location: 35,24 + Owner: Soviets + Actor199: t01 + Location: 108,49 + Owner: Neutral + Actor440: fenc + Location: 88,17 + Owner: Soviets + Actor222: fenc + Location: 94,63 + Owner: Soviets + Actor441: e1 + Location: 89,19 + Owner: Soviets + Actor287: fenc + Location: 93,63 + Owner: Soviets + Actor93: fenc + Location: 96,65 + Owner: Soviets + Actor223: e2 + Location: 94,64 + Owner: Soviets + Actor224: e2 + Location: 92,67 + Owner: Soviets + Actor437: fenc + Location: 98,21 + Owner: Soviets + Actor21: fenc + Location: 97,47 + Owner: Soviets + Actor227: fenc + Location: 96,39 + Owner: Soviets + Actor208: oilb + Location: 105,43 + Owner: Soviets + Actor231: fenc + Location: 94,38 + Owner: Soviets + Actor201: oilb + Location: 105,40 + Owner: Soviets + Actor210: powr + Location: 105,46 + Owner: Soviets + Actor78: barr + Location: 101,40 + Owner: Soviets + Actor151: fenc + Location: 97,45 + Owner: Soviets + Actor235: tc05 + Location: 106,51 + Owner: Neutral + Actor74: fenc + Location: 97,46 + Owner: Soviets + Actor234: tc03 + Location: 107,54 + Owner: Neutral + Actor219: fenc + Location: 97,41 + Owner: Soviets + Actor221: fenc + Location: 97,40 + Owner: Soviets + Actor228: fenc + Location: 95,39 + Owner: Soviets + Actor248: barl + Location: 100,41 + Owner: Soviets + Actor229: fenc + Location: 94,39 + Owner: Soviets + Actor245: e1 + Location: 101,43 + Owner: Soviets + Actor249: brl3 + Location: 100,40 + Owner: Soviets + Actor250: brl3 + Location: 101,39 + Owner: Soviets + Actor258: e2 + Location: 103,45 + Owner: Soviets + Actor443: e1 + Location: 97,105 + Owner: Soviets + Actor260: e1 + Location: 97,43 + Owner: Soviets + Actor108: e1 + Location: 99,47 + Owner: Soviets + Actor266: e1 + Location: 96,47 + Owner: Soviets + Actor279: brl3 + Location: 106,39 + Owner: Soviets + Actor280: barl + Location: 106,42 + Owner: Soviets + Actor171: tsla + Location: 63,56 + Owner: Soviets + Actor281: brik + Location: 57,49 + Owner: Soviets + Actor444: brik + Location: 57,48 + Owner: Soviets + Actor542: e2 + Location: 40,61 + Owner: Soviets + Actor420: brik + Location: 19,67 + Owner: Soviets + Actor205: fenc + Location: 30,26 + Owner: Soviets + Actor309: brik + Location: 50,67 + Owner: Soviets + Actor395: brik + Location: 16,48 + Owner: Soviets + Actor180: tsla + Location: 56,47 + Owner: Soviets + Actor545: e1 + Location: 57,56 + Owner: Soviets + Actor397: brik + Location: 16,49 + Owner: Soviets + Actor301: tc04 + Location: 27,33 + Owner: Neutral + Actor265: miss + Location: 27,23 + Owner: Soviets + Actor402: brik + Location: 22,67 + Owner: Soviets + Actor311: t10 + Location: 33,20 + Owner: Neutral + Actor183: cycl + Location: 44,20 + Owner: Soviets + Actor193: fenc + Location: 95,63 + Owner: Soviets + Actor192: fenc + Location: 95,64 + Owner: Soviets + Actor94: fenc + Location: 96,64 + Owner: Soviets + Actor640: tc04 + Location: 72,31 + Owner: Neutral + Actor641: t02 + Location: 71,29 + Owner: Neutral + Actor394: brik + Location: 16,47 + Owner: Soviets + Actor345: mine + Location: 107,77 + Owner: Neutral + Actor348: e3 + Location: 87,48 + Owner: Soviets + Actor244: fenc + Location: 86,50 + Owner: Soviets + Actor352: fenc + Location: 71,46 + Owner: Soviets + Actor351: fenc + Location: 72,46 + Owner: Soviets + Actor353: fenc + Location: 70,46 + Owner: Soviets + Actor349: fenc + Location: 72,44 + Owner: Soviets + Actor246: fenc + Location: 85,50 + Owner: Soviets + Actor243: fenc + Location: 87,50 + Owner: Soviets + Actor284: fenc + Location: 85,49 + Owner: Soviets + Actor354: fenc + Location: 70,47 + Owner: Soviets + Actor350: fenc + Location: 72,45 + Owner: Soviets + Actor356: sbag + Location: 69,48 + Owner: Soviets + Actor355: fenc + Location: 69,47 + Owner: Soviets + Actor366: e1 + Location: 88,51 + Owner: Soviets + Actor367: e1 + Location: 92,51 + Owner: Soviets + Actor368: e1 + Location: 91,49 + Owner: Soviets + Actor347: e3 + Location: 86,49 + Owner: Soviets + Actor370: e2 + Location: 94,49 + Owner: Soviets + Actor614: fenc + Location: 78,39 + Owner: Soviets + Actor628: fenc + Location: 80,38 + Owner: Soviets + Actor624: fenc + Location: 79,39 + Owner: Soviets + Actor636: fenc + Location: 81,34 + Owner: Soviets + Actor625: fenc + Location: 80,39 + Owner: Soviets + Actor376: e1 + Location: 107,89 + Owner: Allies1 + Actor377: e1 + Location: 108,89 + Owner: Allies1 + Actor378: e1 + Location: 110,88 + Owner: Allies1 + SAM2: sam + Location: 91,65 + Owner: Soviets + Actor326: brik + Location: 43,67 + Owner: Soviets + Actor230: brik + Location: 44,39 + Owner: Soviets + Actor407: fenc + Location: 35,25 + Owner: Soviets + Actor331: cycl + Location: 46,20 + Owner: Soviets + Actor333: cycl + Location: 48,20 + Owner: Soviets + Actor189: t13 + Location: 88,57 + Owner: Neutral + Actor332: cycl + Location: 47,20 + Owner: Soviets + Actor175: tsla + Location: 48,50 + Owner: Soviets + Actor297: e1 + Location: 33,25 + Owner: Soviets + Actor449: 3tnk + Location: 30,67 + Owner: Soviets + Actor416: brik + Location: 16,53 + Owner: Soviets + Actor660: silo + Location: 24,63 + Owner: Soviets + Actor123: dog + Location: 32,57 + Owner: Soviets + Actor124: mine + Location: 49,25 + Owner: Neutral + Actor389: brik + Location: 16,45 + Owner: Soviets + Actor393: brik + Location: 16,46 + Owner: Soviets + Actor319: brik + Location: 47,67 + Owner: Soviets + Actor341: t10 + Location: 57,68 + Owner: Neutral + Actor506: brik + Location: 56,67 + Owner: Soviets + Actor392: brik + Location: 24,67 + Owner: Soviets + Actor466: brik + Location: 58,48 + Owner: Soviets + Actor112: e1 + Location: 98,87 + Owner: Soviets + Actor428: e1 + Location: 90,100 + Owner: Soviets + Actor305: brik + Location: 51,67 + Owner: Soviets + Actor294: brik + Location: 53,67 + Owner: Soviets + Actor296: brik + Location: 52,67 + Owner: Soviets + Actor306: brik + Location: 16,66 + Owner: Soviets + Actor307: brik + Location: 16,67 + Owner: Soviets + Actor298: e2 + Location: 33,23 + Owner: Soviets + Actor415: brik + Location: 16,52 + Owner: Soviets + Actor500: brik + Location: 58,67 + Owner: Soviets + Actor507: brik + Location: 55,67 + Owner: Soviets + Actor385: brik + Location: 17,41 + Owner: Soviets + Actor499: brik + Location: 59,67 + Owner: Soviets + Actor288: 3tnk + Location: 40,38 + Owner: Soviets + Facing: 0 + Actor57: fact + Location: 44,50 + Owner: Soviets + Actor343: 3tnk + Location: 57,58 + Owner: Soviets + Facing: 192 + Actor363: brik + Location: 16,41 + Owner: Soviets + Actor510: e1 + Location: 94,20 + Owner: Soviets + Actor508: e1 + Location: 79,19 + Owner: Soviets + Actor509: fenc + Location: 77,23 + Owner: Soviets + Actor511: sbag + Location: 96,19 + Owner: Soviets + Actor515: tc05 + Location: 108,17 + Owner: Neutral + Actor516: t13 + Location: 72,20 + Owner: Neutral + Actor492: fenc + Location: 74,18 + Owner: Soviets + Actor519: sbag + Location: 93,18 + Owner: Soviets + Actor489: apwr + Location: 76,19 + Owner: Soviets + Actor517: sbag + Location: 96,17 + Owner: Soviets + Actor520: sbag + Location: 93,19 + Owner: Soviets + Actor488: apwr + Location: 80,19 + Owner: Soviets + Actor501: fenc + Location: 74,22 + Owner: Soviets + Actor502: fenc + Location: 74,21 + Owner: Soviets + Actor107: oilb + Location: 68,29 + Owner: Neutral + Actor232: fenc + Location: 94,37 + Owner: Soviets + Actor102: spen + Location: 101,35 + Owner: Soviets + Actor487: apwr + Location: 80,16 + Owner: Soviets + Actor523: t17 + Location: 85,20 + Owner: Neutral + Actor522: t05 + Location: 90,16 + Owner: Neutral + Actor494: fenc + Location: 74,20 + Owner: Soviets + Actor493: fenc + Location: 74,19 + Owner: Soviets + Actor518: sbag + Location: 94,17 + Owner: Soviets + Actor521: sbag + Location: 93,17 + Owner: Soviets + Actor237: tc04 + Location: 99,53 + Owner: Neutral + Actor490: fenc + Location: 74,16 + Owner: Soviets + Actor491: fenc + Location: 74,17 + Owner: Soviets + Actor504: e2 + Location: 78,23 + Owner: Soviets + Actor505: e1 + Location: 84,18 + Owner: Soviets + Actor289: sbag + Location: 95,17 + Owner: Soviets + SAM3: sam + Location: 94,18 + Owner: Soviets + Actor512: sbag + Location: 96,18 + Owner: Soviets + Actor486: apwr + Location: 76,16 + Owner: Soviets + Actor514: tc03 + Location: 104,20 + Owner: Neutral + Actor190: fenc + Location: 31,27 + Owner: Soviets + Actor526: fenc + Location: 76,23 + Owner: Soviets + Actor527: fenc + Location: 75,23 + Owner: Soviets + Actor528: fenc + Location: 74,23 + Owner: Soviets + Actor167: brik + Location: 58,44 + Owner: Soviets + Actor663: dog + Location: 46,46 + Owner: Soviets + Actor413: e1 + Location: 104,38 + Owner: Soviets + Actor403: brik + Location: 17,66 + Owner: Soviets + Actor626: barl + Location: 80,72 + Owner: Soviets + Actor419: e1 + Location: 82,62 + Owner: Soviets + Actor150: sbag + Location: 93,50 + Owner: Soviets + Actor608: brl3 + Location: 81,72 + Owner: Soviets + Actor427: e1 + Location: 76,71 + Owner: Soviets + Actor429: e2 + Location: 78,70 + Owner: Soviets + Actor380: sbag + Location: 70,48 + Owner: Soviets + Actor328: 3tnk + Location: 35,60 + Owner: Soviets + Actor541: e1 + Location: 38,62 + Owner: Soviets + Actor383: brik + Location: 27,67 + Owner: Soviets + Actor391: brik + Location: 25,67 + Owner: Soviets + Actor611: t05 + Location: 81,65 + Owner: Neutral + Actor336: fenc + Location: 90,20 + Owner: Soviets + Actor422: fenc + Location: 96,21 + Owner: Soviets + Actor335: fenc + Location: 89,20 + Owner: Soviets + Actor436: fenc + Location: 97,21 + Owner: Soviets + Actor421: fenc + Location: 91,20 + Owner: Soviets + Actor334: fenc + Location: 88,20 + Owner: Soviets + Actor432: tsla + Location: 60,65 + Owner: Soviets + Actor117: dog + Location: 25,55 + Owner: Soviets + Actor431: brik + Location: 16,54 + Owner: Soviets + Actor293: brik + Location: 54,67 + Owner: Soviets + Actor0: apwr + Location: 49,42 + Owner: Soviets + SAM4: sam + Location: 31,24 + Owner: Soviets + Actor202: fenc + Location: 29,26 + Owner: Soviets + Actor295: e1 + Location: 28,25 + Owner: Soviets + Actor554: e3 + Location: 26,66 + Owner: Soviets + Actor299: dog + Location: 31,23 + Owner: Soviets + Actor452: tent + Location: 40,95 + Owner: Allies2 + Actor170: weap + Location: 23,103 + Owner: Allies2 + Actor460: t08 + Location: 40,110 + Owner: Neutral + Actor206: dome + Location: 38,100 + Owner: Allies2 + Actor204: apwr + Location: 37,107 + Owner: Allies2 + Actor169: tsla + Location: 17,39 + Owner: Soviets + Actor92: powr + Location: 101,46 + Owner: Soviets + Actor318: dome + Location: 55,58 + Owner: Soviets + Actor434: ftur + Location: 42,68 + Owner: Soviets + Actor320: kenn + Location: 54,51 + Owner: Soviets + Actor84: fenc + Location: 110,93 + Owner: Soviets + Actor83: apwr + Location: 37,104 + Owner: Allies2 + Actor162: mine + Location: 19,95 + Owner: Neutral + ReinforcementsEntryPoint: waypoint + Location: 31,111 + Owner: Neutral + Actor481: e2 + Location: 23,41 + Owner: Soviets + Actor480: apwr + Location: 28,40 + Owner: Soviets + Actor483: e2 + Location: 28,54 + Owner: Soviets + Actor537: 3tnk + Location: 43,52 + Owner: Soviets + Actor547: e1 + Location: 38,55 + Owner: Soviets + Actor312: brik + Location: 62,65 + Owner: Soviets + Actor314: brik + Location: 62,67 + Owner: Soviets + Actor96: fenc + Location: 82,71 + Owner: Soviets + Actor433: ftur + Location: 29,68 + Owner: Soviets + Actor313: brik + Location: 62,66 + Owner: Soviets + Actor540: e1 + Location: 32,62 + Owner: Soviets + Actor539: dog + Location: 31,63 + Owner: Soviets + Actor536: dog + Location: 59,55 + Owner: Soviets + Actor177: brik + Location: 58,47 + Owner: Soviets + SovietBarracks: barr + Location: 41,58 + Owner: Soviets + Actor384: brik + Location: 29,66 + Owner: Soviets + Actor379: brik + Location: 61,66 + Owner: Soviets + Actor97: fenc + Location: 111,66 + Owner: Soviets + Actor497: brik + Location: 60,67 + Owner: Soviets + Actor369: brik + Location: 61,67 + Owner: Soviets + Actor538: dog + Location: 40,64 + Owner: Soviets + Actor543: e2 + Location: 56,55 + Owner: Soviets + Actor390: brik + Location: 26,67 + Owner: Soviets + Actor310: fix + Location: 36,51 + Owner: Soviets + Actor401: brik + Location: 23,67 + Owner: Soviets + Actor550: e1 + Location: 55,46 + Owner: Soviets + Actor382: brik + Location: 29,67 + Owner: Soviets + Actor544: e1 + Location: 59,58 + Owner: Soviets + Actor557: e3 + Location: 48,66 + Owner: Soviets + Actor445: 3tnk + Location: 41,67 + Owner: Soviets + Actor79: e1 + Location: 80,87 + Owner: Soviets + Actor42: t07 + Location: 92,110 + Owner: Neutral + Actor558: v10 + Location: 64,90 + Owner: Neutral + ExtractionLZ: waypoint + Location: 30,24 + Owner: Neutral + ExtractionLZEntryPoint: waypoint + Location: 9,9 + Owner: Neutral + Actor111: apwr + Location: 22,55 + Owner: Soviets + Actor120: apwr + Location: 22,52 + Owner: Soviets + Actor426: tsla + Location: 43,64 + Owner: Soviets + Actor191: tsla + Location: 28,64 + Owner: Soviets + Actor386: tsla + Location: 18,65 + Owner: Soviets + Actor424: brik + Location: 17,67 + Owner: Soviets + Actor365: brik + Location: 17,42 + Owner: Soviets + Actor533: brik + Location: 17,54 + Owner: Soviets + Actor317: cycl + Location: 43,20 + Owner: Soviets + Actor482: apwr + Location: 25,40 + Owner: Soviets + Actor555: e1 + Location: 29,50 + Owner: Soviets + Actor645: apwr + Location: 28,43 + Owner: Soviets + Actor414: t13 + Location: 74,43 + Owner: Neutral + Actor290: apwr + Location: 52,42 + Owner: Soviets + Actor54: proc + Location: 25,95 + Owner: Allies2 + Actor455: fenc + Location: 31,93 + Owner: Allies2 + Actor446: spen + Location: 58,17 + Owner: Soviets + Actor213: cycl + Location: 45,20 + Owner: Soviets + Actor448: e2 + Location: 54,22 + Owner: Soviets + Actor468: fenc + Location: 29,93 + Owner: Allies2 + Actor456: fenc + Location: 41,93 + Owner: Allies2 + Actor531: fenc + Location: 45,93 + Owner: Allies2 + Actor461: fenc + Location: 44,93 + Owner: Allies2 + Actor458: fenc + Location: 43,93 + Owner: Allies2 + Actor453: fenc + Location: 27,93 + Owner: Allies2 + Actor470: fenc + Location: 26,93 + Owner: Allies2 + Actor454: pbox.e1 + Location: 32,93 + Owner: Allies2 + Actor465: fenc + Location: 30,93 + Owner: Allies2 + Actor473: pbox.e1 + Location: 40,93 + Owner: Allies2 + Actor472: gun + Location: 41,92 + Owner: Allies2 + Actor451: fenc + Location: 28,93 + Owner: Allies2 + Actor478: fenc + Location: 24,91 + Owner: Allies2 + Actor484: fenc + Location: 23,91 + Owner: Allies2 + Actor476: fenc + Location: 25,92 + Owner: Allies2 + Actor475: gun + Location: 31,92 + Owner: Allies2 + Actor471: fenc + Location: 25,93 + Owner: Allies2 + Actor477: fenc + Location: 25,91 + Owner: Allies2 + Actor534: 1tnk + Location: 37,90 + Owner: Allies2 + Facing: 0 + Actor398: 1tnk + Location: 36,90 + Owner: Allies2 + Facing: 0 + Actor457: fenc + Location: 42,93 + Owner: Allies2 + BadgerDropPoint1: waypoint + Location: 19,96 + Owner: Neutral + BadgerEntryPoint1: waypoint + Location: 40,12 + Owner: Neutral + Actor485: tc03 + Location: 41,101 + Owner: Neutral + Actor495: tc02 + Location: 40,102 + Owner: Neutral + Actor51: t13 + Location: 66,80 + Owner: Neutral + Allies2BasePoint: waypoint + Location: 34,96 + Owner: Neutral + FlamersEntryPoint: waypoint + Location: 16,74 + Owner: Neutral + Actor388: brik + Location: 16,44 + Owner: Soviets + Actor560: e3 + Location: 56,66 + Owner: Soviets + Actor561: e3 + Location: 57,66 + Owner: Soviets + Actor562: e3 + Location: 47,66 + Owner: Soviets + Actor563: e1 + Location: 36,48 + Owner: Soviets + Actor564: apwr + Location: 61,58 + Owner: Soviets + Actor565: e1 + Location: 42,56 + Owner: Soviets + Actor566: e1 + Location: 54,61 + Owner: Soviets + Actor567: e1 + Location: 53,48 + Owner: Soviets + Actor568: e1 + Location: 19,45 + Owner: Soviets + Actor569: e1 + Location: 31,56 + Owner: Soviets + Actor873: brl3 + Location: 45,79 + Owner: Neutral + Actor179: t16 + Location: 24,75 + Owner: Neutral + Actor139: tc02 + Location: 20,72 + Owner: Neutral + Actor570: oilb + Location: 43,80 + Owner: Neutral + Actor885: t12 + Location: 40,77 + Owner: Neutral + Actor584: tc04 + Location: 52,70 + Owner: Neutral + Actor585: tc02 + Location: 49,70 + Owner: Neutral + Actor586: tc01 + Location: 45,70 + Owner: Neutral + Actor587: t17 + Location: 31,84 + Owner: Neutral + SovietRallyPoint: waypoint + Location: 36,65 + Owner: Neutral + Actor605: barl + Location: 91,68 + Owner: Soviets + Actor498: barl + Location: 94,65 + Owner: Soviets + Actor67: tc01 + Location: 97,65 + Owner: Neutral + Actor462: t02 + Location: 65,89 + Owner: Neutral + Actor529: fenc + Location: 107,102 + Owner: Soviets + Actor588: e1 + Location: 69,93 + Owner: Neutral + Actor535: fenc + Location: 101,100 + Owner: Soviets + Actor524: e1 + Location: 69,89 + Owner: Neutral + Actor513: e1 + Location: 67,88 + Owner: Neutral + Actor211: e1 + Location: 105,107 + Owner: Soviets + Actor530: fenc + Location: 106,102 + Owner: Soviets + Actor591: e2 + Location: 104,101 + Owner: Soviets + Actor128: fenc + Location: 108,102 + Owner: Soviets + Actor592: dog + Location: 108,97 + Owner: Soviets + Actor525: e1 + Location: 70,88 + Owner: Neutral + Actor604: brl3 + Location: 90,67 + Owner: Soviets + Actor720: fenc + Location: 110,66 + Owner: Soviets + Actor556: e1 + Location: 110,89 + Owner: Allies1 + Actor600: barl + Location: 92,68 + Owner: Soviets + Actor647: fenc + Location: 84,72 + Owner: Soviets + Actor532: e1 + Location: 106,89 + Owner: Allies1 + SovietTownAttackPoint1: waypoint + Location: 72,110 + Owner: Neutral + Actor464: t05 + Location: 64,82 + Owner: Neutral + Actor463: tc04 + Location: 60,83 + Owner: Neutral + Actor714: e1 + Location: 73,90 + Owner: Neutral + Actor609: e2 + Location: 99,79 + Owner: Soviets + Actor721: fenc + Location: 109,66 + Owner: Soviets + Actor606: brl3 + Location: 89,67 + Owner: Soviets + Actor144: t01 + Location: 98,107 + Owner: Neutral + Actor594: e1 + Location: 73,88 + Owner: Neutral + Actor595: e1 + Location: 73,83 + Owner: Soviets + SovietTownAttackPoint2: waypoint + Location: 86,78 + Owner: Neutral + Actor129: e1 + Location: 102,78 + Owner: Soviets + Actor181: mine + Location: 109,76 + Owner: Neutral + Actor72: dog + Location: 81,71 + Owner: Soviets + Actor617: truk + Location: 104,43 + Owner: Soviets + Actor619: sbag + Location: 67,48 + Owner: Soviets + Actor618: sbag + Location: 68,48 + Owner: Soviets + Actor620: sbag + Location: 67,49 + Owner: Soviets + Actor621: sbag + Location: 67,50 + Owner: Soviets + Actor637: fenc + Location: 82,34 + Owner: Soviets + Actor553: tsla + Location: 37,48 + Owner: Soviets + Actor220: sbag + Location: 92,48 + Owner: Soviets + Actor371: e1 + Location: 62,42 + Owner: Soviets + Actor548: e3 + Location: 60,44 + Owner: Soviets + Actor372: e1 + Location: 63,48 + Owner: Soviets + Actor425: sbag + Location: 71,48 + Owner: Soviets + Actor607: sbag + Location: 72,48 + Owner: Soviets + Actor631: e2 + Location: 68,49 + Owner: Soviets + Actor632: e2 + Location: 71,49 + Owner: Soviets + Actor374: e2 + Location: 59,42 + Owner: Soviets + Actor613: e3 + Location: 70,49 + Owner: Soviets + Actor635: e1 + Location: 66,48 + Owner: Soviets + Actor375: e2 + Location: 56,40 + Owner: Soviets + Actor373: e2 + Location: 61,46 + Owner: Soviets + Actor742: fenc + Location: 84,34 + Owner: Soviets + Actor225: fenc + Location: 84,49 + Owner: Soviets + Actor597: t16 + Location: 82,67 + Owner: Neutral + Actor596: tc01 + Location: 83,65 + Owner: Neutral + Actor559: tc02 + Location: 84,66 + Owner: Neutral + Actor418: tc04 + Location: 81,68 + Owner: Neutral + Actor32: tc05 + Location: 83,67 + Owner: Neutral + Actor496: 3tnk + Location: 86,20 + Owner: Soviets + Actor646: fenc + Location: 84,70 + Owner: Soviets + Actor649: fenc + Location: 86,70 + Owner: Soviets + Actor648: fenc + Location: 85,70 + Owner: Soviets + Actor100: e1 + Location: 87,61 + Owner: Soviets + Actor339: e1 + Location: 80,59 + Owner: Soviets + Actor589: dog + Location: 80,57 + Owner: Soviets + Actor340: e1 + Location: 77,58 + Owner: Soviets + Actor630: 3tnk + Location: 35,65 + Owner: Soviets + Actor633: 3tnk + Location: 36,66 + Owner: Soviets + Actor634: 3tnk + Location: 37,65 + Owner: Soviets + Actor55: wood + Location: 79,94 + Owner: Neutral + Actor168: wood + Location: 79,95 + Owner: Neutral + Actor172: wood + Location: 79,96 + Owner: Neutral + Actor308: cycl + Location: 43,19 + Owner: Soviets + Actor644: cycl + Location: 54,20 + Owner: Soviets + Actor411: silo + Location: 25,62 + Owner: Soviets + Actor240: apwr + Location: 45,16 + Owner: Soviets + Actor551: apwr + Location: 48,16 + Owner: Soviets + Actor643: cycl + Location: 53,20 + Owner: Soviets + Actor304: cycl + Location: 43,18 + Owner: Soviets + Actor303: cycl + Location: 43,17 + Owner: Soviets + Actor302: cycl + Location: 43,16 + Owner: Soviets + Actor661: tc03 + Location: 54,16 + Owner: Neutral + Actor615: cycl + Location: 52,20 + Owner: Soviets + Actor659: silo + Location: 25,63 + Owner: Soviets + Actor664: silo + Location: 24,62 + Owner: Soviets + Actor666: dog + Location: 30,47 + Owner: Soviets + Actor667: tc04 + Location: 88,106 + Owner: Neutral + Actor668: t16 + Location: 80,106 + Owner: Neutral + Actor670: fenc + Location: 95,78 + Owner: Soviets + Actor671: fenc + Location: 94,78 + Owner: Soviets + Actor672: fenc + Location: 93,78 + Owner: Soviets + Actor69: e1 + Location: 90,102 + Owner: Soviets + Actor68: e2 + Location: 92,102 + Owner: Soviets + Actor63: e1 + Location: 92,104 + Owner: Soviets + Actor673: wood + Location: 82,97 + Owner: Neutral + Actor674: wood + Location: 81,97 + Owner: Neutral + Actor682: wood + Location: 74,82 + Owner: Neutral + Actor681: wood + Location: 70,100 + Owner: Neutral + Actor680: wood + Location: 69,100 + Owner: Neutral + Actor679: wood + Location: 84,90 + Owner: Neutral + Actor678: wood + Location: 85,90 + Owner: Neutral + Actor676: wood + Location: 79,97 + Owner: Neutral + Actor677: wood + Location: 86,90 + Owner: Neutral + Actor675: wood + Location: 80,97 + Owner: Neutral + Actor686: brl3 + Location: 82,73 + Owner: Soviets + TownPoint: waypoint + Location: 70,89 + Owner: Neutral + Actor688: e1 + Location: 70,86 + Owner: Neutral + Actor689: e1 + Location: 69,84 + Owner: Neutral + Actor687: e1 + Location: 82,77 + Owner: Soviets + Actor690: e1 + Location: 85,76 + Owner: Soviets + Actor692: e1 + Location: 89,79 + Owner: Soviets + Actor695: e1 + Location: 84,79 + Owner: Soviets + Actor697: e1 + Location: 89,80 + Owner: Soviets + Actor699: e2 + Location: 86,77 + Owner: Soviets + Actor173: proc + Location: 51,16 + Owner: Soviets + Actor701: e1 + Location: 69,110 + Owner: Soviets + Actor702: e1 + Location: 74,109 + Owner: Soviets + Actor704: e1 + Location: 73,110 + Owner: Soviets + Actor705: e1 + Location: 71,109 + Owner: Soviets + Actor694: dog + Location: 87,79 + Owner: Soviets + Actor712: e1 + Location: 71,86 + Owner: Neutral + Actor713: e1 + Location: 68,91 + Owner: Neutral + Actor593: e1 + Location: 73,85 + Owner: Neutral + Actor707: v18 + Location: 68,97 + Owner: Neutral + Actor716: e3 + Location: 66,89 + Owner: Neutral + Actor717: e3 + Location: 66,87 + Owner: Neutral + Actor718: e3 + Location: 64,88 + Owner: Neutral + Actor612: t07 + Location: 80,67 + Owner: Neutral + Actor601: t11 + Location: 74,72 + Owner: Neutral + Actor627: t01 + Location: 84,59 + Owner: Neutral + Actor131: sbag + Location: 92,49 + Owner: Soviets + Actor639: 3tnk + Location: 84,77 + Owner: Soviets + Actor683: wood + Location: 75,82 + Owner: Neutral + Actor684: wood + Location: 76,82 + Owner: Neutral + Actor685: wood + Location: 77,82 + Owner: Neutral + Actor691: wood + Location: 78,82 + Owner: Neutral + Actor693: wood + Location: 79,82 + Owner: Neutral + Actor700: tsla + Location: 55,17 + Owner: Soviets + Actor698: wood + Location: 80,82 + Owner: Neutral + Actor708: v17 + Location: 69,97 + Owner: Neutral + Actor101: dog + Location: 98,74 + Owner: Soviets + Actor715: e2 + Location: 75,34 + Owner: Soviets + Actor91: apc + Location: 102,71 + Owner: Soviets + Actor602: fenc + Location: 99,80 + Owner: Soviets + Actor346: fenc + Location: 100,80 + Owner: Soviets + Actor166: fenc + Location: 101,80 + Owner: Soviets + Actor723: fenc + Location: 93,77 + Owner: Soviets + Actor725: fenc + Location: 75,74 + Owner: Soviets + Actor724: fenc + Location: 76,74 + Owner: Soviets + Actor726: fenc + Location: 74,74 + Owner: Soviets + Actor727: fenc + Location: 73,74 + Owner: Soviets + Actor728: fenc + Location: 72,74 + Owner: Soviets + Actor729: fenc + Location: 72,73 + Owner: Soviets + Actor730: fenc + Location: 72,72 + Owner: Soviets + Actor40: tran.husk1 + Location: 69,87 + Owner: Allies1 + Actor884: barl + Location: 45,80 + Owner: Neutral + Actor357: t05 + Location: 26,79 + Owner: Neutral + Actor575: tc05 + Location: 16,89 + Owner: Neutral + Actor573: 2tnk + Location: 34,92 + Owner: Allies2 + Facing: 0 + Actor577: tc02 + Location: 81,87 + Owner: Neutral + Actor576: tc01 + Location: 15,90 + Owner: Neutral + Actor574: 2tnk + Location: 35,92 + Owner: Allies2 + Facing: 0 + Actor578: v11 + Location: 64,84 + Owner: Neutral + Actor546: 1tnk + Location: 38,90 + Owner: Allies2 + Facing: 0 + BadgerDropPoint2: waypoint + Location: 34,106 + Owner: Neutral + BadgerDropPoint3: waypoint + Location: 26,100 + Owner: Neutral + TanksEntryPoint: waypoint + Location: 16,86 + Owner: Neutral + Actor399: brik + Location: 65,65 + Owner: Soviets + Actor400: brik + Location: 65,64 + Owner: Soviets + Actor405: brik + Location: 65,63 + Owner: Soviets + Actor406: brik + Location: 65,62 + Owner: Soviets + Actor409: brik + Location: 65,61 + Owner: Soviets + Actor447: brik + Location: 65,60 + Owner: Soviets + Actor572: brik + Location: 65,59 + Owner: Soviets + Actor579: brik + Location: 65,58 + Owner: Soviets + Actor580: brik + Location: 65,57 + Owner: Soviets + Actor581: brik + Location: 65,56 + Owner: Soviets + Actor582: brik + Location: 64,56 + Owner: Soviets + Actor583: brik + Location: 64,57 + Owner: Soviets + Actor616: brik + Location: 64,65 + Owner: Soviets + Actor622: brik + Location: 63,65 + Owner: Soviets + Actor623: brik + Location: 64,64 + Owner: Soviets + Actor629: e2 + Location: 40,53 + Owner: Soviets + Actor662: e1 + Location: 47,61 + Owner: Soviets + Actor703: e2 + Location: 51,59 + Owner: Soviets + Actor706: sbag + Location: 62,47 + Owner: Soviets + Actor709: sbag + Location: 62,46 + Owner: Soviets + Actor710: sbag + Location: 62,45 + Owner: Soviets + Actor719: sbag + Location: 61,45 + Owner: Soviets + Actor731: brik + Location: 45,39 + Owner: Soviets + Actor732: sbag + Location: 61,43 + Owner: Soviets + Actor733: sbag + Location: 60,43 + Owner: Soviets + Actor734: sbag + Location: 60,42 + Owner: Soviets + Actor735: sbag + Location: 60,41 + Owner: Soviets + Actor736: sbag + Location: 60,40 + Owner: Soviets + Actor737: sbag + Location: 60,39 + Owner: Soviets + Actor738: sbag + Location: 59,39 + Owner: Soviets + Actor739: sbag + Location: 58,39 + Owner: Soviets + Actor740: sbag + Location: 57,39 + Owner: Soviets + Actor741: sbag + Location: 56,39 + Owner: Soviets + Actor638: fenc + Location: 83,34 + Owner: Soviets + Actor743: fenc + Location: 84,33 + Owner: Soviets + Actor744: fenc + Location: 85,33 + Owner: Soviets + Actor342: e1 + Location: 99,38 + Owner: Soviets + Actor749: fenc + Location: 92,76 + Owner: Soviets + Actor748: fenc + Location: 92,77 + Owner: Soviets + Actor745: fenc + Location: 92,75 + Owner: Soviets + Actor286: e1 + Location: 104,67 + Owner: Soviets + Actor755: e1 + Location: 107,70 + Owner: Soviets + Actor756: e2 + Location: 107,67 + Owner: Soviets + Actor161: proc + Location: 108,69 + Owner: Soviets + Actor285: powr + Location: 102,68 + Owner: Soviets + Actor747: fenc + Location: 93,74 + Owner: Soviets + Actor746: fenc + Location: 93,75 + Owner: Soviets + YakAttackPoint: waypoint + Location: 78,62 + Owner: Neutral + YakEntryPoint: waypoint + Location: 99,10 + Owner: Neutral + Actor116: dog + Location: 38,42 + Owner: Soviets + Actor119: dog + Location: 36,55 + Owner: Soviets + Actor214: dog + Location: 48,61 + Owner: Soviets + Actor262: dog + Location: 50,53 + Owner: Soviets + Actor337: dog + Location: 26,59 + Owner: Soviets + Actor338: dog + Location: 21,43 + Owner: Soviets + Actor344: dog + Location: 23,50 + Owner: Soviets + Actor291: 3tnk + Location: 51,49 + Owner: Soviets + Actor467: dog + Location: 49,19 + Owner: Soviets + BadgerEntryPoint2: waypoint + Location: 119,77 + Owner: Neutral + ParabombPoint1: waypoint + Location: 39,105 + Owner: Neutral + ParabombPoint2: waypoint + Location: 39,108 + Owner: Neutral + Actor722: t14 + Location: 67,52 + Owner: Neutral + Actor750: brik + Location: 17,53 + Owner: Soviets + Actor256: 3tnk + Location: 21,39 + Owner: Soviets + Facing: 0 + Actor430: afld + Location: 54,63 + Owner: Soviets + Actor753: afld + Location: 51,63 + Owner: Soviets + Actor665: brik + Location: 50,38 + Owner: Soviets + Actor757: 3tnk + Location: 31,53 + Owner: Soviets + Actor758: 3tnk + Location: 40,56 + Owner: Soviets + Actor759: 3tnk + Location: 19,48 + Owner: Soviets + Actor760: 3tnk + Location: 53,56 + Owner: Soviets + Actor761: e1 + Location: 47,56 + Owner: Soviets + Actor762: 3tnk + Location: 48,64 + Owner: Soviets + Actor763: tsla + Location: 79,24 + Owner: Soviets + Actor764: e1 + Location: 95,59 + Owner: Soviets + Actor765: e1 + Location: 98,56 + Owner: Soviets + Actor768: fenc + Location: 95,60 + Owner: Soviets + Actor767: dog + Location: 95,57 + Owner: Soviets + Actor766: e1 + Location: 93,56 + Owner: Soviets + Actor769: fenc + Location: 96,60 + Owner: Soviets + Actor775: fenc + Location: 99,57 + Owner: Soviets + Actor774: fenc + Location: 99,58 + Owner: Soviets + Actor773: fenc + Location: 98,58 + Owner: Soviets + Actor772: fenc + Location: 96,58 + Owner: Soviets + Actor771: fenc + Location: 97,58 + Owner: Soviets + Actor770: fenc + Location: 96,59 + Owner: Soviets + Actor776: e1 + Location: 74,69 + Owner: Soviets + Actor777: fenc + Location: 99,56 + Owner: Soviets + Actor359: t02 + Location: 41,81 + Owner: Neutral + Actor779: brik + Location: 24,38 + Owner: Soviets + Actor780: brik + Location: 25,38 + Owner: Soviets + Actor781: brik + Location: 26,38 + Owner: Soviets + Actor782: brik + Location: 27,38 + Owner: Soviets + Actor783: brik + Location: 28,38 + Owner: Soviets + Actor784: brik + Location: 29,38 + Owner: Soviets + Actor785: brik + Location: 30,38 + Owner: Soviets + Actor786: brik + Location: 32,38 + Owner: Soviets + Actor787: brik + Location: 33,38 + Owner: Soviets + Actor788: brik + Location: 34,38 + Owner: Soviets + Actor789: brik + Location: 35,38 + Owner: Soviets + Actor790: brik + Location: 36,38 + Owner: Soviets + Actor791: brik + Location: 37,38 + Owner: Soviets + Actor793: brik + Location: 36,39 + Owner: Soviets + Actor792: brik + Location: 25,39 + Owner: Soviets + Actor794: brik + Location: 37,39 + Owner: Soviets + Actor796: tc03 + Location: 36,27 + Owner: Neutral + Actor795: t16 + Location: 32,36 + Owner: Neutral + Actor797: brik + Location: 24,39 + Owner: Soviets + Actor798: e2 + Location: 28,39 + Owner: Soviets + Actor799: e2 + Location: 34,40 + Owner: Soviets + Actor800: e1 + Location: 39,40 + Owner: Soviets + Actor801: t05 + Location: 43,48 + Owner: Neutral + Actor802: t06 + Location: 22,64 + Owner: Neutral + Actor803: t05 + Location: 56,45 + Owner: Neutral + Actor651: apwr + Location: 61,61 + Owner: Soviets + Actor805: t01 + Location: 37,54 + Owner: Neutral + Actor806: t03 + Location: 30,31 + Owner: Neutral + Actor807: sbag + Location: 37,35 + Owner: Soviets + Actor808: sbag + Location: 36,35 + Owner: Soviets + Actor809: sbag + Location: 35,35 + Owner: Soviets + Actor810: sbag + Location: 34,35 + Owner: Soviets + Actor812: sbag + Location: 23,34 + Owner: Soviets + Actor811: sbag + Location: 23,35 + Owner: Soviets + Actor813: sbag + Location: 31,35 + Owner: Soviets + Actor814: sbag + Location: 30,35 + Owner: Soviets + Actor815: sbag + Location: 30,36 + Owner: Soviets + Actor816: sbag + Location: 29,36 + Owner: Soviets + Actor817: sbag + Location: 28,36 + Owner: Soviets + Actor818: sbag + Location: 27,36 + Owner: Soviets + Actor819: sbag + Location: 26,36 + Owner: Soviets + Actor820: sbag + Location: 24,34 + Owner: Soviets + Actor821: sbag + Location: 25,34 + Owner: Soviets + Actor822: sbag + Location: 26,34 + Owner: Soviets + Actor823: e1 + Location: 38,36 + Owner: Soviets + Actor824: e1 + Location: 32,34 + Owner: Soviets + Actor825: e1 + Location: 22,36 + Owner: Soviets + Actor826: e2 + Location: 24,35 + Owner: Soviets + Actor827: e2 + Location: 31,36 + Owner: Soviets + Actor828: e2 + Location: 28,37 + Owner: Soviets + Actor829: e3 + Location: 34,36 + Owner: Soviets + Actor830: e1 + Location: 18,53 + Owner: Soviets + Actor832: sbag + Location: 16,36 + Owner: Soviets + Actor283: brik + Location: 44,38 + Owner: Soviets + Actor833: sbag + Location: 17,36 + Owner: Soviets + Actor834: sbag + Location: 18,36 + Owner: Soviets + Actor835: sbag + Location: 18,35 + Owner: Soviets + SovietReinforcementsEntryPoint1: waypoint + Location: 42,16 + Owner: Neutral + SovietReinforcementsEntryPoint2: waypoint + Location: 24,16 + Owner: Neutral + Actor837: dog + Location: 36,61 + Owner: Soviets + Actor838: dog + Location: 42,43 + Owner: Soviets + Actor839: dog + Location: 39,48 + Owner: Soviets + Actor840: dog + Location: 34,51 + Owner: Soviets + Actor841: 3tnk + Location: 43,45 + Owner: Soviets + Actor842: 3tnk + Location: 30,62 + Owner: Soviets + Actor843: 3tnk + Location: 26,56 + Owner: Soviets + Actor844: 3tnk + Location: 58,64 + Owner: Soviets + Actor845: 3tnk + Location: 49,58 + Owner: Soviets + Actor846: e1 + Location: 60,61 + Owner: Soviets + Actor847: e1 + Location: 25,52 + Owner: Soviets + Actor848: e1 + Location: 20,65 + Owner: Soviets + Actor849: pbox.e3 + Location: 41,64 + Owner: Soviets + Actor850: pbox.e3 + Location: 30,64 + Owner: Soviets + Actor851: pbox.e3 + Location: 44,34 + Owner: Soviets + Actor852: pbox.e3 + Location: 38,33 + Owner: Soviets + Actor853: pbox.e3 + Location: 23,32 + Owner: Soviets + Actor854: pbox.e3 + Location: 17,31 + Owner: Soviets + Actor650: apwr + Location: 25,43 + Owner: Soviets + Actor652: apwr + Location: 52,45 + Owner: Soviets + Actor653: apwr + Location: 49,45 + Owner: Soviets + Actor654: tsla + Location: 24,36 + Owner: Soviets + Actor655: tsla + Location: 37,36 + Owner: Soviets + Actor656: ftur + Location: 41,40 + Owner: Soviets + Actor657: ftur + Location: 20,37 + Owner: Soviets + Actor658: 3tnk + Location: 25,49 + Owner: Soviets + Actor696: hpad + Location: 28,59 + Owner: Soviets + Actor751: brik + Location: 50,39 + Owner: Soviets + Actor754: brik + Location: 50,40 + Owner: Soviets + Actor804: brik + Location: 49,38 + Owner: Soviets + Actor836: brik + Location: 48,38 + Owner: Soviets + Actor855: brik + Location: 47,38 + Owner: Soviets + Actor856: brik + Location: 46,38 + Owner: Soviets + Actor857: brik + Location: 45,38 + Owner: Soviets + Actor253: e1 + Location: 21,90 + Owner: Allies2 + Actor255: e1 + Location: 23,89 + Owner: Allies2 + Actor270: e1 + Location: 27,90 + Owner: Allies2 + Actor268: e1 + Location: 33,90 + Owner: Allies2 + Actor269: e1 + Location: 34,90 + Owner: Allies2 + Actor267: jeep + Location: 25,89 + Owner: Allies2 + Facing: 0 + Actor882: barl + Location: 46,81 + Owner: Neutral + Actor871: brl3 + Location: 44,82 + Owner: Neutral + Actor874: brl3 + Location: 34,78 + Owner: Neutral + Actor872: brl3 + Location: 39,81 + Owner: Neutral + Actor870: brl3 + Location: 29,79 + Owner: Neutral + Actor450: oilb + Location: 40,80 + Owner: Neutral + Actor148: oilb + Location: 30,77 + Owner: Neutral + Actor435: oilb + Location: 27,77 + Owner: Neutral + Actor868: t10 + Location: 21,77 + Owner: Neutral + Actor358: t16 + Location: 40,78 + Owner: Neutral + Actor261: tc01 + Location: 42,77 + Owner: Neutral + Actor778: t05 + Location: 48,78 + Owner: Neutral + Actor831: t15 + Location: 47,82 + Owner: Neutral + Actor899: e1 + Location: 37,79 + Owner: Soviets + Actor865: t08 + Location: 24,110 + Owner: Neutral + Actor864: t01 + Location: 33,109 + Owner: Neutral + Actor863: t05 + Location: 38,97 + Owner: Neutral + Actor860: tc04 + Location: 18,78 + Owner: Neutral + Actor862: t07 + Location: 41,71 + Owner: Neutral + Actor861: tc04 + Location: 29,73 + Owner: Neutral + Actor867: t01 + Location: 16,68 + Owner: Neutral + Actor909: oilb + Location: 45,86 + Owner: Neutral + Actor883: barl + Location: 44,79 + Owner: Neutral + Actor905: v01 + Location: 20,74 + Owner: Neutral + Actor901: barl + Location: 39,80 + Owner: Neutral + Actor888: barl + Location: 28,79 + Owner: Neutral + Actor881: barl + Location: 43,82 + Owner: Neutral + Actor894: barl + Location: 30,75 + Owner: Soviets + Actor891: barl + Location: 31,77 + Owner: Neutral + Actor897: barl + Location: 25,79 + Owner: Neutral + Actor893: e2 + Location: 30,81 + Owner: Soviets + Actor878: t15 + Location: 34,80 + Owner: Neutral + Actor879: barl + Location: 40,82 + Owner: Neutral + Actor869: brl3 + Location: 31,76 + Owner: Neutral + Actor886: barl + Location: 33,78 + Owner: Neutral + Actor866: e2 + Location: 38,77 + Owner: Soviets + Actor859: brl3 + Location: 25,78 + Owner: Neutral + Actor898: barl + Location: 26,77 + Owner: Neutral + Actor907: e2 + Location: 33,77 + Owner: Soviets + Actor906: v03 + Location: 16,72 + Owner: Neutral + Actor914: brl3 + Location: 44,86 + Owner: Neutral + Actor911: tc03 + Location: 15,92 + Owner: Neutral + Actor912: oilb + Location: 45,89 + Owner: Neutral + Actor908: t16 + Location: 16,91 + Owner: Neutral + Actor919: barl + Location: 44,89 + Owner: Neutral + Actor913: brl3 + Location: 44,91 + Owner: Neutral + Actor922: barl + Location: 47,86 + Owner: Neutral + Actor923: barl + Location: 47,87 + Owner: Neutral + +Smudges: + +Rules: + Player: + -ConquestVictoryConditions: + World: + -CrateDrop: + -SpawnMPUnits: + -MPStartLocations: + Allies02Script: + MissionObjectivesPanel: + ObjectivesPanel: MISSION_OBJECTIVES + TRAN.Husk1: + Burns: + Damage: 0 + TRAN.Husk2: + Burns: + Damage: 0 + E7: + AutoTarget: + InitialStance: ReturnFire + Passenger: + Weight: 0 + EINSTEIN: + Passenger: + Weight: 0 + V01: + ContainsCrate: + TRAN: + -Selectable: + Buildable: + Owner: None + RevealsShroud: + Range: 0 + MEDI: + Buildable: + Prerequisites: + SPY: + Buildable: + Prerequisites: dome + MIG: + Buildable: + Owner: None + YAK: + Buildable: + Owner: None + HELI: + Buildable: + Owner: None + HIND: + Buildable: + Owner: None + SS: + Buildable: + Owner: None + MSUB: + Buildable: + Owner: None + DD: + Buildable: + Owner: None + CA: + Buildable: + Owner: None + PT: + Buildable: + Owner: None + MSLO: + Buildable: + Owner: None + GAP: + Buildable: + Owner: None + SPEN: + Buildable: + Owner: None + SYRD: + Buildable: + Owner: None + IRON: + Buildable: + Owner: None + PDOX: + Buildable: + Owner: None + TSLA: + Buildable: + Owner: None + AGUN: + Buildable: + Owner: None + FTUR: + Buildable: + Owner: None + SAM: + Buildable: + Owner: None + ATEK: + Buildable: + Owner: None + HPAD: + Buildable: + Owner: None + AFLD: + Buildable: + Owner: None + STEK: + Buildable: + Owner: None + BARR: + Buildable: + Owner: None + 4TNK: + Buildable: + Owner: None + MCV: + Buildable: + Owner: None + ARTY: + Buildable: + Owner: None + APC: + Buildable: + Owner: None + MNLY.AP: + Buildable: + Owner: None + MNLY.AT: + Buildable: + Owner: None + TRUK: + Buildable: + Owner: None + TTNK: + Buildable: + Owner: None + FTRK: + Buildable: + Owner: None + CRATE: + GiveCashCrateAction: + SelectionShares: 0 + LevelUpCrateAction: + SelectionShares: 0 + ExplodeCrateAction@fire: + SelectionShares: 0 + ExplodeCrateAction@boom: + SelectionShares: 0 + ExplodeCrateAction@nuke: + SelectionShares: 0 + HideMapCrateAction: + SelectionShares: 0 + HealUnitsCrateAction: + SelectionShares: 10000 + RevealMapCrateAction: + SelectionShares: 0 + SupportPowerCrateAction@parabombs: + SelectionShares: 0 + GiveMcvCrateAction: + SelectionShares: 0 + GiveUnitCrateAction@jeep: + SelectionShares: 0 + GiveUnitCrateAction@arty: + SelectionShares: 0 + GiveUnitCrateAction@v2rl: + SelectionShares: 0 + GiveUnitCrateAction@1tnk: + SelectionShares: 0 + GiveUnitCrateAction@2tnk: + SelectionShares: 0 + GiveUnitCrateAction@3tnk: + SelectionShares: 0 + GiveUnitCrateAction@4tnk: + SelectionShares: 0 + +Sequences: + +Weapons: + +Voices: + +Notifications: diff --git a/mods/ra/mod.yaml b/mods/ra/mod.yaml index 541f24fbc1..1503199386 100644 --- a/mods/ra/mod.yaml +++ b/mods/ra/mod.yaml @@ -64,6 +64,7 @@ ChromeLayout: mods/ra/chrome/dropdowns.yaml mods/ra/chrome/modchooser.yaml mods/ra/chrome/cheats.yaml + mods/ra/chrome/objectives.yaml Weapons: mods/ra/weapons.yaml diff --git a/mods/ra/rules/civilian.yaml b/mods/ra/rules/civilian.yaml index b2ff726db8..b8006d6e2b 100644 --- a/mods/ra/rules/civilian.yaml +++ b/mods/ra/rules/civilian.yaml @@ -8,6 +8,8 @@ FCOM: HP: 400 Armor: Type: Wood + Tooltip: + Name: Forward Command RevealsShroud: Range: 10 Bib: @@ -136,6 +138,7 @@ BARL: Health: HP: 10 Explodes: + Weapon: BarrelExplode Tooltip: Name: Explosive Barrel @@ -146,6 +149,7 @@ BRL3: Health: HP: 10 Explodes: + Weapon: BarrelExplode Tooltip: Name: Explosive Barrel diff --git a/mods/ra/rules/structures.yaml b/mods/ra/rules/structures.yaml index 533f8b38d7..6e0f7cbbe6 100644 --- a/mods/ra/rules/structures.yaml +++ b/mods/ra/rules/structures.yaml @@ -1214,6 +1214,7 @@ KENN: Range: 4 IronCurtainable: -EmitInfantryOnSell: + -AcceptsSupplies: FIX: Inherits: ^Building diff --git a/mods/ra/rules/system.yaml b/mods/ra/rules/system.yaml index e1f6458436..52a499871a 100644 --- a/mods/ra/rules/system.yaml +++ b/mods/ra/rules/system.yaml @@ -355,6 +355,10 @@ CRATE: HideMapCrateAction: SelectionShares: 5 Effect: hide-map + HealUnitsCrateAction: + Notification: heal2.aud + SelectionShares: 2 + Effect: heal RevealMapCrateAction: SelectionShares: 1 Effect: reveal-map diff --git a/mods/ra/uibits/dialog.png b/mods/ra/uibits/dialog.png index b7047caefa..a5f2cc0411 100644 Binary files a/mods/ra/uibits/dialog.png and b/mods/ra/uibits/dialog.png differ diff --git a/mods/ra/weapons.yaml b/mods/ra/weapons.yaml index f85479eead..15fe007964 100644 --- a/mods/ra/weapons.yaml +++ b/mods/ra/weapons.yaml @@ -1107,6 +1107,23 @@ UnitExplodeSmall: Explosion: large_explosion InfDeath: 4 ImpactSound: kaboom15 + +BarrelExplode: + Warhead: + Damage: 500 + Spread: 10 + Versus: + None: 120% + Wood: 200% + Light: 50% + Heavy: 25% + Concrete: 10% + Explosion: napalm + InfDeath: 4 + ImpactSound: firebl3 + SmudgeType: Scorch + Delay: 5 + Size: 2,2 Crush: Warhead: