Make the mission actually winnable

This commit is contained in:
Scott_NZ
2012-08-11 16:58:09 +12:00
parent 0c9f39df78
commit 9ccfb2c322

View File

@@ -1,283 +1,289 @@
#region Copyright & License Information #region Copyright & License Information
/* /*
* Copyright 2007-2012 The OpenRA Developers (see AUTHORS) * Copyright 2007-2012 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made * 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 * available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information, * as published by the Free Software Foundation. For more information,
* see COPYING. * see COPYING.
*/ */
#endregion #endregion
using System; using System;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
using OpenRA.FileFormats; using OpenRA.FileFormats;
using OpenRA.Mods.RA.Activities; using OpenRA.Mods.RA.Activities;
using OpenRA.Mods.RA.Air; using OpenRA.Mods.RA.Air;
using OpenRA.Traits; using OpenRA.Traits;
using OpenRA.Widgets; using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Missions namespace OpenRA.Mods.RA.Missions
{ {
class Allies02ScriptInfo : TraitInfo<Allies02Script>, Requires<SpawnMapActorsInfo> { } class Allies02ScriptInfo : TraitInfo<Allies02Script>, Requires<SpawnMapActorsInfo> { }
class Allies02Script : IWorldLoaded, ITick class Allies02Script : IWorldLoaded, ITick
{ {
static readonly string[] objectives = static readonly string[] objectives =
{ {
"Destroy the SAM sites. Tanya and Einstein must survive.", "Destroy the SAM sites. Tanya and Einstein must survive.",
"Wait for the helicopter and extract Einstein. Tanya and Einstein must survive." "Wait for the helicopter and extract Einstein. Tanya and Einstein must survive."
}; };
int currentObjective; int currentObjective;
Actor sam1; Actor sam1;
Actor sam2; Actor sam2;
Actor sam3; Actor sam3;
Actor sam4; Actor sam4;
Actor tanya; Actor tanya;
Actor einstein; Actor einstein;
Actor chinookHusk; Actor chinookHusk;
Actor allies2BasePoint; Actor allies2BasePoint;
Actor reinforcementsEntryPoint; Actor reinforcementsEntryPoint;
Actor extractionLZEntryPoint; Actor extractionLZEntryPoint;
Actor extractionLZ; Actor extractionLZ;
Actor extractionLZExitPoint; Actor extractionLZExitPoint;
World world; Actor einsteinChinook;
Player allies1; World world;
Player allies2;
Player soviets; Player allies1;
Player allies2;
static readonly string[] reinforcements = { "1tnk", "1tnk", "jeep", "mcv" }; Player soviets;
const string ChinookName = "tran";
const string SignalFlareName = "flare"; static readonly string[] reinforcements = { "1tnk", "1tnk", "jeep", "mcv" };
const string ChinookName = "tran";
void DisplayObjective() const string SignalFlareName = "flare";
{
Game.AddChatLine(Color.LimeGreen, "Objective", objectives[currentObjective]); void DisplayObjective()
Sound.Play("bleep6.aud"); {
} Game.AddChatLine(Color.LimeGreen, "Objective", objectives[currentObjective]);
Sound.Play("bleep6.aud");
void MissionFailed(string text) }
{
if (allies1.WinState != WinState.Undefined) void MissionFailed(string text)
{ {
return; if (allies1.WinState != WinState.Undefined)
} {
allies1.WinState = allies2.WinState = WinState.Lost; return;
Game.AddChatLine(Color.Red, "Mission failed", text); }
Sound.Play("misnlst1.aud"); allies1.WinState = allies2.WinState = WinState.Lost;
} Game.AddChatLine(Color.Red, "Mission failed", text);
Sound.Play("misnlst1.aud");
void MissionAccomplished(string text) }
{
if (allies1.WinState != WinState.Undefined) void MissionAccomplished(string text)
{ {
return; if (allies1.WinState != WinState.Undefined)
} {
allies1.WinState = allies2.WinState = WinState.Won; return;
Game.AddChatLine(Color.Blue, "Mission accomplished", text); }
Sound.Play("misnwon1.aud"); allies1.WinState = allies2.WinState = WinState.Won;
} Game.AddChatLine(Color.Blue, "Mission accomplished", text);
Sound.Play("misnwon1.aud");
public void Tick(Actor self) }
{
if (world.FrameNumber % 3500 == 1) public void Tick(Actor self)
{ {
DisplayObjective(); if (world.FrameNumber % 3500 == 1)
} {
if (world.FrameNumber == 1) DisplayObjective();
{ }
StartReinforcementsTimer(); if (world.FrameNumber == 1)
} {
if (currentObjective == 0) StartReinforcementsTimer();
{ }
if (sam1.Destroyed && sam2.Destroyed && sam3.Destroyed && sam4.Destroyed) if (currentObjective == 0)
{ {
currentObjective++; if (sam1.Destroyed && sam2.Destroyed && sam3.Destroyed && sam4.Destroyed)
DisplayObjective(); {
Sound.Play("flaren1.aud"); currentObjective++;
SpawnSignalFlare(); DisplayObjective();
Game.RunAfterDelay(150, StartChinookTimer); Sound.Play("flaren1.aud");
} SpawnSignalFlare();
} Game.RunAfterDelay(150, StartChinookTimer);
else if (currentObjective == 1) }
{ }
} else if (currentObjective == 1)
if (tanya.Destroyed) {
{ if (einsteinChinook != null && !world.Map.IsInMap(einsteinChinook.Location) && einsteinChinook.Trait<Cargo>().Passengers.Contains(einstein))
MissionFailed("Tanya was killed."); {
} MissionAccomplished("Einstein was rescued.");
if (einstein.Destroyed) }
{ }
MissionFailed("Einstein was killed."); if (tanya.Destroyed)
} {
ManageSovietOre(); MissionFailed("Tanya was killed.");
} }
if (einstein.Destroyed)
{
MissionFailed("Einstein was killed.");
}
ManageSovietOre();
}
void ManageSovietOre() void ManageSovietOre()
{ {
var res = soviets.PlayerActor.Trait<PlayerResources>(); var res = soviets.PlayerActor.Trait<PlayerResources>();
res.TakeOre(res.Ore); res.TakeOre(res.Ore);
res.TakeCash(res.Cash); res.TakeCash(res.Cash);
} }
void SpawnSignalFlare() void SpawnSignalFlare()
{ {
world.CreateActor(SignalFlareName, new TypeDictionary { new OwnerInit(allies1), new LocationInit(extractionLZ.Location) }); world.CreateActor(SignalFlareName, new TypeDictionary { new OwnerInit(allies1), new LocationInit(extractionLZ.Location) });
} }
void StartReinforcementsTimer() void StartReinforcementsTimer()
{ {
var timer = new CountdownTimerWidget("Reinforcements arrive in", 1500 * 12, ReinforcementsTimerExpired, new float2(128, 64)); var timer = new CountdownTimerWidget("Reinforcements arrive in", 1500 * 12, ReinforcementsTimerExpired, new float2(128, 64));
Ui.Root.AddChild(timer); Ui.Root.AddChild(timer);
Sound.Play("timergo1.aud"); Sound.Play("timergo1.aud");
} }
void StartChinookTimer() void StartChinookTimer()
{ {
var timer = new CountdownTimerWidget("Extraction arrives in", 1500 * 6, ChinookTimerExpired, new float2(128, 96)); var timer = new CountdownTimerWidget("Extraction arrives in", 1500 * 6, ChinookTimerExpired, new float2(128, 96));
Ui.Root.AddChild(timer); Ui.Root.AddChild(timer);
Sound.Play("timergo1.aud"); Sound.Play("timergo1.aud");
} }
void ReinforcementsTimerExpired(CountdownTimerWidget timer) void ReinforcementsTimerExpired(CountdownTimerWidget timer)
{ {
timer.Visible = false; timer.Visible = false;
SendReinforcements(); SendReinforcements();
} }
void ChinookTimerExpired(CountdownTimerWidget timer) void ChinookTimerExpired(CountdownTimerWidget timer)
{ {
timer.Visible = false; timer.Visible = false;
SendChinook(); SendChinook();
} }
void SendReinforcements() void SendReinforcements()
{ {
Sound.Play("reinfor1.aud"); Sound.Play("reinfor1.aud");
for (int i = 0; i < reinforcements.Length; i++) for (int i = 0; i < reinforcements.Length; i++)
{ {
var actor = world.CreateActor(reinforcements[i], new TypeDictionary var actor = world.CreateActor(reinforcements[i], new TypeDictionary
{ {
new LocationInit(reinforcementsEntryPoint.Location + new CVec(i, 0)), new LocationInit(reinforcementsEntryPoint.Location + new CVec(i, 0)),
new FacingInit(0), new FacingInit(0),
new OwnerInit(allies2) new OwnerInit(allies2)
}); });
actor.QueueActivity(new Move.Move(allies2BasePoint.Location)); actor.QueueActivity(new Move.Move(allies2BasePoint.Location));
} }
} }
void SendChinook() void SendChinook()
{ {
var chinook = world.CreateActor(ChinookName, new TypeDictionary { new OwnerInit(allies1), new LocationInit(extractionLZEntryPoint.Location) }); einsteinChinook = world.CreateActor(ChinookName, new TypeDictionary { new OwnerInit(allies1), new LocationInit(extractionLZEntryPoint.Location) });
chinook.QueueActivity(new HeliFly(extractionLZ.CenterLocation)); einsteinChinook.QueueActivity(new HeliFly(extractionLZ.CenterLocation));
chinook.QueueActivity(new Turn(0)); einsteinChinook.QueueActivity(new Turn(0));
chinook.QueueActivity(new HeliLand(true)); einsteinChinook.QueueActivity(new HeliLand(true));
chinook.QueueActivity(new WaitFor(() => chinook.Trait<Cargo>().Passengers.Contains(einstein))); einsteinChinook.QueueActivity(new WaitFor(() => einsteinChinook.Trait<Cargo>().Passengers.Contains(einstein)));
chinook.QueueActivity(new Wait(150)); einsteinChinook.QueueActivity(new Wait(150));
chinook.QueueActivity(new HeliFly(extractionLZExitPoint.CenterLocation)); einsteinChinook.QueueActivity(new HeliFly(extractionLZExitPoint.CenterLocation));
chinook.QueueActivity(new RemoveSelf()); einsteinChinook.QueueActivity(new RemoveSelf());
} }
public void WorldLoaded(World w) public void WorldLoaded(World w)
{ {
world = w; world = w;
allies1 = w.Players.Single(p => p.InternalName == "Allies1"); allies1 = w.Players.Single(p => p.InternalName == "Allies1");
allies2 = w.Players.Single(p => p.InternalName == "Allies2"); allies2 = w.Players.Single(p => p.InternalName == "Allies2");
soviets = w.Players.Single(p => p.InternalName == "Soviets"); soviets = w.Players.Single(p => p.InternalName == "Soviets");
var actors = w.WorldActor.Trait<SpawnMapActors>().Actors; var actors = w.WorldActor.Trait<SpawnMapActors>().Actors;
sam1 = actors["SAM1"]; sam1 = actors["SAM1"];
sam2 = actors["SAM2"]; sam2 = actors["SAM2"];
sam3 = actors["SAM3"]; sam3 = actors["SAM3"];
sam4 = actors["SAM4"]; sam4 = actors["SAM4"];
tanya = actors["Tanya"]; tanya = actors["Tanya"];
einstein = actors["Einstein"]; einstein = actors["Einstein"];
chinookHusk = actors["ChinookHusk"]; chinookHusk = actors["ChinookHusk"];
allies2BasePoint = actors["Allies2BasePoint"]; allies2BasePoint = actors["Allies2BasePoint"];
reinforcementsEntryPoint = actors["ReinforcementsEntryPoint"]; reinforcementsEntryPoint = actors["ReinforcementsEntryPoint"];
extractionLZ = actors["ExtractionLZ"]; extractionLZ = actors["ExtractionLZ"];
extractionLZEntryPoint = actors["ExtractionLZEntryPoint"]; extractionLZEntryPoint = actors["ExtractionLZEntryPoint"];
extractionLZExitPoint = actors["ExtractionLZExitPoint"]; extractionLZExitPoint = actors["ExtractionLZExitPoint"];
w.WorldActor.Trait<Shroud>().Explore(w, sam1.Location, 2); w.WorldActor.Trait<Shroud>().Explore(w, sam1.Location, 2);
w.WorldActor.Trait<Shroud>().Explore(w, sam2.Location, 2); w.WorldActor.Trait<Shroud>().Explore(w, sam2.Location, 2);
w.WorldActor.Trait<Shroud>().Explore(w, sam3.Location, 2); w.WorldActor.Trait<Shroud>().Explore(w, sam3.Location, 2);
w.WorldActor.Trait<Shroud>().Explore(w, sam4.Location, 2); w.WorldActor.Trait<Shroud>().Explore(w, sam4.Location, 2);
Game.MoveViewport(((w.LocalPlayer ?? allies1) == allies1 ? chinookHusk.Location : allies2BasePoint.Location).ToFloat2()); Game.MoveViewport(((w.LocalPlayer ?? allies1) == allies1 ? chinookHusk.Location : allies2BasePoint.Location).ToFloat2());
} }
} }
public class CountdownTimerWidget : Widget public class CountdownTimerWidget : Widget
{ {
public string Header { get; set; } public string Header { get; set; }
public int TicksLeft { get; set; } public int TicksLeft { get; set; }
public float2 Position { get; set; } public float2 Position { get; set; }
public CountdownTimerWidget(string header, int ticksLeft, Action<CountdownTimerWidget> onExpired, float2 position) public CountdownTimerWidget(string header, int ticksLeft, Action<CountdownTimerWidget> onExpired, float2 position)
{ {
Header = header; Header = header;
TicksLeft = ticksLeft; TicksLeft = ticksLeft;
OnExpired = onExpired; OnExpired = onExpired;
Position = position; Position = position;
OnOneMinuteRemaining = t => Sound.Play("1minr.aud"); OnOneMinuteRemaining = t => Sound.Play("1minr.aud");
OnTwoMinutesRemaining = t => Sound.Play("2minr.aud"); OnTwoMinutesRemaining = t => Sound.Play("2minr.aud");
OnThreeMinutesRemaining = t => Sound.Play("3minr.aud"); OnThreeMinutesRemaining = t => Sound.Play("3minr.aud");
OnFourMinutesRemaining = t => Sound.Play("4minr.aud"); OnFourMinutesRemaining = t => Sound.Play("4minr.aud");
OnFiveMinutesRemaining = t => Sound.Play("5minr.aud"); OnFiveMinutesRemaining = t => Sound.Play("5minr.aud");
OnTenMinutesRemaining = t => Sound.Play("10minr.aud"); OnTenMinutesRemaining = t => Sound.Play("10minr.aud");
OnTwentyMinutesRemaining = t => Sound.Play("20minr.aud"); OnTwentyMinutesRemaining = t => Sound.Play("20minr.aud");
OnThirtyMinutesRemaining = t => Sound.Play("30minr.aud"); OnThirtyMinutesRemaining = t => Sound.Play("30minr.aud");
OnFortyMinutesRemaining = t => Sound.Play("40minr.aud"); OnFortyMinutesRemaining = t => Sound.Play("40minr.aud");
} }
public Action<CountdownTimerWidget> OnExpired { get; set; } public Action<CountdownTimerWidget> OnExpired { get; set; }
public Action<CountdownTimerWidget> OnOneMinuteRemaining { get; set; } public Action<CountdownTimerWidget> OnOneMinuteRemaining { get; set; }
public Action<CountdownTimerWidget> OnTwoMinutesRemaining { get; set; } public Action<CountdownTimerWidget> OnTwoMinutesRemaining { get; set; }
public Action<CountdownTimerWidget> OnThreeMinutesRemaining { get; set; } public Action<CountdownTimerWidget> OnThreeMinutesRemaining { get; set; }
public Action<CountdownTimerWidget> OnFourMinutesRemaining { get; set; } public Action<CountdownTimerWidget> OnFourMinutesRemaining { get; set; }
public Action<CountdownTimerWidget> OnFiveMinutesRemaining { get; set; } public Action<CountdownTimerWidget> OnFiveMinutesRemaining { get; set; }
public Action<CountdownTimerWidget> OnTenMinutesRemaining { get; set; } public Action<CountdownTimerWidget> OnTenMinutesRemaining { get; set; }
public Action<CountdownTimerWidget> OnTwentyMinutesRemaining { get; set; } public Action<CountdownTimerWidget> OnTwentyMinutesRemaining { get; set; }
public Action<CountdownTimerWidget> OnThirtyMinutesRemaining { get; set; } public Action<CountdownTimerWidget> OnThirtyMinutesRemaining { get; set; }
public Action<CountdownTimerWidget> OnFortyMinutesRemaining { get; set; } public Action<CountdownTimerWidget> OnFortyMinutesRemaining { get; set; }
public override void Tick() public override void Tick()
{ {
if (!IsVisible()) if (!IsVisible())
{ {
return; return;
} }
if (TicksLeft > 0) if (TicksLeft > 0)
{ {
TicksLeft--; TicksLeft--;
switch (TicksLeft) switch (TicksLeft)
{ {
case 1500 * 00: OnExpired(this); break; case 1500 * 00: OnExpired(this); break;
case 1500 * 01: OnOneMinuteRemaining(this); break; case 1500 * 01: OnOneMinuteRemaining(this); break;
case 1500 * 02: OnTwoMinutesRemaining(this); break; case 1500 * 02: OnTwoMinutesRemaining(this); break;
case 1500 * 03: OnThreeMinutesRemaining(this); break; case 1500 * 03: OnThreeMinutesRemaining(this); break;
case 1500 * 04: OnFourMinutesRemaining(this); break; case 1500 * 04: OnFourMinutesRemaining(this); break;
case 1500 * 05: OnFiveMinutesRemaining(this); break; case 1500 * 05: OnFiveMinutesRemaining(this); break;
case 1500 * 10: OnTenMinutesRemaining(this); break; case 1500 * 10: OnTenMinutesRemaining(this); break;
case 1500 * 20: OnTwentyMinutesRemaining(this); break; case 1500 * 20: OnTwentyMinutesRemaining(this); break;
case 1500 * 30: OnThirtyMinutesRemaining(this); break; case 1500 * 30: OnThirtyMinutesRemaining(this); break;
case 1500 * 40: OnFortyMinutesRemaining(this); break; case 1500 * 40: OnFortyMinutesRemaining(this); break;
} }
} }
} }
public override void Draw() public override void Draw()
{ {
if (!IsVisible()) if (!IsVisible())
{ {
return; return;
} }
var font = Game.Renderer.Fonts["Bold"]; var font = Game.Renderer.Fonts["Bold"];
var text = "{0}: {1}".F(Header, WidgetUtils.FormatTime(TicksLeft)); var text = "{0}: {1}".F(Header, WidgetUtils.FormatTime(TicksLeft));
font.DrawTextWithContrast(text, Position, TicksLeft == 0 && Game.LocalTick % 60 >= 30 ? Color.Red : Color.White, Color.Black, 1); font.DrawTextWithContrast(text, Position, TicksLeft == 0 && Game.LocalTick % 60 >= 30 ? Color.Red : Color.White, Color.Black, 1);
} }
} }
} }