Files
OpenRA/mods/ra/maps/in-the-nick-of-time/in-the-nick-of-time.lua
2021-05-22 23:29:42 +02:00

414 lines
15 KiB
Lua

--[[
Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
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("Friendlies coming out!", "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] })
InfantryProduction()
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("Commander, we're detecting Soviet transports headed your way. Get those scientists back to the extraction point in the southeast!", "LANDCOM 16")
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 = { }
InfantryProduction = 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, InfantryProduction)
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("The scientists were in the Command Center!", "LANDCOM 16")
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
UserInterface.SetMissionText("Chronosphere explodes in " .. Utils.FormatTime(ticked), TimerColor)
ticked = ticked - 1
elseif ticked == 0 then
UserInterface.SetMissionText("We're too late!", USSR.Color)
USSR.MarkCompletedObjective(SovietObj)
end
end
WorldLoaded = function()
Greece = Player.GetPlayer("Greece")
USSR = Player.GetPlayer("USSR")
GoodGuy = Player.GetPlayer("GoodGuy")
Trigger.OnObjectiveAdded(Greece, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
SovietObj = USSR.AddObjective("Defeat Allies.")
RescueScientists = Greece.AddObjective("Rescue the scientists and escort them back to the\nextraction point.")
Trigger.OnObjectiveCompleted(Greece, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed")
end)
Trigger.OnObjectiveFailed(Greece, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed")
end)
Trigger.OnPlayerLost(Greece, function()
Media.PlaySpeechNotification(Greece, "Lose")
end)
Trigger.OnPlayerWon(Greece, function()
Media.PlaySpeechNotification(Greece, "Win")
end)
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