diff --git a/OpenRA.Mods.RA/Missions/Allies01Script.cs b/OpenRA.Mods.RA/Missions/Allies01Script.cs index 030db00688..3a1aa79299 100644 --- a/OpenRA.Mods.RA/Missions/Allies01Script.cs +++ b/OpenRA.Mods.RA/Missions/Allies01Script.cs @@ -9,13 +9,11 @@ #endregion using System.Collections.Generic; -using System.Drawing; using System.Linq; using OpenRA.FileFormats; using OpenRA.Mods.RA.Activities; using OpenRA.Mods.RA.Air; using OpenRA.Mods.RA.Move; -using OpenRA.Network; using OpenRA.Scripting; using OpenRA.Traits; @@ -90,31 +88,16 @@ namespace OpenRA.Mods.RA.Missions public void Tick(Actor self) { - if (allies.WinState != WinState.Undefined) - { - return; - } + if (allies.WinState != WinState.Undefined) return; + if (world.FrameNumber % 1000 == 0) - { Sound.Play(Taunts[world.SharedRandom.Next(Taunts.Length)]); - } + if (objectives[FindEinsteinID].Status == ObjectiveStatus.InProgress) { if (AlliesControlLab()) - { - SpawnSignalFlare(); - Sound.Play("flaren1.aud"); - SpawnEinsteinAtLab(); - SendShips(); - objectives[FindEinsteinID].Status = ObjectiveStatus.Completed; - objectives[ExtractEinsteinID].Status = ObjectiveStatus.InProgress; - if (difficulty == "Easy") - { - ExtractEinsteinAtLZ(); - } - OnObjectivesUpdated(true); - currentAttackWaveFrameNumber = world.FrameNumber; - } + LabSecured(); + if (lab.Destroyed) { objectives[FindEinsteinID].Status = ObjectiveStatus.Failed; @@ -126,21 +109,19 @@ namespace OpenRA.Mods.RA.Missions { if (difficulty != "Easy") { - SendAttackWave(); + ManageSovietUnits(); if (world.FrameNumber >= currentAttackWaveFrameNumber + 600) { Sound.Play("enmyapp1.aud"); - SpawnAttackWave(AttackWave); + SpawnSovietUnits(AttackWave); currentAttackWave++; currentAttackWaveFrameNumber = world.FrameNumber; + if (currentAttackWave >= EinsteinChinookAttackWave) - { - SpawnAttackWave(LastAttackWaveAddition); - } + SpawnSovietUnits(LastAttackWaveAddition); + if (currentAttackWave == EinsteinChinookAttackWave) - { ExtractEinsteinAtLZ(); - } } } if (einsteinChinook != null) @@ -159,24 +140,38 @@ namespace OpenRA.Mods.RA.Missions } } } + if (tanya != null && tanya.Destroyed) - { MissionFailed("Tanya was killed."); - } + else if (einstein != null && einstein.Destroyed) - { MissionFailed("Einstein was killed."); - } + ManageSovietOre(); } + void LabSecured() + { + SpawnSignalFlare(); + Sound.Play("flaren1.aud"); + SpawnEinsteinAtLab(); + SendShips(); + objectives[FindEinsteinID].Status = ObjectiveStatus.Completed; + objectives[ExtractEinsteinID].Status = ObjectiveStatus.InProgress; + + if (difficulty == "Easy") + ExtractEinsteinAtLZ(); + + OnObjectivesUpdated(true); + currentAttackWaveFrameNumber = world.FrameNumber; + } + void ManageSovietOre() { var res = soviets.PlayerActor.Trait(); + if (res.Ore > res.OreCapacity * 0.8) - { res.TakeOre(res.OreCapacity / 10); - } } void SpawnSignalFlare() @@ -184,7 +179,7 @@ namespace OpenRA.Mods.RA.Missions world.CreateActor(SignalFlareName, new TypeDictionary { new OwnerInit(allies), new LocationInit(extractionLZ.Location) }); } - void SpawnAttackWave(IEnumerable wave) + void SpawnSovietUnits(IEnumerable wave) { foreach (var unit in wave) { @@ -193,7 +188,7 @@ namespace OpenRA.Mods.RA.Missions } } - void SendAttackWave() + void ManageSovietUnits() { foreach (var unit in world.Actors.Where(a => a != world.WorldActor && a.IsInWorld && a.Owner == soviets && !a.IsDead() && a.IsIdle && a.HasTrait() && a.HasTrait())) @@ -202,20 +197,17 @@ namespace OpenRA.Mods.RA.Missions if (einstein != null) { if (einstein.IsInWorld) - { innerActivity = new Attack(Target.FromActor(einstein), 3); - } + else { var container = world.UnitContaining(einstein); + if (container != null && !container.HasTrait() && container.HasTrait()) - { innerActivity = new Attack(Target.FromActor(container), 3); - } + else - { innerActivity = new Move.Move(extractionLZ.Location, 3); - } } unit.QueueActivity(new AttackMove.AttackMoveActivity(unit, innerActivity)); } @@ -225,10 +217,12 @@ namespace OpenRA.Mods.RA.Missions void SendPatrol() { for (int i = 0; i < Patrol.Length; i++) - { - var actor = world.CreateActor(Patrol[i], new TypeDictionary { new OwnerInit(soviets), new LocationInit(insertionLZ.Location + new CVec(-1 + i, 10 + i * 2)) }); - actor.QueueActivity(new Move.Move(insertionLZ.Location)); - } + world.CreateActor(Patrol[i], new TypeDictionary + { + new OwnerInit(soviets), + new LocationInit(insertionLZ.Location + new CVec(-1 + i, 10 + i * 2)) + }) + .QueueActivity(new Move.Move(insertionLZ.Location)); } bool AlliesControlLab() @@ -245,11 +239,12 @@ namespace OpenRA.Mods.RA.Missions void SendShips() { for (int i = 0; i < Ships.Length; i++) - { - var actor = world.CreateActor(Ships[i], - new TypeDictionary { new OwnerInit(allies), new LocationInit(shipSpawnPoint.Location + new CVec(i * 2, 0)) }); - actor.QueueActivity(new Move.Move(shipMovePoint.Location + new CVec(i * 4, 0))); - } + world.CreateActor(Ships[i], new TypeDictionary + { + new OwnerInit(allies), + new LocationInit(shipSpawnPoint.Location + new CVec(i * 2, 0)) + }) + .QueueActivity(new Move.Move(shipMovePoint.Location + new CVec(i * 4, 0))); } void ExtractEinsteinAtLZ() @@ -282,9 +277,7 @@ namespace OpenRA.Mods.RA.Missions void SetAlliedUnitsToDefensiveStance() { foreach (var actor in world.Actors.Where(a => a.IsInWorld && a.Owner == allies && !a.IsDead() && a.HasTrait())) - { actor.Trait().stance = UnitStance.Defend; - } } public void WorldLoaded(World w) @@ -317,17 +310,14 @@ namespace OpenRA.Mods.RA.Missions Game.MoveViewport(insertionLZ.Location.ToFloat2()); if (MissionUtils.IsSingleClient(world)) - { Media.PlayFMVFullscreen(w, "ally1.vqa", () => - { Media.PlayFMVFullscreen(w, "landing.vqa", () => { InsertTanyaAtLZ(); SendPatrol(); MissionUtils.PlayMissionMusic(); - }); - }); - } + }) + ); else { InsertTanyaAtLZ(); diff --git a/OpenRA.Mods.RA/Missions/Allies02Script.cs b/OpenRA.Mods.RA/Missions/Allies02Script.cs index 8257f6c686..1245227d98 100644 --- a/OpenRA.Mods.RA/Missions/Allies02Script.cs +++ b/OpenRA.Mods.RA/Missions/Allies02Script.cs @@ -9,7 +9,6 @@ #endregion using System.Collections.Generic; -using System.Drawing; using System.Linq; using OpenRA.FileFormats; using OpenRA.Mods.RA.Activities; @@ -17,7 +16,6 @@ using OpenRA.Mods.RA.Air; using OpenRA.Mods.RA.Buildings; using OpenRA.Mods.RA.Effects; using OpenRA.Mods.RA.Move; -using OpenRA.Network; using OpenRA.Traits; using OpenRA.Widgets; @@ -144,9 +142,7 @@ namespace OpenRA.Mods.RA.Missions { MissionUtils.CoopMissionFailed(world, text, allies1, allies2); if (reinforcementsTimer != null) - { reinforcementsTimerWidget.Visible = false; - } } void MissionAccomplished(string text) @@ -156,20 +152,19 @@ namespace OpenRA.Mods.RA.Missions public void Tick(Actor self) { - if (allies1.WinState != WinState.Undefined) - { - return; - } + if (allies1.WinState != WinState.Undefined) return; + if (world.FrameNumber % 50 == 1 && chinookHusk.IsInWorld) - { world.Add(new Smoke(world, chinookHusk.CenterLocation, "smoke_m")); - } + if (world.FrameNumber == 1) { InitializeSovietFactories(); StartReinforcementsTimer(); } + reinforcementsTimer.Tick(); + if (world.FrameNumber == ParatroopersTicks) { MissionUtils.Paradrop(world, soviets, Badger1Passengers, badgerEntryPoint1.Location, badgerDropPoint1.Location); @@ -181,36 +176,35 @@ namespace OpenRA.Mods.RA.Missions MissionUtils.Parabomb(world, soviets, badgerEntryPoint2.Location, parabombPoint1.Location); MissionUtils.Parabomb(world, soviets, badgerEntryPoint2.Location + new CVec(0, 3), parabombPoint2.Location); } + if (allies1 != allies2) { if (world.FrameNumber == TanksTicks) - { RushSovietUnits(); - } + if (world.FrameNumber == FlamersTicks) - { RushSovietFlamers(); - } + if (yak == null || (yak != null && !yak.IsDead() && (yak.GetCurrentActivity() is FlyCircle || yak.IsIdle))) { var alliedUnitsNearYakPoint = world.FindAliveCombatantActorsInCircle(yakAttackPoint.CenterLocation, 10) .Where(a => a.Owner != soviets && a.HasTrait() && a != tanya && a != einstein && a != engineer); if (alliedUnitsNearYakPoint.Any()) - { YakStrafe(alliedUnitsNearYakPoint); - } } } + if (currentReinforcement > -1 && currentReinforcement < Reinforcements.Length && world.FrameNumber % 25 == 0) - { SpawnAlliedUnit(Reinforcements[currentReinforcement++]); - } + if (world.FrameNumber % 25 == 0) { BuildSovietUnits(); ManageSovietUnits(); } + UpdateDeaths(); + if (objectives[FindEinsteinID].Status == ObjectiveStatus.InProgress) { if (AlliesNearTown()) @@ -249,22 +243,21 @@ namespace OpenRA.Mods.RA.Missions { objectives[ExtractEinsteinID].Status = ObjectiveStatus.Completed; objectives[MaintainPresenceID].Status = ObjectiveStatus.Completed; + if (objectives[FewDeathsID].Status == ObjectiveStatus.InProgress) - { objectives[FewDeathsID].Status = ObjectiveStatus.Completed; - } + OnObjectivesUpdated(true); MissionAccomplished("Einstein was rescued."); } } + if (tanya.Destroyed) - { MissionFailed("Tanya was killed."); - } + else if (einstein.Destroyed) - { MissionFailed("Einstein was killed."); - } + world.AddFrameEndTask(w => { if (!world.FindAliveCombatantActorsInCircle(allies2BasePoint.CenterLocation, 20) @@ -301,10 +294,10 @@ namespace OpenRA.Mods.RA.Missions new AltitudeInit(Rules.Info[YakName].Traits.Get().CruiseAltitude) }); } + if (yak.Trait().HasAmmo()) - { yak.QueueActivity(new FlyAttack(Target.FromActor(candidates.Random(world.SharedRandom)))); - } + else { yak.QueueActivity(new FlyOffMap()); @@ -315,9 +308,8 @@ namespace OpenRA.Mods.RA.Missions void BuildSovietUnits() { if (!sovietBarracks.Destroyed) - { BuildSovietUnit(InfantryQueueName, SovietInfantry.Random(world.SharedRandom)); - } + if (!sovietWarFactory.Destroyed) { var vehicles = world.FrameNumber >= SovietVehiclesUpgradeTicks ? SovietVehicles2 : SovietVehicles1; @@ -327,7 +319,9 @@ namespace OpenRA.Mods.RA.Missions void ManageSovietUnits() { - var idleSovietUnitsAtRP = world.FindAliveCombatantActorsInCircle(sovietRallyPoint.CenterLocation, 3).Where(a => a.Owner == soviets && a.IsIdle && a.HasTrait()); + var idleSovietUnitsAtRP = world.FindAliveCombatantActorsInCircle(sovietRallyPoint.CenterLocation, 3) + .Where(a => a.Owner == soviets && a.IsIdle && a.HasTrait()); + if (idleSovietUnitsAtRP.Count() >= SovietGroupSize) { var firstUnit = idleSovietUnitsAtRP.FirstOrDefault(); @@ -335,23 +329,23 @@ namespace OpenRA.Mods.RA.Missions { var closestAlliedBuilding = ClosestAlliedBuilding(firstUnit, 40); if (closestAlliedBuilding != null) - { foreach (var unit in idleSovietUnitsAtRP) { unit.Trait().Nudge(unit, unit, true); unit.QueueActivity(new AttackMove.AttackMoveActivity(unit, new Attack(Target.FromActor(closestAlliedBuilding), 3))); } - } } } - var idleSovietUnits = world.FindAliveCombatantActorsInCircle(allies2BasePoint.CenterLocation, 20).Where(a => a.Owner == soviets && a.IsIdle && a.HasTrait()); + + var idleSovietUnits = world.FindAliveCombatantActorsInCircle(allies2BasePoint.CenterLocation, 20) + .Where(a => a.Owner == soviets && a.IsIdle && a.HasTrait()); + foreach (var unit in idleSovietUnits) { var closestAlliedBuilding = ClosestAlliedBuilding(unit, 40); + if (closestAlliedBuilding != null) - { unit.QueueActivity(new AttackMove.AttackMoveActivity(unit, new Attack(Target.FromActor(closestAlliedBuilding), 3))); - } } } @@ -378,10 +372,8 @@ namespace OpenRA.Mods.RA.Missions void BuildSovietUnit(string category, string unit) { var queue = MissionUtils.FindQueues(world, soviets, category).FirstOrDefault(q => q.CurrentItem() == null); - if (queue == null) - { - return; - } + if (queue == null) return; + queue.ResolveOrder(queue.self, Order.StartProduction(queue.self, unit, 1)); } @@ -407,22 +399,20 @@ namespace OpenRA.Mods.RA.Missions void SpawnAlliedUnit(string unit) { - var u = world.CreateActor(unit, new TypeDictionary + world.CreateActor(unit, new TypeDictionary { new LocationInit(reinforcementsEntryPoint.Location), new FacingInit(0), new OwnerInit(allies2) - }); - u.QueueActivity(new Move.Move(allies2BasePoint.Location)); + }) + .QueueActivity(new Move.Move(allies2BasePoint.Location)); } void RushSovietUnits() { var closestAlliedBuildings = ClosestAlliedBuildings(badgerDropPoint1, 40); - if (!closestAlliedBuildings.Any()) - { - return; - } + if (!closestAlliedBuildings.Any()) return; + foreach (var tank in Tanks) { var unit = world.CreateActor(tank, new TypeDictionary @@ -431,19 +421,15 @@ namespace OpenRA.Mods.RA.Missions new LocationInit(tanksEntryPoint.Location) }); foreach (var building in closestAlliedBuildings) - { unit.QueueActivity(new Attack(Target.FromActor(building), 3)); - } } } void RushSovietFlamers() { var closestAlliedBuilding = ClosestAlliedBuilding(badgerDropPoint1, 40); - if (closestAlliedBuilding == null) - { - return; - } + if (closestAlliedBuilding == null) return; + var apc = world.CreateActor(ApcName, new TypeDictionary { new OwnerInit(soviets), new LocationInit(flamersEntryPoint.Location) }); foreach (var flamer in Flamers) { @@ -474,9 +460,7 @@ namespace OpenRA.Mods.RA.Missions void TransferTownUnitsToAllies() { foreach (var unit in world.FindAliveNonCombatantActorsInCircle(townPoint.CenterLocation, AlliedTownTransferRange).Where(a => a.HasTrait())) - { unit.ChangeOwner(allies1); - } } void SovietsAttackTown() @@ -485,10 +469,9 @@ namespace OpenRA.Mods.RA.Missions .Union(world.FindAliveCombatantActorsInCircle(sovietTownAttackPoint2.CenterLocation, SovietTownAttackGroupRange)) .Union(world.FindAliveCombatantActorsInCircle(townPoint.CenterLocation, AlliedTownTransferRange)) .Where(a => a.HasTrait() && a.Owner == soviets); + foreach (var unit in sovietAttackUnits) - { unit.QueueActivity(new AttackMove.AttackMoveActivity(unit, new Move.Move(townPoint.Location, SovietTownMoveNearEnough))); - } } public void WorldLoaded(World w) @@ -544,13 +527,10 @@ namespace OpenRA.Mods.RA.Missions shroud.Explore(w, sam4.Location, 2); if (w.LocalPlayer == null || w.LocalPlayer == allies1) - { Game.MoveViewport(chinookHusk.Location.ToFloat2()); - } + else - { Game.MoveViewport(allies2BasePoint.Location.ToFloat2()); - } MissionUtils.PlayMissionMusic(); } @@ -560,9 +540,8 @@ namespace OpenRA.Mods.RA.Missions world.AddFrameEndTask(w => { foreach (var actor in actors.Where(a => a.Value.Owner == allies)) - { actor.Value.ChangeOwner(allies2); - } + world.CreateActor("proc", new TypeDictionary { new LocationInit(actors["Allies2ProcPoint"].Location), diff --git a/OpenRA.Mods.RA/Missions/Allies03Script.cs b/OpenRA.Mods.RA/Missions/Allies03Script.cs index f9c59cb1c0..d0bb019f7a 100644 --- a/OpenRA.Mods.RA/Missions/Allies03Script.cs +++ b/OpenRA.Mods.RA/Missions/Allies03Script.cs @@ -132,10 +132,8 @@ namespace OpenRA.Mods.RA.Missions public void Tick(Actor self) { - if (allies1.WinState != WinState.Undefined) - { - return; - } + if (allies1.WinState != WinState.Undefined) return; + if (world.FrameNumber == 1) { SpawnAlliedUnit(McvName); @@ -149,22 +147,25 @@ namespace OpenRA.Mods.RA.Missions attackAtFrame += attackAtFrameIncrement; attackAtFrameIncrement = Math.Max(attackAtFrameIncrement - 5, minAttackAtFrame); } - if (world.FrameNumber >= ReinforcementsTicks1 && currentReinforcement1 < Reinforcements1.Length) + + if (world.FrameNumber == ReinforcementsTicks1 || world.FrameNumber == ReinforcementsTicks2) + Sound.Play("reinfor1.aud"); + + if (world.FrameNumber % 25 == 0) { - if (world.FrameNumber == ReinforcementsTicks1) Sound.Play("reinfor1.aud"); - if (world.FrameNumber % 25 == 0) SpawnAlliedUnit(Reinforcements1[currentReinforcement1++]); - } - if (world.FrameNumber >= ReinforcementsTicks2 && currentReinforcement2 < Reinforcements2.Length) - { - if (world.FrameNumber == ReinforcementsTicks2) Sound.Play("reinfor1.aud"); - if (world.FrameNumber % 25 == 0) SpawnAlliedUnit(Reinforcements2[currentReinforcement2++]); + if (world.FrameNumber >= ReinforcementsTicks1 && currentReinforcement1 < Reinforcements1.Length) + SpawnAlliedUnit(Reinforcements1[currentReinforcement1++]); + + if (world.FrameNumber >= ReinforcementsTicks2 && currentReinforcement2 < Reinforcements2.Length) + SpawnAlliedUnit(Reinforcements2[currentReinforcement2++]); } + + if (sovietParadrops > 0) { if (world.FrameNumber == sovietParadropTicks) - { Sound.Play("sovfapp1.aud"); - } + if (world.FrameNumber >= sovietParadropTicks && world.FrameNumber % ParadropIncrement == 0) { CPos lz; @@ -182,20 +183,21 @@ namespace OpenRA.Mods.RA.Missions } } if (world.FrameNumber % 25 == 0) - { ManageSovietUnits(); - } + if (objectives[AirbaseID].Status != ObjectiveStatus.Completed) { if (world.FrameNumber % 25 == 0) - { BuildSovietAircraft(); - } + ManageSovietAircraft(); } + EvacuateAlliedUnits(exit1TopLeft.CenterLocation, exit1BottomRight.CenterLocation, exit1ExitPoint.Location); EvacuateAlliedUnits(exit2TopLeft.CenterLocation, exit2BottomRight.CenterLocation, exit2ExitPoint.Location); + CheckSovietAirbase(); + if (!world.Actors.Any(a => (a.Owner == allies1 || a.Owner == allies2) && a.IsInWorld && !a.IsDead() && ((a.HasTrait() && !a.HasTrait()) || a.HasTrait()))) { @@ -227,13 +229,11 @@ namespace OpenRA.Mods.RA.Missions if (enemy != null) { if (!aircraft.IsIdle && aircraft.GetCurrentActivity().GetType() != typeof(FlyAttack)) - { aircraft.CancelActivity(); - } + if (plane.Altitude == 0) - { plane.UnReserve(); - } + aircraft.QueueActivity(new FlyAttack(Target.FromActor(enemy))); } } @@ -249,19 +249,15 @@ namespace OpenRA.Mods.RA.Missions bool LandIsQueued(Actor actor) { for (var a = actor.GetCurrentActivity(); a != null; a = a.NextActivity) - { - if (a is ReturnToBase || a is Land) { return true; } - } + if (a is ReturnToBase || a is Land) return true; return false; } void BuildSovietAircraft() { var queue = MissionUtils.FindQueues(world, soviets, "Plane").FirstOrDefault(q => q.CurrentItem() == null); - if (queue == null || SovietAircraft().Count() >= maxSovietYaks) - { - return; - } + if (queue == null || SovietAircraft().Count() >= maxSovietYaks) return; + queue.ResolveOrder(queue.self, Order.StartProduction(queue.self, YakName, 1)); } @@ -284,16 +280,19 @@ namespace OpenRA.Mods.RA.Missions var route = world.SharedRandom.Next(sovietEntryPoints.Length); var spawnPoint = sovietEntryPoints[route]; var rallyPoint = sovietRallyPoints[route]; + IEnumerable units; if (world.FrameNumber >= sovietUnits2Ticks) - { units = SovietUnits2; - } else - { units = SovietUnits1; - } - var unit = world.CreateActor(units.Random(world.SharedRandom), new TypeDictionary { new LocationInit(spawnPoint), new OwnerInit(soviets) }); + + var unit = world.CreateActor(units.Random(world.SharedRandom), + new TypeDictionary + { + new LocationInit(spawnPoint), + new OwnerInit(soviets) + }); unit.QueueActivity(new AttackMove.AttackMoveActivity(unit, new Move.Move(rallyPoint, 3))); } @@ -303,11 +302,10 @@ namespace OpenRA.Mods.RA.Missions .Where(u => (u.Owner == allies1 || u.Owner == allies2) && ((u.HasTrait() && !u.HasTrait()) || u.HasTrait()) && u.IsInWorld && !u.IsDead() && (!u.HasTrait() || !u.Trait().Disguised || (u.Trait().Disguised && u.Trait().disguisedAsPlayer != soviets))); + var enemy = FirstUnshroudedOrDefault(enemies.OrderBy(u => (self.CenterLocation - u.CenterLocation).LengthSquared), world, 10); if (enemy != null) - { self.QueueActivity(new AttackMove.AttackMoveActivity(self, new Attack(Target.FromActor(enemy), 3))); - } } void ManageSovietUnits() @@ -319,27 +317,23 @@ namespace OpenRA.Mods.RA.Missions if (units.Count() >= SovietGroupSize) { foreach (var unit in units) - { AttackNearestAlliedActor(unit); - } } } + var scatteredUnits = world.Actors.Where(u => u.IsInWorld && !u.IsDead() && u.HasTrait() && u.IsIdle && u.Owner == soviets) .Except(world.WorldActor.Trait().Actors.Values) .Except(sovietRallyPoints.SelectMany(rp => world.FindAliveCombatantActorsInCircle(Util.CenterOfCell(rp), 10))); + foreach (var unit in scatteredUnits) - { AttackNearestAlliedActor(unit); - } } void SpawnAlliedUnit(string actor) { SpawnAndMove(actor, allies1, allies1EntryPoint.Location, allies1MovePoint.Location); - if (allies2 != allies1) - { + if (allies1 != allies2) SpawnAndMove(actor, allies2, allies2EntryPoint.Location, allies2MovePoint.Location); - } } Actor SpawnAndMove(string actor, Player owner, CPos entry, CPos to) @@ -369,22 +363,24 @@ namespace OpenRA.Mods.RA.Missions { var units = world.FindAliveCombatantActorsInBox(a, b) .Where(u => u.HasTrait() && !u.HasTrait() && (u.Owner == allies1 || u.Owner == allies2)); + foreach (var unit in units) { unit.CancelActivity(); unit.ChangeOwner(allies); unitsEvacuated++; + var createsShroud = unit.TraitOrDefault(); if (createsShroud != null && objectives[GapGeneratorID].Status == ObjectiveStatus.InProgress) { objectives[GapGeneratorID].Status = ObjectiveStatus.Completed; OnObjectivesUpdated(true); } + var cargo = unit.TraitOrDefault(); if (cargo != null) - { unitsEvacuated += cargo.Passengers.Count(); - } + UpdateUnitsEvacuated(); unit.QueueActivity(new Move.Move(exit)); unit.QueueActivity(new RemoveSelf()); @@ -449,13 +445,10 @@ namespace OpenRA.Mods.RA.Missions paradropBox = new Rectangle(topLeft.Location.X, topLeft.Location.Y, bottomRight.Location.X - topLeft.Location.X, bottomRight.Location.Y - topLeft.Location.Y); if (w.LocalPlayer == null || w.LocalPlayer == allies1) - { Game.MoveViewport(allies1EntryPoint.Location.ToFloat2()); - } + else - { Game.MoveViewport(allies2EntryPoint.Location.ToFloat2()); - } OnObjectivesUpdated(false); MissionUtils.PlayMissionMusic(); diff --git a/OpenRA.Mods.RA/Missions/Allies04Script.cs b/OpenRA.Mods.RA/Missions/Allies04Script.cs index 9ff6ea6a60..30ed34a795 100644 --- a/OpenRA.Mods.RA/Missions/Allies04Script.cs +++ b/OpenRA.Mods.RA/Missions/Allies04Script.cs @@ -104,18 +104,14 @@ namespace OpenRA.Mods.RA.Missions public void Tick(Actor self) { - if (allies1.WinState != WinState.Undefined) - { - return; - } + if (allies1.WinState != WinState.Undefined) return; + if (world.FrameNumber == 1) - { InsertSpies(); - } + if (world.FrameNumber == 25 * 25) - { SendHind(hind1EntryPoint, hind1Points, hind1ExitPoint); - } + if (frameInfiltrated != -1) { if (world.FrameNumber == frameInfiltrated + 100) @@ -131,10 +127,10 @@ namespace OpenRA.Mods.RA.Missions destroyBaseTimerWidget = new CountdownTimerWidget(destroyBaseTimer, "Secure lab in: {0}"); Ui.Root.AddChild(destroyBaseTimerWidget); } + if (world.FrameNumber >= frameInfiltrated + 200) - { destroyBaseTimer.Tick(); - } + if (world.FrameNumber == frameInfiltrated + 1500 * 12 && !bridgeTank.IsDead() && bridgeTank.IsInWorld && !bridge.IsDead()) { bridgeTank.QueueActivity(new Attack(Target.FromPos(bridge.CenterLocation), 4)); @@ -149,12 +145,14 @@ namespace OpenRA.Mods.RA.Missions attackingBridge = false; } } + foreach (var patrol in patrols) - { patrol.DoPatrol(); - } + ManageSovietOre(); + BaseGuardTick(); + if (allies1Spy.IsDead() || (allies2Spy != null && allies2Spy.IsDead())) { objectives[InfiltrateID].Status = ObjectiveStatus.Failed; @@ -162,9 +160,8 @@ namespace OpenRA.Mods.RA.Missions MissionFailed("{0} spy was killed.".F(allies1 != allies2 ? "A" : "The")); } else if (lab.Destroyed) - { MissionFailed("The Soviet research laboratory was destroyed."); - } + else if (!world.Actors.Any(a => (a.Owner == allies1 || a.Owner == allies2) && !a.IsDead() && (a.HasTrait() && !a.HasTrait()) || a.HasTrait())) { @@ -198,10 +195,7 @@ namespace OpenRA.Mods.RA.Missions void OnDestroyBaseTimerExpired(CountdownTimer t) { - if (SovietBaseDestroyed() && objectives[InfiltrateID].Status == ObjectiveStatus.Completed) - { - return; - } + if (SovietBaseDestroyed() && objectives[InfiltrateID].Status == ObjectiveStatus.Completed) return; objectives[DestroyID].Status = ObjectiveStatus.Failed; OnObjectivesUpdated(true); MissionFailed("The Soviet research laboratory was not secured in time."); @@ -211,34 +205,27 @@ namespace OpenRA.Mods.RA.Missions { var res = soviets.PlayerActor.Trait(); if (res.Ore > res.OreCapacity * 0.8) - { res.TakeOre(res.OreCapacity / 10); - } } void BaseGuardTick() { - if (baseGuardTicks <= 0 || baseGuard.IsDead() || !baseGuard.IsInWorld) - { - return; - } + if (baseGuardTicks <= 0 || baseGuard.IsDead() || !baseGuard.IsInWorld) return; + if (hijackTruck.Location == baseGuardTruckPos.Location) { if (--baseGuardTicks <= 0) - { baseGuard.QueueActivity(new Move.Move(baseGuardMovePos.Location)); - } } else - { baseGuardTicks = 100; - } } void OnLabInfiltrated(Actor spy) { if (spy == allies1Spy) allies1SpyInfiltratedLab = true; else if (spy == allies2Spy) allies2SpyInfiltratedLab = true; + if (allies1SpyInfiltratedLab && (allies2SpyInfiltratedLab || allies2Spy == null)) { objectives[InfiltrateID].Status = ObjectiveStatus.Completed; @@ -260,6 +247,7 @@ namespace OpenRA.Mods.RA.Missions { lst.Trait().Load(lst, world.CreateActor(false, "mcv", new TypeDictionary { new OwnerInit(allies2) })); } + lst.QueueActivity(new Move.Move(reinforcementsUnloadPoint.Location)); lst.QueueActivity(new Wait(10)); lst.QueueActivity(new CallFunc(() => @@ -294,10 +282,8 @@ namespace OpenRA.Mods.RA.Missions public void DoPatrol() { - if (actors.Any(a => a.IsDead() || !a.IsIdle || !a.IsInWorld)) - { - return; - } + if (actors.Any(a => a.IsDead() || !a.IsIdle || !a.IsInWorld)) return; + pointIndex = (pointIndex + 1) % points.Length; foreach (var actor in actors.Where(a => !a.IsDead() && a.IsInWorld)) { @@ -316,10 +302,10 @@ namespace OpenRA.Mods.RA.Missions new FacingInit(Util.GetFacing(points.First().ToCPos() - start, 0)), new AltitudeInit(Rules.Info["hind.autotarget"].Traits.Get().CruiseAltitude), }); + foreach (var point in points.Concat(new[] { Util.CenterOfCell(exit) })) - { hind.QueueActivity(new AttackMove.AttackMoveActivity(hind, new HeliFly(point))); - } + hind.QueueActivity(new RemoveSelf()); } @@ -330,6 +316,7 @@ namespace OpenRA.Mods.RA.Missions new OwnerInit(allies1), new LocationInit(lstEntryPoint.Location) }); + allies1Spy = world.CreateActor(false, "spy.strong", new TypeDictionary { new OwnerInit(allies1) }); lst.Trait().Load(lst, allies1Spy); if (allies1 != allies2) @@ -337,6 +324,7 @@ namespace OpenRA.Mods.RA.Missions allies2Spy = world.CreateActor(false, "spy.strong", new TypeDictionary { new OwnerInit(allies2) }); lst.Trait().Load(lst, allies2Spy); } + lst.QueueActivity(new Move.Move(lstUnloadPoint.Location)); lst.QueueActivity(new Wait(10)); lst.QueueActivity(new UnloadCargo(true)); @@ -348,9 +336,7 @@ namespace OpenRA.Mods.RA.Missions void SetupSubStances() { foreach (var actor in world.Actors.Where(a => a.IsInWorld && a.Owner == soviets && !a.IsDead() && a.HasTrait())) - { actor.Trait().stance = UnitStance.Defend; - } } public void WorldLoaded(World w) @@ -366,6 +352,7 @@ namespace OpenRA.Mods.RA.Missions { allies2 = allies1; } + soviets = w.Players.Single(p => p.InternalName == "Soviets"); neutral = w.Players.Single(p => p.InternalName == "Neutral"); objectives[InfiltrateID].Text = Infiltrate.F(allies1 != allies2 ? "spies" : "spy"); @@ -423,6 +410,7 @@ namespace OpenRA.Mods.RA.Missions hind1ExitPoint = actors["Hind1ExitPoint"].Location; reinforcementsEntryPoint = actors["ReinforcementsEntryPoint"]; reinforcementsUnloadPoint = actors["ReinforcementsUnloadPoint"]; + patrols = new[] { new Patrol(world, new[] { "e1", "e1", "e1", "e1", "e1" }, soviets, patrolPoints1, 0), @@ -474,9 +462,8 @@ namespace OpenRA.Mods.RA.Missions public void OnInfiltrate(Actor self, Actor spy) { if (self.Trait().IsEmpty(self)) - { self.ChangeOwner(spy.Owner); - } + self.Trait().Load(self, spy); } @@ -488,9 +475,7 @@ namespace OpenRA.Mods.RA.Missions self.ChangeOwner(OldOwner); } else if (self.Owner == passenger.Owner) - { self.ChangeOwner(self.Trait().Passengers.First().Owner); - } } } @@ -534,25 +519,16 @@ namespace OpenRA.Mods.RA.Missions class Allies04TrivialBuilding { } - class Allies04MaintainBuildingInfo : ITraitInfo + class Allies04MaintainBuildingInfo : TraitInfo { public readonly string Player = null; - - public object Create(ActorInitializer init) { return new Allies04MaintainBuilding(this); } } class Allies04MaintainBuilding : INotifyDamageStateChanged { - Allies04MaintainBuildingInfo info; - - public Allies04MaintainBuilding(Allies04MaintainBuildingInfo info) - { - this.info = info; - } - public void DamageStateChanged(Actor self, AttackInfo e) { - if (self.Owner.InternalName != info.Player) return; + if (self.Owner.InternalName != self.Info.Traits.Get().Player) return; if (self.HasTrait() && e.DamageState == DamageState.Critical && e.PreviousDamageState < DamageState.Critical) self.Trait().Sell(self); diff --git a/OpenRA.Mods.RA/Missions/CountdownTimer.cs b/OpenRA.Mods.RA/Missions/CountdownTimer.cs index 139ee83231..bfbd6ef054 100644 --- a/OpenRA.Mods.RA/Missions/CountdownTimer.cs +++ b/OpenRA.Mods.RA/Missions/CountdownTimer.cs @@ -14,7 +14,7 @@ namespace OpenRA.Mods.RA.Missions { public class CountdownTimer { - public int TicksLeft { get; set; } + public int TicksLeft; public event Action OnExpired = t => { }; public event Action OnOneMinuteRemaining = t => { }; @@ -47,22 +47,21 @@ namespace OpenRA.Mods.RA.Missions public void Tick() { - if (TicksLeft > 0) + if (TicksLeft <= 0) return; + + TicksLeft--; + switch (TicksLeft) { - TicksLeft--; - switch (TicksLeft) - { - case 1500 * 00: OnExpired(this); break; - case 1500 * 01: OnOneMinuteRemaining(this); break; - case 1500 * 02: OnTwoMinutesRemaining(this); break; - case 1500 * 03: OnThreeMinutesRemaining(this); break; - case 1500 * 04: OnFourMinutesRemaining(this); break; - case 1500 * 05: OnFiveMinutesRemaining(this); break; - case 1500 * 10: OnTenMinutesRemaining(this); break; - case 1500 * 20: OnTwentyMinutesRemaining(this); break; - case 1500 * 30: OnThirtyMinutesRemaining(this); break; - case 1500 * 40: OnFortyMinutesRemaining(this); break; - } + case 1500 * 00: OnExpired(this); break; + case 1500 * 01: OnOneMinuteRemaining(this); break; + case 1500 * 02: OnTwoMinutesRemaining(this); break; + case 1500 * 03: OnThreeMinutesRemaining(this); break; + case 1500 * 04: OnFourMinutesRemaining(this); break; + case 1500 * 05: OnFiveMinutesRemaining(this); break; + case 1500 * 10: OnTenMinutesRemaining(this); break; + case 1500 * 20: OnTwentyMinutesRemaining(this); break; + case 1500 * 30: OnThirtyMinutesRemaining(this); break; + case 1500 * 40: OnFortyMinutesRemaining(this); break; } } } diff --git a/OpenRA.Mods.RA/Missions/MissionWidgets.cs b/OpenRA.Mods.RA/Missions/MissionWidgets.cs index 2fd427e8ab..d5f49a9125 100644 --- a/OpenRA.Mods.RA/Missions/MissionWidgets.cs +++ b/OpenRA.Mods.RA/Missions/MissionWidgets.cs @@ -15,8 +15,8 @@ namespace OpenRA.Mods.RA.Missions { public class CountdownTimerWidget : Widget { - public CountdownTimer Timer { get; set; } - public string Format { get; set; } + public CountdownTimer Timer; + public string Format; public CountdownTimerWidget(CountdownTimer timer, string format) { @@ -26,10 +26,8 @@ namespace OpenRA.Mods.RA.Missions public override void Draw() { - if (!IsVisible()) - { - return; - } + if (!IsVisible()) return; + 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); @@ -39,19 +37,14 @@ namespace OpenRA.Mods.RA.Missions public class InfoWidget : Widget { - public string Text { get; set; } + public string Text; - public InfoWidget(string text) - { - Text = text; - } + public InfoWidget(string text) { Text = text; } public override void Draw() { - if (!IsVisible()) - { - return; - } + if (!IsVisible()) return; + var font = Game.Renderer.Fonts["Bold"]; var pos = new float2(Game.viewport.Width * 0.5f - font.Measure(Text).X / 2, Game.viewport.Height * 0.1f); font.DrawTextWithContrast(Text, pos, Color.White, Color.Black, 1); diff --git a/OpenRA.Mods.RA/Missions/Objective.cs b/OpenRA.Mods.RA/Missions/Objective.cs index 5a1fe70128..263858b571 100644 --- a/OpenRA.Mods.RA/Missions/Objective.cs +++ b/OpenRA.Mods.RA/Missions/Objective.cs @@ -8,7 +8,6 @@ */ #endregion -using System; using System.Collections.Generic; using OpenRA.Traits; @@ -16,9 +15,9 @@ namespace OpenRA.Mods.RA.Missions { public class Objective { - public ObjectiveType Type { get; set; } - public string Text { get; set; } - public ObjectiveStatus Status { get; set; } + public ObjectiveType Type; + public string Text; + public ObjectiveStatus Status; public Objective(ObjectiveType type, string text, ObjectiveStatus status) { diff --git a/OpenRA.Mods.RA/Missions/Soviet01ClassicScript.cs b/OpenRA.Mods.RA/Missions/Soviet01ClassicScript.cs index c067687fb2..f3cf682048 100644 --- a/OpenRA.Mods.RA/Missions/Soviet01ClassicScript.cs +++ b/OpenRA.Mods.RA/Missions/Soviet01ClassicScript.cs @@ -111,7 +111,9 @@ namespace OpenRA.Mods.RA.Missions new FacingInit(Util.GetFacing(airfield.Location - entry, 0)), new AltitudeInit(Rules.Info["yak"].Traits.Get().CruiseAltitude) }); + while (yak.Trait().TakeAmmo()) { } + yak.QueueActivity(new ReturnToBase(yak, airfield)); yak.QueueActivity(new ResupplyAircraft()); }