--[[ 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