Remove hardcoded missions

This commit is contained in:
ScottNZ
2014-03-08 00:26:09 +13:00
parent 1d9681a1d2
commit 856120f2b2
34 changed files with 20 additions and 17510 deletions

View File

@@ -1,322 +0,0 @@
#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.Graphics;
using OpenRA.Mods.RA.Activities;
using OpenRA.Mods.RA.Air;
using OpenRA.Mods.RA.Move;
using OpenRA.Scripting;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Missions
{
class Allies01ScriptInfo : TraitInfo<Allies01Script>, Requires<SpawnMapActorsInfo> { }
class Allies01Script : IHasObjectives, IWorldLoaded, ITick
{
public event Action<bool> OnObjectivesUpdated = notify => { };
public IEnumerable<Objective> Objectives { get { return new[] { findEinstein, extractEinstein }; } }
Objective findEinstein = new Objective(ObjectiveType.Primary, FindEinsteinText, ObjectiveStatus.InProgress);
Objective extractEinstein = new Objective(ObjectiveType.Primary, ExtractEinsteinText, ObjectiveStatus.Inactive);
const string FindEinsteinText = "Find Einstein. Tanya and Einstein must survive.";
const string ExtractEinsteinText = "Wait for the helicopter and extract Einstein. Tanya and Einstein must survive.";
Player allies;
Player soviets;
Actor insertionLZ;
Actor extractionLZ;
Actor lab;
Actor insertionLZEntryPoint;
Actor extractionLZEntryPoint;
Actor chinookExitPoint;
Actor shipSpawnPoint;
Actor shipMovePoint;
Actor einstein;
Actor einsteinChinook;
Actor tanya;
Actor attackEntryPoint1;
Actor attackEntryPoint2;
World world;
static readonly string[] Taunts = { "laugh1.aud", "lefty1.aud", "cmon1.aud", "gotit1.aud" };
static readonly string[] Ships = { "ca", "ca", "ca", "ca" };
static readonly string[] Patrol = { "e1", "dog", "e1" };
static readonly string[] AttackWave = { "e1", "e1", "e1", "e1", "e2", "e2", "e2", "e2", "dog" };
static readonly string[] LastAttackWaveAddition = { "3tnk", "e1", "e1", "e1", "e1", "e2", "e2", "e2", "e2" };
int currentAttackWaveFrameNumber;
int currentAttackWave;
const int EinsteinChinookAttackWave = 5;
const int LabClearRange = 5;
const string EinsteinName = "einstein";
const string TanyaName = "e7";
const string SignalFlareName = "flare";
string difficulty;
void MissionAccomplished(string text)
{
MissionUtils.CoopMissionAccomplished(world, text, allies);
}
void MissionFailed(string text)
{
MissionUtils.CoopMissionFailed(world, text, allies);
}
public void Tick(Actor self)
{
if (allies.WinState != WinState.Undefined) return;
if (world.FrameNumber % 1000 == 0)
Sound.Play(Taunts[world.SharedRandom.Next(Taunts.Length)]);
if (findEinstein.Status == ObjectiveStatus.InProgress)
{
if (AlliesControlLab())
LabSecured();
if (lab.IsDead())
{
findEinstein.Status = ObjectiveStatus.Failed;
OnObjectivesUpdated(true);
MissionFailed("Einstein was killed.");
}
}
if (extractEinstein.Status == ObjectiveStatus.InProgress)
{
if (difficulty != "Easy")
{
ManageSovietUnits();
if (world.FrameNumber >= currentAttackWaveFrameNumber + 400)
{
SpawnSovietUnits(AttackWave);
currentAttackWave++;
currentAttackWaveFrameNumber = world.FrameNumber;
if (currentAttackWave >= EinsteinChinookAttackWave)
SpawnSovietUnits(LastAttackWaveAddition);
if (currentAttackWave == EinsteinChinookAttackWave)
ExtractEinsteinAtLZ();
}
}
if (einsteinChinook != null)
{
if (einsteinChinook.IsDead())
{
extractEinstein.Status = ObjectiveStatus.Failed;
OnObjectivesUpdated(true);
MissionFailed("The extraction helicopter was destroyed.");
}
else if (!world.Map.IsInMap(einsteinChinook.Location) && einsteinChinook.Trait<Cargo>().Passengers.Contains(einstein))
{
extractEinstein.Status = ObjectiveStatus.Completed;
OnObjectivesUpdated(true);
MissionAccomplished("Einstein was rescued");
}
}
}
if (tanya != null && tanya.IsDead())
MissionFailed("Tanya was killed.");
else if (einstein != null && einstein.IsDead())
MissionFailed("Einstein was killed.");
MissionUtils.CapOre(soviets);
}
void LabSecured()
{
SpawnSignalFlare();
Sound.Play("flaren1.aud");
SpawnEinsteinAtLab();
SendShips();
lab.QueueActivity(new Transform(lab, "stek") { SkipMakeAnims = true });
findEinstein.Status = ObjectiveStatus.Completed;
extractEinstein.Status = ObjectiveStatus.InProgress;
OnObjectivesUpdated(true);
currentAttackWaveFrameNumber = world.FrameNumber;
if (difficulty == "Easy")
ExtractEinsteinAtLZ();
else
{
var infantry = MissionUtils.FindQueues(world, soviets, "Infantry").FirstOrDefault();
if (infantry != null)
infantry.ResolveOrder(infantry.self, Order.StartProduction(infantry.self, "e1", 5));
}
}
void SpawnSignalFlare()
{
world.CreateActor(SignalFlareName, new TypeDictionary { new OwnerInit(allies), new LocationInit(extractionLZ.Location) });
}
void SpawnSovietUnits(IEnumerable<string> wave)
{
foreach (var unit in wave)
{
var spawnActor = world.SharedRandom.Next(2) == 0 ? attackEntryPoint1 : attackEntryPoint2;
world.CreateActor(unit, new TypeDictionary { new OwnerInit(soviets), new LocationInit(spawnActor.Location) });
}
}
void ManageSovietUnits()
{
foreach (var unit in world.Actors.Where(u => u.IsInWorld && u.Owner == soviets && !u.IsDead() && u.IsIdle
&& u.HasTrait<Mobile>() && u.HasTrait<AttackBase>()))
{
Activity innerActivity;
if (einstein != null)
{
if (einstein.IsInWorld)
innerActivity = new Move.Move(Target.FromActor(einstein), WRange.FromCells(3));
else
{
var container = world.UnitContaining(einstein);
if (container != null && !container.HasTrait<Aircraft>() && container.HasTrait<Mobile>())
innerActivity = new Move.Move(Target.FromActor(container), WRange.FromCells(3));
else
innerActivity = new Move.Move(extractionLZ.Location, 3);
}
unit.QueueActivity(new AttackMove.AttackMoveActivity(unit, innerActivity));
}
}
}
void SendPatrol()
{
for (int i = 0; i < Patrol.Length; i++)
world.CreateActor(Patrol[i], new TypeDictionary
{
new OwnerInit(soviets),
new LocationInit(insertionLZ.Location + new CVec(-1 + i, 10 + i * 2))
})
.QueueActivity(new Move.Move(insertionLZ.Location));
}
bool AlliesControlLab()
{
return MissionUtils.AreaSecuredWithUnits(world, allies, lab.CenterPosition, WRange.FromCells(LabClearRange));
}
void SpawnEinsteinAtLab()
{
einstein = world.CreateActor(EinsteinName, new TypeDictionary { new OwnerInit(allies), new LocationInit(lab.Location) });
einstein.QueueActivity(new Move.Move(lab.Location - new CVec(0, 2)));
}
void SendShips()
{
for (int i = 0; i < Ships.Length; i++)
world.CreateActor(Ships[i], new TypeDictionary
{
new OwnerInit(allies),
new LocationInit(shipSpawnPoint.Location + new CVec(i * 2, 0))
})
.QueueActivity(new Move.Move(shipMovePoint.Location + new CVec(i * 4, 0)));
}
void ExtractEinsteinAtLZ()
{
einsteinChinook = MissionUtils.ExtractUnitWithChinook(
world,
allies,
einstein,
extractionLZEntryPoint.Location,
extractionLZ.Location,
chinookExitPoint.Location);
}
void InsertTanyaAtLZ()
{
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()
{
foreach (var actor in world.Actors.Where(a => a.IsInWorld && a.Owner == allies && !a.IsDead() && a.HasTrait<AutoTarget>()))
actor.Trait<AutoTarget>().Stance = UnitStance.Defend;
}
public void WorldLoaded(World w, WorldRenderer wr)
{
world = w;
difficulty = w.LobbyInfo.GlobalSettings.Difficulty;
Game.Debug("{0} difficulty selected".F(difficulty));
allies = w.Players.Single(p => p.InternalName == "Allies");
soviets = w.Players.Single(p => p.InternalName == "Soviets");
allies.PlayerActor.Trait<PlayerResources>().Cash = 0;
var actors = w.WorldActor.Trait<SpawnMapActors>().Actors;
insertionLZ = actors["InsertionLZ"];
extractionLZ = actors["ExtractionLZ"];
lab = actors["Lab"];
insertionLZEntryPoint = actors["InsertionLZEntryPoint"];
chinookExitPoint = actors["ChinookExitPoint"];
extractionLZEntryPoint = actors["ExtractionLZEntryPoint"];
shipSpawnPoint = actors["ShipSpawnPoint"];
shipMovePoint = actors["ShipMovePoint"];
attackEntryPoint1 = actors["SovietAttackEntryPoint1"];
attackEntryPoint2 = actors["SovietAttackEntryPoint2"];
SetAlliedUnitsToDefensiveStance();
wr.Viewport.Center(insertionLZ.CenterPosition);
if (w.LobbyInfo.IsSinglePlayer)
Media.PlayFMVFullscreen(w, "ally1.vqa", () =>
Media.PlayFMVFullscreen(w, "landing.vqa", () =>
{
InsertTanyaAtLZ();
SendPatrol();
MissionUtils.PlayMissionMusic();
})
);
else
{
InsertTanyaAtLZ();
SendPatrol();
MissionUtils.PlayMissionMusic();
}
}
}
}

View File

@@ -1,478 +0,0 @@
#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.Graphics;
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.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Missions
{
class Allies02ScriptInfo : TraitInfo<Allies02Script>, Requires<SpawnMapActorsInfo> { }
class Allies02Script : IHasObjectives, IWorldLoaded, ITick
{
public event Action<bool> OnObjectivesUpdated = notify => { };
public IEnumerable<Objective> Objectives { get { return new[] { findEinstein, destroySamSites, extractEinstein, maintainPresence, fewDeaths }; } }
Objective findEinstein = new Objective(ObjectiveType.Primary, FindEinsteinText, ObjectiveStatus.InProgress);
Objective destroySamSites = new Objective(ObjectiveType.Primary, DestroySamSitesText, ObjectiveStatus.InProgress);
Objective extractEinstein = new Objective(ObjectiveType.Primary, ExtractEinsteinText, ObjectiveStatus.Inactive);
Objective maintainPresence = new Objective(ObjectiveType.Primary, MaintainPresenceText, ObjectiveStatus.InProgress);
Objective fewDeaths = new Objective(ObjectiveType.Secondary, "", ObjectiveStatus.InProgress);
const string FindEinsteinText = "Find Einstein's crashed helicopter. Tanya must survive.";
const string DestroySamSitesText = "Destroy the SAM sites. Tanya must survive.";
const string ExtractEinsteinText = "Wait for the helicopter and extract Einstein. Tanya and Einstein must survive.";
const string MaintainPresenceText = "Maintain an Allied presence in the area. Reinforcements will arrive soon.";
const string FewDeathsTemplate = "Lose fewer than {0}/{1} units.";
const int DeathsThreshold = 200;
Actor sam1;
Actor sam2;
Actor sam3;
Actor sam4;
Actor[] sams;
Actor tanya;
Actor einstein;
Actor engineer;
Actor chinookHusk;
Actor allies2BasePoint;
Actor reinforcementsEntryPoint;
Actor extractionLZEntryPoint;
Actor extractionLZ;
Actor badgerEntryPoint1;
Actor badgerEntryPoint2;
Actor badgerDropPoint1;
Actor badgerDropPoint2;
Actor badgerDropPoint3;
Actor parabombPoint1;
Actor parabombPoint2;
Actor sovietRallyPoint;
Actor townPoint;
Actor sovietTownAttackPoint1;
Actor sovietTownAttackPoint2;
Actor yakEntryPoint;
Actor yakAttackPoint;
Actor yak;
Actor einsteinChinook;
World world;
Player allies;
Player allies1;
Player allies2;
Player soviets;
Actor sovietBarracks;
Actor sovietWarFactory;
CountdownTimer reinforcementsTimer;
CountdownTimerWidget reinforcementsTimerWidget;
CPos alliedBaseTopLeft;
CPos alliedBaseBottomRight;
const string InfantryQueueName = "Infantry";
const string VehicleQueueName = "Vehicle";
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 = 5;
const int ReinforcementsTicks = 1500 * 16;
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"
};
int currentReinforcement = -1;
const int ParabombTicks = 750;
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" };
const string SignalFlareName = "flare";
const string YakName = "yak";
const int AlliedTownTransferRange = 15;
const int SovietTownAttackGroupRange = 5;
const int SovietTownMoveNearEnough = 3;
void MissionFailed(string text)
{
MissionUtils.CoopMissionFailed(world, text, allies1, allies2);
if (reinforcementsTimer != null)
reinforcementsTimerWidget.Visible = false;
}
void MissionAccomplished(string text)
{
MissionUtils.CoopMissionAccomplished(world, text, allies1, allies2);
}
public void Tick(Actor self)
{
if (allies1.WinState != WinState.Undefined) return;
if (world.FrameNumber % 50 == 1 && chinookHusk.IsInWorld)
world.Add(new Smoke(world, chinookHusk.CenterPosition, "smoke_m"));
if (world.FrameNumber == 1)
{
InitializeSovietFactories();
StartReinforcementsTimer();
}
reinforcementsTimer.Tick();
if (world.FrameNumber == ParatroopersTicks)
{
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 == ParabombTicks)
{
MissionUtils.Parabomb(world, soviets, badgerEntryPoint2.Location, parabombPoint1.Location);
MissionUtils.Parabomb(world, soviets, badgerEntryPoint2.Location + new CVec(0, 3), parabombPoint2.Location);
}
if (allies1 != allies2)
{
if (yak == null || (yak != null && !yak.IsDead() && (yak.GetCurrentActivity() is FlyCircle || yak.IsIdle)))
{
var alliedUnitsNearYakPoint = world.FindAliveCombatantActorsInCircle(yakAttackPoint.CenterPosition, WRange.FromCells(10))
.Where(a => a.Owner != soviets && a.HasTrait<IPositionable>() && a != tanya && a != einstein && a != engineer);
if (alliedUnitsNearYakPoint.Any())
YakStrafe(alliedUnitsNearYakPoint);
}
}
if (currentReinforcement > -1 && currentReinforcement < Reinforcements.Length && world.FrameNumber % 25 == 0)
SpawnAlliedUnit(Reinforcements[currentReinforcement++]);
if (world.FrameNumber % 25 == 0)
{
BuildSovietUnits();
ManageSovietUnits();
}
UpdateDeaths();
if (findEinstein.Status == ObjectiveStatus.InProgress)
{
if (AlliesNearTown())
{
findEinstein.Status = ObjectiveStatus.Completed;
OnObjectivesUpdated(true);
TransferTownUnitsToAllies();
SovietsAttackTown();
}
}
if (destroySamSites.Status == ObjectiveStatus.InProgress)
{
if (sams.All(s => s.IsDead() || s.Owner != soviets))
{
destroySamSites.Status = ObjectiveStatus.Completed;
extractEinstein.Status = ObjectiveStatus.InProgress;
OnObjectivesUpdated(true);
world.CreateActor(SignalFlareName, new TypeDictionary { new OwnerInit(allies1), new LocationInit(extractionLZ.Location) });
Sound.Play("flaren1.aud");
ExtractEinsteinAtLZ();
}
}
if (extractEinstein.Status == ObjectiveStatus.InProgress && einsteinChinook != null)
{
if (einsteinChinook.IsDead())
{
extractEinstein.Status = ObjectiveStatus.Failed;
OnObjectivesUpdated(true);
MissionFailed("The extraction helicopter was destroyed.");
}
else if (!world.Map.IsInMap(einsteinChinook.Location) && einsteinChinook.Trait<Cargo>().Passengers.Contains(einstein))
{
extractEinstein.Status = ObjectiveStatus.Completed;
maintainPresence.Status = ObjectiveStatus.Completed;
if (fewDeaths.Status == ObjectiveStatus.InProgress)
fewDeaths.Status = ObjectiveStatus.Completed;
OnObjectivesUpdated(true);
MissionAccomplished("Einstein was rescued.");
}
}
if (tanya.IsDead())
MissionFailed("Tanya was killed.");
else if (einstein.IsDead())
MissionFailed("Einstein was killed.");
world.AddFrameEndTask(w =>
{
if (!w.FindAliveCombatantActorsInBox(alliedBaseTopLeft, alliedBaseBottomRight)
.Any(a => (a.Owner == allies || a.Owner == allies2) && (a.HasTrait<Building>() && !a.HasTrait<Wall>()) || a.HasTrait<BaseBuilding>()))
{
maintainPresence.Status = ObjectiveStatus.Failed;
OnObjectivesUpdated(true);
MissionFailed("The Allied reinforcements have been defeated.");
}
});
}
void UpdateDeaths()
{
var unitDeaths = allies1.PlayerActor.Trait<PlayerStatistics>().UnitsDead + allies2.PlayerActor.Trait<PlayerStatistics>().UnitsDead;
fewDeaths.Text = FewDeathsTemplate.F(unitDeaths, DeathsThreshold);
OnObjectivesUpdated(false);
if (unitDeaths >= DeathsThreshold && fewDeaths.Status == ObjectiveStatus.InProgress)
{
fewDeaths.Status = ObjectiveStatus.Failed;
OnObjectivesUpdated(true);
}
}
void YakStrafe(IEnumerable<Actor> candidates)
{
if (yak == null)
{
var altitude = Rules.Info[YakName].Traits.Get<PlaneInfo>().CruiseAltitude;
yak = world.CreateActor(YakName, new TypeDictionary
{
new CenterPositionInit(yakEntryPoint.CenterPosition + new WVec(WRange.Zero, WRange.Zero, altitude)),
new OwnerInit(soviets),
new FacingInit(Traits.Util.GetFacing(yakAttackPoint.Location - yakEntryPoint.Location, 0))
});
}
if (yak.Trait<LimitedAmmo>().HasAmmo())
yak.QueueActivity(new FlyAttack(Target.FromActor(candidates.Random(world.SharedRandom))));
else
{
yak.QueueActivity(new FlyOffMap());
yak.QueueActivity(new RemoveSelf());
}
}
void BuildSovietUnits()
{
if (!sovietBarracks.IsDead())
BuildSovietUnit(InfantryQueueName, SovietInfantry.Random(world.SharedRandom));
if (!sovietWarFactory.IsDead())
{
var vehicles = world.FrameNumber >= SovietVehiclesUpgradeTicks ? SovietVehicles2 : SovietVehicles1;
BuildSovietUnit(VehicleQueueName, vehicles.Random(world.SharedRandom));
}
}
void ManageSovietUnits()
{
var units = world.FindAliveCombatantActorsInCircle(sovietRallyPoint.CenterPosition, WRange.FromCells(10))
.Where(u => u.IsIdle && u.HasTrait<Mobile>() && u.HasTrait<AttackBase>() && u.Owner == soviets)
.Except(world.WorldActor.Trait<SpawnMapActors>().Actors.Values);
if (units.Count() >= SovietGroupSize)
{
foreach (var unit in units)
MissionUtils.AttackNearestLandActor(true, unit, allies2);
}
var scatteredUnits = world.Actors.Where(u => u.IsInWorld && !u.IsDead() && u.IsIdle
&& u.HasTrait<Mobile>() && u.HasTrait<AttackBase>() && u.Owner == soviets)
.Except(world.WorldActor.Trait<SpawnMapActors>().Actors.Values)
.Except(units);
foreach (var unit in scatteredUnits)
MissionUtils.AttackNearestLandActor(true, unit, allies2);
}
void SetupAlliedBase()
{
foreach (var actor in world.Actors.Where(a => a.Owner == allies && a != allies.PlayerActor))
{
actor.ChangeOwner(allies2);
if (actor.Info.Name == "proc")
actor.QueueActivity(new Transform(actor, "proc") { SkipMakeAnims = true }); // for harv spawn
foreach (var c in actor.TraitsImplementing<INotifyCapture>())
c.OnCapture(actor, actor, allies, allies2);
}
}
void InitializeSovietFactories()
{
var sbrp = sovietBarracks.Trait<RallyPoint>();
var swrp = sovietWarFactory.Trait<RallyPoint>();
sbrp.rallyPoint = swrp.rallyPoint = sovietRallyPoint.Location;
sbrp.nearEnough = swrp.nearEnough = 6;
sovietBarracks.Trait<PrimaryBuilding>().SetPrimaryProducer(sovietBarracks, true);
sovietWarFactory.Trait<PrimaryBuilding>().SetPrimaryProducer(sovietWarFactory, true);
}
void BuildSovietUnit(string category, string unit)
{
MissionUtils.StartProduction(world, soviets, category, unit);
}
void StartReinforcementsTimer()
{
Sound.Play("timergo1.aud");
reinforcementsTimer = new CountdownTimer(ReinforcementsTicks, ReinforcementsTimerExpired, true);
reinforcementsTimerWidget = new CountdownTimerWidget(reinforcementsTimer, "Allied reinforcements arrive in: {0}");
Ui.Root.AddChild(reinforcementsTimerWidget);
}
void ReinforcementsTimerExpired(CountdownTimer countdownTimer)
{
reinforcementsTimerWidget.Visible = false;
currentReinforcement++;
Sound.Play("aarrivs1.aud");
}
void SpawnAlliedUnit(string unit)
{
world.CreateActor(unit, new TypeDictionary
{
new LocationInit(reinforcementsEntryPoint.Location),
new FacingInit(0),
new OwnerInit(allies2)
})
.QueueActivity(new Move.Move(allies2BasePoint.Location));
}
void ExtractEinsteinAtLZ()
{
einsteinChinook = MissionUtils.ExtractUnitWithChinook(
world,
allies1,
einstein,
extractionLZEntryPoint.Location,
extractionLZ.Location,
extractionLZEntryPoint.Location);
}
bool AlliesNearTown()
{
return world.FindAliveCombatantActorsInCircle(townPoint.CenterPosition, WRange.FromCells(AlliedTownTransferRange))
.Any(a => a.Owner == allies1 && a.HasTrait<IPositionable>());
}
void TransferTownUnitsToAllies()
{
foreach (var unit in world.FindAliveNonCombatantActorsInCircle(townPoint.CenterPosition, WRange.FromCells(AlliedTownTransferRange))
.Where(a => a.HasTrait<Mobile>()))
unit.ChangeOwner(allies1);
}
void SovietsAttackTown()
{
var sovietAttackUnits = world.FindAliveCombatantActorsInCircle(sovietTownAttackPoint1.CenterPosition, WRange.FromCells(SovietTownAttackGroupRange))
.Union(world.FindAliveCombatantActorsInCircle(sovietTownAttackPoint2.CenterPosition, WRange.FromCells(SovietTownAttackGroupRange)))
.Union(world.FindAliveCombatantActorsInCircle(townPoint.CenterPosition, WRange.FromCells(AlliedTownTransferRange)))
.Where(a => a.HasTrait<IPositionable>() && 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, WorldRenderer wr)
{
world = w;
allies1 = w.Players.Single(p => p.InternalName == "Allies1");
allies2 = w.Players.SingleOrDefault(p => p.InternalName == "Allies2");
allies1.PlayerActor.Trait<PlayerResources>().Cash = 5000;
if (allies2 == null)
allies2 = allies1;
else
allies2.PlayerActor.Trait<PlayerResources>().Cash = 5000;
allies = w.Players.Single(p => p.InternalName == "Allies");
soviets = w.Players.Single(p => p.InternalName == "Soviets");
soviets.PlayerActor.Trait<PlayerResources>().Cash = 1000;
var actors = w.WorldActor.Trait<SpawnMapActors>().Actors;
sam1 = actors["SAM1"];
sam2 = actors["SAM2"];
sam3 = actors["SAM3"];
sam4 = actors["SAM4"];
sams = new[] { sam1, sam2, sam3, 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"];
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"];
townPoint = actors["TownPoint"];
sovietTownAttackPoint1 = actors["SovietTownAttackPoint1"];
sovietTownAttackPoint2 = actors["SovietTownAttackPoint2"];
yakEntryPoint = actors["YakEntryPoint"];
yakAttackPoint = actors["YakAttackPoint"];
alliedBaseTopLeft = actors["AlliedBaseTopLeft"].Location;
alliedBaseBottomRight = actors["AlliedBaseBottomRight"].Location;
SetupAlliedBase();
var shroud = allies1.Shroud;
shroud.Explore(w, sam1.Location, WRange.FromCells(2));
shroud.Explore(w, sam2.Location, WRange.FromCells(2));
shroud.Explore(w, sam3.Location, WRange.FromCells(2));
shroud.Explore(w, sam4.Location, WRange.FromCells(2));
if (w.LocalPlayer == null || w.LocalPlayer == allies1)
wr.Viewport.Center(chinookHusk.CenterPosition);
else
wr.Viewport.Center(allies2BasePoint.CenterPosition);
MissionUtils.PlayMissionMusic();
}
}
}

View File

@@ -1,459 +0,0 @@
#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.Drawing;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Mods.RA.Activities;
using OpenRA.Mods.RA.Air;
using OpenRA.Mods.RA.Buildings;
using OpenRA.Mods.RA.Move;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Missions
{
class Allies03ScriptInfo : TraitInfo<Allies03Script>, Requires<SpawnMapActorsInfo> { }
class Allies03Script : IHasObjectives, IWorldLoaded, ITick
{
public event Action<bool> OnObjectivesUpdated = notify => { };
public IEnumerable<Objective> Objectives { get { return new[] { evacuateUnits, destroyAirbases, evacuateMgg }; } }
Objective evacuateUnits = new Objective(ObjectiveType.Primary, EvacuateUnitsText, ObjectiveStatus.InProgress);
Objective destroyAirbases = new Objective(ObjectiveType.Secondary, DestroyAirbasesText, ObjectiveStatus.InProgress);
Objective evacuateMgg = new Objective(ObjectiveType.Secondary, EvacuateMggText, ObjectiveStatus.InProgress);
const string EvacuateUnitsText = "Following the rescue of Einstein, the Allies are now being flanked from both sides."
+ " Evacuate {0} units before the remaining Allied forces in the area are wiped out.";
const string DestroyAirbasesText = "Destroy the nearby Soviet airbases.";
const string EvacuateMggText = "Einstein has recently developed a technology which allows us to obscure units from the enemy."
+ " Evacuate at least one prototype mobile gap generator intact.";
const string ShortEvacuateTemplate = "{0}/{1} units evacuated";
int unitsEvacuatedThreshold;
int unitsEvacuated;
InfoWidget evacuateWidget;
World world;
Player allies1;
Player allies2;
Player allies;
Player soviets;
Actor exit1TopLeft;
Actor exit1BottomRight;
Actor exit1ExitPoint;
Actor exit2TopLeft;
Actor exit2BottomRight;
Actor exit2ExitPoint;
Actor sovietEntryPoint1;
Actor sovietEntryPoint2;
Actor sovietEntryPoint3;
Actor sovietEntryPoint4;
Actor sovietEntryPoint5;
Actor sovietEntryPoint6;
CPos[] sovietEntryPoints;
Actor sovietRallyPoint1;
Actor sovietRallyPoint2;
Actor sovietRallyPoint3;
Actor sovietRallyPoint4;
Actor sovietRallyPoint5;
Actor sovietRallyPoint6;
CPos[] sovietRallyPoints;
Actor[] sovietAirfields;
Rectangle paradropBox;
const int ReinforcementsTicks1 = 1500 * 5;
static readonly string[] Reinforcements1 = { "mgg", "2tnk", "2tnk", "2tnk", "2tnk", "1tnk", "1tnk", "jeep", "jeep", "e1", "e1", "e1", "e1", "e3", "e3" };
int currentReinforcement1;
const int ReinforcementsTicks2 = 1500 * 10;
static readonly string[] Reinforcements2 = { "mgg", "2tnk", "2tnk", "2tnk", "2tnk", "truk", "truk", "truk", "truk", "truk", "truk", "1tnk", "1tnk", "jeep", "jeep" };
int currentReinforcement2;
static readonly string[] SovietUnits1 = { "3tnk", "3tnk", "3tnk", "3tnk", "3tnk", "3tnk", "v2rl", "v2rl", "ftrk", "apc", "e1", "e1", "e2", "e3", "e3", "e4" };
static readonly string[] SovietUnits2 = { "4tnk", "4tnk", "4tnk", "4tnk", "3tnk", "3tnk", "3tnk", "3tnk", "v2rl", "v2rl", "ftrk", "apc", "e1", "e1", "e2", "e3", "e3", "e4" };
int sovietUnits2Ticks;
const int SovietGroupSize = 5;
int sovietParadropTicks;
const int ParadropIncrement = 200;
static readonly string[] ParadropTerrainTypes = { "Clear", "Road", "Rough", "Beach", "Ore" };
static readonly string[] SovietParadroppers = { "e1", "e1", "e3", "e3", "e4" };
int sovietParadrops;
int maxSovietYaks;
int attackAtFrame;
int attackAtFrameIncrement;
int minAttackAtFrame;
Actor allies1EntryPoint;
Actor allies1MovePoint;
Actor allies2EntryPoint;
Actor allies2MovePoint;
const string McvName = "mcv";
const string YakName = "yak";
string difficulty;
void MissionFailed(string text)
{
MissionUtils.CoopMissionFailed(world, text, allies1, allies2);
}
void MissionAccomplished(string text)
{
MissionUtils.CoopMissionAccomplished(world, text, allies1, allies2);
}
public void Tick(Actor self)
{
if (allies1.WinState != WinState.Undefined) return;
if (world.FrameNumber == 1)
{
SpawnAlliedUnit(McvName);
evacuateWidget = new InfoWidget("");
Ui.Root.AddChild(evacuateWidget);
UpdateUnitsEvacuated();
}
if (world.FrameNumber == attackAtFrame)
{
SpawnSovietUnits();
attackAtFrame += attackAtFrameIncrement;
attackAtFrameIncrement = Math.Max(attackAtFrameIncrement - 5, minAttackAtFrame);
}
if (world.FrameNumber == ReinforcementsTicks1 || world.FrameNumber == ReinforcementsTicks2)
Sound.Play("reinfor1.aud");
if (world.FrameNumber % 25 == 0)
{
if (world.FrameNumber >= ReinforcementsTicks1 && currentReinforcement1 < Reinforcements1.Length)
SpawnAlliedUnit(Reinforcements1[currentReinforcement1++]);
if (world.FrameNumber >= ReinforcementsTicks2 && currentReinforcement2 < Reinforcements2.Length)
SpawnAlliedUnit(Reinforcements2[currentReinforcement2++]);
}
if (sovietParadrops > 0)
{
if (world.FrameNumber == sovietParadropTicks)
Sound.Play("sovfapp1.aud");
if (world.FrameNumber >= sovietParadropTicks && world.FrameNumber % ParadropIncrement == 0)
{
CPos lz;
CPos entry;
do
{
var x = world.SharedRandom.Next(paradropBox.X, paradropBox.X + paradropBox.Width);
var y = world.SharedRandom.Next(paradropBox.Y, paradropBox.Y + paradropBox.Height);
entry = new CPos(0, y);
lz = new CPos(x, y);
}
while (!ParadropTerrainTypes.Contains(world.GetTerrainType(lz)));
MissionUtils.Paradrop(world, soviets, SovietParadroppers, entry, lz);
sovietParadrops--;
}
}
if (world.FrameNumber % 25 == 0)
ManageSovietUnits();
if (destroyAirbases.Status != ObjectiveStatus.Completed)
{
if (world.FrameNumber % 25 == 0)
BuildSovietAircraft();
ManageSovietAircraft();
}
EvacuateAlliedUnits(exit1TopLeft.Location, exit1BottomRight.Location, exit1ExitPoint.Location);
EvacuateAlliedUnits(exit2TopLeft.Location, exit2BottomRight.Location, exit2ExitPoint.Location);
CheckSovietAirbases();
if (!world.Actors.Any(a => (a.Owner == allies1 || a.Owner == allies2) && a.IsInWorld && !a.IsDead()
&& ((a.HasTrait<Building>() && !a.HasTrait<Wall>()) || a.HasTrait<BaseBuilding>())))
{
evacuateUnits.Status = ObjectiveStatus.Failed;
OnObjectivesUpdated(true);
MissionFailed("The remaining Allied forces in the area have been wiped out.");
}
}
Actor FirstUnshroudedOrDefault(IEnumerable<Actor> actors, World world, int shroudRange)
{
return actors.FirstOrDefault(u => world.FindAliveCombatantActorsInCircle(u.CenterPosition, WRange.FromCells(shroudRange)).All(a => !a.HasTrait<CreatesShroud>()));
}
void ManageSovietAircraft()
{
var enemies = world.Actors
.Where(u => (u.Owner == allies1 || u.Owner == allies2)
&& ((u.HasTrait<Building>() && !u.HasTrait<Wall>()) || u.HasTrait<Mobile>()) && u.IsInWorld && !u.IsDead()
&& (!u.HasTrait<Spy>() || !u.Trait<Spy>().Disguised || (u.Trait<Spy>().Disguised && u.Trait<Spy>().disguisedAsPlayer != soviets)));
foreach (var aircraft in SovietAircraft())
{
var pos = aircraft.CenterPosition;
var plane = aircraft.Trait<Plane>();
var ammo = aircraft.Trait<LimitedAmmo>();
if ((pos.Z == 0 && ammo.FullAmmo()) || (pos.Z != 0 && ammo.HasAmmo()))
{
var enemy = FirstUnshroudedOrDefault(enemies.OrderBy(u => (aircraft.CenterPosition - u.CenterPosition).LengthSquared), world, 10);
if (enemy != null)
{
if (!aircraft.IsIdle && aircraft.GetCurrentActivity().GetType() != typeof(FlyAttack))
aircraft.CancelActivity();
if (pos.Z == 0)
plane.UnReserve();
aircraft.QueueActivity(new FlyAttack(Target.FromActor(enemy)));
}
}
else if (pos.Z != 0 && !LandIsQueued(aircraft))
{
aircraft.CancelActivity();
aircraft.QueueActivity(new ReturnToBase(aircraft, null));
aircraft.QueueActivity(new ResupplyAircraft());
}
}
}
bool LandIsQueued(Actor actor)
{
for (var a = actor.GetCurrentActivity(); a != null; a = a.NextActivity)
if (a is ReturnToBase || a is Land) return true;
return false;
}
void BuildSovietAircraft()
{
var queue = MissionUtils.FindQueues(world, soviets, "Plane").FirstOrDefault(q => q.CurrentItem() == null);
if (queue == null || SovietAircraft().Count() >= maxSovietYaks) return;
queue.ResolveOrder(queue.self, Order.StartProduction(queue.self, YakName, 1));
}
IEnumerable<Actor> SovietAircraft()
{
return world.Actors.Where(a => a.HasTrait<AttackPlane>() && a.Owner == soviets && a.IsInWorld && !a.IsDead());
}
void CheckSovietAirbases()
{
if (destroyAirbases.Status != ObjectiveStatus.Completed && sovietAirfields.All(a => a.IsDead() || a.Owner != soviets))
{
destroyAirbases.Status = ObjectiveStatus.Completed;
OnObjectivesUpdated(true);
}
}
void SpawnSovietUnits()
{
var route = world.SharedRandom.Next(sovietEntryPoints.Length);
var spawnPoint = sovietEntryPoints[route];
var rallyPoint = sovietRallyPoints[route];
IEnumerable<string> units;
if (world.FrameNumber >= sovietUnits2Ticks)
units = SovietUnits2;
else
units = SovietUnits1;
var unit = world.CreateActor(units.Random(world.SharedRandom),
new TypeDictionary
{
new LocationInit(spawnPoint),
new OwnerInit(soviets)
});
unit.QueueActivity(new AttackMove.AttackMoveActivity(unit, new Move.Move(rallyPoint, 3)));
}
void AttackNearestAlliedActor(Actor self)
{
var enemies = world.Actors.Where(u => u.AppearsHostileTo(self) && (u.Owner == allies1 || u.Owner == allies2)
&& ((u.HasTrait<Building>() && !u.HasTrait<Wall>()) || u.HasTrait<Mobile>()) && u.IsInWorld && !u.IsDead());
var enemy = FirstUnshroudedOrDefault(enemies.OrderBy(u => (self.CenterPosition - u.CenterPosition).LengthSquared), world, 10);
if (enemy != null)
self.QueueActivity(new AttackMove.AttackMoveActivity(self, new Attack(Target.FromActor(enemy), WRange.FromCells(3))));
}
void ManageSovietUnits()
{
foreach (var rallyPoint in sovietRallyPoints)
{
var units = world.FindAliveCombatantActorsInCircle(rallyPoint.CenterPosition, WRange.FromCells(10))
.Where(u => u.IsIdle && u.HasTrait<Mobile>() && u.HasTrait<AttackBase>() && u.Owner == soviets);
if (units.Count() >= SovietGroupSize)
{
foreach (var unit in units)
AttackNearestAlliedActor(unit);
}
}
var scatteredUnits = world.Actors.Where(u => u.IsInWorld && !u.IsDead() && u.HasTrait<Mobile>() && u.IsIdle && u.Owner == soviets)
.Except(world.WorldActor.Trait<SpawnMapActors>().Actors.Values)
.Except(sovietRallyPoints.SelectMany(rp => world.FindAliveCombatantActorsInCircle(rp.CenterPosition, WRange.FromCells(10))));
foreach (var unit in scatteredUnits)
AttackNearestAlliedActor(unit);
}
void SpawnAlliedUnit(string actor)
{
SpawnAndMove(actor, allies1, allies1EntryPoint.Location, allies1MovePoint.Location);
if (allies1 != allies2)
SpawnAndMove(actor, allies2, allies2EntryPoint.Location, allies2MovePoint.Location);
}
Actor SpawnAndMove(string actor, Player owner, CPos entry, CPos to)
{
var unit = world.CreateActor(actor, new TypeDictionary
{
new OwnerInit(owner),
new LocationInit(entry),
new FacingInit(Traits.Util.GetFacing(to - entry, 0))
});
unit.QueueActivity(new Move.Move(to));
return unit;
}
void UpdateUnitsEvacuated()
{
evacuateWidget.Text = ShortEvacuateTemplate.F(unitsEvacuated, unitsEvacuatedThreshold);
if (evacuateUnits.Status == ObjectiveStatus.InProgress && unitsEvacuated >= unitsEvacuatedThreshold)
{
evacuateUnits.Status = ObjectiveStatus.Completed;
OnObjectivesUpdated(true);
MissionAccomplished("The remaining Allied forces in the area have evacuated.");
}
}
void EvacuateAlliedUnits(CPos tl, CPos br, CPos exit)
{
var units = world.FindAliveCombatantActorsInBox(tl, br)
.Where(u => u.HasTrait<Mobile>() && !u.HasTrait<Aircraft>() && (u.Owner == allies1 || u.Owner == allies2));
foreach (var unit in units)
{
unit.CancelActivity();
unit.ChangeOwner(allies);
unitsEvacuated++;
var createsShroud = unit.TraitOrDefault<CreatesShroud>();
if (createsShroud != null && evacuateMgg.Status == ObjectiveStatus.InProgress)
{
evacuateMgg.Status = ObjectiveStatus.Completed;
OnObjectivesUpdated(true);
}
var cargo = unit.TraitOrDefault<Cargo>();
if (cargo != null)
unitsEvacuated += cargo.Passengers.Count();
UpdateUnitsEvacuated();
unit.QueueActivity(new Move.Move(exit));
unit.QueueActivity(new RemoveSelf());
}
}
public void WorldLoaded(World w, WorldRenderer wr)
{
world = w;
difficulty = w.LobbyInfo.GlobalSettings.Difficulty;
Game.Debug("{0} difficulty selected".F(difficulty));
allies1 = w.Players.Single(p => p.InternalName == "Allies1");
allies2 = w.Players.SingleOrDefault(p => p.InternalName == "Allies2");
var res = allies1.PlayerActor.Trait<PlayerResources>();
if (allies2 == null)
{
res.Cash = 10000;
allies2 = allies1;
}
else
{
res.Cash = 5000;
res = allies2.PlayerActor.Trait<PlayerResources>();
res.Cash = 5000;
}
attackAtFrame = attackAtFrameIncrement = difficulty == "Hard" || difficulty == "Normal" ? 500 : 600;
minAttackAtFrame = difficulty == "Hard" || difficulty == "Normal" ? 100 : 150;
unitsEvacuatedThreshold = difficulty == "Hard" ? 200 : difficulty == "Normal" ? 100 : 50;
maxSovietYaks = difficulty == "Hard" ? 4 : difficulty == "Normal" ? 2 : 0;
sovietParadrops = difficulty == "Hard" ? 40 : difficulty == "Normal" ? 20 : 0;
sovietParadropTicks = difficulty == "Hard" ? 1500 * 17 : 1500 * 20;
sovietUnits2Ticks = difficulty == "Hard" ? 1500 * 12 : 1500 * 15;
evacuateUnits.Text = evacuateUnits.Text.F(unitsEvacuatedThreshold);
allies = w.Players.Single(p => p.InternalName == "Allies");
soviets = w.Players.Single(p => p.InternalName == "Soviets");
var actors = w.WorldActor.Trait<SpawnMapActors>().Actors;
exit1TopLeft = actors["Exit1TopLeft"];
exit1BottomRight = actors["Exit1BottomRight"];
exit1ExitPoint = actors["Exit1ExitPoint"];
exit2TopLeft = actors["Exit2TopLeft"];
exit2BottomRight = actors["Exit2BottomRight"];
exit2ExitPoint = actors["Exit2ExitPoint"];
allies1EntryPoint = actors["Allies1EntryPoint"];
allies1MovePoint = actors["Allies1MovePoint"];
allies2EntryPoint = actors["Allies2EntryPoint"];
allies2MovePoint = actors["Allies2MovePoint"];
sovietEntryPoint1 = actors["SovietEntryPoint1"];
sovietEntryPoint2 = actors["SovietEntryPoint2"];
sovietEntryPoint3 = actors["SovietEntryPoint3"];
sovietEntryPoint4 = actors["SovietEntryPoint4"];
sovietEntryPoint5 = actors["SovietEntryPoint5"];
sovietEntryPoint6 = actors["SovietEntryPoint6"];
sovietEntryPoints = new[] { sovietEntryPoint1, sovietEntryPoint2, sovietEntryPoint3, sovietEntryPoint4, sovietEntryPoint5, sovietEntryPoint6 }.Select(p => p.Location).ToArray();
sovietRallyPoint1 = actors["SovietRallyPoint1"];
sovietRallyPoint2 = actors["SovietRallyPoint2"];
sovietRallyPoint3 = actors["SovietRallyPoint3"];
sovietRallyPoint4 = actors["SovietRallyPoint4"];
sovietRallyPoint5 = actors["SovietRallyPoint5"];
sovietRallyPoint6 = actors["SovietRallyPoint6"];
sovietRallyPoints = new[] { sovietRallyPoint1, sovietRallyPoint2, sovietRallyPoint3, sovietRallyPoint4, sovietRallyPoint5, sovietRallyPoint6 }.Select(p => p.Location).ToArray();
sovietAirfields = actors.Values.Where(a => a.Owner == soviets && a.HasTrait<Production>() && a.Info.Traits.Get<ProductionInfo>().Produces.Contains("Plane")).ToArray();
var topLeft = actors["ParadropBoxTopLeft"];
var bottomRight = actors["ParadropBoxBottomRight"];
paradropBox = new Rectangle(topLeft.Location.X, topLeft.Location.Y, bottomRight.Location.X - topLeft.Location.X, bottomRight.Location.Y - topLeft.Location.Y);
if (w.LocalPlayer == null || w.LocalPlayer == allies1)
wr.Viewport.Center(allies1EntryPoint.CenterPosition);
else
wr.Viewport.Center(allies2EntryPoint.CenterPosition);
OnObjectivesUpdated(false);
MissionUtils.PlayMissionMusic();
}
}
}

View File

@@ -1,576 +0,0 @@
#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.Drawing;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Mods.RA.Activities;
using OpenRA.Mods.RA.Buildings;
using OpenRA.Mods.RA.Move;
using OpenRA.Mods.RA.Render;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Missions
{
class Allies04ScriptInfo : TraitInfo<Allies04Script>, Requires<SpawnMapActorsInfo> { }
class Allies04Script : IHasObjectives, IWorldLoaded, ITick
{
public event Action<bool> OnObjectivesUpdated = notify => { };
public IEnumerable<Objective> Objectives { get { return new[] { infiltrateLab, destroyBase }; } }
Objective infiltrateLab = new Objective(ObjectiveType.Primary, "", ObjectiveStatus.InProgress);
Objective destroyBase = new Objective(ObjectiveType.Primary, DestroyBaseText, ObjectiveStatus.Inactive);
const string InfiltrateLabTemplate = "The Soviets are currently developing a new defensive system named the \"Iron Curtain\" at their main research laboratory."
+ " Get our {0} into the laboratory undetected.";
const string DestroyBaseText = "Secure the laboratory and destroy the rest of the Soviet base. Ensure that the laboratory is not destroyed.";
Actor hijackTruck;
Actor baseGuard;
Actor baseGuardMovePos;
Actor baseGuardTruckPos;
Actor lab;
int baseGuardTicks = 100;
Actor allies1Spy;
Actor allies2Spy;
bool allies1SpyInfiltratedLab;
bool allies2SpyInfiltratedLab;
int frameInfiltrated = -1;
CountdownTimer destroyBaseTimer;
CountdownTimerWidget destroyBaseTimerWidget;
Player allies1;
Player allies2;
Player soviets;
Player creeps;
World world;
WorldRenderer worldRenderer;
List<Patrol> patrols;
CPos[] patrolPoints1;
CPos[] patrolPoints2;
CPos[] patrolPoints3;
CPos[] patrolPoints4;
CPos[] patrolPoints5;
Actor reinforcementsEntryPoint;
Actor reinforcementsUnloadPoint;
Actor spyReinforcementsEntryPoint;
Actor spyReinforcementsUnloadPoint;
Actor spyReinforcementsExitPoint;
string difficulty;
int destroyBaseTicks;
int nextCivilianMove = 1;
Actor bridgeTank;
Actor bridgeAttackPoint;
Actor bridge;
bool attackingBridge;
bool attackingTown = true;
Actor[] townAttackers;
void MissionFailed(string text)
{
MissionUtils.CoopMissionFailed(world, text, allies1, allies2);
}
void MissionAccomplished(string text)
{
MissionUtils.CoopMissionAccomplished(world, text, allies1, allies2);
}
public void Tick(Actor self)
{
if (allies1.WinState != WinState.Undefined) return;
if (world.FrameNumber == 1)
InsertSpies();
if (frameInfiltrated != -1)
{
if (world.FrameNumber == frameInfiltrated + 100)
{
Sound.Play("aarrivs1.aud");
worldRenderer.Viewport.Center(reinforcementsUnloadPoint.CenterPosition);
world.AddFrameEndTask(w => SendReinforcements());
}
if (world.FrameNumber == frameInfiltrated + 200)
{
Sound.Play("timergo1.aud");
destroyBaseTimer = new CountdownTimer(destroyBaseTicks, OnDestroyBaseTimerExpired, true);
destroyBaseTimerWidget = new CountdownTimerWidget(destroyBaseTimer, "Secure lab in: {0}");
Ui.Root.AddChild(destroyBaseTimerWidget);
}
if (world.FrameNumber >= frameInfiltrated + 200)
destroyBaseTimer.Tick();
if (world.FrameNumber == frameInfiltrated + 1500 * 12 && !bridgeTank.IsDead() && bridgeTank.IsInWorld && !bridge.IsDead())
{
bridgeTank.QueueActivity(new Attack(Target.FromPos(bridge.CenterPosition), WRange.FromCells(4)));
attackingBridge = true;
}
if (attackingBridge && bridge.IsDead())
{
if (!bridgeTank.IsDead())
bridgeTank.CancelActivity();
attackingBridge = false;
}
if (world.FrameNumber == frameInfiltrated + 1500 * 6)
foreach (var attacker in townAttackers.Where(a => !a.IsDead() && a.IsInWorld))
{
attacker.CancelActivity();
attacker.QueueActivity(new AttackMove.AttackMoveActivity(attacker, new Move.Move(reinforcementsUnloadPoint.Location + new CVec(10, -15), 3)));
}
}
if (attackingTown)
{
foreach (var attacker in townAttackers.Where(u => u.IsIdle && !u.IsDead() && u.IsInWorld))
{
var enemies = world.Actors.Where(u => u.Owner == creeps && u.HasTrait<ITargetable>()
&& ((u.HasTrait<Building>() && !u.HasTrait<Wall>() && !u.HasTrait<Bridge>()) || u.HasTrait<Mobile>()) && !u.IsDead() && u.IsInWorld);
var enemy = enemies.ClosestTo(attacker);
if (enemy != null)
attacker.QueueActivity(new AttackMove.AttackMoveActivity(attacker, new Attack(Target.FromActor(enemy), WRange.FromCells(3))));
else
{
attackingTown = false;
break;
}
}
}
foreach (var patrol in patrols)
patrol.DoPatrol();
MissionUtils.CapOre(soviets);
BaseGuardTick();
if (world.FrameNumber == nextCivilianMove)
{
var civilians = world.Actors.Where(a => !a.IsDead() && a.IsInWorld && a.Owner == creeps && a.HasTrait<Mobile>());
if (civilians.Any())
{
var civilian = civilians.Random(world.SharedRandom);
civilian.Trait<Mobile>().Nudge(civilian, civilian, true);
nextCivilianMove += world.SharedRandom.Next(1, 75);
}
}
world.AddFrameEndTask(w =>
{
if ((allies1Spy.IsDead() && !allies1SpyInfiltratedLab) || (allies2Spy != null && allies2Spy.IsDead() && !allies2SpyInfiltratedLab))
{
infiltrateLab.Status = ObjectiveStatus.Failed;
OnObjectivesUpdated(true);
MissionFailed("{0} spy was killed.".F(allies1 != allies2 ? "A" : "The"));
}
else if (lab.IsDead())
{
if (infiltrateLab.Status == ObjectiveStatus.InProgress)
infiltrateLab.Status = ObjectiveStatus.Failed;
else if (destroyBase.Status == ObjectiveStatus.InProgress)
destroyBase.Status = ObjectiveStatus.Failed;
OnObjectivesUpdated(true);
MissionFailed("The Soviet research laboratory was destroyed.");
}
else if (!world.Actors.Any(a => (a.Owner == allies1 || a.Owner == allies2) && !a.IsDead()
&& (a.HasTrait<Building>() && !a.HasTrait<Wall>()) || a.HasTrait<BaseBuilding>()))
{
destroyBase.Status = ObjectiveStatus.Failed;
OnObjectivesUpdated(true);
MissionFailed("The remaining Allied forces in the area have been wiped out.");
}
else if (SovietBaseDestroyed() && infiltrateLab.Status == ObjectiveStatus.Completed)
{
destroyBase.Status = ObjectiveStatus.Completed;
OnObjectivesUpdated(true);
MissionAccomplished("The Soviet research laboratory has been secured successfully.");
}
});
}
bool SovietBaseDestroyed()
{
return !world.Actors.Any(a => a.Owner == soviets && a.IsInWorld && !a.IsDead()
&& a.HasTrait<Building>() && !a.HasTrait<Wall>() && !a.HasTrait<Allies04TrivialBuilding>() && a != lab);
}
void OnDestroyBaseTimerExpired(CountdownTimer t)
{
if (SovietBaseDestroyed() && infiltrateLab.Status == ObjectiveStatus.Completed) return;
destroyBase.Status = ObjectiveStatus.Failed;
OnObjectivesUpdated(true);
MissionFailed("The Soviet research laboratory was not secured in time.");
}
void BaseGuardTick()
{
if (baseGuardTicks <= 0 || baseGuard.IsDead() || !baseGuard.IsInWorld) return;
if (hijackTruck.Location == baseGuardTruckPos.Location)
{
if (--baseGuardTicks <= 0)
baseGuard.QueueActivity(new Move.Move(baseGuardMovePos.Location));
}
else
baseGuardTicks = 100;
}
void OnLabInfiltrated(Actor spy)
{
if (spy == allies1Spy) allies1SpyInfiltratedLab = true;
else if (spy == allies2Spy) allies2SpyInfiltratedLab = true;
if (allies1SpyInfiltratedLab && (allies2SpyInfiltratedLab || allies2Spy == null))
{
infiltrateLab.Status = ObjectiveStatus.Completed;
destroyBase.Status = ObjectiveStatus.InProgress;
OnObjectivesUpdated(true);
frameInfiltrated = world.FrameNumber;
foreach (var actor in world.Actors.Where(a => !a.IsDead() && a.HasTrait<Allies04TransformOnLabInfiltrate>()))
actor.QueueActivity(false, new Transform(actor, actor.Info.Traits.Get<Allies04TransformOnLabInfiltrateInfo>().ToActor) { SkipMakeAnims = true });
}
}
void SendReinforcements()
{
var lst = world.CreateActor("lst.unselectable", new TypeDictionary
{
new OwnerInit(allies1),
new LocationInit(reinforcementsEntryPoint.Location)
});
lst.Trait<Cargo>().Load(lst, world.CreateActor(false, "mcv", new TypeDictionary { new OwnerInit(allies1) }));
if (allies1 != allies2)
lst.Trait<Cargo>().Load(lst, world.CreateActor(false, "mcv", new TypeDictionary { new OwnerInit(allies2) }));
lst.QueueActivity(new Move.Move(reinforcementsUnloadPoint.Location));
lst.QueueActivity(new Wait(10));
lst.QueueActivity(new CallFunc(() =>
{
allies1.PlayerActor.Trait<PlayerResources>().GiveCash(allies1 == allies2 ? 5000 : 2500);
if (allies1 != allies2)
allies2.PlayerActor.Trait<PlayerResources>().GiveCash(2500);
}));
lst.AddTrait(new TransformedAction(self =>
{
self.QueueActivity(new Wait(10));
self.QueueActivity(new Move.Move(reinforcementsEntryPoint.Location));
self.QueueActivity(new RemoveSelf());
}));
lst.QueueActivity(new UnloadCargo(lst, true));
lst.QueueActivity(new Transform(lst, "lst.unselectable.nocargo") { SkipMakeAnims = true });
}
class Patrol
{
Actor[] actors;
CPos[] points;
int pointIndex;
World world;
public Patrol(World world, string[] actorNames, Player owner, CPos[] points, int pointIndex)
{
this.world = world;
this.points = points;
this.pointIndex = pointIndex;
var td = new TypeDictionary { new OwnerInit(owner), new LocationInit(points[pointIndex]) };
actors = actorNames.Select(a => world.CreateActor(a, td)).ToArray();
}
public void DoPatrol()
{
if (actors.Any(a => a.IsDead() || !a.IsIdle || !a.IsInWorld)) return;
pointIndex = (pointIndex + 1) % points.Length;
foreach (var actor in actors.Where(a => !a.IsDead() && a.IsInWorld))
{
actor.QueueActivity(new Wait(world.SharedRandom.Next(50, 75)));
actor.QueueActivity(new AttackMove.AttackMoveActivity(actor, new Move.Move(points[pointIndex], 0)));
}
}
}
void InsertSpies()
{
var lst = world.CreateActor("lst.unselectable", new TypeDictionary
{
new OwnerInit(allies1),
new LocationInit(spyReinforcementsEntryPoint.Location)
});
allies1Spy = world.CreateActor(false, "spy.strong", new TypeDictionary { new OwnerInit(allies1) });
lst.Trait<Cargo>().Load(lst, allies1Spy);
if (allies1 != allies2)
{
allies2Spy = world.CreateActor(false, "spy.strong", new TypeDictionary { new OwnerInit(allies2) });
lst.Trait<Cargo>().Load(lst, allies2Spy);
}
lst.AddTrait(new TransformedAction(self =>
{
self.QueueActivity(new Wait(10));
self.QueueActivity(new Move.Move(spyReinforcementsExitPoint.Location));
self.QueueActivity(new RemoveSelf());
}));
lst.QueueActivity(new Move.Move(spyReinforcementsUnloadPoint.Location));
lst.QueueActivity(new Wait(10));
lst.QueueActivity(new UnloadCargo(lst, true));
lst.QueueActivity(new Transform(lst, "lst.unselectable.nocargo") { SkipMakeAnims = true });
}
void SetupSubStances()
{
foreach (var actor in world.Actors.Where(a => a.IsInWorld && a.Owner == soviets && !a.IsDead() && a.HasTrait<TargetableSubmarine>()))
actor.Trait<AutoTarget>().Stance = UnitStance.Defend;
}
public void WorldLoaded(World w, WorldRenderer wr)
{
world = w;
worldRenderer = wr;
difficulty = w.LobbyInfo.GlobalSettings.Difficulty;
Game.Debug("{0} difficulty selected".F(difficulty));
allies1 = w.Players.Single(p => p.InternalName == "Allies1");
allies2 = w.Players.SingleOrDefault(p => p.InternalName == "Allies2");
allies1.PlayerActor.Trait<PlayerResources>().Cash = 0;
if (allies2 == null)
allies2 = allies1;
else
allies2.PlayerActor.Trait<PlayerResources>().Cash = 0;
soviets = w.Players.Single(p => p.InternalName == "Soviets");
creeps = w.Players.Single(p => p.InternalName == "Creeps");
infiltrateLab.Text = InfiltrateLabTemplate.F(allies1 != allies2 ? "spies" : "spy");
destroyBaseTicks = difficulty == "Hard" ? 1500 * 25 : difficulty == "Normal" ? 1500 * 28 : 1500 * 31;
var actors = w.WorldActor.Trait<SpawnMapActors>().Actors;
spyReinforcementsEntryPoint = actors["SpyReinforcementsEntryPoint"];
spyReinforcementsUnloadPoint = actors["SpyReinforcementsUnloadPoint"];
spyReinforcementsExitPoint = actors["SpyReinforcementsExitPoint"];
hijackTruck = actors["HijackTruck"];
baseGuard = actors["BaseGuard"];
baseGuardMovePos = actors["BaseGuardMovePos"];
baseGuardTruckPos = actors["BaseGuardTruckPos"];
patrolPoints1 = new[]
{
actors["PatrolPoint11"].Location,
actors["PatrolPoint12"].Location,
actors["PatrolPoint13"].Location,
actors["PatrolPoint14"].Location,
actors["PatrolPoint15"].Location
};
patrolPoints2 = patrolPoints1;
patrolPoints3 = new[]
{
actors["PatrolPoint21"].Location,
actors["PatrolPoint22"].Location,
actors["PatrolPoint23"].Location,
actors["PatrolPoint24"].Location,
actors["PatrolPoint25"].Location
};
patrolPoints4 = new[]
{
actors["PatrolPoint31"].Location,
actors["PatrolPoint32"].Location,
actors["PatrolPoint33"].Location,
actors["PatrolPoint34"].Location
};
patrolPoints5 = new[]
{
actors["PatrolPoint41"].Location,
actors["PatrolPoint42"].Location,
actors["PatrolPoint43"].Location,
actors["PatrolPoint44"].Location,
actors["PatrolPoint45"].Location
};
lab = actors["Lab"];
lab.AddTrait(new InfiltrateAction(OnLabInfiltrated));
lab.AddTrait(new TransformedAction(self => lab = self));
reinforcementsEntryPoint = actors["ReinforcementsEntryPoint"];
reinforcementsUnloadPoint = actors["ReinforcementsUnloadPoint"];
patrols = new List<Patrol>
{
new Patrol(world, new[] { "e1", "e1", "e1", "e1", "e1" }, soviets, patrolPoints1, 0),
new Patrol(world, new[] { "e1", "dog.patrol", "dog.patrol" }, soviets, patrolPoints2, 2),
new Patrol(world, new[] { "e1", "dog.patrol", "dog.patrol" }, soviets, patrolPoints4, 0),
new Patrol(world, new[] { "e1", "dog.patrol", "dog.patrol" }, soviets, patrolPoints5, 0),
};
if (difficulty == "Hard")
patrols.Add(new Patrol(world, new[] { "e1", "e1", "dog.patrol" }, soviets, patrolPoints3, 0));
bridgeTank = actors["BridgeTank"];
bridgeAttackPoint = actors["BridgeAttackPoint"];
bridge = world.Actors
.Where(a => a.HasTrait<Bridge>() && !a.IsDead())
.OrderBy(a => (a.Location - bridgeAttackPoint.Location).LengthSquared)
.FirstOrDefault();
var ta1 = actors["TownAttacker1"];
var ta2 = actors["TownAttacker2"];
var ta3 = actors["TownAttacker3"];
var ta4 = actors["TownAttacker4"];
var ta5 = actors["TownAttacker5"];
var ta6 = actors["TownAttacker6"];
var ta7 = actors["TownAttacker7"];
townAttackers = new[] { ta1, ta2, ta3, ta4, ta5, ta6, ta7 };
OnObjectivesUpdated(false);
SetupSubStances();
worldRenderer.Viewport.Center(spyReinforcementsEntryPoint.CenterPosition);
MissionUtils.PlayMissionMusic();
}
}
class Allies04HijackableInfo : ITraitInfo, Requires<InfiltratableInfo>
{
public object Create(ActorInitializer init) { return new Allies04Hijackable(init.self); }
}
class Allies04Hijackable : IAcceptInfiltrator, INotifyPassengerExited
{
public Player OldOwner;
void OnTruckHijacked(Actor spy) { }
public Allies04Hijackable(Actor self)
{
OldOwner = self.Owner;
self.AddTrait(new InfiltrateAction(OnTruckHijacked));
}
public void OnInfiltrate(Actor self, Actor spy)
{
if (self.Trait<Cargo>().IsEmpty(self))
self.ChangeOwner(spy.Owner);
self.Trait<Cargo>().Load(self, spy);
}
public void PassengerExited(Actor self, Actor passenger)
{
if (self.Trait<Cargo>().IsEmpty(self))
{
self.CancelActivity();
self.ChangeOwner(OldOwner);
}
else if (self.Owner == passenger.Owner)
self.ChangeOwner(self.Trait<Cargo>().Passengers.First().Owner);
}
}
class Allies04RenderHijackedInfo : RenderUnitInfo
{
public override object Create(ActorInitializer init) { return new Allies04RenderHijacked(init.self, this); }
}
class Allies04RenderHijacked : RenderUnit
{
Allies04Hijackable hijackable;
Allies04RenderHijackedInfo info;
public Allies04RenderHijacked(Actor self, Allies04RenderHijackedInfo info)
: base(self)
{
this.info = info;
hijackable = self.Trait<Allies04Hijackable>();
}
protected override string PaletteName(Actor self)
{
return info.Palette ?? info.PlayerPalette + hijackable.OldOwner.InternalName;
}
}
class Allies04TrivialBuildingInfo : TraitInfo<Allies04TrivialBuilding> { }
class Allies04TrivialBuilding { }
class Allies04MaintainBuildingInfo : TraitInfo<Allies04MaintainBuilding>
{
public readonly string Player = null;
}
class Allies04MaintainBuilding : INotifyDamageStateChanged
{
public void DamageStateChanged(Actor self, AttackInfo e)
{
if (self.Owner.InternalName != self.Info.Traits.Get<Allies04MaintainBuildingInfo>().Player) return;
if (self.HasTrait<Sellable>() && e.DamageState == DamageState.Critical && e.PreviousDamageState < DamageState.Critical)
self.Trait<Sellable>().Sell(self);
else if (self.HasTrait<RepairableBuilding>() && e.DamageState > DamageState.Undamaged && e.PreviousDamageState == DamageState.Undamaged)
self.Trait<RepairableBuilding>().RepairBuilding(self, self.Owner);
}
}
class Allies04TransformOnLabInfiltrateInfo : TraitInfo<Allies04TransformOnLabInfiltrate>
{
[ActorReference]
public readonly string ToActor = null;
}
class Allies04TransformOnLabInfiltrate { }
class Allies04HazyPaletteEffectInfo : TraitInfo<Allies04HazyPaletteEffect> { }
class Allies04HazyPaletteEffect : IPaletteModifier
{
static readonly string[] ExcludePalettes = { "cursor", "chrome", "colorpicker", "fog", "shroud" };
public void AdjustPalette(Dictionary<string, Palette> palettes)
{
foreach (var pal in palettes)
{
if (ExcludePalettes.Contains(pal.Key))
continue;
for (var x = 0; x < 256; x++)
{
var from = pal.Value.GetColor(x);
var to = Color.FromArgb(from.A, Color.FromKnownColor(KnownColor.DarkOrange));
pal.Value.SetColor(x, Exts.ColorLerp(0.15f, from, to));
}
}
}
}
}

View File

@@ -1,68 +0,0 @@
#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;
namespace OpenRA.Mods.RA.Missions
{
public class CountdownTimer
{
public int TicksLeft;
public event Action<CountdownTimer> OnExpired = t => { };
public event Action<CountdownTimer> OnOneMinuteRemaining = t => { };
public event Action<CountdownTimer> OnTwoMinutesRemaining = t => { };
public event Action<CountdownTimer> OnThreeMinutesRemaining = t => { };
public event Action<CountdownTimer> OnFourMinutesRemaining = t => { };
public event Action<CountdownTimer> OnFiveMinutesRemaining = t => { };
public event Action<CountdownTimer> OnTenMinutesRemaining = t => { };
public event Action<CountdownTimer> OnTwentyMinutesRemaining = t => { };
public event Action<CountdownTimer> OnThirtyMinutesRemaining = t => { };
public event Action<CountdownTimer> OnFortyMinutesRemaining = t => { };
public CountdownTimer(int ticksLeft, Action<CountdownTimer> 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) return;
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;
}
}
}
}

View File

@@ -1,379 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2013 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 System.Linq;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Mods.RA.Activities;
using OpenRA.Mods.RA.Buildings;
using OpenRA.Mods.RA.Move;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Missions
{
class FortLonestarScriptInfo : TraitInfo<FortLonestarScript>, Requires<SpawnMapActorsInfo> { }
class FortLonestarScript : IWorldLoaded, ITick
{
Player multi0;
Player soviets;
Actor entry1;
Actor entry2;
Actor entry3;
Actor entry4;
Actor entry5;
Actor entry6;
Actor entry7;
Actor entry8;
CPos[] sovietEntryPoints;
Actor paradrop1;
Actor paradrop2;
Actor paradrop3;
Actor paradrop4;
Actor patrol1;
Actor patrol2;
Actor patrol3;
Actor patrol4;
World world;
int WaveNumber = 0;
InfoWidget evacuateWidget;
const string ShortEvacuateTemplate = "Wave {0}";
static readonly string[] Patrol = { "e1", "e2", "e1" };
static readonly string[] Infantry = { "e4", "e1", "e1", "e2", "e1", "e2" };
static readonly string[] Vehicles = { "arty", "ftrk", "ftrk", "apc", "apc" };
const string tank = "3tnk";
const string v2 = "v2rl";
const string boss = "4tnk";
const int TimerTicks = 1;
int AttackSquad = 6;
int AttackSquadCount = 1;
int VehicleSquad = 2;
int VehicleSquadCount = 1;
int patrolAttackFrame;
int patrolattackAtFrameIncrement;
int WaveAttackFrame;
int WaveAttackAtFrameIncrement;
int VehicleAttackFrame;
int VehicleAttackAtFrameIncrement;
void MissionAccomplished(string text)
{
MissionUtils.CoopMissionAccomplished(world, text, multi0);
}
void AttackNearestAlliedActor(Actor self)
{
var enemies = world.Actors.Where(u => u.IsInWorld && !u.IsDead() && (u.Owner == multi0)
&& ((u.HasTrait<Building>() && !u.HasTrait<Mobile>())));
var targetEnemy = enemies.ClosestTo(self);
if (targetEnemy != null)
self.QueueActivity(new AttackMove.AttackMoveActivity(self, new Attack(Target.FromActor(targetEnemy), WRange.FromCells(6))));
}
void SendVehicles()
{
if (SpawnVehicles == true)
{
for (int i = 1; i <= VehicleSquadCount; i++)
{
var route = world.SharedRandom.Next(sovietEntryPoints.Length);
var spawnPoint = sovietEntryPoints[route];
for (int r = 1; r <= VehicleSquad; r++)
{
var squad = world.CreateActor(Vehicles.Random(world.SharedRandom),
new TypeDictionary
{
new LocationInit(spawnPoint),
new OwnerInit(soviets)
});
squad.QueueActivity(new AttackMove.AttackMoveActivity(squad, new Move.Move(paradrop1.Location, 3)));
}
}
}
}
void SendWave()
{
if (SpawnWave == true)
{
for (int i = 1; i <= AttackSquadCount; i++)
{
world.Actors.Where(u => u.IsInWorld && !u.IsDead() && (u.Owner == soviets)
&& !u.HasTrait<Mobile>());
var route = world.SharedRandom.Next(sovietEntryPoints.Length);
var spawnPoint = sovietEntryPoints[route];
for (int r = 1; r < AttackSquad; r++)
{
var squad = world.CreateActor(Infantry.Random(world.SharedRandom),
new TypeDictionary
{
new LocationInit(spawnPoint),
new OwnerInit(soviets)
});
squad.QueueActivity(new AttackMove.AttackMoveActivity(squad, new Move.Move(paradrop1.Location, 3)));
var scatteredUnits = world.FindAliveCombatantActorsInCircle(paradrop1.Location.CenterPosition, WRange.FromCells(15))
.Where(unit => unit.IsIdle && unit.HasTrait<Mobile>() && unit.Owner == soviets);
foreach (var unit in scatteredUnits)
{
AttackNearestAlliedActor(unit);
}
}
}
}
}
void SendPatrol(string[] squad, Player owner, CPos location, CPos move)
{
if (SpawnPatrol)
{
for (int i = 0; i < squad.Length; i++)
{
var actor = world.CreateActor(squad[i], new TypeDictionary
{
new OwnerInit(owner),
new LocationInit(location)
});
actor.QueueActivity(new AttackMove.AttackMoveActivity(actor, new Move.Move(move, 3)));
AttackNearestAlliedActor(actor);
}
}
}
void SendBoss(string unit)
{
var route = world.SharedRandom.Next(sovietEntryPoints.Length);
var spawnPoint = sovietEntryPoints[route];
var actor = world.CreateActor(unit, new TypeDictionary
{
new OwnerInit(soviets),
new LocationInit(spawnPoint)
});
if (multi0 != null)
{
AttackNearestAlliedActor(actor);
}
}
void Wave(string text)
{
Game.AddChatLine(Color.Cyan, "Wave Sequence", text);
}
public void Tick(Actor self)
{
if (multi0.WinState != WinState.Undefined) return;
if (world.FrameNumber == patrolAttackFrame)
{
patrolAttackFrame += patrolattackAtFrameIncrement;
patrolattackAtFrameIncrement = Math.Max(patrolattackAtFrameIncrement - 5, 100);
SendPatrol(Patrol, soviets, patrol1.Location, paradrop1.Location);
SendPatrol(Patrol, soviets, patrol2.Location, paradrop2.Location);
SendPatrol(Patrol, soviets, patrol3.Location, paradrop3.Location);
SendPatrol(Patrol, soviets, patrol4.Location, paradrop4.Location);
}
if (world.FrameNumber == WaveAttackFrame)
{
WaveAttackFrame += WaveAttackAtFrameIncrement;
WaveAttackAtFrameIncrement = Math.Max(WaveAttackAtFrameIncrement - 5, 100);
SendWave();
}
if (world.FrameNumber == VehicleAttackFrame)
{
VehicleAttackFrame += VehicleAttackAtFrameIncrement;
VehicleAttackAtFrameIncrement = Math.Max(VehicleAttackAtFrameIncrement - 5, 100);
SendVehicles();
}
if (world.FrameNumber == TimerTicks)
{
evacuateWidget = new InfoWidget("");
Ui.Root.AddChild(evacuateWidget);
WaveNumber++;
Wave("One Initializing");
UpdateWaveSequence();
}
if (world.FrameNumber == 1500 * 2)
{
WaveNumber++;
Wave("Two Initializing");
SpawnPatrol = false;
AttackSquad = 7;
AttackSquadCount = 2;
UpdateWaveSequence();
MissionUtils.Parabomb(world, soviets, entry1.Location, paradrop1.Location);
MissionUtils.Parabomb(world, soviets, entry1.Location, paradrop1.Location + new CVec(0, -2));
}
if (world.FrameNumber == 1500 * 4)
{
WaveNumber++;
Wave("Three Initializing");
UpdateWaveSequence();
AttackSquad = 8;
}
if (world.FrameNumber == 1500 * 6)
{
WaveNumber++;
Wave("Four Initializing");
UpdateWaveSequence();
AttackSquad = 9;
MissionUtils.Parabomb(world, soviets, entry1.Location, paradrop1.Location);
MissionUtils.Parabomb(world, soviets, entry2.Location, paradrop3.Location);
AttackSquadCount = 3;
VehicleSquad = 3;
}
if (world.FrameNumber == 1500 * 8)
{
WaveNumber++;
Wave("Five Initializing");
UpdateWaveSequence();
AttackSquad = 10;
VehicleSquad = 4;
VehicleSquadCount = 2;
SendBoss(tank);
}
if (world.FrameNumber == 1500 * 11)
{
WaveNumber++;
Wave("Six Initializing");
UpdateWaveSequence();
AttackSquad = 11;
AttackSquadCount = 4;
MissionUtils.Parabomb(world, soviets, entry1.Location, paradrop1.Location);
MissionUtils.Parabomb(world, soviets, entry4.Location, paradrop1.Location);
MissionUtils.Parabomb(world, soviets, entry6.Location, paradrop3.Location);
MissionUtils.Parabomb(world, soviets, entry5.Location, paradrop3.Location);
SendBoss(tank);
SendBoss(tank);
}
if (world.FrameNumber == 1500 * 14)
{
WaveNumber++;
Wave("Seven Initializing");
UpdateWaveSequence();
AttackSquad = 12;
VehicleSquad = 5;
VehicleSquadCount = 3;
SendBoss(v2);
}
if (world.FrameNumber == 1500 * 17)
{
SpawnVehicles = true;
WaveNumber++;
Wave("Eight Initializing");
UpdateWaveSequence();
AttackSquad = 13;
AttackSquadCount = 5;
MissionUtils.Parabomb(world, soviets, entry1.Location, paradrop1.Location);
MissionUtils.Parabomb(world, soviets, entry4.Location, paradrop1.Location);
MissionUtils.Parabomb(world, soviets, entry6.Location, paradrop3.Location);
MissionUtils.Parabomb(world, soviets, entry5.Location, paradrop3.Location);
MissionUtils.Parabomb(world, soviets, entry2.Location, paradrop2.Location);
MissionUtils.Parabomb(world, soviets, entry3.Location, paradrop2.Location);
SendBoss(v2);
SendBoss(tank);
SendBoss(v2);
}
if (world.FrameNumber == 1500 * 21)
{
WaveNumber++;
Wave("Nine Initializing");
UpdateWaveSequence();
AttackSquad = 14;
VehicleSquad = 6;
VehicleSquadCount = 4;
SendBoss(v2);
SendBoss(tank);
SendBoss(tank);
}
if (world.FrameNumber == 1500 * 25)
{
WaveNumber++;
Wave("Ten Initializing");
UpdateWaveSequence();
AttackSquad = 15;
AttackSquadCount = 6;
for (int i = 0; i < 2; i++)
{
MissionUtils.Parabomb(world, soviets, entry1.Location, paradrop1.Location + new CVec(0, -2));
MissionUtils.Parabomb(world, soviets, entry2.Location, paradrop3.Location + new CVec(0, -2));
MissionUtils.Parabomb(world, soviets, entry4.Location, paradrop2.Location + new CVec(0, -2));
MissionUtils.Parabomb(world, soviets, entry5.Location, paradrop4.Location + new CVec(0, -2));
MissionUtils.Parabomb(world, soviets, entry2.Location, paradrop1.Location + new CVec(0, 2));
MissionUtils.Parabomb(world, soviets, entry4.Location, paradrop3.Location + new CVec(0, 2));
MissionUtils.Parabomb(world, soviets, entry3.Location, paradrop2.Location + new CVec(0, 2));
MissionUtils.Parabomb(world, soviets, entry5.Location, paradrop4.Location + new CVec(0, 2));
}
SendBoss(boss);
}
if (world.FrameNumber == 1500 * 30)
{
SpawnWave = false;
SpawnVehicles = false;
}
if (world.FrameNumber == 1500 * 31)
{
MissionAccomplished("You and your mates have Survived the Onslaught!");
}
}
void UpdateWaveSequence()
{
evacuateWidget.Text = ShortEvacuateTemplate.F(WaveNumber);
}
bool SpawnPatrol = true;
bool SpawnWave = true;
bool SpawnVehicles = true;
public void WorldLoaded(World w, WorldRenderer wr)
{
world = w;
soviets = w.Players.Single(p => p.InternalName == "Soviets");
multi0 = w.Players.Single(p => p.InternalName == "Multi0");
patrolAttackFrame = 750;
patrolattackAtFrameIncrement = 750;
WaveAttackFrame = 500;
WaveAttackAtFrameIncrement = 500;
VehicleAttackFrame = 2000;
VehicleAttackAtFrameIncrement = 2000;
var actors = w.WorldActor.Trait<SpawnMapActors>().Actors;
entry1 = actors["Entry1"];
entry2 = actors["Entry2"];
entry3 = actors["Entry3"];
entry4 = actors["Entry4"];
entry5 = actors["Entry5"];
entry6 = actors["Entry6"];
entry7 = actors["Entry7"];
entry8 = actors["Entry8"];
sovietEntryPoints = new[] { entry1, entry2, entry3, entry4, entry5, entry6, entry7, entry8 }.Select(p => p.Location).ToArray();
paradrop1 = actors["Paradrop1"];
paradrop2 = actors["Paradrop2"];
paradrop3 = actors["Paradrop3"];
paradrop4 = actors["Paradrop4"];
patrol1 = actors["Patrol1"];
patrol2 = actors["Patrol2"];
patrol3 = actors["Patrol3"];
patrol4 = actors["Patrol4"];
MissionUtils.PlayMissionMusic();
Game.AddChatLine(Color.Cyan, "Mission", "Defend Fort LoneStar At All costs!");
}
}
}

