#region Copyright & License Information /* * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, * see COPYING. */ #endregion using System; using System.Collections.Generic; using System.Linq; using OpenRA.FileFormats; using OpenRA.Mods.RA; using OpenRA.Mods.RA.Activities; using OpenRA.Mods.RA.Move; using OpenRA.Traits; using OpenRA.Widgets; using OpenRA.Scripting; namespace OpenRA.Mods.Cnc.Missions { class Gdi01ScriptInfo : TraitInfo { } class Gdi01Script: IWorldLoaded, ITick { Dictionary Actors; Dictionary Players; public void WorldLoaded(World w) { Players = w.Players.ToDictionary(p => p.InternalName); Actors = w.WorldActor.Trait().Actors; var b = w.Map.Bounds; Game.MoveViewport(new CPos(b.Left + b.Width/2, b.Top + b.Height/2).ToFloat2()); Action afterFMV = () => { Sound.PlayMusic(Rules.Music["aoi"]); started = true; }; Game.RunAfterDelay(0, () => Media.PlayFMVFullscreen(w, "gdi1.vqa", () => Media.PlayFMVFullscreen(w, "landing.vqa", afterFMV))); } public void OnVictory(World w) { Action afterFMV = () => { Players["GoodGuy"].WinState = WinState.Won; started = false; Sound.StopMusic(); Sound.PlayToPlayer(Players["GoodGuy"], "accom1.aud"); }; Game.RunAfterDelay(0, () => Media.PlayFMVFullscreen(w, "consyard.vqa", afterFMV)); } public void OnLose(World w) { Action afterFMV = () => { Players["GoodGuy"].WinState = WinState.Lost; started = false; Sound.StopMusic(); Sound.PlayToPlayer(Players["GoodGuy"], "fail1.aud"); }; Game.RunAfterDelay(0, () => Media.PlayFMVFullscreen(w, "gameover.vqa", afterFMV)); } int ticks = 0; bool started = false; int lastBadCount = -1; public void Tick(Actor self) { if (!started) return; if (ticks == 0) { SetGunboatPath(); self.World.AddFrameEndTask(w => { //Initial Nod reinforcements foreach (var i in new[]{ "e1", "e1" }) { var a = self.World.CreateActor(i.ToLowerInvariant(), new TypeDictionary { new OwnerInit(Players["BadGuy"]), new FacingInit(0), new LocationInit(Actors["nod0"].Location), }); var mobile = a.Trait(); a.QueueActivity(mobile.MoveTo(Actors["nod1"].Location, 2 )); a.QueueActivity(mobile.MoveTo(Actors["nod2"].Location, 2 )); a.QueueActivity(mobile.MoveTo(Actors["nod3"].Location, 2 )); // TODO: Queue hunt order } }); } // GoodGuy win conditions // BadGuy is dead var badcount = self.World.Actors.Count(a => a != a.Owner.PlayerActor && a.Owner == Players["BadGuy"] && !a.IsDead()); if (badcount != lastBadCount) { Game.Debug("{0} badguys remain".F(badcount)); lastBadCount = badcount; if (badcount == 0) OnVictory(self.World); } //GoodGuy lose conditions: MCV/cyard must survive var hasAnything = self.World.ActorsWithTrait() .Any( a => a.Actor.Owner == Players["GoodGuy"] ); if (!hasAnything) OnLose(self.World); // GoodGuy reinforcements if (ticks == 25*5) { ReinforceFromSea(self.World, Actors["lstStart"].Location, Actors["lstEnd"].Location, new CPos(53, 53), new string[] {"e1","e1","e1"}, Players["GoodGuy"]); } if (ticks == 25*15) { ReinforceFromSea(self.World, Actors["lstStart"].Location, Actors["lstEnd"].Location, new CPos(53, 53), new string[] {"e1","e1","e1"}, Players["GoodGuy"]); } if (ticks == 25*30) { ReinforceFromSea(self.World, Actors["lstStart"].Location, Actors["lstEnd"].Location, new CPos(53, 53), new string[] {"jeep"}, Players["GoodGuy"]); } if (ticks == 25*60) { ReinforceFromSea(self.World, Actors["lstStart"].Location, Actors["lstEnd"].Location, new CPos(53, 53), new string[] {"jeep"}, Players["GoodGuy"]); } ticks++; } void SetGunboatPath() { var self = Actors[ "Gunboat" ]; var mobile = self.Trait(); self.Trait().stance = UnitStance.AttackAnything; //TODO: this is ignored self.QueueActivity(mobile.ScriptedMove(Actors["gunboatLeft"].Location)); self.QueueActivity(mobile.ScriptedMove(Actors["gunboatRight"].Location)); self.QueueActivity(new CallFunc(() => SetGunboatPath())); } void ReinforceFromSea(World world, CPos startPos, CPos endPos, CPos unload, string[] items, Player player) { world.AddFrameEndTask(w => { Sound.PlayToPlayer(w.LocalPlayer,"reinfor1.aud"); var a = w.CreateActor("lst", new TypeDictionary { new LocationInit( startPos ), new OwnerInit( player ), new FacingInit( 0 ), }); var mobile = a.Trait(); var cargo = a.Trait(); foreach (var i in items) cargo.Load(a, world.CreateActor(false, i.ToLowerInvariant(), new TypeDictionary { new OwnerInit( player ), new FacingInit( 0 ), })); a.CancelActivity(); a.QueueActivity(mobile.ScriptedMove(endPos)); a.QueueActivity(new CallFunc(() => { while (!cargo.IsEmpty(a)) { var b = cargo.Unload(a); world.AddFrameEndTask(w2 => { if (b.Destroyed) return; w2.Add(b); b.TraitsImplementing().FirstOrDefault().SetPosition(b, a.Location); b.QueueActivity(mobile.MoveTo(unload, 2)); }); } })); a.QueueActivity(new Wait(25)); a.QueueActivity(mobile.ScriptedMove(startPos)); a.QueueActivity(new RemoveSelf()); }); } } }