diff --git a/OpenRA.Mods.RA/Missions/FortScript.cs b/OpenRA.Mods.RA/Missions/FortScript.cs index 9ed070dff6..0e310707ee 100644 --- a/OpenRA.Mods.RA/Missions/FortScript.cs +++ b/OpenRA.Mods.RA/Missions/FortScript.cs @@ -35,23 +35,23 @@ namespace OpenRA.Mods.RA.Missions Actor paradrop2; Actor paradrop3; Actor paradrop4; - - Actor baseA; - Actor baseB; - + Actor patrol1; + Actor patrol2; + Actor patrol3; + Actor patrol4; World world; int WaveNumber = 0; InfoWidget evacuateWidget; const string ShortEvacuateTemplate = "Wave {0}"; - static readonly string[] PatrolA = { "e1", "e2", "e1" }; + static readonly string[] Patrol = { "e1", "e2", "e1" }; static readonly string[] Infantry = { "e4", "e1", "e1", "e2", "e1", "e2" }; - static readonly string[] InfantryAdvanced = { "e4", "e1", "e1", "shok", "e1", "e2", "e4" }; - static readonly string[] Vehicles = { "arty", "ftrk", "ftrk", "jeep", "jeep", "jeep", "apc", "apc", }; - static readonly string[] Volkov = { "e8" }; + static readonly string[] Vehicles = { "arty", "ftrk", "ftrk", "apc", "apc", }; + const string tank = "3tnk"; + const string v2 = "v2rl"; const string boss = "4tnk"; + const int TimerTicks = 1; - const int PatrolTicks = 1500; int AttackSquad = 6; int AttackSquadCount = 1; @@ -87,14 +87,16 @@ namespace OpenRA.Mods.RA.Missions { for (int i = 1; i <= VehicleSquadCount; i++) { - var enemies = world.Actors.Where(u => u.IsInWorld && !u.IsDead() && (u.Owner == soviets) - && !u.HasTrait()); var route = world.SharedRandom.Next(sovietEntryPoints.Length); var spawnPoint = sovietEntryPoints[route]; for (int r = 1; r <= VehicleSquad; r++) { var squad = world.CreateActor(Vehicles.Random(world.SharedRandom), - new TypeDictionary { new LocationInit(spawnPoint), new OwnerInit(soviets) }); + new TypeDictionary + { + new LocationInit(spawnPoint), + new OwnerInit(soviets) + }); squad.QueueActivity(new AttackMove.AttackMoveActivity(squad, new Move.Move(paradrop1.Location, 3))); } } @@ -107,23 +109,18 @@ namespace OpenRA.Mods.RA.Missions { for (int i = 1; i <= AttackSquadCount; i++) { - var enemies = world.Actors.Where(u => u.IsInWorld && !u.IsDead() && (u.Owner == soviets) + world.Actors.Where(u => u.IsInWorld && !u.IsDead() && (u.Owner == soviets) && !u.HasTrait()); var route = world.SharedRandom.Next(sovietEntryPoints.Length); var spawnPoint = sovietEntryPoints[route]; - IEnumerable units; - if (world.FrameNumber >= 1500 * 10) - { - units = InfantryAdvanced; - } - else - { - units = Infantry; - } for (int r = 1; r < AttackSquad; r++) { var squad = world.CreateActor(Infantry.Random(world.SharedRandom), - new TypeDictionary { new LocationInit(spawnPoint), new OwnerInit(soviets) }); + new TypeDictionary + { + new LocationInit(spawnPoint), + new OwnerInit(soviets) + }); squad.QueueActivity(new AttackMove.AttackMoveActivity(squad, new Move.Move(paradrop1.Location, 3))); var scatteredUnits = world.FindAliveCombatantActorsInCircle(Util.CenterOfCell(paradrop1.Location), 15) .Where(unit => unit.IsIdle && unit.HasTrait() && unit.Owner == soviets); @@ -136,75 +133,35 @@ namespace OpenRA.Mods.RA.Missions } } - void SendPatrol() + void SendPatrol(string[] squad, Player owner, CPos location, CPos move) { - if (SpawnPatrol == true) + if (SpawnPatrol) { - for (int i = 0; i < PatrolA.Length; i++) + for (int i = 0; i < squad.Length; i++) { - var inf = world.CreateActor(PatrolA.Random(world.SharedRandom), - new TypeDictionary { new LocationInit(paradrop1.Location + new CVec(0, -10)), new OwnerInit(soviets) }); - inf.QueueActivity(new AttackMove.AttackMoveActivity(inf, new Move.Move(paradrop1.Location + new CVec(0, 0)))); - var units = world.FindAliveCombatantActorsInCircle(Util.CenterOfCell(paradrop1.Location), 20) - .Where(u => u.Owner == soviets); - foreach (var unit in units) - { - AttackNearestAlliedActor(unit); - } - } - for (int i = 0; i < PatrolA.Length; i++) - { - var inf = world.CreateActor(PatrolA.Random(world.SharedRandom), - new TypeDictionary { new LocationInit(paradrop4.Location + new CVec(10, 0)), new OwnerInit(soviets) }); - inf.QueueActivity(new AttackMove.AttackMoveActivity(inf, new Move.Move(paradrop4.Location + new CVec(0, 0)))); - var units = world.FindAliveCombatantActorsInCircle(Util.CenterOfCell(paradrop1.Location), 20) - .Where(u => u.Owner == soviets); - foreach (var unit in units) - { - AttackNearestAlliedActor(unit); - } - } - for (int i = 0; i < PatrolA.Length; i++) - { - var inf = world.CreateActor(PatrolA.Random(world.SharedRandom), - new TypeDictionary { new LocationInit(paradrop3.Location + new CVec(0, 10)), new OwnerInit(soviets) }); - inf.QueueActivity(new AttackMove.AttackMoveActivity(inf, new Move.Move(paradrop3.Location + new CVec(0, 0)))); - var units = world.FindAliveCombatantActorsInCircle(Util.CenterOfCell(paradrop1.Location), 20) - .Where(u => u.Owner == soviets); - foreach (var unit in units) - { - AttackNearestAlliedActor(unit); - } - } - for (int i = 0; i < PatrolA.Length; i++) - { - var inf = world.CreateActor(PatrolA.Random(world.SharedRandom), - new TypeDictionary { new LocationInit(paradrop2.Location + new CVec(-10, 0)), new OwnerInit(soviets) }); - inf.QueueActivity(new AttackMove.AttackMoveActivity(inf, new Move.Move(paradrop2.Location + new CVec(0, 0)))); - var units = world.FindAliveCombatantActorsInCircle(Util.CenterOfCell(paradrop1.Location), 20) - .Where(u => u.Owner == soviets); - foreach (var unit in units) - { - AttackNearestAlliedActor(unit); - } + var actor = world.CreateActor(squad[i], new TypeDictionary + { + new OwnerInit(owner), + new LocationInit(location) + }); + actor.QueueActivity(new AttackMove.AttackMoveActivity(actor, new Move.Move(move, 3))); + AttackNearestAlliedActor(actor); } } } - void SendVolkov() + void SendBoss(string unit) { - for (int i = 0; i < Volkov.Length; i++) + var route = world.SharedRandom.Next(sovietEntryPoints.Length); + var spawnPoint = sovietEntryPoints[route]; + var actor = world.CreateActor(unit, new TypeDictionary + { + new OwnerInit(soviets), + new LocationInit(spawnPoint) + }); + if (multi0 != null) { - var route = world.SharedRandom.Next(sovietEntryPoints.Length); - var spawnPoint = sovietEntryPoints[route]; - var actor = world.CreateActor(Volkov[i], new TypeDictionary { new OwnerInit(soviets), new LocationInit(spawnPoint) }); - actor.QueueActivity(new Move.Move(paradrop1.Location + new CVec(4, -11))); - var scatteredUnits = world.FindAliveCombatantActorsInCircle(Util.CenterOfCell(paradrop1.Location + new CVec(4, -11)), 4) - .Where(unit => unit.IsIdle && unit.HasTrait() && unit.Owner == soviets); - foreach (var unit in scatteredUnits) - { - AttackNearestAlliedActor(unit); - } + AttackNearestAlliedActor(actor); } } @@ -213,23 +170,16 @@ namespace OpenRA.Mods.RA.Missions Game.AddChatLine(Color.Cyan, "Wave Sequence", text); } - void FinalWave(string text) - { - Game.AddChatLine(Color.DarkRed, "Boss Wave Sequence Initializing", text); - } - public void Tick(Actor self) { - var unitsAndBuildings = world.Actors.Where(a => !a.IsDead() && a.IsInWorld && (a.HasTrait() && a.HasTrait())); - if (!unitsAndBuildings.Any(a => a.Owner == soviets)) - { - MissionAccomplished("You and your mates have survived the onslaught!"); - } if (world.FrameNumber == patrolAttackFrame) { patrolAttackFrame += patrolattackAtFrameIncrement; patrolattackAtFrameIncrement = Math.Max(patrolattackAtFrameIncrement - 5, 100); - SendPatrol(); + SendPatrol(Patrol, soviets, patrol1.Location, paradrop1.Location); + SendPatrol(Patrol, soviets, patrol2.Location, paradrop2.Location); + SendPatrol(Patrol, soviets, patrol3.Location, paradrop3.Location); + SendPatrol(Patrol, soviets, patrol4.Location, paradrop4.Location); } if (world.FrameNumber == WaveAttackFrame) { @@ -286,11 +236,11 @@ namespace OpenRA.Mods.RA.Missions Wave("Five Initializing"); UpdateWaveSequence(); AttackSquad = 10; - SendVolkov(); VehicleSquad = 4; VehicleSquadCount = 2; + SendBoss(tank); } - if (world.FrameNumber == 1500 * 10) + if (world.FrameNumber == 1500 * 11) { WaveNumber++; Wave("Six Initializing"); @@ -301,8 +251,10 @@ namespace OpenRA.Mods.RA.Missions MissionUtils.Parabomb(world, soviets, entry4.Location, paradrop1.Location); MissionUtils.Parabomb(world, soviets, entry6.Location, paradrop3.Location); MissionUtils.Parabomb(world, soviets, entry5.Location, paradrop3.Location); + SendBoss(tank); + SendBoss(tank); } - if (world.FrameNumber == 1500 * 12) + if (world.FrameNumber == 1500 * 14) { WaveNumber++; Wave("Seven Initializing"); @@ -310,9 +262,9 @@ namespace OpenRA.Mods.RA.Missions AttackSquad = 12; VehicleSquad = 5; VehicleSquadCount = 3; - SendVolkov(); + SendBoss(v2); } - if (world.FrameNumber == 1500 * 14) + if (world.FrameNumber == 1500 * 17) { SpawnVehicles = true; WaveNumber++; @@ -326,8 +278,11 @@ namespace OpenRA.Mods.RA.Missions MissionUtils.Parabomb(world, soviets, entry5.Location, paradrop3.Location); MissionUtils.Parabomb(world, soviets, entry2.Location, paradrop2.Location); MissionUtils.Parabomb(world, soviets, entry3.Location, paradrop2.Location); + SendBoss(v2); + SendBoss(tank); + SendBoss(v2); } - if (world.FrameNumber == 1500 * 16) + if (world.FrameNumber == 1500 * 21) { WaveNumber++; Wave("Nine Initializing"); @@ -335,30 +290,36 @@ namespace OpenRA.Mods.RA.Missions AttackSquad = 14; VehicleSquad = 6; VehicleSquadCount = 4; - SendVolkov(); + SendBoss(v2); + SendBoss(tank); + SendBoss(tank); } - if (world.FrameNumber == 1500 * 18) + if (world.FrameNumber == 1500 * 25) { WaveNumber++; Wave("Ten Initializing"); UpdateWaveSequence(); AttackSquad = 15; AttackSquadCount = 6; - MissionUtils.Parabomb(world, soviets, entry1.Location, paradrop1.Location + new CVec(0, -2)); - MissionUtils.Parabomb(world, soviets, entry2.Location, paradrop3.Location + new CVec(0, -2)); - MissionUtils.Parabomb(world, soviets, entry4.Location, paradrop2.Location + new CVec(0, -2)); - MissionUtils.Parabomb(world, soviets, entry5.Location, paradrop4.Location + new CVec(0, -2)); - MissionUtils.Parabomb(world, soviets, entry2.Location, paradrop1.Location + new CVec(0, 2)); - MissionUtils.Parabomb(world, soviets, entry4.Location, paradrop3.Location + new CVec(0, 2)); - MissionUtils.Parabomb(world, soviets, entry3.Location, paradrop2.Location + new CVec(0, 2)); - MissionUtils.Parabomb(world, soviets, entry5.Location, paradrop4.Location + new CVec(0, 2)); + for (int i = 0; i < 2; i++) + { + MissionUtils.Parabomb(world, soviets, entry1.Location, paradrop1.Location + new CVec(0, -2)); + MissionUtils.Parabomb(world, soviets, entry2.Location, paradrop3.Location + new CVec(0, -2)); + MissionUtils.Parabomb(world, soviets, entry4.Location, paradrop2.Location + new CVec(0, -2)); + MissionUtils.Parabomb(world, soviets, entry5.Location, paradrop4.Location + new CVec(0, -2)); + MissionUtils.Parabomb(world, soviets, entry2.Location, paradrop1.Location + new CVec(0, 2)); + MissionUtils.Parabomb(world, soviets, entry4.Location, paradrop3.Location + new CVec(0, 2)); + MissionUtils.Parabomb(world, soviets, entry3.Location, paradrop2.Location + new CVec(0, 2)); + MissionUtils.Parabomb(world, soviets, entry5.Location, paradrop4.Location + new CVec(0, 2)); + } + SendBoss(boss); } - if (world.FrameNumber == 1500 * 19) + if (world.FrameNumber == 1500 * 30) { SpawnWave = false; SpawnVehicles = false; } - if (world.FrameNumber == 1500 * 20) + if (world.FrameNumber == 1500 * 31) { MissionAccomplished("You and your mates have Survived the Onslaught!"); } @@ -400,8 +361,10 @@ namespace OpenRA.Mods.RA.Missions paradrop2 = actors["Paradrop2"]; paradrop3 = actors["Paradrop3"]; paradrop4 = actors["Paradrop4"]; - baseA = actors["BaseA"]; - baseB = actors["BaseB"]; + patrol1 = actors["Patrol1"]; + patrol2 = actors["Patrol2"]; + patrol3 = actors["Patrol3"]; + patrol4 = actors["Patrol4"]; MissionUtils.PlayMissionMusic(); Game.AddChatLine(Color.Cyan, "Mission", "Defend Fort LoneStar At All costs!"); } diff --git a/mods/ra/maps/Fort-Lonestar/map.yaml b/mods/ra/maps/Fort-Lonestar/map.yaml index 75e8ede1ef..f6fac8e0e6 100644 --- a/mods/ra/maps/Fort-Lonestar/map.yaml +++ b/mods/ra/maps/Fort-Lonestar/map.yaml @@ -55,7 +55,7 @@ Players: PlayerReference@Soviets: Name: Soviets Race: soviet - ColorRamp: 0,255,128,10 + ColorRamp: 0,255,128 Enemies: Multi0,Multi1,Multi2,Multi3 Actors: @@ -392,32 +392,20 @@ Actors: Paradrop4: waypoint Location: 36,32 Owner: Neutral - Rally1: waypoint - Location: 25,17 + Patrol3: waypoint + Location: 32,46 Owner: Neutral - Rally2: waypoint - Location: 38,17 - Owner: Neutral - Rally3: waypoint - Location: 16,31 - Owner: Neutral - Rally4: waypoint - Location: 24,47 - Owner: Neutral - Rally5: waypoint - Location: 37,47 - Owner: Neutral - Rally6: waypoint - Location: 47,32 + Patrol4: waypoint + Location: 46,32 Owner: Neutral Actor20: apwr Location: 37,4 Owner: Soviets - BaseA: waypoint - Location: 24,24 + Patrol2: waypoint + Location: 17,32 Owner: Neutral - BaseB: waypoint - Location: 40,40 + Patrol1: waypoint + Location: 32,18 Owner: Neutral Actor34: sniper Location: 9,26 @@ -741,41 +729,45 @@ Rules: Prerequisites: barr,oilb Valued: Cost: 750 - E8: - Inherits: ^Infantry + 3TNK: + Inherits: ^Tank Buildable: - Queue: Infantry - BuildPaletteOrder: 110 - Prerequisites: stek - Owner: None + Queue: Vehicle + BuildPaletteOrder: 40 + Prerequisites: fix + Owner: soviet + Hotkey: h Valued: - Cost: 1800 - Tooltip: - Name: Volkov - Description: Elite commando infantry, armed with \nmodular cannons and grenade launcher.\n Strong vs Vehicles, Infantry\n Weak vs Aircraft - Selectable: - Voice: VolkovVoice - Bounds: 12,17,0,-9 + Cost: 1150 + Health: - HP: 200 + HP: 700 Armor: Type: Heavy Mobile: Speed: 5 + Crushes: wall, atmine, crate, infantry RevealsShroud: Range: 7 - Passenger: - PipType: Red - AttackFrontal: - PrimaryWeapon: VolkNapalm + Turreted: + ROT: 5 + Armament: + Weapon: VolkNapalm + Recoil: 200 + RecoilRecovery: 38 + LocalOffset: 0,85,0, 0,-85,0 + AttackTurreted: + RenderUnit: + WithTurret: + AutoTarget: Explodes: Weapon: UnitExplodeSmall + EmptyWeapon: UnitExplodeSmall Chance: 100 - TakeCover: - -RenderInfantry: - RenderInfantryProne: - IdleAnimations: idle1 - -CrushableInfantry: + LeavesHusk: + HuskActor: 3TNK.Husk + Selectable: + Bounds: 30,30 MECH: Buildable: Owner: None @@ -789,14 +781,32 @@ Rules: Buildable: Owner: soviet,allies Prerequisites: barr,oilb - Valued: - Cost: 120 - SNIPER: - Buildable: - Owner: allies,soviet - Prerequisites: barr,oilb Valued: Cost: 150 + SNIPER: + Inherits: ^Infantry + Valued: + Cost: 300 + Buildable: + Queue: Infantry + BuildPaletteOrder: 80 + Owner: soviet + Prerequisites: barr,oilb + Hotkey: n + Selectable: + Bounds: 12,17,0,-6 + Mobile: + Speed: 4 + Health: + HP: 200 + Passenger: + PipType: Red + RevealsShroud: + Range: 6 + AutoTarget: + InitialStance: HoldFire + Armament: + Weapon: Sniper SPY: Inherits: ^Infantry Buildable: @@ -806,9 +816,6 @@ Rules: Owner: allies, soviets Valued: Cost: 300 - SpyToolTip: - Name: Spy - Description: Infiltrates enemy structures to gather \nintelligence. Exact effect depends on the \nbuilding infiltrated.\n Strong vs Nothing\n Weak vs Everything\n Special Ability: Disguised Selectable: Voice: SpyVoice Bounds: 12,17,0,-9 @@ -830,6 +837,56 @@ Rules: IdleAnimations: idle1,idle2 AttackFrontal: PrimaryWeapon: SilencedPPK + FTRK: + Inherits: ^Vehicle + Valued: + Cost: 600 + Health: + HP: 150 + Armor: + Type: Light + Mobile: + ROT: 10 + Speed: 9 + RevealsShroud: + Range: 4 + Turreted: + ROT: 5 + Offset: -298,0,298 + Armament: + Weapon: FLAK-23 + Recoil: 85 + AttackTurreted: + RenderUnit: + WithTurret: + AutoTarget: + Explodes: + Weapon: UnitExplodeSmall + EmptyWeapon: UnitExplodeSmall + Selectable: + Bounds: 28,28,0,0 + APC: + Inherits: ^Tank + Health: + HP: 400 + Armor: + Type: Heavy + Mobile: + Speed: 10 + RevealsShroud: + Range: 5 + Armament: + Weapon: M60mg + LocalOffset: 0,0,171 + AttackFrontal: + RenderUnit: + WithMuzzleFlash: + AutoTarget: + Cargo: + Types: Infantry + MaxWeight: 5 + PipCount: 5 + UnloadFacing: 220 ARTY: Inherits: ^Tank Buildable: @@ -859,25 +916,35 @@ Rules: Weapon: UnitExplode Chance: 50 AutoTarget: + V2RL: + Inherits: ^Vehicle + Valued: + Cost: 700 + Health: + HP: 150 + Armor: + Type: Light + Mobile: + Speed: 7 + RevealsShroud: + Range: 5 + Armament: + Weapon: SCUD + AttackFrontal: + RenderUnitReload: + AutoTarget: + Explodes: + Weapon: SCUD + EmptyWeapon: 4TNK: Inherits: ^Tank Buildable: - Queue: Vehicle - BuildPaletteOrder: 100 - Prerequisites: fix,stek - Owner: soviet - Valued: - Cost: 1800 - Tooltip: - Name: Mammoth Tank - Description: Big and slow tank, with anti-air capability.\n Strong vs Tanks, Aircraft\n Weak vs Infantry Health: - HP: 5000 + HP: 2500 Armor: Type: Heavy Mobile: Speed: 4 - Crushes: wall, atmine, crate, infantry RevealsShroud: Range: 14 Turreted: @@ -890,7 +957,8 @@ Rules: PrimaryRecoil: 8 PrimaryRecoilRecovery: 0.7 SecondaryRecoil: 2 - RenderUnitTurreted: + RenderUnit: + WithTurret: AutoTarget: Explodes: Weapon: napalm @@ -900,7 +968,7 @@ Rules: SelfHealing: Step: 2 Ticks: 1 - HealIfBelow: 80% + HealIfBelow: 40% DamageCooldown: 150 Selectable: Bounds: 44,38,0,-4 @@ -940,20 +1008,10 @@ Rules: -GainsExperience: Tooltip: Name: Badger - Contrail@1: - ContrailOffset: 11, -11 - Contrail@2: - ContrailOffset: -11, -11 FallsToEarth: Spins: no Moves: yes Explosion: UnitExplode - SmokeTrailWhenDamaged@0: - Offset: 11, -11 - Interval: 2 - SmokeTrailWhenDamaged@1: - Offset: -11, -11 - Interval: 2 -EjectOnDeath: -GpsDot: @@ -996,18 +1054,18 @@ Weapons: Shadow: false Proximity: true Trail: smokey - ContrailLength: 10 + ContrailLength: 150 Inaccuracy: 20 Image: DRAGON ROT: 10 RangeLimit: 80 Warhead: - Spread: 12 + Spread: 15 Versus: - None: 90% - Wood: 150% - Light: 150% - Heavy: 150% + None: 125% + Wood: 110% + Light: 110% + Heavy: 100% Concrete: 200% Explosion: nuke WaterExplosion: nuke @@ -1016,7 +1074,7 @@ Weapons: Damage: 250 VolkNapalm: ROF: 40 - Range: 7 + Range: 8 Report: volknapalm ValidTargets: Ground Burst: 6 @@ -1077,17 +1135,64 @@ Weapons: Warhead: Spread: 10 Versus: - None: 100% + None: 80% Wood: 100% Light: 60% - Heavy: 25% + Heavy: 75% Concrete: 35% Explosion: small_napalm WaterExplosion: small_napalm InfDeath: 5 SmudgeType: Scorch ImpactSound: firebl3 - Damage: 6 + Damage: 10 + FLAK-23: + ROF: 10 + Range: 8 + Report: AACANON3 + ValidTargets: Air,Ground + Projectile: Bullet + Speed: 100 + High: true + Warhead: + Spread: 5 + Versus: + None: 35% + Wood: 30% + Light: 30% + Heavy: 40% + Concrete: 30% + Explosion: med_explosion + Damage: 25 + SCUD: + ROF: 280 + Range: 10 + MinRange: 3 + Report: MISSILE1 + Projectile: Bullet + Speed: 10 + Arm: 10 + High: true + Shadow: false + Proximity: true + Trail: smokey + Inaccuracy: 10 + Image: V2 + Angle: .1 + Warhead: + Spread: 20 + Versus: + None: 100% + Wood: 90% + Light: 80% + Heavy: 70% + Explosion: nuke + WaterExplosion: large_splash + InfDeath: 3 + SmudgeType: Crater + Damage: 500 + ImpactSound: kaboom1 + WaterImpactSound: kaboom1 SilencedPPK: ROF: 80 Range: 2.5