View File

@@ -1,253 +0,0 @@
#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.Drawing;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Mods.RA.Activities;
using OpenRA.Mods.RA.Air;
using OpenRA.Mods.RA.Buildings;
using OpenRA.Mods.RA.Move;
using OpenRA.Network;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Missions
{
public static class MissionUtils
{
public static IEnumerable<Actor> FindAliveCombatantActorsInCircle(this World world, WPos location, WRange range)
{
return world.FindActorsInCircle(location, range)
.Where(u => u.IsInWorld && u != world.WorldActor && !u.IsDead() && !u.Owner.NonCombatant);
}
public static IEnumerable<Actor> FindAliveCombatantActorsInBox(this World world, CPos a, CPos b)
{
return world.FindActorsInBox(a, b)
.Where(u => u.IsInWorld && u != world.WorldActor && !u.IsDead() && !u.Owner.NonCombatant);
}
public static IEnumerable<Actor> FindAliveNonCombatantActorsInCircle(this World world, WPos location, WRange range)
{
return world.FindActorsInCircle(location, range)
.Where(u => u.IsInWorld && u != world.WorldActor && !u.IsDead() && u.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(chinook, Target.FromCell(lz)));
chinook.QueueActivity(new Turn(0));
chinook.QueueActivity(new HeliLand(true));
chinook.QueueActivity(new WaitFor(() => chinook.Trait<Cargo>().Passengers.Contains(unit)));
chinook.QueueActivity(new Wait(150));
chinook.QueueActivity(new HeliFly(chinook, Target.FromCell(exit)));
chinook.QueueActivity(new RemoveSelf());
return chinook;
}
public static Pair<Actor, Actor> InsertUnitWithChinook(World world, Player owner, string unitName, CPos entry, CPos lz, CPos exit, Action<Actor> 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<Cargo>().Load(chinook, unit);
chinook.QueueActivity(new HeliFly(chinook, Target.FromCell(lz)));
chinook.QueueActivity(new Turn(0));
chinook.QueueActivity(new HeliLand(true));
chinook.QueueActivity(new UnloadCargo(chinook, true));
chinook.QueueActivity(new CallFunc(() => afterUnload(unit)));
chinook.QueueActivity(new Wait(150));
chinook.QueueActivity(new HeliFly(chinook, Target.FromCell(exit)));
chinook.QueueActivity(new RemoveSelf());
return Pair.New(chinook, unit);
}
public static void Paradrop(World world, Player owner, IEnumerable<string> units, CPos entry, CPos location)
{
var altitude = Rules.Info["badr"].Traits.Get<PlaneInfo>().CruiseAltitude;
var badger = world.CreateActor("badr", new TypeDictionary
{
new CenterPositionInit(entry.CenterPosition + new WVec(WRange.Zero, WRange.Zero, altitude)),
new OwnerInit(owner),
new FacingInit(Util.GetFacing(location - entry, 0))
});
badger.QueueActivity(new FlyAttack(Target.FromCell(location)));
badger.Trait<ParaDrop>().SetLZ(location);
var cargo = badger.Trait<Cargo>();
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 altitude = Rules.Info["badr.bomber"].Traits.Get<PlaneInfo>().CruiseAltitude;
var badger = world.CreateActor("badr.bomber", new TypeDictionary
{
new CenterPositionInit(entry.CenterPosition + new WVec(WRange.Zero, WRange.Zero, altitude)),
new OwnerInit(owner),
new FacingInit(Util.GetFacing(location - entry, 0))
});
badger.Trait<AttackBomber>().SetTarget(location.CenterPosition);
badger.QueueActivity(new Fly(badger, Target.FromCell(location)));
badger.QueueActivity(new FlyOffMap());
badger.QueueActivity(new RemoveSelf());
}
public static bool AreaSecuredWithUnits(World world, Player player, WPos location, WRange range)
{
var units = world.FindAliveCombatantActorsInCircle(location, range).Where(a => a.HasTrait<IPositionable>());
return units.Any() && units.All(a => a.Owner == player);
}
public static IEnumerable<ProductionQueue> FindQueues(World world, Player player, string category)
{
return world.ActorsWithTrait<ProductionQueue>()
.Where(a => a.Actor.Owner == player && a.Trait.Info.Type == category)
.Select(a => a.Trait);
}
public static void StartProduction(World world, Player player, string category, string item)
{
var queue = FindQueues(world, player, category).FirstOrDefault(q => q.CurrentItem() == null);
if (queue != null)
queue.ResolveOrder(queue.self, Order.StartProduction(queue.self, item, 1));
}
public static Actor UnitContaining(this World world, Actor actor)
{
return world.Actors.FirstOrDefault(a => a.HasTrait<Cargo>() && a.Trait<Cargo>().Passengers.Contains(actor));
}
public static void PlayMissionMusic()
{
if (!Rules.InstalledMusic.Any() || !Game.Settings.Sound.MapMusic)
return;
Game.ConnectionStateChanged += StopMusic;
PlayMusic();
}
static void PlayMusic()
{
var track = Rules.InstalledMusic.Random(Game.CosmeticRandom);
Sound.PlayMusicThen(track.Value, PlayMusic);
}
static void StopMusic(OrderManager orderManager)
{
if (!orderManager.GameStarted)
{
Sound.StopMusic();
Game.ConnectionStateChanged -= StopMusic;
}
}
public static void CoopMissionAccomplished(World world, string text, params Player[] players)
{
if (players.First().WinState != WinState.Undefined)
return;
foreach (var player in players)
player.WinState = WinState.Won;
if (text != null)
Game.AddChatLine(Color.Blue, "Mission accomplished", text);
Sound.Play("misnwon1.aud");
}
public static void CoopMissionFailed(World world, string text, params Player[] players)
{
if (players.First().WinState != WinState.Undefined)
return;
foreach (var player in players)
{
player.WinState = WinState.Lost;
foreach (var actor in world.Actors.Where(a => a.IsInWorld && a.Owner == player && !a.IsDead()))
{
actor.Kill(actor);
}
}
if (text != null)
Game.AddChatLine(Color.Red, "Mission failed", text);
Sound.Play("misnlst1.aud");
}
public static Actor CreateActor(this World world, bool addToWorld, string name, Player owner, CPos? location, int? facing)
{
var td = new TypeDictionary { new OwnerInit(owner) };
if (location.HasValue)
td.Add(new LocationInit(location.Value));
if (facing.HasValue)
td.Add(new FacingInit(facing.Value));
return world.CreateActor(addToWorld, name, td);
}
public static Actor CreateActor(this World world, string name, Player owner, CPos? location, int? facing)
{
return CreateActor(world, true, name, owner, location, facing);
}
public static void CapOre(Player player)
{
var res = player.PlayerActor.Trait<PlayerResources>();
if (res.Ore > res.OreCapacity * 0.8)
res.Ore = (int)(res.OreCapacity * 0.8);
}
public static void AttackNearestLandActor(bool queued, Actor self, Player enemyPlayer)
{
var enemies = self.World.Actors.Where(u => u.AppearsHostileTo(self) && u.Owner == enemyPlayer
&& ((u.HasTrait<Building>() && !u.HasTrait<Wall>()) || (u.HasTrait<Mobile>() && !u.HasTrait<Aircraft>())) && u.IsInWorld && !u.IsDead());
var enemy = enemies.ClosestTo(self);
if (enemy != null)
self.QueueActivity(queued, new AttackMove.AttackMoveActivity(self, new Attack(Target.FromActor(enemy), WRange.FromCells(3))));
}
}
class TransformedAction : INotifyTransformed
{
Action<Actor> a;
public TransformedAction(Action<Actor> a)
{
this.a = a;
}
public void OnTransformed(Actor toActor)
{
a(toActor);
}
}
class InfiltrateAction : IAcceptInfiltrator
{
Action<Actor> a;
public InfiltrateAction(Action<Actor> a)
{
this.a = a;
}
public void OnInfiltrate(Actor self, Actor spy)
{
a(spy);
}
}
}

