Merge pull request #3372 from ScottNZ/missions

Mission objectives refactoring
This commit is contained in:
Matthias Mailänder
2013-06-05 09:37:44 -07:00
11 changed files with 148 additions and 175 deletions

View File

@@ -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")

View File

@@ -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);
}
}

View File

@@ -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");

View File

@@ -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;

View File

@@ -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
{

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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())

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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