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:
401
mods/ra/maps/in-the-nick-of-time/in-the-nick-of-time.lua
Normal file
401
mods/ra/maps/in-the-nick-of-time/in-the-nick-of-time.lua
Normal file
@@ -0,0 +1,401 @@
|
||||
--[[
|
||||
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.
|
||||
]]
|
||||
StartUnits = { "jeep", "jeep", "1tnk", "1tnk", "1tnk", "1tnk", "2tnk", "2tnk" }
|
||||
StartingPlanes = { Yak1, Yak2 }
|
||||
ReinforcementFootprint1 = { CPos.New(93,78), CPos.New(94,78), CPos.New(95,78) }
|
||||
InfantrySquad = { "e1", "e1", "e1", "e3", "e3" }
|
||||
ReinforcementFootprint2 = { CPos.New(63,84), CPos.New(63,85), CPos.New(63,86), CPos.New(63,87) }
|
||||
SouthWaterPath1 = { SouthWaterEntry.Location, SouthWaterLanding1.Location }
|
||||
SouthWaterPath2 = { SouthWaterEntry.Location, SouthWaterLanding2.Location }
|
||||
SouthWaterTeam = { "dtrk", "1tnk", "1tnk", "2tnk", "2tnk" }
|
||||
SouthChinookPath = { ChinookEntry1.Location, ChinookLZ1.Location }
|
||||
SouthChinookChalk = { "e3", "e3", "e3", "e1", "e1" }
|
||||
MammothAttackFootprint = { CPos.New(49,81), CPos.New(50,81), CPos.New(51,81), CPos.New(52,81), CPos.New(53,81) }
|
||||
BridgeMammoths = { Mammoth2, Mammoth3 }
|
||||
ReinforcementFootprint3 = { CPos.New(60,74), CPos.New(61,74) }
|
||||
MoneyTrucks = { "truk", "truk" }
|
||||
SovietHouseSquad = { "e2", "e2", "e2", "e3", "e3" }
|
||||
AlliedHouseSquad = { "e6", "e6", "medi", "spy", "mech" }
|
||||
MediumTanks = { Medium1, Medium2, Medium3, Medium4 }
|
||||
ReinforcementFootprint4 = { CPos.New(77,64), CPos.New(78,64), CPos.New(79,64), CPos.New(85,67), CPos.New(85,68), CPos.New(85,69) }
|
||||
LightTanks = { LightTank1, LightTank2 }
|
||||
ReinforcementFootprint5 = { CPos.New(92,54), CPos.New(92,55), CPos.New(92,56), CPos.New(92,57), CPos.New(96,62), CPos.New(97,62), CPos.New(98,62), CPos.New(99,62) }
|
||||
ReinforcementFootprint6 = { CPos.New(97,51), CPos.New(98,51) }
|
||||
NorthChinookPath = { ChinookEntry2.Location, ChinookLZ2.Location }
|
||||
NorthChinookChalk = { "e3", "e3", "e3", "e3", "e3" }
|
||||
Scientists = { "einstein", "chan", "chan", "chan", "chan" }
|
||||
NorthWaterPath1 = { NorthWaterEntry.Location, NorthWaterLanding1.Location }
|
||||
NorthWaterPath2 = { NorthWaterEntry.Location, NorthWaterLanding2.Location }
|
||||
NorthWaterPath3 = { NorthWaterEntry.Location, NorthWaterLanding3.Location }
|
||||
NorthWaterTeam = { "1tnk", "1tnk", "1tnk", "2tnk", "2tnk" }
|
||||
BoatofMammoths = { "4tnk", "4tnk", "4tnk", "4tnk", "4tnk" }
|
||||
EvacuateFootprint = { CPos.New(93,92), CPos.New(94,92), CPos.New(95,92), CPos.New(96,92), CPos.New(97,92), CPos.New(98,92), CPos.New(99,92) }
|
||||
TimerTicks = DateTime.Minutes(54)
|
||||
|
||||
AlliedReinforcements = function()
|
||||
Reinforcements.Reinforce(Greece, StartUnits, { AlliesEntry.Location, AlliesRally.Location }, 6)
|
||||
Trigger.AfterDelay(DateTime.Seconds(1), function()
|
||||
UnitsArrived = true
|
||||
end)
|
||||
|
||||
local foot1Triggered
|
||||
Trigger.OnEnteredFootprint(ReinforcementFootprint1, function(actor, id)
|
||||
if actor.Owner == Greece and not foot1Triggered then
|
||||
Trigger.RemoveFootprintTrigger(id)
|
||||
foot1Triggered = true
|
||||
|
||||
Media.PlaySpeechNotification(Greece, "ReinforcementsArrived")
|
||||
Reinforcements.Reinforce(Greece, InfantrySquad, { InfantrySquadEntry.Location, InfantrySquadStop.Location }, 2)
|
||||
end
|
||||
end)
|
||||
|
||||
local foot2Triggered
|
||||
Trigger.OnEnteredFootprint(ReinforcementFootprint2, function(actor, id)
|
||||
if actor.Owner == Greece and not foot2Triggered then
|
||||
Trigger.RemoveFootprintTrigger(id)
|
||||
foot2Triggered = true
|
||||
|
||||
Media.PlaySpeechNotification(Greece, "ReinforcementsArrived")
|
||||
local demoTeam = Reinforcements.ReinforceWithTransport(Greece, "lst.reinforcement", SouthWaterTeam, SouthWaterPath1, { SouthWaterPath1[1] })
|
||||
local chinookChalk1 = Reinforcements.ReinforceWithTransport(Greece, "tran.reinforcement", SouthChinookChalk, SouthChinookPath, { SouthChinookPath[1] })
|
||||
end
|
||||
end)
|
||||
|
||||
local foot3Triggered
|
||||
Trigger.OnEnteredFootprint(ReinforcementFootprint3, function(actor, id)
|
||||
if actor.Owner == Greece and not foot3Triggered then
|
||||
Trigger.RemoveFootprintTrigger(id)
|
||||
foot3Triggered = true
|
||||
|
||||
Media.PlaySound("chrono2.aud")
|
||||
Actor.Create("ctnk", true, { Owner = Greece, Location = ChronoBeam1.Location })
|
||||
Actor.Create("ctnk", true, { Owner = Greece, Location = ChronoBeam1.Location + CVec.New(1,1) })
|
||||
|
||||
Reinforcements.Reinforce(USSR, MoneyTrucks, { AlliesEntry.Location, TruckStop1.Location }, 0)
|
||||
Utils.Do(StartingPlanes, function(yaks)
|
||||
InitializeAttackAircraft(yaks, Greece)
|
||||
end)
|
||||
|
||||
if not USSRHouse.IsDead then
|
||||
local houseSquad = Reinforcements.Reinforce(USSR, SovietHouseSquad, { VillageSpawnUSSR.Location }, 0)
|
||||
Utils.Do(houseSquad, IdleHunt)
|
||||
Trigger.OnAllKilled(houseSquad, function()
|
||||
if not AlliesHouse.IsDead then
|
||||
Media.PlaySoundNotification(Greece, "AlertBleep")
|
||||
Media.DisplayMessage(UserInterface.GetFluentMessage("friendlies-coming-out"), UserInterface.GetFluentMessage("medic"))
|
||||
Reinforcements.Reinforce(Greece, AlliedHouseSquad, { VillageSpawnAllies.Location, VillageRally.Location }, 0)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local foot4Triggered
|
||||
Trigger.OnEnteredFootprint(ReinforcementFootprint4, function(actor, id)
|
||||
if actor.Owner == Greece and not foot4Triggered then
|
||||
Trigger.RemoveFootprintTrigger(id)
|
||||
foot4Triggered = true
|
||||
|
||||
Media.PlaySpeechNotification(Greece, "ReinforcementsArrived")
|
||||
Paradrop3.TargetParatroopers(ParaLZ3.CenterPosition, Angle.New(935))
|
||||
end
|
||||
end)
|
||||
|
||||
local foot5Triggered
|
||||
Trigger.OnEnteredFootprint(ReinforcementFootprint5, function(actor, id)
|
||||
if actor.Owner == Greece and not foot5Triggered then
|
||||
Trigger.RemoveFootprintTrigger(id)
|
||||
foot5Triggered = true
|
||||
|
||||
Media.PlaySound("chrono2.aud")
|
||||
Actor.Create("ctnk", true, { Owner = Greece, Location = ChronoBeam2.Location })
|
||||
Actor.Create("ctnk", true, { Owner = Greece, Location = ChronoBeam2.Location + CVec.New(1,1) })
|
||||
|
||||
Utils.Do(LightTanks, IdleHunt)
|
||||
end
|
||||
end)
|
||||
|
||||
local foot6Triggered
|
||||
Trigger.OnEnteredFootprint(ReinforcementFootprint6, function(actor, id)
|
||||
if actor.Owner == Greece and not foot6Triggered then
|
||||
Trigger.RemoveFootprintTrigger(id)
|
||||
foot6Triggered = true
|
||||
|
||||
Media.PlaySpeechNotification(Greece, "ReinforcementsArrived")
|
||||
local chinookChalk2 = Reinforcements.ReinforceWithTransport(Greece, "tran.reinforcement", NorthChinookChalk, NorthChinookPath, { NorthChinookPath[1] })
|
||||
ProduceInfantry()
|
||||
TankProduction()
|
||||
end
|
||||
end)
|
||||
|
||||
Trigger.OnEnteredProximityTrigger(ScientistEscape.CenterPosition, WDist.FromCells(3), function(actor, id)
|
||||
if actor.Owner == Greece then
|
||||
Trigger.RemoveProximityTrigger(id)
|
||||
ScientistsFreed = true
|
||||
|
||||
Media.PlaySpeechNotification(Greece, "TargetFreed")
|
||||
VIPs = Reinforcements.Reinforce(Greece, Scientists, { ScientistEscape.Location, ScientistRally.Location }, 2)
|
||||
Actor.Create("flare", true, { Owner = Greece, Location = DefaultCameraPosition.Location })
|
||||
|
||||
Trigger.OnAnyKilled(VIPs, function()
|
||||
Greece.MarkFailedObjective(RescueScientists)
|
||||
end)
|
||||
|
||||
-- Add the footprint trigger in a frame end task (delay 0) to avoid crashes
|
||||
local left = #VIPs
|
||||
Trigger.AfterDelay(0, function()
|
||||
Trigger.OnEnteredFootprint(EvacuateFootprint, function(a, id)
|
||||
if a.Type == "chan" or a.Type == "einstein" then
|
||||
a.Owner = GoodGuy
|
||||
a.Stop()
|
||||
a.Move(AlliesEntry.Location)
|
||||
|
||||
-- in case units get stuck
|
||||
Trigger.OnIdle(a, function()
|
||||
a.Move(AlliesEntry.Location)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
Trigger.OnEnteredFootprint({ AlliesEntry.Location }, function(a, id)
|
||||
if a.Type == "chan" or a.Type == "einstein" then
|
||||
a.Stop()
|
||||
a.Destroy()
|
||||
|
||||
left = left - 1
|
||||
if left == 0 then
|
||||
if not Greece.IsObjectiveCompleted(RescueScientists) and not Greece.IsObjectiveFailed(RescueScientists) then
|
||||
Greece.MarkCompletedObjective(RescueScientists)
|
||||
end
|
||||
end
|
||||
else
|
||||
a.Stop()
|
||||
a.Destroy()
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(5), function()
|
||||
Media.PlaySpeechNotification(Greece, "ReinforcementsArrived")
|
||||
Media.DisplayMessage(UserInterface.GetFluentMessage("get-scientists-evacuation-point"), UserInterface.GetFluentMessage("landcom-16-capitalized"))
|
||||
local northTeam = Reinforcements.ReinforceWithTransport(Greece, "lst.reinforcement", NorthWaterTeam, NorthWaterPath1, { NorthWaterPath1[1] })
|
||||
end)
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(10), function()
|
||||
Media.PlaySpeechNotification(Greece, "SovietForcesApproaching")
|
||||
local mammoths1 = Reinforcements.ReinforceWithTransport(USSR, "lst.reinforcement", BoatofMammoths, NorthWaterPath2, { NorthWaterPath2[1] })[2]
|
||||
Utils.Do(mammoths1, function(unit)
|
||||
Trigger.OnAddedToWorld(unit, IdleHunt)
|
||||
end)
|
||||
local mammoths2 = Reinforcements.ReinforceWithTransport(USSR, "lst.reinforcement", BoatofMammoths, NorthWaterPath3, { NorthWaterPath3[1] })[2]
|
||||
Utils.Do(mammoths2, function(unit)
|
||||
Trigger.OnAddedToWorld(unit, IdleHunt)
|
||||
end)
|
||||
end)
|
||||
|
||||
local footMammoth2Triggered
|
||||
Trigger.OnEnteredFootprint(MammothAttackFootprint, function(actor, id)
|
||||
if actor.Type == "chan" and not footMammoth2Triggered then
|
||||
Trigger.RemoveFootprintTrigger(id)
|
||||
footMammoth2Triggered = true
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(10), function()
|
||||
Media.PlaySpeechNotification(Greece, "SovietForcesApproaching")
|
||||
local mammoths3 = Reinforcements.ReinforceWithTransport(USSR, "lst.reinforcement", BoatofMammoths, SouthWaterPath1, { SouthWaterPath1[1] })[2]
|
||||
Utils.Do(mammoths3, function(unit)
|
||||
Trigger.OnAddedToWorld(unit, IdleHunt)
|
||||
end)
|
||||
local mammoths4 = Reinforcements.ReinforceWithTransport(USSR, "lst.reinforcement", BoatofMammoths, SouthWaterPath2, { SouthWaterPath2[1] })[2]
|
||||
Utils.Do(mammoths4, function(unit)
|
||||
Trigger.OnAddedToWorld(unit, IdleHunt)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
EnemyActions = function()
|
||||
Utils.Do(StartingPlanes, function(a)
|
||||
a.ReturnToBase()
|
||||
end)
|
||||
|
||||
local firstDrop = Paradrop1.TargetParatroopers(ParaLZ1.CenterPosition, Angle.New(214))
|
||||
Utils.Do(firstDrop, function(a)
|
||||
Trigger.OnPassengerExited(a, function(t, p)
|
||||
IdleHunt(p)
|
||||
end)
|
||||
end)
|
||||
|
||||
local footMammothTriggered
|
||||
Trigger.OnEnteredFootprint(MammothAttackFootprint, function(actor, id)
|
||||
if actor.Owner == Greece and not footMammothTriggered then
|
||||
Trigger.RemoveFootprintTrigger(id)
|
||||
footMammothTriggered = true
|
||||
|
||||
Utils.Do(BridgeMammoths, IdleHunt)
|
||||
|
||||
local secondDrop = Paradrop2.TargetParatroopers(ParaLZ2.CenterPosition, Angle.New(808))
|
||||
Utils.Do(secondDrop, function(a)
|
||||
Trigger.OnPassengerExited(a, function(t, p)
|
||||
IdleHunt(p)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(Tesla2, function()
|
||||
Utils.Do(MediumTanks, function(tank)
|
||||
if not tank.IsDead then
|
||||
IdleHunt(tank)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
EnemyInfantry = { "e1", "e1", "e3" }
|
||||
Tanks = { "1tnk", "3tnk" }
|
||||
AttackGroupSize = 4
|
||||
ProductionDelay = DateTime.Seconds(10)
|
||||
IdlingUnits = { }
|
||||
|
||||
ProduceInfantry = function()
|
||||
if (Tent1.IsDead or Tent1.Owner ~= USSR) and (Tent2.IsDead or Tent2.Owner ~= USSR) then
|
||||
return
|
||||
end
|
||||
|
||||
local toBuild = { Utils.Random(EnemyInfantry) }
|
||||
|
||||
USSR.Build(toBuild, function(unit)
|
||||
IdlingUnits[#IdlingUnits + 1] = unit[1]
|
||||
Trigger.AfterDelay(ProductionDelay, ProduceInfantry)
|
||||
|
||||
if #IdlingUnits >= (AttackGroupSize * 1.5) then
|
||||
SendAttack()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
TankProduction = function()
|
||||
if WarFactory.IsDead or WarFactory.Owner ~= USSR then
|
||||
return
|
||||
end
|
||||
|
||||
local toBuild = { Utils.Random(Tanks) }
|
||||
|
||||
USSR.Build(toBuild, function(unit)
|
||||
IdlingUnits[#IdlingUnits + 1] = unit[1]
|
||||
Trigger.AfterDelay(ProductionDelay, TankProduction)
|
||||
|
||||
if #IdlingUnits >= (AttackGroupSize * 1.5) then
|
||||
SendAttack()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
SendAttack = function()
|
||||
local units = { }
|
||||
|
||||
for i = 0, AttackGroupSize, 1 do
|
||||
local number = Utils.RandomInteger(1, #IdlingUnits)
|
||||
|
||||
if IdlingUnits[number] and not IdlingUnits[number].IsDead then
|
||||
units[i] = IdlingUnits[number]
|
||||
table.remove(IdlingUnits, number)
|
||||
end
|
||||
end
|
||||
|
||||
Utils.Do(units, function(unit)
|
||||
if not unit.IsDead then
|
||||
IdleHunt(unit)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
LoseTriggers = function()
|
||||
Trigger.OnKilled(ForwardCommand, function()
|
||||
if not ScientistsFreed then
|
||||
Greece.MarkFailedObjective(RescueScientists)
|
||||
Media.DisplayMessage(UserInterface.GetFluentMessage("scientists-killed-in-command-center"), UserInterface.GetFluentMessage("landcom-16-capitalized"))
|
||||
end
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(Chronosphere, function()
|
||||
Greece.MarkFailedObjective(RescueScientists)
|
||||
end)
|
||||
|
||||
Trigger.OnCapture(Chronosphere, function()
|
||||
Chronosphere.Kill()
|
||||
end)
|
||||
end
|
||||
|
||||
Ticked = TimerTicks
|
||||
Tick = function()
|
||||
if Greece.HasNoRequiredUnits() and UnitsArrived then
|
||||
USSR.MarkCompletedObjective(SovietObj)
|
||||
end
|
||||
|
||||
if Ticked > 0 then
|
||||
if (Ticked % DateTime.Seconds(1)) == 0 then
|
||||
Timer = UserInterface.GetFluentMessage("chronosphere-explodes-in", { ["time"] = Utils.FormatTime(Ticked) })
|
||||
UserInterface.SetMissionText(Timer, TimerColor)
|
||||
end
|
||||
Ticked = Ticked - 1
|
||||
elseif Ticked == 0 then
|
||||
UserInterface.SetMissionText(UserInterface.GetFluentMessage("too-late"), USSR.Color)
|
||||
USSR.MarkCompletedObjective(SovietObj)
|
||||
end
|
||||
end
|
||||
|
||||
WorldLoaded = function()
|
||||
Greece = Player.GetPlayer("Greece")
|
||||
USSR = Player.GetPlayer("USSR")
|
||||
GoodGuy = Player.GetPlayer("GoodGuy")
|
||||
|
||||
InitObjectives(Greece)
|
||||
|
||||
SovietObj = AddPrimaryObjective(USSR, "")
|
||||
RescueScientists = AddPrimaryObjective(Greece, "rescue-scientists-extraction-point")
|
||||
|
||||
Camera.Position = DefaultCameraPosition.CenterPosition
|
||||
Paradrop1 = Actor.Create("paradrop1", false, { Owner = USSR })
|
||||
Paradrop2 = Actor.Create("paradrop2", false, { Owner = USSR })
|
||||
Paradrop3 = Actor.Create("paradrop3", false, { Owner = Greece })
|
||||
TimerColor = Greece.Color
|
||||
Tent1.IsPrimaryBuilding = true
|
||||
AlliedReinforcements()
|
||||
EnemyActions()
|
||||
LoseTriggers()
|
||||
|
||||
Trigger.AfterDelay(DateTime.Minutes(24), function()
|
||||
Media.PlaySpeechNotification(Greece, "ThirtyMinutesRemaining")
|
||||
end)
|
||||
Trigger.AfterDelay(DateTime.Minutes(34), function()
|
||||
Media.PlaySpeechNotification(Greece, "TwentyMinutesRemaining")
|
||||
end)
|
||||
Trigger.AfterDelay(DateTime.Minutes(44), function()
|
||||
Media.PlaySpeechNotification(Greece, "TenMinutesRemaining")
|
||||
end)
|
||||
Trigger.AfterDelay(DateTime.Minutes(49), function()
|
||||
Media.PlaySpeechNotification(Greece, "WarningFiveMinutesRemaining")
|
||||
end)
|
||||
Trigger.AfterDelay(DateTime.Minutes(50), function()
|
||||
Media.PlaySpeechNotification(Greece, "WarningFourMinutesRemaining")
|
||||
end)
|
||||
Trigger.AfterDelay(DateTime.Minutes(51), function()
|
||||
Media.PlaySpeechNotification(Greece, "WarningThreeMinutesRemaining")
|
||||
end)
|
||||
Trigger.AfterDelay(DateTime.Minutes(52), function()
|
||||
Media.PlaySpeechNotification(Greece, "WarningTwoMinutesRemaining")
|
||||
end)
|
||||
Trigger.AfterDelay(DateTime.Minutes(53), function()
|
||||
Media.PlaySpeechNotification(Greece, "WarningOneMinuteRemaining")
|
||||
end)
|
||||
end
|
||||
Reference in New Issue
Block a user