View File

@@ -1,55 +0,0 @@
#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.Drawing;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Missions
{
public class CountdownTimerWidget : Widget
{
public CountdownTimer Timer;
public string Format;
public CountdownTimerWidget(CountdownTimer timer, string format)
{
Timer = timer;
Format = format;
}
public override void Draw()
{
if (!IsVisible()) return;
// TODO: Don't hardcode the screen position
var font = Game.Renderer.Fonts["Bold"];
var text = Format.F(WidgetUtils.FormatTime(Timer.TicksLeft));
var pos = new float2(Game.Renderer.Resolution.Width * 0.5f - font.Measure(text).X / 2, Game.Renderer.Resolution.Height * 0.1f);
font.DrawTextWithContrast(text, pos, Timer.TicksLeft <= 25 * 60 && Game.LocalTick % 50 < 25 ? Color.Red : Color.White, Color.Black, 1);
}
}
public class InfoWidget : Widget
{
public string Text;
public InfoWidget(string text) { Text = text; }
public override void Draw()
{
if (!IsVisible()) return;
// TODO: Don't hardcode the screen position
var font = Game.Renderer.Fonts["Bold"];
var pos = new float2(Game.Renderer.Resolution.Width * 0.5f - font.Measure(Text).X / 2, Game.Renderer.Resolution.Height * 0.1f);
font.DrawTextWithContrast(Text, pos, Color.White, Color.Black, 1);
}
}
}

View File

@@ -1,342 +0,0 @@
#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.Graphics;
using OpenRA.Mods.RA.Activities;
using OpenRA.Mods.RA.Buildings;
using OpenRA.Mods.RA.Move;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Missions
{
class MonsterTankMadnessScriptInfo : ITraitInfo, Requires<SpawnMapActorsInfo>
{
public readonly string[] FirstStartUnits = null;
public readonly string[] SecondStartUnits = null;
public readonly string[] ThirdStartUnits = null;
public readonly string[] FirstBaseUnits = null;
public readonly string[] CivilianEvacuees = null;
public object Create(ActorInitializer init) { return new MonsterTankMadnessScript(this); }
}
class MonsterTankMadnessScript : IHasObjectives, IWorldLoaded, ITick
{
MonsterTankMadnessScriptInfo info;
public MonsterTankMadnessScript(MonsterTankMadnessScriptInfo info)
{
this.info = info;
}
public event Action<bool> OnObjectivesUpdated = notify => { };
public IEnumerable<Objective> Objectives { get { return new[] { findOutpost, evacuateDemitri, infiltrateRadarDome }; } }
Objective findOutpost = new Objective(ObjectiveType.Primary, FindOutpostText, ObjectiveStatus.InProgress);
Objective evacuateDemitri = new Objective(ObjectiveType.Primary, EvacuateDemitriText, ObjectiveStatus.InProgress);
Objective infiltrateRadarDome = new Objective(ObjectiveType.Primary, InfiltrateRadarDomeText, ObjectiveStatus.InProgress);
const string FindOutpostText = "Find our outpost and start repairs on it.";
const string EvacuateDemitriText = "Find and evacuate Dr. Demitri. He is missing -- likely hiding in the village to the far south.";
const string InfiltrateRadarDomeText = "Reprogram the Super Tanks by sending a spy into the Soviet radar dome.";
//const string Briefing = "Dr. Demitri, creator of a Soviet Super Tank, wants to defect."
// + " We planned to extract him while the Soviets were testing their new weapon, but something has gone wrong."
// + " The Super Tanks are out of control, and Demitri is missing -- likely hiding in the village to the far south."
// + " Find our outpost and start repairs on it, then find and evacuate Demitri."
// + " As for the tanks, we can reprogram them. Send a spy into the Soviet radar dome in the NE, turning the tanks on their creators.";
World world;
Player neutral;
Player greece;
Player ussr;
Player badGuy;
Player turkey;
Actor startEntryPoint;
Actor startMovePoint;
Actor startBridgeEndPoint;
Actor alliedBaseTopLeft;
Actor alliedBaseBottomRight;
Actor alliedBaseEntryPoint;
Actor alliedBaseMovePoint;
Actor demitriChurch;
Actor demitriChurchSpawnPoint;
Actor demitriTriggerAreaCenter;
Actor demitri;
Actor demitriLZ;
Actor demitriLZFlare;
Actor demitriChinook;
Actor provingGroundsCameraPoint;
Actor[] superTanks;
Actor hospital;
Actor hospitalCivilianSpawnPoint;
Actor hospitalSuperTankPoint;
Actor superTankDome;
bool hospitalEvacuated;
bool superTanksDestroyed;
int baseTransferredTick = -1;
int superTankDomeInfiltratedTick = -1;
void MissionAccomplished(string text)
{
MissionUtils.CoopMissionAccomplished(world, text, greece);
}
void MissionFailed(string text)
{
MissionUtils.CoopMissionFailed(world, text, greece);
}
public void Tick(Actor self)
{
if (greece.WinState != WinState.Undefined) return;
if (world.FrameNumber == 1)
SpawnAndMoveBridgeUnits(info.FirstStartUnits);
else if (world.FrameNumber == 25 * 3)
SpawnAndMoveBridgeUnits(info.SecondStartUnits);
else if (world.FrameNumber == 25 * 8)
SpawnAndMoveBridgeUnits(info.ThirdStartUnits);
MissionUtils.CapOre(ussr);
if (!hospitalEvacuated && !hospital.IsDead() && MissionUtils.AreaSecuredWithUnits(world, greece, hospital.CenterPosition, WRange.FromCells(5)))
{
EvacuateCivilians();
hospitalEvacuated = true;
}
if (baseTransferredTick == -1)
{
var actorsInBase = world.FindActorsInBox(alliedBaseTopLeft.Location, alliedBaseBottomRight.Location).Where(a => a != a.Owner.PlayerActor);
if (actorsInBase.Any(a => a.Owner == greece))
{
SetupAlliedBase(actorsInBase);
baseTransferredTick = world.FrameNumber;
findOutpost.Status = ObjectiveStatus.Completed;
OnObjectivesUpdated(true);
}
}
else if (superTankDomeInfiltratedTick == -1)
{
if (world.FrameNumber == baseTransferredTick + 25 * 100)
foreach (var tank in superTanks.Where(t => !t.IsDead() && t.IsInWorld))
tank.QueueActivity(false, new Move.Move(hospitalSuperTankPoint.Location, 2));
else if (world.FrameNumber == baseTransferredTick + 25 * 180)
foreach (var tank in superTanks.Where(t => !t.IsDead() && t.IsInWorld))
tank.QueueActivity(false, new Move.Move(alliedBaseBottomRight.Location, 2));
else if (world.FrameNumber == baseTransferredTick + 25 * 280)
foreach (var tank in superTanks.Where(t => !t.IsDead() && t.IsInWorld))
tank.QueueActivity(false, new Move.Move(demitriTriggerAreaCenter.Location, 2));
else if (world.FrameNumber == baseTransferredTick + 25 * 480)
foreach (var tank in superTanks.Where(t => !t.IsDead() && t.IsInWorld))
tank.QueueActivity(false, new Move.Move(demitriLZ.Location, 4));
}
else
{
if (world.FrameNumber % 25 == 0)
foreach (var tank in superTanks.Where(t => !t.IsDead() && t.IsInWorld && t.IsIdle))
MissionUtils.AttackNearestLandActor(false, tank, ussr);
if (world.FrameNumber == superTankDomeInfiltratedTick + 25 * 180)
{
foreach (var actor in world.Actors.Where(a => !a.IsDead() && (a.Owner == ussr || a.Owner == badGuy)))
actor.Kill(actor);
}
if (world.FrameNumber == superTankDomeInfiltratedTick + 25 * 181)
{
foreach (var tank in superTanks.Where(t => !t.IsDead()))
tank.Kill(tank);
superTanksDestroyed = true;
}
}
if (evacuateDemitri.Status != ObjectiveStatus.Completed)
{
if (demitri == null)
{
if (demitriChurch.IsDead())
{
evacuateDemitri.Status = ObjectiveStatus.Failed;
OnObjectivesUpdated(true);
MissionFailed("Dr. Demitri was killed.");
}
else if (MissionUtils.AreaSecuredWithUnits(world, greece, demitriTriggerAreaCenter.CenterPosition, WRange.FromCells(3)))
{
demitri = world.CreateActor("demitri", greece, demitriChurchSpawnPoint.Location, null);
demitri.QueueActivity(new Move.Move(demitriTriggerAreaCenter.Location, 0));
demitriLZFlare = world.CreateActor("flare", greece, demitriLZ.Location, null);
Sound.Play("flaren1.aud");
var chinookEntry = new CPos(demitriLZ.Location.X, 0);
demitriChinook = MissionUtils.ExtractUnitWithChinook(world, greece, demitri, chinookEntry, demitriLZ.Location, chinookEntry);
}
}
else if (demitri.IsDead())
{
evacuateDemitri.Status = ObjectiveStatus.Failed;
OnObjectivesUpdated(true);
MissionFailed("Dr. Demitri was killed.");
}
else if (demitriChinook != null && !demitriChinook.IsDead() && !world.Map.IsInMap(demitriChinook.Location) && demitriChinook.Trait<Cargo>().Passengers.Contains(demitri))
{
demitriLZFlare.Destroy();
SpawnAndMoveAlliedBaseUnits(info.FirstBaseUnits);
evacuateDemitri.Status = ObjectiveStatus.Completed;
OnObjectivesUpdated(true);
}
}
if (!world.Actors.Any(a => a.Owner == greece && a.IsInWorld && !a.IsDead()
&& ((a.HasTrait<Building>() && !a.HasTrait<Wall>()) || a.HasTrait<BaseBuilding>() || a.HasTrait<Mobile>())))
{
MissionFailed("The remaining Allied forces in the area have been wiped out.");
}
if (superTankDomeInfiltratedTick == -1 && superTankDome.IsDead())
{
infiltrateRadarDome.Status = ObjectiveStatus.Failed;
OnObjectivesUpdated(true);
MissionFailed("The Soviet radar dome was destroyed.");
}
if (superTanksDestroyed && evacuateDemitri.Status == ObjectiveStatus.Completed)
{
MissionAccomplished("Dr. Demitri has been extracted and the super tanks have been dealt with.");
}
}
void SetupAlliedBase(IEnumerable<Actor> actors)
{
foreach (var actor in actors)
{
// hack hack hack
actor.ChangeOwner(greece);
if (actor.Info.Name == "pbox")
{
actor.AddTrait(new TransformedAction(s => s.Trait<Cargo>().Load(s, world.CreateActor(false, "e1", greece, null, null))));
actor.QueueActivity(new Transform(actor, "hbox.e1") { SkipMakeAnims = true });
}
else if (actor.Info.Name == "proc")
actor.QueueActivity(new Transform(actor, "proc") { SkipMakeAnims = true });
foreach (var c in actor.TraitsImplementing<INotifyCapture>())
c.OnCapture(actor, actor, neutral, greece);
}
}
void EvacuateCivilians()
{
foreach (var unit in info.CivilianEvacuees)
{
var actor = world.CreateActor(unit, neutral, hospitalCivilianSpawnPoint.Location, null);
actor.Trait<Mobile>().Nudge(actor, actor, true);
actor.QueueActivity(new Move.Move(alliedBaseEntryPoint.Location, 0));
actor.QueueActivity(new RemoveSelf());
}
}
void SpawnAndMoveBridgeUnits(string[] units)
{
Sound.Play("reinfor1.aud");
foreach (var unit in units)
world.CreateActor(unit, greece, startEntryPoint.Location, Traits.Util.GetFacing(startBridgeEndPoint.CenterPosition - startEntryPoint.CenterPosition, 0))
.QueueActivity(new Move.Move(startMovePoint.Location, 0));
}
void SpawnAndMoveAlliedBaseUnits(string[] units)
{
Sound.Play("reinfor1.aud");
foreach (var unit in units)
world.CreateActor(unit, greece, alliedBaseEntryPoint.Location, Traits.Util.GetFacing(alliedBaseMovePoint.CenterPosition - alliedBaseEntryPoint.CenterPosition, 0))
.QueueActivity(new Move.Move(alliedBaseMovePoint.Location, 0));
}
void OnSuperTankDomeInfiltrated(Actor spy)
{
if (superTankDomeInfiltratedTick != -1) return;
superTankDome.QueueActivity(new Transform(superTankDome, "dome") { SkipMakeAnims = true });
world.AddFrameEndTask(_ =>
{
superTanks.Do(world.Remove);
turkey.Stances[greece] = turkey.Stances[neutral] = Stance.Ally;
greece.Stances[turkey] = neutral.Stances[turkey] = Stance.Ally;
greece.Shroud.ExploreAll(world);
superTanks.Do(world.Add);
});
foreach (var tank in superTanks.Where(t => !t.IsDead() && t.IsInWorld))
MissionUtils.AttackNearestLandActor(false, tank, ussr);
superTankDomeInfiltratedTick = world.FrameNumber;
infiltrateRadarDome.Status = ObjectiveStatus.Completed;
OnObjectivesUpdated(true);
}
public void WorldLoaded(World w, WorldRenderer wr)
{
world = w;
neutral = w.Players.Single(p => p.InternalName == "Neutral");
greece = w.Players.Single(p => p.InternalName == "Greece");
ussr = w.Players.Single(p => p.InternalName == "USSR");
badGuy = w.Players.Single(p => p.InternalName == "BadGuy");
turkey = w.Players.Single(p => p.InternalName == "Turkey");
greece.PlayerActor.Trait<PlayerResources>().Cash = 0;
ussr.PlayerActor.Trait<PlayerResources>().Cash = 2000;
var actors = w.WorldActor.Trait<SpawnMapActors>().Actors;
startEntryPoint = actors["StartEntryPoint"];
startMovePoint = actors["StartMovePoint"];
startBridgeEndPoint = actors["StartBridgeEndPoint"];
alliedBaseTopLeft = actors["AlliedBaseTopLeft"];
alliedBaseBottomRight = actors["AlliedBaseBottomRight"];
alliedBaseEntryPoint = actors["AlliedBaseEntryPoint"];
alliedBaseMovePoint = actors["AlliedBaseMovePoint"];
demitriChurch = actors["DemitriChurch"];
demitriChurchSpawnPoint = actors["DemitriChurchSpawnPoint"];
demitriTriggerAreaCenter = actors["DemitriTriggerAreaCenter"];
demitriLZ = actors["DemitriLZ"];
hospital = actors["Hospital"];
hospitalCivilianSpawnPoint = actors["HospitalCivilianSpawnPoint"];
hospitalSuperTankPoint = actors["HospitalSuperTankPoint"];
superTanks = actors.Values.Where(a => a.Info.Name == "5tnk" && a.Owner == turkey).ToArray();
provingGroundsCameraPoint = actors["ProvingGroundsCameraPoint"];
world.CreateActor("camera", greece, provingGroundsCameraPoint.Location, null);
superTankDome = actors["SuperTankDome"];
superTankDome.AddTrait(new InfiltrateAction(OnSuperTankDomeInfiltrated));
superTankDome.AddTrait(new TransformedAction(self => superTankDome = self));
wr.Viewport.Center(startEntryPoint.CenterPosition);
MissionUtils.PlayMissionMusic();
}
}
}

