diff --git a/OpenRA.Mods.RA/Missions/DesertShellmapScript.cs b/OpenRA.Mods.RA/Missions/DesertShellmapScript.cs index 70ff420876..8d34c3df9b 100644 --- a/OpenRA.Mods.RA/Missions/DesertShellmapScript.cs +++ b/OpenRA.Mods.RA/Missions/DesertShellmapScript.cs @@ -10,7 +10,11 @@ using System.Collections.Generic; using System.Linq; +using OpenRA.FileFormats; +using OpenRA.Mods.RA.Activities; +using OpenRA.Mods.RA.Air; using OpenRA.Mods.RA.Move; +using OpenRA.Scripting; using OpenRA.Traits; namespace OpenRA.Mods.RA.Missions @@ -35,8 +39,8 @@ namespace OpenRA.Mods.RA.Missions int nextCivilianMove = 1; Actor attackLocation; - Actor coastRP1; - Actor coastRP2; + Actor coastWP1; + Actor coastWP2; int coastUnitsLeft; static readonly string[] CoastUnits = { "e1", "e1", "e2", "e3", "e4" }; @@ -49,26 +53,47 @@ namespace OpenRA.Mods.RA.Missions Actor offmapAttackerSpawn3; Actor[] offmapAttackerSpawns; static readonly string[] OffmapAttackers = { "ftrk", "apc", "ttnk", "1tnk" }; + static readonly string[] AttackerCargo = { "e1", "e2", "e3", "e4" }; + + static readonly string[] HeavyTanks = { "3tnk", "3tnk", "3tnk", "3tnk", "3tnk", "3tnk" }; + Actor heavyTankSpawn; + Actor heavyTankWP; + static readonly string[] MediumTanks = { "2tnk", "2tnk", "2tnk", "2tnk", "2tnk", "2tnk" }; + Actor mediumTankChronoSpawn; Dictionary mapActors; + Actor chronosphere; + Actor ironCurtain; + + CPos[] mig1Waypoints; + CPos[] mig2Waypoints; + public void Tick(Actor self) { if (world.FrameNumber % 100 == 0) { - var u = world.CreateActor(OffmapAttackers.Random(world.SharedRandom), soviets, offmapAttackerSpawns.Random(world.SharedRandom).Location, 128); + var actor = OffmapAttackers.Random(world.SharedRandom); + var spawn = offmapAttackerSpawns.Random(world.SharedRandom); + var u = world.CreateActor(actor, soviets, spawn.Location, Util.GetFacing(attackLocation.Location - spawn.Location, 0)); + var cargo = u.TraitOrDefault(); + if (cargo != null) + { + while (cargo.HasSpace(1)) + cargo.Load(u, world.CreateActor(false, AttackerCargo.Random(world.SharedRandom), soviets, null, null)); + } u.QueueActivity(new AttackMove.AttackMoveActivity(u, new Move.Move(attackLocation.Location, 0))); } if (world.FrameNumber % 25 == 0) - foreach (var actor in world.Actors.Where(a => a.IsInWorld && a.Owner == soviets && a.IsIdle && !a.IsDead() && a.HasTrait() && a.HasTrait()) - .Except(mapActors.Values)) - actor.QueueActivity(new AttackMove.AttackMoveActivity(actor, new Move.Move(attackLocation.Location, 0))); + foreach (var actor in world.Actors.Where(a => a.IsInWorld && a.IsIdle && !a.IsDead() + && a.HasTrait() && a.HasTrait()).Except(mapActors.Values)) + MissionUtils.AttackNearestLandActor(true, actor, actor.Owner == soviets ? allies : soviets); if (world.FrameNumber % 20 == 0 && coastUnitsLeft-- > 0) { - var u = world.CreateActor(CoastUnits.Random(world.SharedRandom), soviets, coastRP1.Location, null); - u.QueueActivity(new Move.Move(coastRP2.Location, 0)); + var u = world.CreateActor(CoastUnits.Random(world.SharedRandom), soviets, coastWP1.Location, null); + u.QueueActivity(new Move.Move(coastWP2.Location, 0)); u.QueueActivity(new AttackMove.AttackMoveActivity(u, new Move.Move(attackLocation.Location, 0))); } @@ -83,6 +108,9 @@ namespace OpenRA.Mods.RA.Missions } } + if (world.FrameNumber == 1) + MissionUtils.Paradrop(world, soviets, ParadropUnits, paradropEntry.Location, paradropLZ.Location); + if (--waitTicks <= 0) { if (++mul <= div) @@ -98,12 +126,58 @@ namespace OpenRA.Mods.RA.Missions coastUnitsLeft = 15; if (viewportTargetNumber == 1) MissionUtils.Paradrop(world, soviets, ParadropUnits, paradropEntry.Location, paradropLZ.Location); + if (viewportTargetNumber == 2) + { + AttackWithHeavyTanks(); + ChronoSpawnMediumTanks(); + } + if (viewportTargetNumber == 4) + { + FlyMigs(mig1Waypoints); + FlyMigs(mig2Waypoints); + } } } MissionUtils.CapOre(soviets); } + void AttackWithHeavyTanks() + { + foreach (var tank in HeavyTanks) + { + var u = world.CreateActor(tank, soviets, heavyTankSpawn.Location, Util.GetFacing(heavyTankWP.Location - heavyTankSpawn.Location, 0)); + u.QueueActivity(new AttackMove.AttackMoveActivity(u, new Move.Move(heavyTankWP.Location, 0))); + } + ironCurtain.Trait().Activate(ironCurtain, new Order { TargetLocation = heavyTankSpawn.Location }); + } + + void ChronoSpawnMediumTanks() + { + var chronoInfo = new List>(); + foreach (var tank in MediumTanks.Select((x, i) => new { x, i })) + { + var u = world.CreateActor(tank.x, allies, mediumTankChronoSpawn.Location, Util.GetFacing(heavyTankWP.Location - mediumTankChronoSpawn.Location, 0)); + chronoInfo.Add(Pair.New(u, new CPos(mediumTankChronoSpawn.Location.X + tank.i, mediumTankChronoSpawn.Location.Y))); + } + RASpecialPowers.Chronoshift(world, chronoInfo, chronosphere, -1, false); + foreach (var tank in chronoInfo) + tank.First.QueueActivity(new AttackMove.AttackMoveActivity(tank.First, new Move.Move(heavyTankSpawn.Location, 0))); + } + + void FlyMigs(CPos[] waypoints) + { + var m = world.CreateActor("mig", new TypeDictionary + { + new OwnerInit(soviets), + new LocationInit(waypoints[0]), + new FacingInit(Util.GetFacing(waypoints[1] - waypoints[0], 0)) + }); + foreach (var waypoint in waypoints) + m.QueueActivity(Fly.ToCell(waypoint)); + m.QueueActivity(new RemoveSelf()); + } + public void WorldLoaded(World w) { world = w; @@ -115,8 +189,8 @@ namespace OpenRA.Mods.RA.Missions mapActors = w.WorldActor.Trait().Actors; attackLocation = mapActors["AttackLocation"]; - coastRP1 = mapActors["CoastRP1"]; - coastRP2 = mapActors["CoastRP2"]; + coastWP1 = mapActors["CoastWP1"]; + coastWP2 = mapActors["CoastWP2"]; paradropLZ = mapActors["ParadropLZ"]; paradropEntry = mapActors["ParadropEntry"]; @@ -132,6 +206,16 @@ namespace OpenRA.Mods.RA.Missions offmapAttackerSpawn3 = mapActors["OffmapAttackerSpawn3"]; offmapAttackerSpawns = new[] { offmapAttackerSpawn1, offmapAttackerSpawn2, offmapAttackerSpawn3 }; + heavyTankSpawn = mapActors["HeavyTankSpawn"]; + heavyTankWP = mapActors["HeavyTankWP"]; + mediumTankChronoSpawn = mapActors["MediumTankChronoSpawn"]; + + chronosphere = mapActors["Chronosphere"]; + ironCurtain = mapActors["IronCurtain"]; + + mig1Waypoints = new[] { mapActors["Mig11"], mapActors["Mig12"], mapActors["Mig13"], mapActors["Mig14"] }.Select(a => a.Location).ToArray(); + mig2Waypoints = new[] { mapActors["Mig21"], mapActors["Mig22"], mapActors["Mig23"], mapActors["Mig24"] }.Select(a => a.Location).ToArray(); + foreach (var actor in mapActors.Values.Where(a => a.Owner == allies || a.HasTrait())) { if (actor.Owner == allies && actor.HasTrait()) @@ -144,8 +228,18 @@ namespace OpenRA.Mods.RA.Missions viewportTarget = viewportTargets[1]; Game.viewport.Center(viewportOrigin); Sound.SoundVolumeModifier = 0.25f; + } + } - MissionUtils.Paradrop(world, soviets, ParadropUnits, paradropEntry.Location, paradropLZ.Location); + class DesertShellmapAutoUnloadInfo : TraitInfo, Requires { } + + class DesertShellmapAutoUnload : INotifyDamage + { + public void Damaged(Actor self, AttackInfo e) + { + var cargo = self.Trait(); + if (!cargo.IsEmpty(self) && !(self.GetCurrentActivity() is UnloadCargo)) + self.QueueActivity(false, new UnloadCargo(true)); } } } diff --git a/mods/ra/maps/desert-shellmap/map.bin b/mods/ra/maps/desert-shellmap/map.bin index 1687d864ff..9b1aa33b14 100644 Binary files a/mods/ra/maps/desert-shellmap/map.bin and b/mods/ra/maps/desert-shellmap/map.bin differ diff --git a/mods/ra/maps/desert-shellmap/map.yaml b/mods/ra/maps/desert-shellmap/map.yaml index afec2a3181..9ccc1dbd04 100644 --- a/mods/ra/maps/desert-shellmap/map.yaml +++ b/mods/ra/maps/desert-shellmap/map.yaml @@ -200,9 +200,6 @@ Actors: Actor50: apwr Location: 51,14 Owner: Soviets - Actor53: truk - Location: 55,43 - Owner: Neutral Actor153: apwr Location: 87,84 Owner: Allies @@ -342,10 +339,10 @@ Actors: AttackLocation: waypoint Location: 55,61 Owner: Neutral - CoastRP1: waypoint + CoastWP1: waypoint Location: 1,79 Owner: Neutral - CoastRP2: waypoint + CoastWP2: waypoint Location: 36,81 Owner: Neutral Actor64: e1 @@ -411,7 +408,7 @@ Actors: Actor115: tsla Location: 40,24 Owner: Soviets - Actor107: iron + IronCurtain: iron Location: 110,40 Owner: Soviets Actor117: fix @@ -525,10 +522,10 @@ Actors: Location: 84,84 Owner: Allies ParadropEntry: waypoint - Location: 60,126 + Location: 62,126 Owner: Neutral ParadropLZ: waypoint - Location: 60,88 + Location: 62,86 Owner: Neutral Actor149: pbox.e1 Location: 67,84 @@ -590,7 +587,7 @@ Actors: Location: 77,70 Owner: Allies Facing: 20 - Actor158: pdox + Chronosphere: pdox Location: 78,91 Owner: Allies Actor159: tent @@ -748,6 +745,81 @@ Actors: OffmapAttackerSpawn3: waypoint Location: 1,50 Owner: Neutral + Actor213: 2tnk + Location: 79,70 + Owner: Allies + Facing: 0 + Actor214: 2tnk + Location: 80,70 + Owner: Allies + Facing: 0 + HeavyTankWP: waypoint + Location: 79,69 + Owner: Neutral + Actor221: powr + Location: 74,84 + Owner: Allies + Actor215: 2tnk + Location: 82,71 + Owner: Allies + Facing: 0 + HeavyTankSpawn: waypoint + Location: 80,50 + Owner: Neutral + Actor216: arty + Location: 74,71 + Owner: Allies + Facing: 0 + MediumTankChronoSpawn: waypoint + Location: 80,60 + Owner: Neutral + Actor220: powr + Location: 76,84 + Owner: Allies + Actor219: gun + Location: 85,70 + Owner: Allies + Actor53: gap + Location: 76,71 + Owner: Allies + Mig11: waypoint + Location: 94,1 + Owner: Neutral + Mig12: waypoint + Location: 68,33 + Owner: Neutral + Mig22: waypoint + Location: 70,35 + Owner: Neutral + Mig13: waypoint + Location: 41,38 + Owner: Neutral + Mig14: waypoint + Location: 1,26 + Owner: Neutral + Mig23: waypoint + Location: 41,40 + Owner: Neutral + Mig24: waypoint + Location: 1,28 + Owner: Neutral + Actor227: 2tnk + Location: 45,62 + Owner: Allies + Facing: 0 + Actor230: e1 + Location: 64,63 + Owner: Allies + Actor229: e1 + Location: 47,62 + Owner: Allies + Actor228: 2tnk + Location: 65,63 + Owner: Allies + Facing: 0 + Mig21: waypoint + Location: 96,3 + Owner: Neutral Smudges: @@ -780,12 +852,19 @@ Rules: Weapon: Dragon Turreted: AttackTurreted: + APC: + DesertShellmapAutoUnload: + MIG: + Plane: + Speed: 30 Sequences: Weapons: 8Inch: Report: tank6 + 2Inch: + Range: 10 Voices: