From 03f03ff501793afe94ae2318e7309b566718bc92 Mon Sep 17 00:00:00 2001 From: Scott_NZ Date: Mon, 4 Feb 2013 22:33:21 +1300 Subject: [PATCH] More MonsterTankMadness work. Add routines for super tanks, civilian evacuees, proving grounds camera, base transfer, Demitri extraction --- .../Missions/MonsterTankMadnessScript.cs | 188 +++++++++++++----- mods/ra/maps/monster-tank-madness/map.yaml | 14 +- 2 files changed, 143 insertions(+), 59 deletions(-) diff --git a/OpenRA.Mods.RA/Missions/MonsterTankMadnessScript.cs b/OpenRA.Mods.RA/Missions/MonsterTankMadnessScript.cs index 77e9cb6fbe..b402b406cf 100644 --- a/OpenRA.Mods.RA/Missions/MonsterTankMadnessScript.cs +++ b/OpenRA.Mods.RA/Missions/MonsterTankMadnessScript.cs @@ -25,6 +25,7 @@ namespace OpenRA.Mods.RA.Missions 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); } } @@ -78,16 +79,29 @@ namespace OpenRA.Mods.RA.Missions Actor demitriLZFlare; Actor demitriChinook; + Actor provingGroundsCameraPoint; + + Actor[] superTanks; + + Actor hospital; + Actor hospitalCivilianSpawnPoint; + Actor hospitalSuperTankPoint; + + bool demitriExtracted; + bool hospitalEvacuated; + + bool superTanksAttackingGreece; + int baseTransferredTick = -1; void MissionAccomplished(string text) { - MissionUtils.CoopMissionAccomplished(world, text, ussr); + MissionUtils.CoopMissionAccomplished(world, text, greece); } void MissionFailed(string text) { - MissionUtils.CoopMissionFailed(world, text, ussr); + MissionUtils.CoopMissionFailed(world, text, greece); } public void Tick(Actor self) @@ -95,21 +109,20 @@ namespace OpenRA.Mods.RA.Missions if (greece.WinState != WinState.Undefined) return; if (world.FrameNumber == 1) - { - Sound.Play("reinfor1.aud"); SpawnAndMoveBridgeUnits(info.FirstStartUnits); - } else if (world.FrameNumber == 25 * 3) - { - Sound.Play("reinfor1.aud"); SpawnAndMoveBridgeUnits(info.SecondStartUnits); - } else if (world.FrameNumber == 25 * 8) - { - Sound.Play("reinfor1.aud"); SpawnAndMoveBridgeUnits(info.ThirdStartUnits); + + MissionUtils.CapOre(ussr); + + if (!hospitalEvacuated && !hospital.IsDead() && MissionUtils.AreaSecuredWithUnits(world, greece, hospital.CenterLocation, 5)) + { + EvacuateCivilians(); + hospitalEvacuated = true; } if (baseTransferredTick == -1) @@ -118,69 +131,129 @@ namespace OpenRA.Mods.RA.Missions if (actorsInBase.Any(a => a.Owner == greece)) { foreach (var actor in actorsInBase) - { - // hack hack hack - actor.ChangeOwner(greece); - if (actor.Info.Name == "pbox") - { - actor.AddTrait(new TransformedAction(s => s.Trait().Load(s, - world.CreateActor(false, "e1", new TypeDictionary { new OwnerInit(greece) })))); - actor.QueueActivity(new Transform(actor, "hbox.e1") { SkipMakeAnims = true }); - } - else if (actor.Info.Name == "proc.nofreeactor") - { - actor.QueueActivity(new Transform(actor, "proc") { SkipMakeAnims = true }); - } - var building = actor.TraitOrDefault(); - if (building != null) - building.OnCapture(actor, actor, neutral, greece); - } + TransferActorToAllies(actor); baseTransferredTick = world.FrameNumber; } } else { + if (world.FrameNumber == baseTransferredTick + 25 * 120) + foreach (var tank in superTanks.Where(t => !t.IsDead() && t.IsInWorld)) + tank.QueueActivity(false, new Move.Move(hospitalSuperTankPoint.Location, 2)); - } - if (demitri == null) - { - if (demitriChurch.IsDead()) - MissionFailed("Dr. Demitri was killed."); + else if (world.FrameNumber == baseTransferredTick + 25 * 200) + foreach (var tank in superTanks.Where(t => !t.IsDead() && t.IsInWorld)) + tank.QueueActivity(false, new Move.Move(alliedBaseBottomRight.Location, 2)); - else if (world.FindAliveCombatantActorsInCircle(demitriTriggerAreaCenter.CenterLocation, 3).Any(a => a.Owner == greece)) - { - demitri = world.CreateActor("demitri", new TypeDictionary + else if (world.FrameNumber == baseTransferredTick + 25 * 260) + 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 * 500) + foreach (var tank in superTanks.Where(t => !t.IsDead() && t.IsInWorld)) { - new OwnerInit(greece), - new LocationInit(demitriChurchSpawnPoint.Location) - }); - demitri.QueueActivity(new Move.Move(demitriTriggerAreaCenter.Location, 0)); - demitriLZFlare = world.CreateActor("flare", new TypeDictionary { new OwnerInit(greece), new LocationInit(demitriLZ.Location) }); - Sound.Play("flaren1.aud"); - var chinookEntry = new CPos(demitriLZ.Location.X, 0); - demitriChinook = MissionUtils.ExtractUnitWithChinook(world, greece, demitri, chinookEntry, demitriLZ.Location, chinookEntry); + tank.QueueActivity(false, new AttackMove.AttackMoveActivity(tank, new Move.Move(demitriLZ.Location, 2))); + superTanksAttackingGreece = true; + } + + if (superTanksAttackingGreece) + foreach (var tank in superTanks.Where(t => !t.IsDead() && t.IsInWorld && t.IsIdle)) + AttackNearestAlliedActor(tank); + } + if (!demitriExtracted) + { + if (demitri == null) + { + if (demitriChurch.IsDead()) + { + objectives[BriefingID].Status = ObjectiveStatus.Failed; + OnObjectivesUpdated(true); + MissionFailed("Dr. Demitri was killed."); + } + + else if (MissionUtils.AreaSecuredWithUnits(world, greece, demitriTriggerAreaCenter.CenterLocation, 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()) + { + objectives[BriefingID].Status = ObjectiveStatus.Failed; + OnObjectivesUpdated(true); + MissionFailed("Dr. Demitri was killed."); + } + else if (demitriChinook != null && !demitriChinook.IsDead() && !world.Map.IsInMap(demitriChinook.Location) && demitriChinook.Trait().Passengers.Contains(demitri)) + { + demitriLZFlare.Destroy(); + SpawnAndMoveAlliedBaseUnits(info.FirstBaseUnits); + demitriExtracted = true; } } - else if (demitri.IsDead()) - MissionFailed("Dr. Demitri was killed."); - else if (demitriChinook != null && !demitriChinook.IsDead() && !world.Map.IsInMap(demitriChinook.Location) && demitriChinook.Trait().Passengers.Contains(demitri)) + if (!world.Actors.Any(a => a.Owner == greece && a.IsInWorld && !a.IsDead() + && ((a.HasTrait() && !a.HasTrait()) || a.HasTrait()))) { - demitriLZFlare.Destroy(); - Sound.Play("reinfor1.aud"); - SpawnAndMoveAlliedBaseUnits(info.FirstBaseUnits); + objectives[BriefingID].Status = ObjectiveStatus.Failed; + OnObjectivesUpdated(true); + MissionFailed("The remaining Allied forces in the area have been wiped out."); + } + } + + void AttackNearestAlliedActor(Actor self) + { + var enemies = world.Actors.Where(u => u.AppearsHostileTo(self) && u.Owner == greece + && ((u.HasTrait() && !u.HasTrait()) || u.HasTrait()) && u.IsInWorld && !u.IsDead()); + + var enemy = enemies.OrderBy(u => (self.CenterLocation - u.CenterLocation).LengthSquared).FirstOrDefault(); + if (enemy != null) + self.QueueActivity(new AttackMove.AttackMoveActivity(self, new Attack(Target.FromActor(enemy), 3))); + } + + void TransferActorToAllies(Actor actor) + { + // hack hack hack + actor.ChangeOwner(greece); + if (actor.Info.Name == "pbox") + { + actor.AddTrait(new TransformedAction(s => s.Trait().Load(s, world.CreateActor(false, "e1", greece, null, null)))); + actor.QueueActivity(new Transform(actor, "hbox.e1") { SkipMakeAnims = true }); + } + else if (actor.Info.Name == "proc.nofreeactor") + actor.QueueActivity(new Transform(actor, "proc") { SkipMakeAnims = true }); + var building = actor.TraitOrDefault(); + if (building != null) + building.OnCapture(actor, actor, neutral, greece); + } + + void EvacuateCivilians() + { + foreach (var unit in info.CivilianEvacuees) + { + var actor = world.CreateActor(unit, neutral, hospitalCivilianSpawnPoint.Location, null); + actor.Trait().Nudge(actor, actor, true); + actor.QueueActivity(new Move.Move(alliedBaseEntryPoint.Location, 0)); + actor.QueueActivity(new RemoveSelf()); } } void SpawnAndMoveBridgeUnits(string[] units) { - MissionUtils.SpawnAndMoveActors(world, greece, units, startEntryPoint.Location, startMovePoint.Location, - Util.GetFacing(startBridgeEndPoint.CenterLocation - startEntryPoint.CenterLocation, 0)); + Sound.Play("reinfor1.aud"); + foreach (var unit in units) + world.CreateActor(unit, greece, startEntryPoint.Location, Util.GetFacing(startBridgeEndPoint.CenterLocation - startEntryPoint.CenterLocation, 0)) + .QueueActivity(new Move.Move(startMovePoint.Location, 0)); } void SpawnAndMoveAlliedBaseUnits(string[] units) { - MissionUtils.SpawnAndMoveActors(world, greece, units, alliedBaseEntryPoint.Location, alliedBaseMovePoint.Location, - Util.GetFacing(alliedBaseMovePoint.CenterLocation - alliedBaseEntryPoint.CenterLocation, 0)); + Sound.Play("reinfor1.aud"); + foreach (var unit in units) + world.CreateActor(unit, greece, alliedBaseEntryPoint.Location, Util.GetFacing(alliedBaseMovePoint.CenterLocation - alliedBaseEntryPoint.CenterLocation, 0)) + .QueueActivity(new Move.Move(alliedBaseMovePoint.Location, 0)); } public void WorldLoaded(World w) @@ -210,6 +283,15 @@ namespace OpenRA.Mods.RA.Missions 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); + Game.MoveViewport(startEntryPoint.Location.ToFloat2()); MissionUtils.PlayMissionMusic(); } diff --git a/mods/ra/maps/monster-tank-madness/map.yaml b/mods/ra/maps/monster-tank-madness/map.yaml index 405c7c47ba..dc199f140a 100644 --- a/mods/ra/maps/monster-tank-madness/map.yaml +++ b/mods/ra/maps/monster-tank-madness/map.yaml @@ -49,6 +49,7 @@ Players: OwnsWorld: True NonCombatant: True Race: allies + Enemies: Turkey PlayerReference@Ukraine: Name: Ukraine Race: soviet @@ -59,7 +60,7 @@ Players: Name: Turkey Race: allies ColorRamp: 14,123,167,28 - Enemies: Greece,BadGuy,USSR,Ukraine + Enemies: Greece,BadGuy,USSR,Ukraine,Neutral PlayerReference@Creeps: Name: Creeps NonCombatant: True @@ -1783,7 +1784,7 @@ Actors: Owner: Neutral Health: 0.1367188 Facing: 0 - Actor513: hosp + Hospital: hosp Location: 43,43 Owner: Neutral Health: 1 @@ -2430,13 +2431,13 @@ Actors: AlliedBaseTopLeft: waypoint Location: 19,16 Owner: Neutral - waypoint19: waypoint + HospitalCivilianSpawnPoint: waypoint Location: 44,43 Owner: Neutral waypoint20: waypoint Location: 43,48 Owner: Neutral - waypoint21: waypoint + HospitalSuperTankPoint: waypoint Location: 47,46 Owner: Neutral waypoint22: waypoint @@ -2460,7 +2461,7 @@ Actors: waypoint28: waypoint Location: 86,40 Owner: Neutral - waypoint29: waypoint + ProvingGroundsCameraPoint: waypoint Location: 85,55 Owner: Neutral waypoint30: waypoint @@ -2535,6 +2536,7 @@ Rules: SecondStartUnits: e1, e1, e1, e3, e3 ThirdStartUnits: spy, e6, e6 FirstBaseUnits: 1tnk, 1tnk, 2tnk, arty, arty + CivilianEvacuees: c1, c2, c5, c7, c8 MissionObjectivesPanel: ObjectivesPanel: MISSION_OBJECTIVES DEMITRI: @@ -2723,7 +2725,7 @@ Weapons: Image: 120MM Warhead: Spread: 3 - Versus: + Versus: None: 20% Wood: 75% Light: 75%