View File

@@ -1,52 +0,0 @@
#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;
public string Text;
public ObjectiveStatus Status;
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 interface IHasObjectives
{
event Action<bool> OnObjectivesUpdated;
IEnumerable<Objective> 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; } }
}
}

View File

@@ -1,208 +0,0 @@
#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.Graphics;
using OpenRA.Mods.RA.Activities;
using OpenRA.Mods.RA.Air;
using OpenRA.Mods.RA.Buildings;
using OpenRA.Mods.RA.Move;
using OpenRA.Scripting;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Missions
{
class Soviet01ClassicScriptInfo : TraitInfo<Soviet01ClassicScript>, Requires<SpawnMapActorsInfo> { }
class Soviet01ClassicScript : IHasObjectives, IWorldLoaded, ITick
{
public event Action<bool> OnObjectivesUpdated = notify => { };
public IEnumerable<Objective> Objectives { get { return new[] { destroy }; } }
Objective destroy = new Objective(ObjectiveType.Primary, DestroyText, ObjectiveStatus.InProgress);
const string DestroyText = "A pitiful excuse for resistance has blockaded itself in this village."
+ " Stalin has decided to make an example of them. Kill them all and destroy their homes."
+ " You will have Yak aircraft to use in teaching these rebels a lesson.";
World world;
Player ussr;
Player france;
Actor startJeep;
Actor startJeepMovePoint;
Actor church;
bool startJeepParadropped;
bool churchParadropped;
Actor paradropPoint1;
Actor paradropEntryPoint1;
Actor paradropPoint2;
Actor paradropEntryPoint2;
Actor airfield1;
Actor airfield2;
Actor airfield3;
Actor[] airfields;
const string BadgerName = "badr";
static readonly string[] Reinforcements = { "e1", "e1", "e1", "e2", "e2" };
void MissionAccomplished(string text)
{
MissionUtils.CoopMissionAccomplished(world, text, ussr);
}
void MissionFailed(string text)
{
MissionUtils.CoopMissionFailed(world, text, ussr);
}
public void Tick(Actor self)
{
if (ussr.WinState != WinState.Undefined) return;
var unitsAndBuildings = world.Actors.Where(a => !a.IsDead() && a.IsInWorld && (a.HasTrait<Mobile>() || (a.HasTrait<Building>() && !a.HasTrait<Wall>())));
if (!unitsAndBuildings.Any(a => a.Owner == france))
{
destroy.Status = ObjectiveStatus.Completed;
MissionAccomplished("We destroyed the resistance.");
}
else if (!unitsAndBuildings.Any(a => a.Owner == ussr))
{
destroy.Status = ObjectiveStatus.Failed;
MissionFailed("We were destroyed by the resistance.");
}
if (!startJeepParadropped && startJeep.IsDead())
{
Sound.Play("reinfor1.aud");
MissionUtils.Paradrop(world, ussr, Reinforcements, paradropEntryPoint1.Location, paradropPoint1.Location);
startJeepParadropped = true;
}
if (!churchParadropped && church.IsDead())
{
Sound.Play("reinfor1.aud");
MissionUtils.Paradrop(world, ussr, Reinforcements, paradropEntryPoint2.Location, paradropPoint2.Location);
churchParadropped = true;
}
}
void LandYaks()
{
foreach (var airfield in airfields)
{
var entry = airfield.Location - new CVec(10, 0);
var altitude = Rules.Info["yak"].Traits.Get<PlaneInfo>().CruiseAltitude;
var yak = world.CreateActor("yak", new TypeDictionary
{
new CenterPositionInit(entry.CenterPosition + new WVec(WRange.Zero, WRange.Zero, altitude)),
new OwnerInit(ussr),
new FacingInit(Traits.Util.GetFacing(airfield.Location - entry, 0))
});
while (yak.Trait<LimitedAmmo>().TakeAmmo()) { }
yak.QueueActivity(new ReturnToBase(yak, airfield));
yak.QueueActivity(new ResupplyAircraft());
}
}
void MoveJeep()
{
startJeep.QueueActivity(new Move.Move(startJeepMovePoint.Location, 0));
startJeep.QueueActivity(new Turn(128));
startJeep.QueueActivity(new CallFunc(() =>
{
var bridge = world.Actors.Where(a => a.HasTrait<BridgeHut>()).ClosestTo(startJeep);
bridge.Trait<BridgeHut>().Demolish(bridge, startJeep);
}));
}
public void WorldLoaded(World w, WorldRenderer wr)
{
world = w;
ussr = w.Players.Single(p => p.InternalName == "USSR");
france = w.Players.Single(p => p.InternalName == "France");
var actors = w.WorldActor.Trait<SpawnMapActors>().Actors;
startJeep = actors["StartJeep"];
startJeepMovePoint = actors["StartJeepMovePoint"];
paradropPoint1 = actors["ParadropPoint1"];
paradropEntryPoint1 = actors["ParadropEntryPoint1"];
paradropPoint2 = actors["ParadropPoint2"];
paradropEntryPoint2 = actors["ParadropEntryPoint2"];
church = actors["Church"];
airfield1 = actors["Airfield1"];
airfield2 = actors["Airfield2"];
airfield3 = actors["Airfield3"];
airfields = new[] { airfield1, airfield2, airfield3 };
wr.Viewport.Center(startJeep.CenterPosition);
if (w.LobbyInfo.IsSinglePlayer)
{
Media.PlayFMVFullscreen(w, "soviet1.vqa", () =>
{
LandYaks();
MoveJeep();
MissionUtils.PlayMissionMusic();
});
}
else
{
LandYaks();
MoveJeep();
MissionUtils.PlayMissionMusic();
}
}
}
class Soviet01ClassicContainsActorsInfo : ITraitInfo
{
public readonly string[] Actors = { };
public object Create(ActorInitializer init) { return new Soviet01ClassicContainsActors(this); }
}
class Soviet01ClassicContainsActors : INotifyDamage
{
bool spawned;
Soviet01ClassicContainsActorsInfo info;
public Soviet01ClassicContainsActors(Soviet01ClassicContainsActorsInfo info)
{
this.info = info;
}
public void Damaged(Actor self, AttackInfo e)
{
if (spawned || self.IsDead())
{
return;
}
foreach (var actor in info.Actors)
{
var unit = self.World.CreateActor(actor, new TypeDictionary
{
new OwnerInit(self.Owner),
new LocationInit(self.Location)
});
unit.Trait<Mobile>().Nudge(unit, unit, true);
}
spawned = true;
}
}
}

View File

@@ -1,346 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2013 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.Graphics;
using OpenRA.Mods.RA.Activities;
using OpenRA.Mods.RA.Buildings;
using OpenRA.Mods.RA.Move;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Missions
{
class Survival01ScriptInfo : TraitInfo<Survival01Script>, Requires<SpawnMapActorsInfo> { }
class Survival01Script : IHasObjectives, IWorldLoaded, ITick
{
public event Action<bool> OnObjectivesUpdated = notify => { };
public IEnumerable<Objective> Objectives { get { return new[] { maintainPresence, destroySoviets }; } }
Objective maintainPresence = new Objective(ObjectiveType.Primary, MaintainPresenceText, ObjectiveStatus.InProgress);
Objective destroySoviets = new Objective(ObjectiveType.Primary, DestroySovietsText, ObjectiveStatus.Inactive);
const string MaintainPresenceText = "Enforce your position and hold-out the onslaught until reinforcements arrive. We must not lose the base!";
const string DestroySovietsText = "Take control of French reinforcements and dismantle the nearby Soviet base.";
Player allies;
Player soviets;
Actor sovietEntryPoint1;
Actor sovietEntryPoint2;
Actor sovietEntryPoint3;
Actor sovietEntryPoint4;
Actor sovietEntryPoint5;
CPos[] sovietEntryPoints;
Actor sovietRallyPoint1;
Actor sovietRallyPoint2;
Actor sovietRallyPoint3;
Actor sovietRallyPoint4;
Actor sovietRallyPoint5;
CPos[] sovietRallyPoints;
Actor sovietinfantryentry1;
Actor sovietinfantryrally1;
Actor badgerEntryPoint1;
Actor badgerEntryPoint2;
Actor paraDrop1;
Actor paraDrop2;
Actor sovietEntryPoint7;
Actor alliesbase1;
Actor alliesbase2;
Actor alliesbase;
Actor sam1;
Actor sam2;
Actor barrack1;
World world;
CountdownTimer survivalTimer;
CountdownTimerWidget survivalTimerWidget;
int attackAtFrame;
int attackAtFrameIncrement;
int attackAtFrameInf;
int attackAtFrameIncrementInf;
const int paradropTicks = 750;
static readonly string[] badger1Passengers = { "e1", "e1", "e1", "e2", "e2" };
const int factoryClearRange = 10;
static readonly string[] squad1 = { "e1", "e1" };
static readonly string[] squad2 = { "e2", "e2" };
static readonly string[] sovietVehicles = { "3tnk", "3tnk", "3tnk", "3tnk", "3tnk", "3tnk", "v2rl", "v2rl", "ftrk", "ftrk", "ftrk", "apc", "apc" };
static readonly string[] sovietInfantry = { "e1", "e1", "e1", "e1", "e2", "e2", "e2", "e4", "e4", "e3", };
static readonly string[] reinforcements = { "2tnk", "2tnk", "2tnk", "2tnk", "2tnk", "1tnk", "1tnk", "1tnk", "arty", "arty", "arty", "jeep", "jeep" };
const int sovietAttackGroupSize = 5;
const int sovietInfantryGroupSize = 7;
const int timerTicks = 1500 * 25;
bool spawningSovietUnits = true;
bool spawningInfantry = true;
string difficulty;
void MissionAccomplished(string text)
{
MissionUtils.CoopMissionAccomplished(world, text, allies);
}
public void Tick(Actor self)
{
if (allies.WinState != WinState.Undefined)
return;
survivalTimer.Tick();
if (world.FrameNumber == attackAtFrame)
{
attackAtFrame += attackAtFrameIncrement;
attackAtFrameIncrement = Math.Max(attackAtFrameIncrement - 5, 100);
SpawnSovietUnits();
ManageSovietUnits();
MissionUtils.CapOre(soviets);
}
if (world.FrameNumber == attackAtFrameInf)
{
attackAtFrameInf += attackAtFrameIncrementInf;
attackAtFrameIncrementInf = Math.Max(attackAtFrameIncrementInf - 5, 100);
SpawnSovietInfantry();
}
if (barrack1.Destroyed)
{
spawningInfantry = false;
}
if (world.FrameNumber == paradropTicks)
{
MissionUtils.Paradrop(world, soviets, badger1Passengers, badgerEntryPoint1.Location, paraDrop1.Location);
MissionUtils.Paradrop(world, soviets, badger1Passengers, badgerEntryPoint2.Location, paraDrop2.Location);
}
if (world.FrameNumber == paradropTicks * 2)
{
MissionUtils.Paradrop(world, soviets, badger1Passengers, badgerEntryPoint1.Location, alliesbase2.Location);
MissionUtils.Paradrop(world, soviets, badger1Passengers, badgerEntryPoint2.Location, alliesbase1.Location);
}
if (world.FrameNumber == 1500 * 23)
{
attackAtFrame = 100;
attackAtFrameIncrement = 100;
}
if (world.FrameNumber == 1500 * 25)
{
spawningSovietUnits = false;
spawningInfantry = false;
}
if (destroySoviets.Status == ObjectiveStatus.InProgress)
{
if (barrack1.Destroyed)
{
destroySoviets.Status = ObjectiveStatus.Completed;
OnObjectivesUpdated(true);
MissionAccomplished("The French forces have survived and dismantled the soviet presence in the area!");
}
}
}
void SendSquad1()
{
for (int i = 0; i < squad1.Length; i++)
{
var actor = world.CreateActor(squad1[i], new TypeDictionary { new OwnerInit(soviets), new LocationInit(alliesbase1.Location + new CVec(-2 + i, -6 + i * 2)) });
actor.QueueActivity(new Move.Move(alliesbase1.Location));
}
}
void SendSquad2()
{
for (int i = 0; i < squad2.Length; i++)
{
var actor = world.CreateActor(squad2[i], new TypeDictionary { new OwnerInit(soviets), new LocationInit(alliesbase2.Location + new CVec(-9 + i, -2 + i * 2)) });
actor.QueueActivity(new Move.Move(alliesbase2.Location));
}
}
void SpawnSovietInfantry()
{
if (spawningInfantry)
{
var units = world.CreateActor((sovietInfantry).Random(world.SharedRandom), new TypeDictionary { new LocationInit(sovietinfantryentry1.Location), new OwnerInit(soviets) });
units.QueueActivity(new Move.Move(sovietinfantryrally1.Location, 3));
var unitsincircle = world.FindAliveCombatantActorsInCircle(sovietinfantryrally1.CenterPosition, WRange.FromCells(10))
.Where(a => a.Owner == soviets && a.IsIdle && a.HasTrait<IPositionable>());
if (unitsincircle.Count() >= sovietInfantryGroupSize)
{
foreach (var scatteredunits in unitsincircle)
AttackNearestAlliedActor(scatteredunits);
}
}
}
void SpawnSovietUnits()
{
if (spawningSovietUnits)
{
var route = world.SharedRandom.Next(sovietEntryPoints.Length);
var spawnPoint = sovietEntryPoints[route];
var rallyPoint = sovietRallyPoints[route];
var unit = world.CreateActor(sovietVehicles.Random(world.SharedRandom),
new TypeDictionary { new LocationInit(spawnPoint), new OwnerInit(soviets) });
unit.QueueActivity(new AttackMove.AttackMoveActivity(unit, new Move.Move(rallyPoint, 3)));
}
}
void AttackNearestAlliedActor(Actor self)
{
var enemies = world.Actors.Where(u => u.IsInWorld && !u.IsDead() && (u.Owner == allies)
&& ((u.HasTrait<Building>() && !u.HasTrait<Wall>()) || u.HasTrait<Mobile>()));
var targetEnemy = enemies.ClosestTo(self);
if (targetEnemy != null)
self.QueueActivity(new AttackMove.AttackMoveActivity(self, new Attack(Target.FromActor(targetEnemy), WRange.FromCells(3))));
}
void ManageSovietUnits()
{
foreach (var rallyPoint in sovietRallyPoints)
{
var units = world.FindAliveCombatantActorsInCircle(rallyPoint.CenterPosition, WRange.FromCells(4))
.Where(u => u.IsIdle && u.HasTrait<Mobile>() && u.Owner == soviets);
if (units.Count() >= sovietAttackGroupSize)
{
foreach (var unit in units)
{
AttackNearestAlliedActor(unit);
}
}
}
var scatteredUnits = world.Actors.Where(u => u.IsInWorld && !u.IsDead() && u.HasTrait<Mobile>() && u.IsIdle && u.Owner == soviets)
.Except(world.WorldActor.Trait<SpawnMapActors>().Actors.Values)
.Except(sovietRallyPoints.SelectMany(rp => world.FindAliveCombatantActorsInCircle(rp.CenterPosition, WRange.FromCells(4))));
foreach (var unit in scatteredUnits)
{
AttackNearestAlliedActor(unit);
}
}
void StartCountDownTimer()
{
Sound.Play("timergo1.aud");
survivalTimer = new CountdownTimer(timerTicks, CountDownTimerExpired, true);
survivalTimerWidget = new CountdownTimerWidget(survivalTimer, "Survive: {0}");
Ui.Root.AddChild(survivalTimerWidget);
}
void SendReinforcements()
{
foreach (var unit in reinforcements)
{
var u = world.CreateActor(unit, new TypeDictionary
{
new LocationInit(sovietEntryPoint7.Location),
new FacingInit(0),
new OwnerInit(allies)
});
u.QueueActivity(new Move.Move(alliesbase.Location));
}
}
void CountDownTimerExpired(CountdownTimer countDownTimer)
{
survivalTimerWidget.Visible = false;
SendReinforcements();
maintainPresence.Status = ObjectiveStatus.Completed;
destroySoviets.Status = ObjectiveStatus.InProgress;
OnObjectivesUpdated(true);
}
public void WorldLoaded(World w, WorldRenderer wr)
{
world = w;
allies = w.Players.SingleOrDefault(p => p.InternalName == "Allies");
if (allies != null)
{
attackAtFrameInf = 300;
attackAtFrameIncrementInf = 300;
attackAtFrame = 450;
attackAtFrameIncrement = 450;
}
difficulty = w.LobbyInfo.GlobalSettings.Difficulty;
Game.Debug("{0} difficulty selected".F(difficulty));
switch (difficulty)
{
case "Hard":
attackAtFrameIncrement = 350;
attackAtFrameIncrementInf = 200;
break;
case "Normal":
attackAtFrameIncrement = 450;
attackAtFrameIncrementInf = 300;
break;
case "Easy":
attackAtFrameIncrement = 550;
attackAtFrameIncrementInf = 400;
break;
}
soviets = w.Players.Single(p => p.InternalName == "Soviets");
var actors = w.WorldActor.Trait<SpawnMapActors>().Actors;
sovietEntryPoint1 = actors["sovietEntryPoint1"];
sovietEntryPoint2 = actors["sovietEntryPoint2"];
sovietEntryPoint3 = actors["sovietEntryPoint3"];
sovietEntryPoint4 = actors["sovietEntryPoint4"];
sovietEntryPoint5 = actors["sovietEntryPoint5"];
sovietEntryPoints = new[] { sovietEntryPoint1, sovietEntryPoint2, sovietEntryPoint3, sovietEntryPoint4, sovietEntryPoint5 }.Select(p => p.Location).ToArray();
sovietRallyPoint1 = actors["sovietRallyPoint1"];
sovietRallyPoint2 = actors["sovietRallyPoint2"];
sovietRallyPoint3 = actors["sovietRallyPoint3"];
sovietRallyPoint4 = actors["sovietRallyPoint4"];
sovietRallyPoint5 = actors["sovietRallyPoint5"];
sovietRallyPoints = new[] { sovietRallyPoint1, sovietRallyPoint2, sovietRallyPoint3, sovietRallyPoint4, sovietRallyPoint5 }.Select(p => p.Location).ToArray();
alliesbase = actors["alliesbase"];
alliesbase1 = actors["alliesbase1"];
alliesbase2 = actors["alliesbase2"];
badgerEntryPoint1 = actors["BadgerEntryPoint1"];
badgerEntryPoint2 = actors["BadgerEntryPoint2"];
sovietEntryPoint7 = actors["sovietEntryPoint7"];
sovietinfantryentry1 = actors["SovietInfantryEntry1"];
sovietinfantryrally1 = actors["SovietInfantryRally1"];
paraDrop1 = actors["ParaDrop1"];
paraDrop2 = actors["ParaDrop2"];
barrack1 = actors["Barrack1"];
sam1 = actors["Sam1"];
sam2 = actors["Sam2"];
var shroud = allies.PlayerActor.Trait<Shroud>();
shroud.Explore(w, sam1.Location, WRange.FromCells(4));
shroud.Explore(w, sam2.Location, WRange.FromCells(4));
wr.Viewport.Center(alliesbase.CenterPosition);
StartCountDownTimer();
SendSquad1();
SendSquad2();
MissionUtils.PlayMissionMusic();
}
}
}

View File

