Merge pull request #3372 from ScottNZ/missions
Mission objectives refactoring
This commit is contained in:
@@ -26,19 +26,13 @@ namespace OpenRA.Mods.RA.Missions
|
||||
{
|
||||
public event Action<bool> OnObjectivesUpdated = notify => { };
|
||||
|
||||
public IEnumerable<Objective> Objectives { get { return objectives.Values; } }
|
||||
public IEnumerable<Objective> Objectives { get { return new[] { findEinstein, extractEinstein }; } }
|
||||
|
||||
Dictionary<int, Objective> objectives = new Dictionary<int, Objective>
|
||||
{
|
||||
{ FindEinsteinID, new Objective(ObjectiveType.Primary, FindEinstein, ObjectiveStatus.InProgress) },
|
||||
{ ExtractEinsteinID, new Objective(ObjectiveType.Primary, ExtractEinstein, ObjectiveStatus.Inactive) }
|
||||
};
|
||||
Objective findEinstein = new Objective(ObjectiveType.Primary, FindEinsteinText, ObjectiveStatus.InProgress);
|
||||
Objective extractEinstein = new Objective(ObjectiveType.Primary, ExtractEinsteinText, ObjectiveStatus.Inactive);
|
||||
|
||||
const int FindEinsteinID = 0;
|
||||
const int ExtractEinsteinID = 1;
|
||||
|
||||
const string FindEinstein = "Find Einstein. Tanya and Einstein must survive.";
|
||||
const string ExtractEinstein = "Wait for the helicopter and extract Einstein. Tanya and Einstein must survive.";
|
||||
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;
|
||||
@@ -94,19 +88,19 @@ namespace OpenRA.Mods.RA.Missions
|
||||
if (world.FrameNumber % 1000 == 0)
|
||||
Sound.Play(Taunts[world.SharedRandom.Next(Taunts.Length)]);
|
||||
|
||||
if (objectives[FindEinsteinID].Status == ObjectiveStatus.InProgress)
|
||||
if (findEinstein.Status == ObjectiveStatus.InProgress)
|
||||
{
|
||||
if (AlliesControlLab())
|
||||
LabSecured();
|
||||
|
||||
if (lab.Destroyed)
|
||||
if (lab.IsDead())
|
||||
{
|
||||
objectives[FindEinsteinID].Status = ObjectiveStatus.Failed;
|
||||
findEinstein.Status = ObjectiveStatus.Failed;
|
||||
OnObjectivesUpdated(true);
|
||||
MissionFailed("Einstein was killed.");
|
||||
}
|
||||
}
|
||||
if (objectives[ExtractEinsteinID].Status == ObjectiveStatus.InProgress)
|
||||
if (extractEinstein.Status == ObjectiveStatus.InProgress)
|
||||
{
|
||||
if (difficulty != "Easy")
|
||||
{
|
||||
@@ -126,25 +120,25 @@ namespace OpenRA.Mods.RA.Missions
|
||||
}
|
||||
if (einsteinChinook != null)
|
||||
{
|
||||
if (einsteinChinook.Destroyed)
|
||||
if (einsteinChinook.IsDead())
|
||||
{
|
||||
objectives[ExtractEinsteinID].Status = ObjectiveStatus.Failed;
|
||||
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))
|
||||
{
|
||||
objectives[ExtractEinsteinID].Status = ObjectiveStatus.Completed;
|
||||
extractEinstein.Status = ObjectiveStatus.Completed;
|
||||
OnObjectivesUpdated(true);
|
||||
MissionAccomplished("Einstein was rescued");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tanya != null && tanya.Destroyed)
|
||||
if (tanya != null && tanya.IsDead())
|
||||
MissionFailed("Tanya was killed.");
|
||||
|
||||
else if (einstein != null && einstein.Destroyed)
|
||||
else if (einstein != null && einstein.IsDead())
|
||||
MissionFailed("Einstein was killed.");
|
||||
|
||||
MissionUtils.CapOre(soviets);
|
||||
@@ -158,9 +152,10 @@ namespace OpenRA.Mods.RA.Missions
|
||||
SendShips();
|
||||
lab.QueueActivity(new Transform(lab, "stek") { SkipMakeAnims = true });
|
||||
|
||||
objectives[FindEinsteinID].Status = ObjectiveStatus.Completed;
|
||||
objectives[ExtractEinsteinID].Status = ObjectiveStatus.InProgress;
|
||||
findEinstein.Status = ObjectiveStatus.Completed;
|
||||
extractEinstein.Status = ObjectiveStatus.InProgress;
|
||||
OnObjectivesUpdated(true);
|
||||
|
||||
currentAttackWaveFrameNumber = world.FrameNumber;
|
||||
|
||||
if (difficulty == "Easy")
|
||||
|
||||
@@ -28,27 +28,19 @@ namespace OpenRA.Mods.RA.Missions
|
||||
{
|
||||
public event Action<bool> OnObjectivesUpdated = notify => { };
|
||||
|
||||
public IEnumerable<Objective> Objectives { get { return objectives.Values; } }
|
||||
public IEnumerable<Objective> Objectives { get { return new[] { findEinstein, destroySamSites, extractEinstein, maintainPresence, fewDeaths }; } }
|
||||
|
||||
Dictionary<int, Objective> objectives = new Dictionary<int, Objective>()
|
||||
{
|
||||
{ FindEinsteinID, new Objective(ObjectiveType.Primary, FindEinstein, ObjectiveStatus.InProgress) },
|
||||
{ DestroySamSitesID, new Objective(ObjectiveType.Primary, DestroySamSites, ObjectiveStatus.InProgress) },
|
||||
{ ExtractEinsteinID, new Objective(ObjectiveType.Primary, ExtractEinstein, ObjectiveStatus.Inactive) },
|
||||
{ MaintainPresenceID, new Objective(ObjectiveType.Primary, MaintainPresence, ObjectiveStatus.InProgress) },
|
||||
{ FewDeathsID, new Objective(ObjectiveType.Secondary, "", ObjectiveStatus.InProgress) }
|
||||
};
|
||||
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 int FindEinsteinID = 0;
|
||||
const int DestroySamSitesID = 1;
|
||||
const int ExtractEinsteinID = 2;
|
||||
const int MaintainPresenceID = 3;
|
||||
const int FewDeathsID = 4;
|
||||
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 FindEinstein = "Find Einstein's crashed helicopter. Tanya must survive.";
|
||||
const string DestroySamSites = "Destroy the SAM sites. Tanya must survive.";
|
||||
const string ExtractEinstein = "Wait for the helicopter and extract Einstein. Tanya and Einstein must survive.";
|
||||
const string MaintainPresence = "Maintain an Allied presence in the area. Reinforcements will arrive soon.";
|
||||
const string FewDeathsTemplate = "Lose fewer than {0}/{1} units.";
|
||||
|
||||
const int DeathsThreshold = 200;
|
||||
@@ -195,44 +187,45 @@ namespace OpenRA.Mods.RA.Missions
|
||||
|
||||
UpdateDeaths();
|
||||
|
||||
if (objectives[FindEinsteinID].Status == ObjectiveStatus.InProgress)
|
||||
if (findEinstein.Status == ObjectiveStatus.InProgress)
|
||||
{
|
||||
if (AlliesNearTown())
|
||||
{
|
||||
objectives[FindEinsteinID].Status = ObjectiveStatus.Completed;
|
||||
findEinstein.Status = ObjectiveStatus.Completed;
|
||||
OnObjectivesUpdated(true);
|
||||
TransferTownUnitsToAllies();
|
||||
SovietsAttackTown();
|
||||
}
|
||||
}
|
||||
if (objectives[DestroySamSitesID].Status == ObjectiveStatus.InProgress)
|
||||
if (destroySamSites.Status == ObjectiveStatus.InProgress)
|
||||
{
|
||||
if (sams.All(s => s.IsDead() || s.Owner != soviets))
|
||||
{
|
||||
objectives[DestroySamSitesID].Status = ObjectiveStatus.Completed;
|
||||
objectives[ExtractEinsteinID].Status = ObjectiveStatus.InProgress;
|
||||
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 (objectives[ExtractEinsteinID].Status == ObjectiveStatus.InProgress && einsteinChinook != null)
|
||||
if (extractEinstein.Status == ObjectiveStatus.InProgress && einsteinChinook != null)
|
||||
{
|
||||
if (einsteinChinook.IsDead())
|
||||
{
|
||||
objectives[ExtractEinsteinID].Status = ObjectiveStatus.Failed;
|
||||
objectives[MaintainPresenceID].Status = ObjectiveStatus.Failed;
|
||||
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))
|
||||
{
|
||||
objectives[ExtractEinsteinID].Status = ObjectiveStatus.Completed;
|
||||
objectives[MaintainPresenceID].Status = ObjectiveStatus.Completed;
|
||||
extractEinstein.Status = ObjectiveStatus.Completed;
|
||||
maintainPresence.Status = ObjectiveStatus.Completed;
|
||||
|
||||
if (objectives[FewDeathsID].Status == ObjectiveStatus.InProgress)
|
||||
objectives[FewDeathsID].Status = ObjectiveStatus.Completed;
|
||||
if (fewDeaths.Status == ObjectiveStatus.InProgress)
|
||||
fewDeaths.Status = ObjectiveStatus.Completed;
|
||||
|
||||
OnObjectivesUpdated(true);
|
||||
MissionAccomplished("Einstein was rescued.");
|
||||
@@ -250,7 +243,7 @@ namespace OpenRA.Mods.RA.Missions
|
||||
if (!w.FindAliveCombatantActorsInBox(alliedBaseTopLeft.ToPPos(), alliedBaseBottomRight.ToPPos())
|
||||
.Any(a => (a.Owner == allies || a.Owner == allies2) && (a.HasTrait<Building>() && !a.HasTrait<Wall>()) || a.HasTrait<BaseBuilding>()))
|
||||
{
|
||||
objectives[MaintainPresenceID].Status = ObjectiveStatus.Failed;
|
||||
maintainPresence.Status = ObjectiveStatus.Failed;
|
||||
OnObjectivesUpdated(true);
|
||||
MissionFailed("The Allied reinforcements have been defeated.");
|
||||
}
|
||||
@@ -260,11 +253,11 @@ namespace OpenRA.Mods.RA.Missions
|
||||
void UpdateDeaths()
|
||||
{
|
||||
var unitDeaths = allies1.Deaths + allies2.Deaths;
|
||||
objectives[FewDeathsID].Text = FewDeathsTemplate.F(unitDeaths, DeathsThreshold);
|
||||
fewDeaths.Text = FewDeathsTemplate.F(unitDeaths, DeathsThreshold);
|
||||
OnObjectivesUpdated(false);
|
||||
if (unitDeaths >= DeathsThreshold && objectives[FewDeathsID].Status == ObjectiveStatus.InProgress)
|
||||
if (unitDeaths >= DeathsThreshold && fewDeaths.Status == ObjectiveStatus.InProgress)
|
||||
{
|
||||
objectives[FewDeathsID].Status = ObjectiveStatus.Failed;
|
||||
fewDeaths.Status = ObjectiveStatus.Failed;
|
||||
OnObjectivesUpdated(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,29 +28,23 @@ namespace OpenRA.Mods.RA.Missions
|
||||
{
|
||||
public event Action<bool> OnObjectivesUpdated = notify => { };
|
||||
|
||||
public IEnumerable<Objective> Objectives { get { return objectives.Values; } }
|
||||
public IEnumerable<Objective> Objectives { get { return new[] { evacuateUnits, destroyAirbases, evacuateMgg }; } }
|
||||
|
||||
Dictionary<int, Objective> objectives = new Dictionary<int, Objective>
|
||||
{
|
||||
{ EvacuateID, new Objective(ObjectiveType.Primary, Evacuate, ObjectiveStatus.InProgress) },
|
||||
{ AirbaseID, new Objective(ObjectiveType.Secondary, Airbase, ObjectiveStatus.InProgress) },
|
||||
{ GapGeneratorID, new Objective(ObjectiveType.Secondary, GapGenerator , ObjectiveStatus.InProgress) }
|
||||
};
|
||||
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 int EvacuateID = 0;
|
||||
const int AirbaseID = 1;
|
||||
const int GapGeneratorID = 2;
|
||||
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 Evacuate = "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 Airbase = "Destroy the nearby Soviet airbases.";
|
||||
const string GapGenerator = "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;
|
||||
const string ShortEvacuateTemplate = "{0}/{1} units evacuated";
|
||||
|
||||
World world;
|
||||
Player allies1;
|
||||
@@ -185,7 +179,7 @@ namespace OpenRA.Mods.RA.Missions
|
||||
if (world.FrameNumber % 25 == 0)
|
||||
ManageSovietUnits();
|
||||
|
||||
if (objectives[AirbaseID].Status != ObjectiveStatus.Completed)
|
||||
if (destroyAirbases.Status != ObjectiveStatus.Completed)
|
||||
{
|
||||
if (world.FrameNumber % 25 == 0)
|
||||
BuildSovietAircraft();
|
||||
@@ -196,12 +190,12 @@ namespace OpenRA.Mods.RA.Missions
|
||||
EvacuateAlliedUnits(exit1TopLeft.CenterLocation, exit1BottomRight.CenterLocation, exit1ExitPoint.Location);
|
||||
EvacuateAlliedUnits(exit2TopLeft.CenterLocation, exit2BottomRight.CenterLocation, exit2ExitPoint.Location);
|
||||
|
||||
CheckSovietAirbase();
|
||||
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>())))
|
||||
{
|
||||
objectives[EvacuateID].Status = ObjectiveStatus.Failed;
|
||||
evacuateUnits.Status = ObjectiveStatus.Failed;
|
||||
OnObjectivesUpdated(true);
|
||||
MissionFailed("The remaining Allied forces in the area have been wiped out.");
|
||||
}
|
||||
@@ -266,11 +260,11 @@ namespace OpenRA.Mods.RA.Missions
|
||||
return world.Actors.Where(a => a.HasTrait<AttackPlane>() && a.Owner == soviets && a.IsInWorld && !a.IsDead());
|
||||
}
|
||||
|
||||
void CheckSovietAirbase()
|
||||
void CheckSovietAirbases()
|
||||
{
|
||||
if (objectives[AirbaseID].Status != ObjectiveStatus.Completed && sovietAirfields.All(a => a.IsDead() || a.Owner != soviets))
|
||||
if (destroyAirbases.Status != ObjectiveStatus.Completed && sovietAirfields.All(a => a.IsDead() || a.Owner != soviets))
|
||||
{
|
||||
objectives[AirbaseID].Status = ObjectiveStatus.Completed;
|
||||
destroyAirbases.Status = ObjectiveStatus.Completed;
|
||||
OnObjectivesUpdated(true);
|
||||
}
|
||||
}
|
||||
@@ -349,9 +343,9 @@ namespace OpenRA.Mods.RA.Missions
|
||||
void UpdateUnitsEvacuated()
|
||||
{
|
||||
evacuateWidget.Text = ShortEvacuateTemplate.F(unitsEvacuated, unitsEvacuatedThreshold);
|
||||
if (objectives[EvacuateID].Status == ObjectiveStatus.InProgress && unitsEvacuated >= unitsEvacuatedThreshold)
|
||||
if (evacuateUnits.Status == ObjectiveStatus.InProgress && unitsEvacuated >= unitsEvacuatedThreshold)
|
||||
{
|
||||
objectives[EvacuateID].Status = ObjectiveStatus.Completed;
|
||||
evacuateUnits.Status = ObjectiveStatus.Completed;
|
||||
OnObjectivesUpdated(true);
|
||||
MissionAccomplished("The remaining Allied forces in the area have evacuated.");
|
||||
}
|
||||
@@ -369,9 +363,9 @@ namespace OpenRA.Mods.RA.Missions
|
||||
unitsEvacuated++;
|
||||
|
||||
var createsShroud = unit.TraitOrDefault<CreatesShroud>();
|
||||
if (createsShroud != null && objectives[GapGeneratorID].Status == ObjectiveStatus.InProgress)
|
||||
if (createsShroud != null && evacuateMgg.Status == ObjectiveStatus.InProgress)
|
||||
{
|
||||
objectives[GapGeneratorID].Status = ObjectiveStatus.Completed;
|
||||
evacuateMgg.Status = ObjectiveStatus.Completed;
|
||||
OnObjectivesUpdated(true);
|
||||
}
|
||||
|
||||
@@ -416,7 +410,7 @@ namespace OpenRA.Mods.RA.Missions
|
||||
sovietParadropTicks = difficulty == "Hard" ? 1500 * 17 : 1500 * 20;
|
||||
sovietUnits2Ticks = difficulty == "Hard" ? 1500 * 12 : 1500 * 15;
|
||||
|
||||
objectives[EvacuateID].Text = objectives[EvacuateID].Text.F(unitsEvacuatedThreshold);
|
||||
evacuateUnits.Text = evacuateUnits.Text.F(unitsEvacuatedThreshold);
|
||||
|
||||
allies = w.Players.Single(p => p.InternalName == "Allies");
|
||||
soviets = w.Players.Single(p => p.InternalName == "Soviets");
|
||||
|
||||
@@ -17,7 +17,6 @@ using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
using OpenRA.Mods.RA.Move;
|
||||
using OpenRA.Mods.RA.Render;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Widgets;
|
||||
|
||||
@@ -29,19 +28,15 @@ namespace OpenRA.Mods.RA.Missions
|
||||
{
|
||||
public event Action<bool> OnObjectivesUpdated = notify => { };
|
||||
|
||||
public IEnumerable<Objective> Objectives { get { return objectives.Values; } }
|
||||
public IEnumerable<Objective> Objectives { get { return new[] { infiltrateLab, destroyBase }; } }
|
||||
|
||||
Dictionary<int, Objective> objectives = new Dictionary<int, Objective>
|
||||
{
|
||||
{ InfiltrateID, new Objective(ObjectiveType.Primary, "", ObjectiveStatus.InProgress) },
|
||||
{ DestroyID, new Objective(ObjectiveType.Primary, Destroy, ObjectiveStatus.Inactive) }
|
||||
};
|
||||
Objective infiltrateLab = new Objective(ObjectiveType.Primary, "", ObjectiveStatus.InProgress);
|
||||
Objective destroyBase = new Objective(ObjectiveType.Primary, DestroyBaseText, ObjectiveStatus.Inactive);
|
||||
|
||||
const int InfiltrateID = 0;
|
||||
const int DestroyID = 1;
|
||||
const string Destroy = "Secure the laboratory and destroy the rest of the Soviet base. Ensure that the laboratory is not destroyed.";
|
||||
const string Infiltrate = "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 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;
|
||||
@@ -175,7 +170,7 @@ namespace OpenRA.Mods.RA.Missions
|
||||
|
||||
if (allies1Spy.IsDead() || (allies2Spy != null && allies2Spy.IsDead()))
|
||||
{
|
||||
objectives[InfiltrateID].Status = ObjectiveStatus.Failed;
|
||||
infiltrateLab.Status = ObjectiveStatus.Failed;
|
||||
OnObjectivesUpdated(true);
|
||||
MissionFailed("{0} spy was killed.".F(allies1 != allies2 ? "A" : "The"));
|
||||
}
|
||||
@@ -184,13 +179,13 @@ namespace OpenRA.Mods.RA.Missions
|
||||
else if (!world.Actors.Any(a => (a.Owner == allies1 || a.Owner == allies2) && !a.IsDead()
|
||||
&& (a.HasTrait<Building>() && !a.HasTrait<Wall>()) || a.HasTrait<BaseBuilding>()))
|
||||
{
|
||||
objectives[DestroyID].Status = ObjectiveStatus.Failed;
|
||||
destroyBase.Status = ObjectiveStatus.Failed;
|
||||
OnObjectivesUpdated(true);
|
||||
MissionFailed("The remaining Allied forces in the area have been wiped out.");
|
||||
}
|
||||
else if (SovietBaseDestroyed() && objectives[InfiltrateID].Status == ObjectiveStatus.Completed)
|
||||
else if (SovietBaseDestroyed() && infiltrateLab.Status == ObjectiveStatus.Completed)
|
||||
{
|
||||
objectives[DestroyID].Status = ObjectiveStatus.Completed;
|
||||
destroyBase.Status = ObjectiveStatus.Completed;
|
||||
OnObjectivesUpdated(true);
|
||||
MissionAccomplished("The Soviet research laboratory has been secured successfully.");
|
||||
}
|
||||
@@ -214,8 +209,8 @@ namespace OpenRA.Mods.RA.Missions
|
||||
|
||||
void OnDestroyBaseTimerExpired(CountdownTimer t)
|
||||
{
|
||||
if (SovietBaseDestroyed() && objectives[InfiltrateID].Status == ObjectiveStatus.Completed) return;
|
||||
objectives[DestroyID].Status = ObjectiveStatus.Failed;
|
||||
if (SovietBaseDestroyed() && infiltrateLab.Status == ObjectiveStatus.Completed) return;
|
||||
destroyBase.Status = ObjectiveStatus.Failed;
|
||||
OnObjectivesUpdated(true);
|
||||
MissionFailed("The Soviet research laboratory was not secured in time.");
|
||||
}
|
||||
@@ -240,8 +235,8 @@ namespace OpenRA.Mods.RA.Missions
|
||||
|
||||
if (allies1SpyInfiltratedLab && (allies2SpyInfiltratedLab || allies2Spy == null))
|
||||
{
|
||||
objectives[InfiltrateID].Status = ObjectiveStatus.Completed;
|
||||
objectives[DestroyID].Status = ObjectiveStatus.InProgress;
|
||||
infiltrateLab.Status = ObjectiveStatus.Completed;
|
||||
destroyBase.Status = ObjectiveStatus.InProgress;
|
||||
OnObjectivesUpdated(true);
|
||||
frameInfiltrated = world.FrameNumber;
|
||||
|
||||
@@ -362,7 +357,7 @@ namespace OpenRA.Mods.RA.Missions
|
||||
|
||||
soviets = w.Players.Single(p => p.InternalName == "Soviets");
|
||||
creeps = w.Players.Single(p => p.InternalName == "Creeps");
|
||||
objectives[InfiltrateID].Text = Infiltrate.F(allies1 != allies2 ? "spies" : "spy");
|
||||
infiltrateLab.Text = InfiltrateLabTemplate.F(allies1 != allies2 ? "spies" : "spy");
|
||||
|
||||
destroyBaseTicks = difficulty == "Hard" ? 1500 * 25 : difficulty == "Normal" ? 1500 * 28 : 1500 * 31;
|
||||
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
*/
|
||||
#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;
|
||||
@@ -15,10 +19,6 @@ using OpenRA.Mods.RA.Buildings;
|
||||
using OpenRA.Mods.RA.Move;
|
||||
using OpenRA.Network;
|
||||
using OpenRA.Traits;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
|
||||
namespace OpenRA.Mods.RA.Missions
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace OpenRA.Mods.RA.Missions
|
||||
var font = Game.Renderer.Fonts["Bold"];
|
||||
var text = Format.F(WidgetUtils.FormatTime(Timer.TicksLeft));
|
||||
var pos = new float2(Game.viewport.Width * 0.5f - font.Measure(text).X / 2, Game.viewport.Height * 0.1f);
|
||||
font.DrawTextWithContrast(text, pos, Timer.TicksLeft <= 25 * 10 && Game.LocalTick % 50 < 25 ? Color.Red : Color.White, Color.Black, 1);
|
||||
font.DrawTextWithContrast(text, pos, Timer.TicksLeft <= 25 * 60 && Game.LocalTick % 50 < 25 ? Color.Red : Color.White, Color.Black, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,23 +40,15 @@ namespace OpenRA.Mods.RA.Missions
|
||||
|
||||
public event Action<bool> OnObjectivesUpdated = notify => { };
|
||||
|
||||
public IEnumerable<Objective> Objectives { get { return objectives.Values; } }
|
||||
public IEnumerable<Objective> Objectives { get { return new[] { findOutpost, evacuateDemitri, infiltrateRadarDome }; } }
|
||||
|
||||
Dictionary<int, Objective> objectives = new Dictionary<int, Objective>
|
||||
{
|
||||
{ FindOutpostID, new Objective(ObjectiveType.Primary, FindOutpost, ObjectiveStatus.InProgress) },
|
||||
{ EvacuateDemitriID, new Objective(ObjectiveType.Primary, EvacuateDemitri, ObjectiveStatus.InProgress) },
|
||||
{ InfiltrateRadarDomeID, new Objective(ObjectiveType.Primary, InfiltrateRadarDome, ObjectiveStatus.InProgress) },
|
||||
};
|
||||
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 int FindOutpostID = 0;
|
||||
const string FindOutpost = "Find our outpost and start repairs on it.";
|
||||
|
||||
const int EvacuateDemitriID = 1;
|
||||
const string EvacuateDemitri = "Find and evacuate Dr. Demitri. He is missing -- likely hiding in the village to the far south.";
|
||||
|
||||
const int InfiltrateRadarDomeID = 2;
|
||||
const string InfiltrateRadarDome = "Reprogram the Super Tanks by sending a spy into the Soviet radar dome.";
|
||||
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."
|
||||
@@ -142,7 +134,7 @@ namespace OpenRA.Mods.RA.Missions
|
||||
{
|
||||
SetupAlliedBase(actorsInBase);
|
||||
baseTransferredTick = world.FrameNumber;
|
||||
objectives[FindOutpostID].Status = ObjectiveStatus.Completed;
|
||||
findOutpost.Status = ObjectiveStatus.Completed;
|
||||
OnObjectivesUpdated(true);
|
||||
}
|
||||
}
|
||||
@@ -181,13 +173,13 @@ namespace OpenRA.Mods.RA.Missions
|
||||
superTanksDestroyed = true;
|
||||
}
|
||||
}
|
||||
if (objectives[EvacuateDemitriID].Status != ObjectiveStatus.Completed)
|
||||
if (evacuateDemitri.Status != ObjectiveStatus.Completed)
|
||||
{
|
||||
if (demitri == null)
|
||||
{
|
||||
if (demitriChurch.IsDead())
|
||||
{
|
||||
objectives[EvacuateDemitriID].Status = ObjectiveStatus.Failed;
|
||||
evacuateDemitri.Status = ObjectiveStatus.Failed;
|
||||
OnObjectivesUpdated(true);
|
||||
MissionFailed("Dr. Demitri was killed.");
|
||||
}
|
||||
@@ -204,7 +196,7 @@ namespace OpenRA.Mods.RA.Missions
|
||||
}
|
||||
else if (demitri.IsDead())
|
||||
{
|
||||
objectives[EvacuateDemitriID].Status = ObjectiveStatus.Failed;
|
||||
evacuateDemitri.Status = ObjectiveStatus.Failed;
|
||||
OnObjectivesUpdated(true);
|
||||
MissionFailed("Dr. Demitri was killed.");
|
||||
}
|
||||
@@ -212,7 +204,7 @@ namespace OpenRA.Mods.RA.Missions
|
||||
{
|
||||
demitriLZFlare.Destroy();
|
||||
SpawnAndMoveAlliedBaseUnits(info.FirstBaseUnits);
|
||||
objectives[EvacuateDemitriID].Status = ObjectiveStatus.Completed;
|
||||
evacuateDemitri.Status = ObjectiveStatus.Completed;
|
||||
OnObjectivesUpdated(true);
|
||||
}
|
||||
}
|
||||
@@ -223,11 +215,11 @@ namespace OpenRA.Mods.RA.Missions
|
||||
}
|
||||
if (superTankDomeInfiltratedTick == -1 && superTankDome.IsDead())
|
||||
{
|
||||
objectives[InfiltrateRadarDomeID].Status = ObjectiveStatus.Failed;
|
||||
infiltrateRadarDome.Status = ObjectiveStatus.Failed;
|
||||
OnObjectivesUpdated(true);
|
||||
MissionFailed("The Soviet radar dome was destroyed.");
|
||||
}
|
||||
if (superTanksDestroyed && objectives[EvacuateDemitriID].Status == ObjectiveStatus.Completed)
|
||||
if (superTanksDestroyed && evacuateDemitri.Status == ObjectiveStatus.Completed)
|
||||
{
|
||||
MissionAccomplished("Dr. Demitri has been extracted and the super tanks have been dealt with.");
|
||||
}
|
||||
@@ -298,7 +290,7 @@ namespace OpenRA.Mods.RA.Missions
|
||||
|
||||
superTankDomeInfiltratedTick = world.FrameNumber;
|
||||
|
||||
objectives[InfiltrateRadarDomeID].Status = ObjectiveStatus.Completed;
|
||||
infiltrateRadarDome.Status = ObjectiveStatus.Completed;
|
||||
OnObjectivesUpdated(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,15 +27,11 @@ namespace OpenRA.Mods.RA.Missions
|
||||
{
|
||||
public event Action<bool> OnObjectivesUpdated = notify => { };
|
||||
|
||||
public IEnumerable<Objective> Objectives { get { return objectives.Values; } }
|
||||
public IEnumerable<Objective> Objectives { get { return new[] { destroy }; } }
|
||||
|
||||
Dictionary<int, Objective> objectives = new Dictionary<int, Objective>
|
||||
{
|
||||
{ DestroyID, new Objective(ObjectiveType.Primary, Destroy, ObjectiveStatus.InProgress) }
|
||||
};
|
||||
Objective destroy = new Objective(ObjectiveType.Primary, DestroyText, ObjectiveStatus.InProgress);
|
||||
|
||||
const int DestroyID = 0;
|
||||
const string Destroy = "A pitiful excuse for resistance has blockaded itself in this village."
|
||||
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.";
|
||||
|
||||
@@ -80,12 +76,12 @@ namespace OpenRA.Mods.RA.Missions
|
||||
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))
|
||||
{
|
||||
objectives[DestroyID].Status = ObjectiveStatus.Completed;
|
||||
destroy.Status = ObjectiveStatus.Completed;
|
||||
MissionAccomplished("We destroyed the resistance.");
|
||||
}
|
||||
else if (!unitsAndBuildings.Any(a => a.Owner == ussr))
|
||||
{
|
||||
objectives[DestroyID].Status = ObjectiveStatus.Failed;
|
||||
destroy.Status = ObjectiveStatus.Failed;
|
||||
MissionFailed("We were destroyed by the resistance.");
|
||||
}
|
||||
if (!startJeepParadropped && startJeep.IsDead())
|
||||
|
||||
@@ -8,15 +8,15 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
using OpenRA.Mods.RA.Move;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Widgets;
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
|
||||
namespace OpenRA.Mods.RA.Missions
|
||||
{
|
||||
@@ -26,19 +26,13 @@ namespace OpenRA.Mods.RA.Missions
|
||||
{
|
||||
public event Action<bool> OnObjectivesUpdated = notify => { };
|
||||
|
||||
public IEnumerable<Objective> Objectives { get { return objectives.Values; } }
|
||||
public IEnumerable<Objective> Objectives { get { return new[] { maintainPresence, destroySoviets }; } }
|
||||
|
||||
Dictionary<int, Objective> objectives = new Dictionary<int, Objective>
|
||||
{
|
||||
{ maintainPresenceID, new Objective(ObjectiveType.Primary, maintainPresence, ObjectiveStatus.InProgress) },
|
||||
{ destroySovietsID, new Objective(ObjectiveType.Primary, destroySoviets, ObjectiveStatus.Inactive) }
|
||||
};
|
||||
Objective maintainPresence = new Objective(ObjectiveType.Primary, MaintainPresenceText, ObjectiveStatus.InProgress);
|
||||
Objective destroySoviets = new Objective(ObjectiveType.Primary, DestroySovietsText, ObjectiveStatus.Inactive);
|
||||
|
||||
const int maintainPresenceID = 0;
|
||||
const int destroySovietsID = 1;
|
||||
|
||||
const string maintainPresence = "Enforce your position and hold-out the onslaught until reinforcements arrive. We must not lose the base!";
|
||||
const string destroySoviets = "Take control of french reinforcements and dismantle the nearby Soviet base.";
|
||||
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;
|
||||
@@ -155,11 +149,11 @@ namespace OpenRA.Mods.RA.Missions
|
||||
spawningInfantry = false;
|
||||
}
|
||||
|
||||
if (objectives[destroySovietsID].Status == ObjectiveStatus.InProgress)
|
||||
if (destroySoviets.Status == ObjectiveStatus.InProgress)
|
||||
{
|
||||
if (barrack1.Destroyed)
|
||||
{
|
||||
objectives[destroySovietsID].Status = ObjectiveStatus.Completed;
|
||||
destroySoviets.Status = ObjectiveStatus.Completed;
|
||||
OnObjectivesUpdated(true);
|
||||
MissionAccomplished("The French forces have survived and dismantled the soviet presence in the area!");
|
||||
}
|
||||
@@ -273,8 +267,8 @@ namespace OpenRA.Mods.RA.Missions
|
||||
{
|
||||
survivalTimerWidget.Visible = false;
|
||||
SendReinforcements();
|
||||
objectives[maintainPresenceID].Status = ObjectiveStatus.Completed;
|
||||
objectives[destroySovietsID].Status = ObjectiveStatus.InProgress;
|
||||
maintainPresence.Status = ObjectiveStatus.Completed;
|
||||
destroySoviets.Status = ObjectiveStatus.InProgress;
|
||||
OnObjectivesUpdated(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -56,31 +56,47 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
public void UpdateObjectives(bool notify)
|
||||
{
|
||||
if (notify)
|
||||
{
|
||||
objectivesButton.Highlighted = true;
|
||||
}
|
||||
|
||||
primaryPanel.RemoveChildren();
|
||||
secondaryPanel.RemoveChildren();
|
||||
|
||||
foreach (var o in objectives.Objectives.Where(o => o.Status != ObjectiveStatus.Inactive))
|
||||
{
|
||||
var objective = o;
|
||||
if (objective.Type == ObjectiveType.Secondary)
|
||||
|
||||
Widget widget;
|
||||
LabelWidget objectiveText;
|
||||
LabelWidget objectiveStatus;
|
||||
|
||||
if (objective.Type == ObjectiveType.Primary)
|
||||
{
|
||||
var template = secondaryTemplate.Clone();
|
||||
template.Get<LabelWidget>("SECONDARY_OBJECTIVE").GetText = () => objective.Text;
|
||||
template.Get<LabelWidget>("SECONDARY_STATUS").GetText = () => GetObjectiveStatusText(objective.Status);
|
||||
secondaryPanel.AddChild(template);
|
||||
widget = primaryTemplate.Clone();
|
||||
objectiveText = widget.Get<LabelWidget>("PRIMARY_OBJECTIVE");
|
||||
objectiveStatus = widget.Get<LabelWidget>("PRIMARY_STATUS");
|
||||
SetupWidget(widget, objectiveText, objectiveStatus, objective);
|
||||
primaryPanel.AddChild(widget);
|
||||
}
|
||||
else
|
||||
{
|
||||
var template = primaryTemplate.Clone();
|
||||
template.Get<LabelWidget>("PRIMARY_OBJECTIVE").GetText = () => objective.Text;
|
||||
template.Get<LabelWidget>("PRIMARY_STATUS").GetText = () => GetObjectiveStatusText(objective.Status);
|
||||
primaryPanel.AddChild(template);
|
||||
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)
|
||||
|
||||
@@ -34,13 +34,12 @@ Background@MISSION_OBJECTIVES:
|
||||
Y:70
|
||||
Width:PARENT_RIGHT-50
|
||||
Height:200
|
||||
ItemSpacing:5
|
||||
ItemSpacing:20
|
||||
Children:
|
||||
Container@PRIMARY_OBJECTIVE_TEMPLATE:
|
||||
X:15
|
||||
Y:0-15
|
||||
Y:0
|
||||
Width:PARENT_RIGHT
|
||||
Height:60
|
||||
Children:
|
||||
Label@PRIMARY_OBJECTIVE:
|
||||
X:0
|
||||
@@ -75,13 +74,12 @@ Background@MISSION_OBJECTIVES:
|
||||
Y:305
|
||||
Width:PARENT_RIGHT-50
|
||||
Height:200
|
||||
ItemSpacing:5
|
||||
ItemSpacing:20
|
||||
Children:
|
||||
Container@SECONDARY_OBJECTIVE_TEMPLATE:
|
||||
X:15
|
||||
Y:0-15
|
||||
Y:0
|
||||
Width:PARENT_RIGHT
|
||||
Height:60
|
||||
Children:
|
||||
Label@SECONDARY_OBJECTIVE:
|
||||
X:0
|
||||
|
||||
Reference in New Issue
Block a user