Initial commit: OpenRA game engine
Fork from OpenRA/OpenRA with one-click launch script (start-ra.cmd) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
374
mods/ra/maps/production-disruption/production-disruption.lua
Normal file
374
mods/ra/maps/production-disruption/production-disruption.lua
Normal file
@@ -0,0 +1,374 @@
|
||||
--[[
|
||||
Copyright (c) The OpenRA Developers and Contributors
|
||||
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, either version 3 of
|
||||
the License, or (at your option) any later version. For more
|
||||
information, see COPYING.
|
||||
]]
|
||||
FlameWallRevealed = false
|
||||
TimerTicks = DateTime.Minutes(12)
|
||||
LSTType = "lst.reinforcement"
|
||||
RifleSquad1 = { Rifle1, Rifle2, Rifle3 }
|
||||
RifleSquad2 = { Rifle4, Rifle5, Rifle6 }
|
||||
Heavys = { Heavy1, Heavy2 }
|
||||
FlameTowerWall = { FlameTower1, FlameTower2 }
|
||||
DemoEngiPath = { WaterEntry1.Location, Beach1.Location }
|
||||
DemoEngiTeam = { "dtrk", "dtrk", "e6", "e6", "e6" }
|
||||
SovietWaterEntry1 = { WaterEntry2.Location, Beach2.Location }
|
||||
SovietWaterEntry2 = { WaterEntry2.Location, Beach3.Location }
|
||||
SovietSquad = { "e1", "e1", "e2", "e4", "e4" }
|
||||
V2Squad = { "v2rl", "v2rl" }
|
||||
SubEscapePath = { SubPath1, SubPath2, SubPath3 }
|
||||
|
||||
MissionStart = function()
|
||||
if Difficulty == "normal" then
|
||||
local northCoil = Actor.Create("tsla", true, { Owner = USSR, Location = EasyCamera.Location })
|
||||
Actor.Create("4tnk", true, { Owner = USSR, Facing = Angle.South, Location = Mammoth.Location })
|
||||
Actor.Create("4tnk", true, { Owner = USSR, Facing = Angle.South, Location = Mammoth.Location + CVec.New(1,0) })
|
||||
Actor.Create("v2rl", true, { Owner = USSR, Facing = Angle.South, Location = V2.Location })
|
||||
-- Avoid leaving infantry stranded on the island.
|
||||
northCoil.GrantCondition("no-actors-on-sell")
|
||||
end
|
||||
|
||||
SpawnTemporaryCamera(SouthLZ.Location, DateTime.Seconds(15))
|
||||
Chalk1.TargetParatroopers(SouthLZ.CenterPosition, Angle.New(740))
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(1), function()
|
||||
Chalk2.TargetParatroopers(SouthLZ.CenterPosition, Angle.New(780))
|
||||
end)
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(5), function()
|
||||
UnitsArrived = true
|
||||
SpawnTemporaryCamera(TeslaCam.Location, DateTime.Seconds(10))
|
||||
end)
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(10), function()
|
||||
Utils.Do(RifleSquad1, function(actor)
|
||||
if not actor.IsDead then
|
||||
actor.AttackMove(SouthLZ.Location)
|
||||
IdleHunt(actor)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(15), function()
|
||||
Utils.Do(RifleSquad2, function(actor)
|
||||
if not actor.IsDead then
|
||||
actor.AttackMove(SouthLZ.Location)
|
||||
IdleHunt(actor)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
SetupTriggers = function()
|
||||
SetupFlameWall()
|
||||
SetupNorthBase()
|
||||
|
||||
Trigger.OnKilled(Church, function()
|
||||
Actor.Create("healcrate", true, { Owner = Greece, Location = ChurchCrate.Location })
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(ObjectiveDome, function()
|
||||
if not DomeCaptured then
|
||||
Greece.MarkFailedObjective(CaptureDome)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Avoid notifications unless part of the the northern base is captured.
|
||||
Greece.PlayLowPowerNotification = false
|
||||
local notifiers = Utils.Where(USSR.GetActors(), function(actor)
|
||||
return actor.HasProperty("StartBuildingRepairs")
|
||||
end)
|
||||
|
||||
Utils.Do(notifiers, function(n)
|
||||
Trigger.OnCapture(n, function()
|
||||
Greece.PlayLowPowerNotification = true
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
SetupFlameWall = function()
|
||||
Trigger.OnAllKilled(FlameTowerWall, function()
|
||||
SpawnTemporaryCamera(RadarCam.Location, DateTime.Seconds(5))
|
||||
end)
|
||||
|
||||
-- Give some warning if they are not yet revealed by the power cut.
|
||||
Trigger.OnEnteredProximityTrigger(FlameCam.CenterPosition, WDist.FromCells(8), function(actor, id)
|
||||
if FlameWallRevealed then
|
||||
Trigger.RemoveProximityTrigger(id)
|
||||
return
|
||||
end
|
||||
|
||||
if actor.Owner == Greece then
|
||||
FlameWallRevealed = true
|
||||
Trigger.RemoveProximityTrigger(id)
|
||||
SpawnTemporaryCamera(FlameCam.Location, DateTime.Seconds(10))
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
SetupNorthBase = function()
|
||||
local bombsPrepared = false
|
||||
local tanksAlerted = false
|
||||
|
||||
Trigger.OnKilledOrCaptured(SubPen, function()
|
||||
Greece.MarkCompletedObjective(StopProduction)
|
||||
end)
|
||||
|
||||
Trigger.OnDamaged(SubPen, function(_, attacker)
|
||||
if tanksAlerted or attacker.Type == "badr.bomber" then
|
||||
return
|
||||
end
|
||||
|
||||
tanksAlerted = true
|
||||
Utils.Do(Heavys, IdleHunt)
|
||||
end)
|
||||
|
||||
Trigger.OnKilledOrCaptured(ForwardCommand, function()
|
||||
StartFireSale()
|
||||
-- The original mission used four waypoints (7-10) for drops.
|
||||
-- For simplicity, a four-Badger team will target the middle.
|
||||
Chalk3.TargetParatroopers(NorthLZ.CenterPosition, Angle.New(927))
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(2), function()
|
||||
Media.PlaySpeechNotification(Greece, "ReinforcementsArrived")
|
||||
end)
|
||||
|
||||
if not bombsPrepared then
|
||||
bombsPrepared = true
|
||||
BombNorthBase()
|
||||
end
|
||||
end)
|
||||
|
||||
Trigger.OnAllKilledOrCaptured(USSR.GetActorsByType("sam"), function()
|
||||
if not bombsPrepared then
|
||||
bombsPrepared = true
|
||||
BombNorthBase()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
PowerDown = false
|
||||
PowerDownTeslas = function()
|
||||
if not PowerDown then
|
||||
CaptureDome = AddSecondaryObjective(Greece, "capture-enemy-radar-dome")
|
||||
Greece.MarkCompletedObjective(PowerDownTeslaCoils)
|
||||
Media.PlaySoundNotification(Greece, "RadarDown")
|
||||
PowerDown = true
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(1), function()
|
||||
Media.PlaySpeechNotification(Greece, "ReinforcementsArrived")
|
||||
end)
|
||||
|
||||
local bridge = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Type == "bridge1" end)[1]
|
||||
if not bridge.IsDead then
|
||||
bridge.Kill()
|
||||
end
|
||||
|
||||
local demoEngis = Reinforcements.ReinforceWithTransport(Greece, LSTType, DemoEngiTeam, DemoEngiPath, { DemoEngiPath[1] })[2]
|
||||
Trigger.OnAllRemovedFromWorld(Utils.Where(demoEngis, function(a) return a.Type == "e6" end), function()
|
||||
if not DomeCaptured then
|
||||
Greece.MarkFailedObjective(CaptureDome)
|
||||
end
|
||||
if not DomeCaptured and bridge.IsDead then
|
||||
Greece.MarkFailedObjective(StopProduction)
|
||||
end
|
||||
end)
|
||||
|
||||
Trigger.OnCapture(ObjectiveDome, function()
|
||||
DomeCaptured = true
|
||||
Greece.MarkCompletedObjective(CaptureDome)
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(3), function()
|
||||
SendChronos()
|
||||
SendWaterSquads()
|
||||
Actor.Create("camera", true, { Owner = Greece, Location = EasyCamera.Location })
|
||||
end)
|
||||
end)
|
||||
|
||||
if not FlameWallRevealed then
|
||||
FlameWallRevealed = true
|
||||
SpawnTemporaryCamera(FlameCam.Location, DateTime.Seconds(10))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
BombNorthBase = function()
|
||||
local proxy = Actor.Create("powerproxy.parabombs", false, { Owner = Greece })
|
||||
proxy.TargetAirstrike(BomberTarget1.CenterPosition, Angle.New(970))
|
||||
proxy.TargetAirstrike(BomberTarget2.CenterPosition, Angle.New(932))
|
||||
proxy.Destroy()
|
||||
end
|
||||
|
||||
SendChronos = function()
|
||||
local payload = { }
|
||||
local proxy = Actor.Create("powerproxy.chronoshift", false, { Owner = Greece })
|
||||
local spawns =
|
||||
{
|
||||
{ cell = ChronoSpawn2.Location, facing = Angle.NorthWest },
|
||||
{ cell = ChronoSpawn1.Location, facing = Angle.NorthEast },
|
||||
{ cell = ChronoSpawn3.Location, facing = Angle.South }
|
||||
}
|
||||
|
||||
Utils.Do(spawns, function(spawn)
|
||||
local tank = Actor.Create("ctnk", true, { Owner = Greece, Facing = spawn.facing })
|
||||
payload[tank] = spawn.cell
|
||||
end)
|
||||
|
||||
Media.PlaySound("chrono2.aud")
|
||||
proxy.Chronoshift(payload)
|
||||
proxy.Destroy()
|
||||
end
|
||||
|
||||
SendWaterSquads = function()
|
||||
local sovietWaterSquad1 = Reinforcements.ReinforceWithTransport(USSR, LSTType, SovietSquad, { WaterEntry2.Location, Beach2.Location }, { WaterEntry2.Location })[2]
|
||||
Utils.Do(sovietWaterSquad1, function(a)
|
||||
Trigger.OnAddedToWorld(a, IdleHunt)
|
||||
end)
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(5), function()
|
||||
local sovietWaterSquad2 = Reinforcements.ReinforceWithTransport(USSR, LSTType, SovietSquad, { WaterEntry2.Location, Beach3.Location }, { WaterEntry2.Location })[2]
|
||||
Utils.Do(sovietWaterSquad2, function(a)
|
||||
Trigger.OnAddedToWorld(a, function()
|
||||
a.AttackMove(FlameCam.Location)
|
||||
IdleHunt(a)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(13), function()
|
||||
local sovietWaterSquad2 = Reinforcements.ReinforceWithTransport(USSR, LSTType, V2Squad, { WaterEntry2.Location, Beach2.Location }, { WaterEntry2.Location })[2]
|
||||
Utils.Do(sovietWaterSquad2, function(a)
|
||||
Trigger.OnAddedToWorld(a, function()
|
||||
a.AttackMove(FlameCam.Location)
|
||||
IdleHunt(a)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
MissileSubEscape = function()
|
||||
local missileSub = Actor.Create("msub", true, { Owner = USSR, Location = MissileSubSpawn.Location })
|
||||
Actor.Create("camera", true, { Owner = Greece, Location = SubPath2.Location })
|
||||
DestroySub = AddPrimaryObjective(Greece, "destroy-escaping-submarine")
|
||||
|
||||
Utils.Do(SubEscapePath, function(waypoint)
|
||||
missileSub.Move(waypoint.Location)
|
||||
end)
|
||||
|
||||
Trigger.OnEnteredFootprint({ SubPath3.Location }, function(a, id)
|
||||
if a.Owner == USSR and a.Type == "msub" then
|
||||
Trigger.RemoveFootprintTrigger(id)
|
||||
USSR.MarkCompletedObjective(EscapeWithSub)
|
||||
end
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(missileSub, function()
|
||||
Greece.MarkCompletedObjective(DestroySub)
|
||||
end)
|
||||
end
|
||||
|
||||
StartFireSale = function()
|
||||
local structures = Utils.Where(USSR.GetActors(), function(actor)
|
||||
return actor.HasProperty("StartBuildingRepairs")
|
||||
end)
|
||||
|
||||
if #structures == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
SpawnTemporaryCamera(BomberTarget1.Location, DateTime.Seconds(5))
|
||||
SpawnTemporaryCamera(BomberTarget2.Location, DateTime.Seconds(5))
|
||||
|
||||
Utils.Do(structures, function(building)
|
||||
building.Sell()
|
||||
end)
|
||||
|
||||
Trigger.OnAllRemovedFromWorld(structures, function()
|
||||
Utils.Do(USSR.GetGroundAttackers(), IdleHunt)
|
||||
end)
|
||||
end
|
||||
|
||||
SpawnTemporaryCamera = function(location, duration)
|
||||
local camera = Actor.Create("camera", true, { Owner = Greece, Location = location })
|
||||
|
||||
Trigger.AfterDelay(duration, function()
|
||||
if camera.IsInWorld then
|
||||
camera.Destroy()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
FinishTimer = function()
|
||||
local submarineEscapes = UserInterface.GetFluentMessage("submarine-escapes")
|
||||
|
||||
for i = 0, 5 do
|
||||
local c = TimerColor
|
||||
if i % 2 == 0 then
|
||||
c = HSLColor.White
|
||||
end
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(i), function() UserInterface.SetMissionText(submarineEscapes, c) end)
|
||||
end
|
||||
Trigger.AfterDelay(DateTime.Seconds(6), function() UserInterface.SetMissionText("") end)
|
||||
end
|
||||
|
||||
UnitsArrived = false
|
||||
TimerFinished = false
|
||||
Ticked = TimerTicks
|
||||
Tick = function()
|
||||
if BadGuy.PowerState ~= "Normal" then
|
||||
PowerDownTeslas()
|
||||
end
|
||||
|
||||
if Greece.HasNoRequiredUnits() and UnitsArrived then
|
||||
USSR.MarkCompletedObjective(EscapeWithSub)
|
||||
end
|
||||
|
||||
if Ticked > 0 then
|
||||
if (Ticked % DateTime.Seconds(1)) == 0 then
|
||||
Timer = UserInterface.GetFluentMessage("submarine-construction-complete-in", { ["time"] = Utils.FormatTime(Ticked) })
|
||||
UserInterface.SetMissionText(Timer, TimerColor)
|
||||
end
|
||||
Ticked = Ticked - 1
|
||||
elseif Ticked == 0 and not TimerFinished then
|
||||
FinishTimer()
|
||||
MissileSubEscape()
|
||||
TimerFinished = true
|
||||
end
|
||||
end
|
||||
|
||||
WorldLoaded = function()
|
||||
Greece = Player.GetPlayer("Greece")
|
||||
USSR = Player.GetPlayer("USSR")
|
||||
BadGuy = Player.GetPlayer("BadGuy")
|
||||
|
||||
EscapeWithSub = AddPrimaryObjective(USSR, "")
|
||||
StopProduction = AddPrimaryObjective(Greece, "destroy-soviet-sub-pen")
|
||||
PowerDownTeslaCoils = AddPrimaryObjective(Greece, "power-down-tesla-coils")
|
||||
|
||||
InitObjectives(Greece)
|
||||
|
||||
Trigger.AfterDelay(DateTime.Minutes(2), function()
|
||||
Media.PlaySpeechNotification(Greece, "TenMinutesRemaining")
|
||||
end)
|
||||
Trigger.AfterDelay(DateTime.Minutes(7), function()
|
||||
Media.PlaySpeechNotification(Greece, "WarningFiveMinutesRemaining")
|
||||
end)
|
||||
Trigger.AfterDelay(DateTime.Minutes(9), function()
|
||||
Media.PlaySpeechNotification(Greece, "WarningThreeMinutesRemaining")
|
||||
end)
|
||||
Trigger.AfterDelay(DateTime.Minutes(11), function()
|
||||
Media.PlaySpeechNotification(Greece, "WarningOneMinuteRemaining")
|
||||
end)
|
||||
|
||||
Camera.Position = DefaultCameraPosition.CenterPosition
|
||||
TimerColor = USSR.Color
|
||||
Chalk1 = Actor.Create("chalk1", false, { Owner = Greece })
|
||||
Chalk2 = Actor.Create("chalk2", false, { Owner = Greece })
|
||||
Chalk3 = Actor.Create("chalk3", false, { Owner = Greece })
|
||||
MissionStart()
|
||||
SetupTriggers()
|
||||
end
|
||||
Reference in New Issue
Block a user