@@ -1,411 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2013 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.Collections.Generic;
using System.Linq;
using System;
using System.Drawing;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Mods.RA.Activities;
using OpenRA.Mods.RA.Move;
using OpenRA.Traits;
using OpenRA.Widgets;
using OpenRA.Mods.RA.Buildings;
namespace OpenRA.Mods.RA.Missions
{
class Survival02ScriptInfo : TraitInfo<Survival02Script>, Requires<SpawnMapActorsInfo> { }
class Survival02Script : IHasObjectives, IWorldLoaded, ITick
{
public event Action<bool> OnObjectivesUpdated = notify => { };
public IEnumerable<Objective> Objectives { get { return objectives.Values; } }
Dictionary<int, Objective> objectives = new Dictionary<int, Objective>
{
{ maintainPresenceID, new Objective(ObjectiveType.Primary, maintainPresence, ObjectiveStatus.InProgress) },
{ destroySovietsID, new Objective(ObjectiveType.Primary, destroySoviets, ObjectiveStatus.Inactive) },
};
const int destroySovietsID = 0;
const string destroySoviets = "Excellent work Commander! We have reinforced our position enough to initiate a counter-attack. Destroy the remaining Soviet forces in the area!";
const int maintainPresenceID = 1;
const string maintainPresence = "Commander! The Soviets have rendered us useless... Reports indicate Soviet reinforcements are coming to finish us off... the situation looks bleak...";
Player allies;
Player soviets;
Actor sovietEntry1;
Actor sovietEntry2;
Actor sovietEntry3;
CPos[] sovietentrypoints;
CPos[] newsovietentrypoints;
Actor sovietrally;
Actor sovietrally1;
Actor sovietrally2;
Actor sovietrally3;
Actor sovietrally4;
Actor sovietrally5;
Actor sovietrally6;
Actor sovietrally8;
CPos[] sovietrallypoints;
CPos[] newsovietrallypoints;
Actor sovietparadrop1;
Actor sovietparadrop2;
Actor sovietparadrop3;
Actor sovietparadropEntry;
Actor alliesbase;
Actor factory;
Actor barrack1;
Actor drum1;
Actor drum2;
Actor drum3;
Actor FranceEntry;
Actor FranceRally;
Actor FranceparaEntry1;
Actor FranceparaEntry2;
Actor FranceparaEntry3;
World world;
WorldRenderer worldRenderer;
CountdownTimer survivalTimer;
CountdownTimerWidget survivalTimerWidget;
const int timerTicks = 1500 * 10;
const int attackTicks = 1500 * 1;
const int sovietAttackGroupSize = 7;
const int SovietGroupSize = 4;
const string Camera = "Camera";
const string InfantryQueueName = "Infantry";
const string Flare = "flare";
static readonly string[] FrenchSquad = { "2tnk", "2tnk", "mcv" };
static readonly string[] SovietInfantry = { "e1", "e4", "e2" };
static readonly string[] SovietVehicles = { "3tnk", "3tnk", "v2rl" };
static readonly string[] SovietTanks = { "3tnk", "3tnk", "3tnk" };
static readonly string[] squad = { "e1", "e1", "e2", "e4", "e4" };
static readonly string[] platoon = { "e1", "e1", "e2", "e4", "e4", "e1", "e1", "e2", "e4", "e4" };
int ProduceAtFrame;
int ProduceAtFrameIncrement;
int attackAtFrame;
int attackAtFrameIncrement;
void MissionAccomplished(string text)
{
MissionUtils.CoopMissionAccomplished(world, text, allies);
}
void MissionFailed(string text)
{
MissionUtils.CoopMissionFailed(world, text, allies);
}
void Message(string text)
{
Game.AddChatLine(Color.Aqua, "Incoming Report", text);
}
void SetSovietUnitsToDefensiveStance()
{
foreach (var actor in world.Actors.Where(a => a.IsInWorld && a.Owner == soviets && !a.IsDead() && a.HasTrait<AutoTarget>()))
actor.Trait<AutoTarget>().Stance = UnitStance.Defend;
}
Actor FirstUnshroudedOrDefault(IEnumerable<Actor> actors, World world, int shroudRange)
{
return actors.FirstOrDefault(u => world.FindAliveCombatantActorsInCircle(u.CenterPosition, WRange.FromCells(shroudRange)).All(a => !a.HasTrait<CreatesShroud>()));
}
void AttackNearestAlliedActor(Actor self)
{
var enemies = world.Actors.Where(u => u.AppearsHostileTo(self) && (u.Owner == allies)
&& ((u.HasTrait<Building>() && !u.HasTrait<Wall>()) || u.HasTrait<Mobile>()) && u.IsInWorld && !u.IsDead());
var enemy = FirstUnshroudedOrDefault(enemies.OrderBy(u => (self.CenterPosition - u.CenterPosition).LengthSquared), world, 20);
if (enemy != null)
self.QueueActivity(new AttackMove.AttackMoveActivity(self, new Attack(Target.FromActor(enemy), WRange.FromCells(3))));
}
void SpawnAndAttack(string[] squad, Player owner, CPos location)
{
for (int i = 0; i < squad.Length; i++)
{
var actor = world.CreateActor(squad[i], new TypeDictionary { new OwnerInit(owner), new LocationInit(location) });
AttackNearestAlliedActor(actor);
}
}
void SpawnFlare(Player owner, Actor location)
{
world.CreateActor(Flare, new TypeDictionary { new OwnerInit(owner), new LocationInit(location.Location) });
}
void FinalAttack()
{
SpawnAndAttack(SovietTanks, soviets, sovietEntry1.Location);
SpawnAndAttack(SovietTanks, soviets, sovietEntry1.Location);
SpawnAndAttack(SovietTanks, soviets, sovietEntry2.Location);
SpawnAndAttack(platoon, soviets, sovietEntry1.Location);
SpawnAndAttack(platoon, soviets, sovietEntry2.Location);
}
void FrenchReinforcements()
{
worldRenderer.Viewport.Center(sovietrally1.CenterPosition);
MissionUtils.Parabomb(world, allies, FranceparaEntry1.Location, drum3.Location);
MissionUtils.Parabomb(world, allies, FranceparaEntry3.Location, drum2.Location);
MissionUtils.Parabomb(world, allies, FranceparaEntry2.Location, drum1.Location);
for (int i = 0; i < FrenchSquad.Length; i++)
{
var actor = world.CreateActor(FrenchSquad[i], new TypeDictionary { new OwnerInit(allies), new LocationInit(FranceEntry.Location) });
actor.QueueActivity(new Move.Move(FranceRally.Location));
}
}
public void Tick(Actor self)
{
if (allies.WinState != WinState.Undefined)
return;
survivalTimer.Tick();
if (allies != null)
{
ManageSovietUnits();
}
var unitsAndBuildings = world.Actors.Where(a => !a.IsDead() && a.IsInWorld && (a.HasTrait<Mobile>() || (a.HasTrait<Building>() && !a.HasTrait<Wall>())));
if (!unitsAndBuildings.Any(a => a.Owner == soviets))
{
objectives[destroySovietsID].Status = ObjectiveStatus.Completed;
MissionAccomplished("We have destroyed the remaining Soviet presence!");
}
if (world.FrameNumber == ProduceAtFrame)
{
ProduceAtFrame += ProduceAtFrameIncrement;
ProduceAtFrameIncrement = Math.Max(ProduceAtFrameIncrement - 5, 100);
InitializeSovietFactories(barrack1, sovietrally.Location);
BuildSovietUnits(factory, barrack1);
}
if (world.FrameNumber == attackAtFrame)
{
attackAtFrame += attackAtFrameIncrement;
attackAtFrameIncrement = Math.Max(attackAtFrameIncrement - 5, 100);
ManageSovietVehicles();
if (producing)
{
BuildSovietVehicles(sovietentrypoints, sovietrallypoints);
}
else
BuildSovietVehicles(newsovietentrypoints, newsovietrallypoints);
}
if (world.FrameNumber == attackTicks)
{
SpawnAndAttack(squad, soviets, sovietrally5.Location);
SpawnAndAttack(squad, soviets, sovietrally6.Location);
}
if (world.FrameNumber == attackTicks * 3)
{
SpawnFlare(soviets, sovietparadrop3);
MissionUtils.Paradrop(world, soviets, squad, sovietparadropEntry.Location, sovietparadrop3.Location);
SpawnAndAttack(squad, soviets, sovietrally2.Location);
SpawnAndAttack(platoon, soviets, sovietrally5.Location);
SpawnAndAttack(platoon, soviets, sovietrally6.Location);
}
if (world.FrameNumber == attackTicks * 5)
{
SpawnFlare(soviets, sovietparadrop2);
MissionUtils.Paradrop(world, soviets, squad, sovietparadropEntry.Location, sovietparadrop2.Location);
}
if (world.FrameNumber == attackTicks * 7)
{
SpawnFlare(soviets, sovietparadrop1);
MissionUtils.Paradrop(world, soviets, squad, sovietparadropEntry.Location, sovietparadrop1.Location);
}
if (world.FrameNumber == attackTicks * 10)
{
SpawnFlare(soviets, sovietparadrop1);
MissionUtils.Paradrop(world, soviets, squad, sovietparadropEntry.Location, sovietparadrop1.Location);
ManageSovietUnits();
}
if (world.FrameNumber == attackTicks * 12)
{
Sound.Play("reinfor1.aud");
FrenchReinforcements();
}
}
void StartCountDownTimer()
{
Sound.Play("timergo1.aud");
survivalTimer = new CountdownTimer(timerTicks, CountDownTimerExpired, true);
survivalTimerWidget = new CountdownTimerWidget(survivalTimer, "Time Until Soviet Reinforcements Arrive: {0}");
Ui.Root.AddChild(survivalTimerWidget);
}
void CountDownTimerExpired(CountdownTimer countDownTimer)
{
survivalTimerWidget.Visible = false;
Message("The Soviet reinforcements are approuching!");
BuildSovietVehicles(newsovietentrypoints, newsovietrallypoints);
FinalAttack();
producing = false;
objectives[maintainPresenceID].Status = ObjectiveStatus.Completed;
objectives[destroySovietsID].Status = ObjectiveStatus.InProgress;
OnObjectivesUpdated(true);
}
void InitializeSovietFactories(Actor tent, CPos rally)
{
if (tent.IsInWorld && !tent.IsDead())
{
var sbrp = tent.Trait<RallyPoint>();
sbrp.rallyPoint = rally;
sbrp.nearEnough = 6;
}
}
void BuildSovietUnit(string category, string unit)
{
var queueTent = MissionUtils.FindQueues(world, soviets, category).FirstOrDefault(q => q.CurrentItem() == null);
if (queueTent == null) return;
queueTent.ResolveOrder(queueTent.self, Order.StartProduction(queueTent.self, unit, 1));
}
void BuildSovietUnits(Actor factory, Actor tent)
{
if (barrack1.IsInWorld && !barrack1.IsDead())
{
BuildSovietUnit(InfantryQueueName, SovietInfantry.Random(world.SharedRandom));
}
}
void ManageSovietUnits()
{
var units = world.FindAliveCombatantActorsInCircle(sovietrally.CenterPosition, WRange.FromCells(3))
.Where(u => u.IsIdle && u.HasTrait<IPositionable>() && u.HasTrait<AttackBase>() && u.Owner == soviets);
if (units.Count() >= sovietAttackGroupSize)
{
foreach (var unit in units)
{
var route = world.SharedRandom.Next(sovietrallypoints.Length);
unit.QueueActivity(new Move.Move(sovietrally3.Location));
unit.QueueActivity(new Wait(300));
unit.QueueActivity(new Move.Move(sovietrallypoints[route]));
AttackNearestAlliedActor(unit);
}
}
}
void BuildSovietVehicles(CPos[] spawnpoints, CPos[] rallypoints)
{
var route = world.SharedRandom.Next(spawnpoints.Length);
var spawnPoint = spawnpoints[route];
var rally = world.SharedRandom.Next(rallypoints.Length);
var rallyPoint = rallypoints[rally];
var unit = world.CreateActor(SovietVehicles.Random(world.SharedRandom),
new TypeDictionary
{
new LocationInit(spawnPoint),
new OwnerInit(soviets)
});
unit.QueueActivity(new AttackMove.AttackMoveActivity(unit, new Move.Move(rallyPoint, 3)));
}
void ManageSovietVehicles()
{
foreach (var rallyPoint in sovietrallypoints)
{
var units = world.FindAliveCombatantActorsInCircle(rallyPoint.CenterPosition, WRange.FromCells(10))
.Where(u => u.IsIdle && u.HasTrait<Mobile>() && u.HasTrait<AttackBase>() && u.Owner == soviets);
if (units.Count() >= SovietGroupSize)
{
foreach (var unit in units)
AttackNearestAlliedActor(unit);
}
}
var scatteredUnits = world.Actors.Where(u => u.IsInWorld && !u.IsDead() && u.HasTrait<Mobile>() && u.IsIdle && u.Owner == soviets)
.Except(world.WorldActor.Trait<SpawnMapActors>().Actors.Values)
.Except(sovietrallypoints.SelectMany(rp => world.FindAliveCombatantActorsInCircle(rp.CenterPosition, WRange.FromCells(10))));
foreach (var unit in scatteredUnits)
AttackNearestAlliedActor(unit);
}
bool producing = true;
public void WorldLoaded(World w, WorldRenderer wr)
{
world = w;
worldRenderer = wr;
allies = w.Players.SingleOrDefault(p => p.InternalName == "Allies");
if (allies != null)
{
ProduceAtFrame = 300;
ProduceAtFrameIncrement = 300;
attackAtFrame = 450;
attackAtFrameIncrement = 450;
}
soviets = w.Players.Single(p => p.InternalName == "Soviets");
var actors = w.WorldActor.Trait<SpawnMapActors>().Actors;
sovietEntry1 = actors["SovietEntry1"];
sovietEntry2 = actors["SovietEntry2"];
sovietEntry3 = actors["SovietEntry3"];
sovietentrypoints = new[] { sovietEntry1, sovietEntry2, sovietEntry3 }.Select(p => p.Location).ToArray();
sovietrally = actors["SovietRally"];
sovietrally1 = actors["SovietRally1"];
sovietrally2 = actors["SovietRally2"];
sovietrally3 = actors["SovietRally3"];
sovietrally4 = actors["SovietRally4"];
sovietrally5 = actors["SovietRally5"];
sovietrally6 = actors["SovietRally6"];
sovietrally8 = actors["SovietRally8"];
sovietrallypoints = new[] { sovietrally2, sovietrally4, sovietrally5, sovietrally6 }.Select(p => p.Location).ToArray();
alliesbase = actors["AlliesBase"];
sovietparadropEntry = actors["SovietParaDropEntry"];
sovietparadrop1 = actors["SovietParaDrop1"];
sovietparadrop2 = actors["SovietParaDrop2"];
sovietparadrop3 = actors["SovietParaDrop3"];
barrack1 = actors["barrack1"];
factory = actors["Factory"];
drum1 = actors["drum1"];
drum2 = actors["drum2"];
drum3 = actors["drum3"];
FranceEntry = actors["FranceEntry"];
FranceRally = actors["FranceRally"];
FranceparaEntry1 = actors["FranceparaEntry1"];
FranceparaEntry2 = actors["FranceparaEntry2"];
FranceparaEntry3 = actors["FranceparaEntry3"];
newsovietentrypoints = new[] { sovietparadropEntry, sovietEntry3 }.Select(p => p.Location).ToArray();
newsovietrallypoints = new[] { sovietrally3, sovietrally4, sovietrally8 }.Select(p => p.Location).ToArray();
worldRenderer.Viewport.Center(alliesbase.CenterPosition);
StartCountDownTimer();
SetSovietUnitsToDefensiveStance();
world.CreateActor(Camera, new TypeDictionary
{
new OwnerInit(allies),
new LocationInit(sovietrally1.Location),
});
MissionUtils.PlayMissionMusic();
}
}
}

View File

@@ -261,22 +261,9 @@
<Compile Include="Lint\CheckTraitPrerequisites.cs" />
<Compile Include="Lint\LintBuildablePrerequisites.cs" />
<Compile Include="MadTank.cs" />
<Compile Include="Missions\FortLonestarScript.cs" />
<Compile Include="Missions\Survival02Script.cs" />
<Compile Include="MPStartLocations.cs" />
<Compile Include="Mine.cs" />
<Compile Include="Minelayer.cs" />
<Compile Include="Missions\Allies01Script.cs" />
<Compile Include="Missions\Allies02Script.cs" />
<Compile Include="Missions\Allies03Script.cs" />
<Compile Include="Missions\Allies04Script.cs" />
<Compile Include="Missions\CountdownTimer.cs" />
<Compile Include="Missions\MissionUtils.cs" />
<Compile Include="Missions\MissionWidgets.cs" />
<Compile Include="Missions\MonsterTankMadnessScript.cs" />
<Compile Include="Missions\Objective.cs" />
<Compile Include="Missions\Soviet01ClassicScript.cs" />
<Compile Include="Missions\Survival01Script.cs" />
<Compile Include="Modifiers\FrozenUnderFog.cs" />
<Compile Include="Modifiers\HiddenUnderFog.cs" />
<Compile Include="Move\Drag.cs" />
@@ -407,7 +394,6 @@
<Compile Include="Widgets\Logic\LobbyUtils.cs" />
<Compile Include="Widgets\Logic\MainMenuLogic.cs" />
<Compile Include="Widgets\Logic\MapChooserLogic.cs" />
<Compile Include="Widgets\Logic\MissionObjectivesLogic.cs" />
<Compile Include="Widgets\Logic\MusicPlayerLogic.cs" />
<Compile Include="Widgets\Logic\ObserverStatsLogic.cs" />
<Compile Include="Widgets\Logic\OrderButtonsChromeLogic.cs" />

View File

@@ -17,7 +17,7 @@ using OpenRA.Effects;
using OpenRA.FileFormats;
using OpenRA.Mods.RA.Activities;
using OpenRA.Mods.RA.Air;
using OpenRA.Mods.RA.Missions;
using OpenRA.Network;
using OpenRA.Scripting;
using OpenRA.Support;
using OpenRA.Traits;
@@ -245,7 +245,25 @@ namespace OpenRA.Mods.RA.Scripting
[LuaGlobal]
public void PlayRandomMusic()
{
MissionUtils.PlayMissionMusic();
if (!Rules.InstalledMusic.Any() || !Game.Settings.Sound.MapMusic)
return;
Game.ConnectionStateChanged += StopMusic;
PlayMusic();
}
void PlayMusic()
{
var track = Rules.InstalledMusic.Random(Game.CosmeticRandom);
Sound.PlayMusicThen(track.Value, PlayMusic);
}
void StopMusic(OrderManager orderManager)
{
if (!orderManager.GameStarted)
{
Sound.StopMusic();
Game.ConnectionStateChanged -= StopMusic;
}
}
[LuaGlobal]

View File

@@ -1,111 +0,0 @@
#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<IHasObjectives>().First();
objectivesButton = gameRoot.Get<ButtonWidget>("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;
Widget widget;
LabelWidget objectiveText;
LabelWidget objectiveStatus;
if (objective.Type == ObjectiveType.Primary)
{
widget = primaryTemplate.Clone();
objectiveText = widget.Get<LabelWidget>("PRIMARY_OBJECTIVE");
objectiveStatus = widget.Get<LabelWidget>("PRIMARY_STATUS");
SetupWidget(widget, objectiveText, objectiveStatus, objective);
primaryPanel.AddChild(widget);
}
else
{
widget = secondaryTemplate.Clone();
objectiveText = widget.Get<LabelWidget>("SECONDARY_OBJECTIVE");
objectiveStatus = widget.Get<LabelWidget>("SECONDARY_STATUS");
SetupWidget(widget, objectiveText, objectiveStatus, objective);
secondaryPanel.AddChild(widget);
}
}
}
void SetupWidget(Widget widget, LabelWidget objectiveText, LabelWidget objectiveStatus, Objective objective)
{
var font = Game.Renderer.Fonts[objectiveText.Font];
var text = WidgetUtils.WrapText(objective.Text, objectiveText.Bounds.Width, font);
widget.Bounds.Height = objectiveText.Bounds.Height = objectiveStatus.Bounds.Height = font.Measure(text).Y;
objectiveText.GetText = () => text;
objectiveStatus.GetText = () => GetObjectiveStatusText(objective.Status);
}
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 "";
}
}
}
}

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -1,446 +0,0 @@
Selectable: True
MapFormat: 6
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: Campaign
Options:
Crates: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 5000
ConfigurableStartingUnits: False
Difficulties: Easy,Normal
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
Required: True
LockRace: True
Race: allies
LockColor: True
ColorRamp: 161,134,200
LockSpawn: True
LockTeam: True
Allies: Creeps
Enemies: Soviets
PlayerReference@Soviets:
Name: Soviets
Race: soviet
ColorRamp: 3,255,127
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.autotargetignore
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
Actor1000: camera.large
Location: 1,1
Owner: Soviets
Smudges:
Rules:
Player:
-ConquestVictoryConditions:
World:
-CrateSpawner:
-SpawnMPUnits:
-MPStartLocations:
Allies01Script:
MissionObjectivesPanel:
ObjectivesPanel: MISSION_OBJECTIVES
TRAN:
-Selectable:
RevealsShroud:
Range: 0c0
E7:
AutoTarget:
InitialStance: Defend
Passenger:
Weight: 0
EINSTEIN:
Passenger:
Weight: 0
STEK.AutoTargetIgnore:
Inherits: STEK
RenderBuilding:
Image: STEK
Tooltip:
Icon: STEK
AutoTargetIgnore:
^Vehicle:
GivesBounty:
Percentage: 0
^Tank:
GivesBounty:
Percentage: 0
^Infantry:
GivesBounty:
Percentage: 0
^Ship:
GivesBounty:
Percentage: 0
^Plane:
GivesBounty:
Percentage: 0
^Building:
GivesBounty:
Percentage: 0
CAMERA.Large:
Inherits: CAMERA
RevealsShroud:
Range: 1000c0
Sequences:
VoxelSequences:
Weapons:
8Inch:
ROF: 200
Range: 25c0
Burst: 2
Report: TURRET1.AUD
Projectile: Bullet
Speed: 512
High: true
Angle: 62
Inaccuracy: 4c170
Image: 120MM
ContrailLength: 10
Warhead:
Spread: 213
Versus:
None: 60%
Wood: 75%
Light: 60%
Heavy: 25%
Explosion: large_explosion
WaterExplosion: large_splash
InfDeath: 2
SmudgeType: Crater
Damage: 500
ImpactSound: kaboom12.aud
WaterImpactSound: splash9.aud
Voices:
Notifications:
Translations:

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,953 +0,0 @@
Selectable: True
MapFormat: 6
RequiresMod: ra
Title: Soviet 01 (Classic)
Description: Lesson in Blood
Author: Westwood Studios
Tileset: SNOW
MapSize: 128,128
Bounds: 32,47,32,38
UseAsShellmap: False
Type: Campaign
Options:
Crates: False
Fog: True
Shroud: True
AllyBuildRadius: False
FragileAlliances: False
StartingCash: 0
ConfigurableStartingUnits: False
Players:
PlayerReference@GoodGuy:
Name: GoodGuy
Race: allies
ColorRamp: 161,134,200
Allies: France,Germany,Turkey
Enemies: USSR
PlayerReference@France:
Name: France
Race: allies
ColorRamp: 115,115,143
Allies: GoodGuy,Germany,Turkey
Enemies: USSR
PlayerReference@Germany:
Name: Germany
Race: allies
ColorRamp: 0,0,80
Allies: GoodGuy,France,Turkey
Enemies: USSR
PlayerReference@USSR:
Name: USSR
Playable: True
AllowBots: False
Required: True
LockRace: True
Race: soviet
LockColor: True
ColorRamp: 3,255,127
LockSpawn: True
LockTeam: True
Enemies: GoodGuy,France,Germany,Turkey
PlayerReference@Turkey:
Name: Turkey
Race: allies
ColorRamp: 14,123,167
Allies: GoodGuy,France,Germany
Enemies: USSR
PlayerReference@Neutral:
Name: Neutral
OwnsWorld: True
NonCombatant: True
Race: allies
PlayerReference@Creeps:
Name: Creeps
NonCombatant: True
Race: allies
Actors:
Actor0: wood
Location: 44,50
Owner: Neutral
Actor1: wood
Location: 44,51
Owner: Neutral
Actor2: wood
Location: 44,52
Owner: Neutral
Actor3: wood
Location: 44,53
Owner: Neutral
Actor4: wood
Location: 45,53
Owner: Neutral
Actor5: wood
Location: 56,65
Owner: Neutral
Actor6: v14
Location: 54,66
Owner: Neutral
Actor7: v14
Location: 55,66
Owner: Neutral
Actor8: wood
Location: 56,66
Owner: Neutral
Actor9: wood
Location: 53,67
Owner: Neutral
Actor10: wood
Location: 55,67
Owner: Neutral
Actor11: wood
Location: 56,67
Owner: Neutral
Actor12: wood
Location: 45,69
Owner: Neutral
Actor13: wood
Location: 46,69
Owner: Neutral
Actor14: wood
Location: 47,69
Owner: Neutral
Actor15: wood
Location: 45,70
Owner: Neutral
Actor16: wood
Location: 51,70
Owner: Neutral
Actor17: wood
Location: 53,71
Owner: Neutral
Actor18: wood
Location: 52,72
Owner: Neutral
Actor19: wood
Location: 53,72
Owner: Neutral
Actor20: t16
Location: 53,52
Owner: Neutral
Actor21: tc03
Location: 60,61
Owner: Neutral
Actor22: tc01
Location: 48,47
Owner: Neutral
Actor23: t06
Location: 73,59
Owner: Neutral
Actor24: t01
Location: 49,74
Owner: Neutral
Actor25: t14
Location: 60,69
Owner: Neutral
Actor26: t16
Location: 59,72
Owner: Neutral
Actor27: t14
Location: 60,72
Owner: Neutral
Actor28: t07
Location: 62,72
Owner: Neutral
Actor29: t10
Location: 54,74
Owner: Neutral
Actor30: tc02
Location: 46,49
Owner: Neutral
Actor31: t01
Location: 53,57
Owner: Neutral
Actor32: tc05
Location: 41,51
Owner: Neutral
Actor33: t06
Location: 44,53
Owner: Neutral
Actor34: t01
Location: 44,70
Owner: Neutral
Actor35: t16
Location: 52,72
Owner: Neutral
Actor36: tc02
Location: 32,51
Owner: Neutral
Actor37: tc04
Location: 32,55
Owner: Neutral
Actor38: tc05
Location: 32,60
Owner: Neutral
Actor39: tc02
Location: 42,57
Owner: Neutral
Actor40: tc02
Location: 43,68
Owner: Neutral
Actor41: tc01
Location: 42,67
Owner: Neutral
Actor42: tc04
Location: 32,72
Owner: Neutral
Actor43: tc03
Location: 51,77
Owner: Neutral
Actor44: tc01
Location: 39,72
Owner: Neutral
Actor45: t17
Location: 35,76
Owner: Neutral
Actor46: t15
Location: 59,75
Owner: Neutral
Actor47: tc03
Location: 35,65
Owner: Neutral
Actor48: t01
Location: 35,56
Owner: Neutral
Actor49: t10
Location: 47,59
Owner: Neutral
Actor50: t08
Location: 48,64
Owner: Neutral
Actor51: barl
Location: 33,54
Owner: GoodGuy
Health: 1
Facing: 0
Actor52: brl3
Location: 57,53
Owner: GoodGuy
Health: 1
Facing: 0
Actor53: v08
Location: 41,54
Owner: France
Health: 0.5195313
Facing: 0
Actor54: v07.civilians
Location: 54,65
Owner: France
Health: 0.4375
Facing: 0
Actor55: v07
Location: 38,52
Owner: France
Health: 0.4375
Facing: 0
Actor56: v06
Location: 46,51
Owner: France
Health: 0.9921875
Facing: 0
Actor57: v05
Location: 36,55
Owner: France
Health: 0.5
Facing: 0
Actor58: v04
Location: 35,51
Owner: France
Health: 0.3515625
Facing: 0
Actor59: v02
Location: 36,57
Owner: France
Health: 0.5625
Facing: 0
Actor60: brl3
Location: 34,52
Owner: GoodGuy
Health: 1
Facing: 0
Actor61: barl
Location: 57,54
Owner: GoodGuy
Health: 1
Facing: 0
Actor62: barl
Location: 55,54
Owner: GoodGuy
Health: 1
Facing: 0
Actor63: brl3
Location: 51,72
Owner: Germany
Health: 1
Facing: 0
Actor64: brl3
Location: 51,71
Owner: Germany
Health: 1
Facing: 0
Actor65: brl3
Location: 47,71
Owner: Germany
Health: 1
Facing: 0
Actor66: barl
Location: 46,71
Owner: Germany
Health: 1
Facing: 0
Actor67: barl
Location: 47,70
Owner: Germany
Health: 1
Facing: 0
Actor68: brl3
Location: 43,50
Owner: GoodGuy
Health: 1
Facing: 0
Actor69: brl3
Location: 45,52
Owner: GoodGuy
Health: 1
Facing: 0
Actor70: barl
Location: 41,51
Owner: France
Health: 1
Facing: 0
Actor71: barl
Location: 50,72
Owner: Germany
Health: 1
Facing: 0
Actor72: barl
Location: 42,50
Owner: GoodGuy
Health: 1
Facing: 0
Airfield1: afld.noproduction
Location: 35,81
Owner: USSR
Health: 1
Facing: 0
Actor74: powr
Location: 43,82
Owner: USSR
Health: 1
Facing: 0
Actor75: barl
Location: 56,53
Owner: GoodGuy
Health: 1
Facing: 0
Actor76: barl
Location: 58,53
Owner: GoodGuy
Health: 1
Facing: 0
Actor77: brl3
Location: 59,53
Owner: GoodGuy
Health: 1
Facing: 0
Actor78: brl3
Location: 54,53
Owner: GoodGuy
Health: 1
Facing: 0
Actor79: barl
Location: 59,56
Owner: GoodGuy
Health: 1
Facing: 0
Actor80: brl3
Location: 48,66
Owner: GoodGuy
Health: 1
Facing: 0
Actor81: barl
Location: 45,65
Owner: GoodGuy
Health: 1
Facing: 0
Actor82: barl
Location: 34,57
Owner: GoodGuy
Health: 1
Facing: 0
Actor83: brl3
Location: 35,58
Owner: GoodGuy
Health: 1
Facing: 0
Actor84: barl
Location: 46,67
Owner: GoodGuy
Health: 1
Facing: 0
Actor85: barl
Location: 48,67
Owner: GoodGuy
Health: 1
Facing: 0
Actor86: brl3
Location: 38,65
Owner: GoodGuy
Health: 1
Facing: 0
Actor87: barl
Location: 40,52
Owner: GoodGuy
Health: 1
Facing: 0
Actor88: barl
Location: 39,64
Owner: GoodGuy
Health: 1
Facing: 0
Actor89: brl3
Location: 41,53
Owner: GoodGuy
Health: 1
Facing: 0
Actor90: brl3
Location: 46,66
Owner: GoodGuy
Health: 1
Facing: 0
Airfield2: afld.noproduction
Location: 39,77
Owner: USSR
Health: 1
Facing: 0
Actor92: powr
Location: 45,82
Owner: USSR
Health: 1
Facing: 0
Airfield3: afld.noproduction
Location: 37,79
Owner: USSR
Health: 1
Facing: 0
Actor94: barl
Location: 35,56
Owner: GoodGuy
Health: 1
Facing: 0
Actor95: brl3
Location: 38,64
Owner: GoodGuy
Health: 1
Facing: 0
Actor96: brl3
Location: 34,55
Owner: GoodGuy
Health: 1
Facing: 0
Actor97: barl
Location: 35,55
Owner: GoodGuy
Health: 1
Facing: 0
Actor98: barl
Location: 45,50
Owner: GoodGuy
Health: 1
Facing: 0
Actor99: v04
Location: 58,54
Owner: France
Health: 0.4140625
Facing: 0
Actor100: v02
Location: 56,54
Owner: France
Health: 0.7070313
Facing: 0
Actor101: dome
Location: 45,79
Owner: USSR
Health: 1
Facing: 0
Actor102: barl
Location: 46,61
Owner: GoodGuy
Health: 1
Facing: 0
Actor103: brl3
Location: 43,66
Owner: GoodGuy
Health: 1
Facing: 0
Actor104: barl
Location: 43,67
Owner: GoodGuy
Health: 1
Facing: 0
Actor105: brl3
Location: 59,57
Owner: GoodGuy
Health: 1
Facing: 0
Actor106: barl
Location: 57,58
Owner: GoodGuy
Health: 1
Facing: 0
Actor107: barl
Location: 58,58
Owner: GoodGuy
Health: 1
Facing: 0
Actor108: brl3
Location: 59,58
Owner: GoodGuy
Health: 1
Facing: 0
Actor109: brl3
Location: 56,58
Owner: GoodGuy
Health: 1
Facing: 0
Actor110: barl
Location: 56,59
Owner: GoodGuy
Health: 1
Facing: 0
Actor111: barl
Location: 56,60
Owner: GoodGuy
Health: 1
Facing: 0
Actor112: barl
Location: 41,68
Owner: GoodGuy
Health: 1
Facing: 0
Actor113: barl
Location: 42,67
Owner: GoodGuy
Health: 1
Facing: 0
Actor114: brl3
Location: 49,55
Owner: GoodGuy
Health: 1
Facing: 0
Actor115: barl
Location: 48,55
Owner: GoodGuy
Health: 1
Facing: 0
Actor116: barl
Location: 47,56
Owner: GoodGuy
Health: 1
Facing: 0
Actor117: brl3
Location: 46,56
Owner: GoodGuy
Health: 1
Facing: 0
Actor118: pbox.e1
Location: 46,55
Owner: France
Health: 1
Facing: 0
Actor119: pbox.e1
Location: 48,54
Owner: France
Health: 1
Facing: 0
Actor120: barl
Location: 34,51
Owner: GoodGuy
Health: 1
Facing: 0
Actor121: v05.civilians
Location: 48,62
Owner: France
Health: 0.4140625
Facing: 0
Church: v01
Location: 40,63
Owner: France
Health: 0.5390625
Facing: 0
Actor123: jeep
Location: 46,52
Owner: France
Health: 0.6640625
Facing: 96
StartJeep: jeep
Location: 44,76
Owner: France
Health: 0.5195313
Facing: 32
Actor125: jeep
Location: 55,57
Owner: France
Health: 1
Facing: 160
Actor126: jeep
Location: 39,65
Owner: France
Health: 0.625
Facing: 64
Actor127: c9
Location: 50,64
Owner: France
Health: 1
Facing: 192
SubCell: 1
Actor128: c8
Location: 47,61
Owner: France
Health: 1
Facing: 0
SubCell: 3
Actor129: c8
Location: 41,50
Owner: Turkey
Health: 1
Facing: 224
SubCell: 3
Actor130: c6
Location: 46,61
Owner: France
Health: 1
Facing: 128
SubCell: 2
Actor131: c5
Location: 46,61
Owner: France
Health: 1
Facing: 0
SubCell: 1
Actor132: c4
Location: 44,67
Owner: France
Health: 1
Facing: 96
SubCell: 1
Actor133: c2
Location: 40,54
Owner: France
Health: 1
Facing: 160
SubCell: 2
Actor134: c2
Location: 45,61
Owner: France
Health: 1
Facing: 64
SubCell: 4
Actor135: e1
Location: 54,60
Owner: France
Health: 1
Facing: 160
SubCell: 4
Actor136: e1
Location: 49,60
Owner: France
Health: 1
Facing: 128
SubCell: 2
Actor137: c5
Location: 45,51
Owner: France
Health: 1
Facing: 224
SubCell: 0
Actor138: e1
Location: 34,58
Owner: France
Health: 1
Facing: 96
SubCell: 0
Actor139: e1
Location: 53,54
Owner: France
Health: 1
Facing: 128
SubCell: 2
Actor140: e1
Location: 58,56
Owner: France
Health: 1
Facing: 128
SubCell: 1
Actor141: e1
Location: 58,52
Owner: France
Health: 1
Facing: 160
SubCell: 0
Actor142: e1
Location: 54,64
Owner: France
Health: 1
Facing: 160
SubCell: 3
Actor143: c7
Location: 56,54
Owner: France
Health: 1
Facing: 0
SubCell: 3
Actor144: e1
Location: 40,51
Owner: France
Health: 1
Facing: 160
SubCell: 0
Actor145: e1
Location: 35,53
Owner: France
Health: 1
Facing: 96
SubCell: 1
Actor146: e1
Location: 35,54
Owner: France
Health: 1
Facing: 0
SubCell: 4
Actor147: e1
Location: 43,64
Owner: France
Health: 1
Facing: 96
SubCell: 0
Actor148: e1
Location: 56,63
Owner: France
Health: 1
Facing: 192
SubCell: 2
Actor149: e1
Location: 40,67
Owner: France
Health: 1
Facing: 32
SubCell: 4
Actor150: e1
Location: 42,81
Owner: USSR
Health: 0.1367188
Facing: 0
SubCell: 2
waypoint3: waypoint
Location: 47,51
Owner: Neutral
waypoint6: waypoint
Location: 58,55
Owner: Neutral
waypoint10: waypoint
Location: 48,62
Owner: Neutral
waypoint14: waypoint
Location: 66,47
Owner: Neutral
waypoint15: waypoint
Location: 58,54
Owner: Neutral
StartJeepMovePoint: waypoint
Location: 47,66
Owner: Neutral
waypoint17: waypoint
Location: 49,68
Owner: Neutral
waypoint18: waypoint
Location: 54,64
Owner: Neutral
waypoint19: waypoint
Location: 55,64
Owner: Neutral
ParadropEntryPoint1: waypoint
Location: 67,65
Owner: Neutral
waypoint21: waypoint
Location: 58,57
Owner: Neutral
waypoint22: waypoint
Location: 66,73
Owner: Neutral
waypoint23: waypoint
Location: 49,51
Owner: Neutral
waypoint24: waypoint
Location: 54,60
Owner: Neutral
waypoint25: waypoint
Location: 35,59
Owner: Neutral
waypoint37: waypoint
Location: 61,68
Owner: Neutral
waypoint44: waypoint
Location: 34,47
Owner: Neutral
waypoint57: waypoint
Location: 38,57
Owner: Neutral
waypoint67: waypoint
Location: 39,59
Owner: Neutral
waypoint72: waypoint
Location: 47,70
Owner: Neutral
waypoint78: waypoint
Location: 39,67
Owner: Neutral
waypoint79: waypoint
Location: 52,60
Owner: Neutral
waypoint81: waypoint
Location: 42,82
Owner: Neutral
waypoint82: waypoint
Location: 44,77
Owner: Neutral
ParadropEntryPoint2: waypoint
Location: 32,70
Owner: Neutral
ParadropPoint2: waypoint
Location: 47,65
Owner: Neutral
ParadropPoint1: waypoint
Location: 47,67
Owner: Neutral
waypoint96: waypoint
Location: 37,58
Owner: Neutral
waypoint98: waypoint
Location: 44,79
Owner: Neutral
Actor1000: camera.large
Location: 1,1
Owner: France
Smudges:
Rules:
Player:
-ConquestVictoryConditions:
World:
-CrateSpawner:
-SpawnMPUnits:
-MPStartLocations:
Soviet01ClassicScript:
MissionObjectivesPanel:
ObjectivesPanel: MISSION_OBJECTIVES
V01:
ContainsCrate:
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
AFLD.NoProduction:
Inherits: ^Building
Valued:
Cost: 500
Tooltip:
Name: Airfield
Building:
Power: -20
Footprint: xxx xxx
Dimensions: 3,2
Health:
HP: 1000
Armor:
Type: Wood
RevealsShroud:
Range: 7c0
Exit@1:
SpawnOffset: 0,170,0
ExitCell: 1,1
Facing: 192
RenderBuilding:
Image: AFLD
BelowUnits:
Reservable:
YAK:
Plane:
RearmBuildings: afld.noproduction
JEEP:
Explodes:
V05.Civilians:
Inherits: V05
RenderBuilding:
Image: V05
Soviet01ClassicContainsActors:
Actors: c3, c4, c7
V07.Civilians:
Inherits: V07
RenderBuilding:
Image: V07
Soviet01ClassicContainsActors:
Actors: c1, c6
CAMERA.Large:
Inherits: CAMERA
RevealsShroud:
Range: 1000c0
Sequences:
VoxelSequences:
Weapons:
Voices:
Notifications:
Translations: