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:
397
mods/ra/maps/negotiations/negotiations-reinforcements.lua
Normal file
397
mods/ra/maps/negotiations/negotiations-reinforcements.lua
Normal file
@@ -0,0 +1,397 @@
|
||||
--[[
|
||||
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.
|
||||
]]
|
||||
ReinforceAllies = function()
|
||||
Media.PlaySpeechNotification(Greece, "ReinforcementsArrived")
|
||||
local proxy = SpawnMiscActor("paradrop.allies", GoodGuy, TanyaDrop.Location, DateTime.Seconds(1))
|
||||
local planes = proxy.TargetParatroopers(TanyaDrop.CenterPosition, Angle.SouthEast)
|
||||
|
||||
Utils.Do(planes, function(plane)
|
||||
Trigger.OnPassengerExited(plane, function(_, passenger)
|
||||
passenger.Owner = Greece
|
||||
end)
|
||||
|
||||
Trigger.OnAllKilled(plane.Passengers, CheckAlliedDestruction)
|
||||
end)
|
||||
|
||||
local demoTypes = { "2tnk", "2tnk", "2tnk", "dtrk" }
|
||||
local artilleryTypes = {"2tnk", "2tnk", "arty", "arty", "mech", "mech", "mech" }
|
||||
local groundPath = { WestRoadEntry.Location, WestRoadRally.Location }
|
||||
|
||||
local demoTeam = Reinforcements.Reinforce(Greece, demoTypes, groundPath)
|
||||
Trigger.OnAllKilled(demoTeam, CheckAlliedDestruction)
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(30), function()
|
||||
if AlliesDefeated then
|
||||
return
|
||||
end
|
||||
|
||||
Media.PlaySpeechNotification(Greece, "ReinforcementsArrived")
|
||||
local artilleryTeam = Reinforcements.Reinforce(Greece, artilleryTypes, groundPath)
|
||||
Trigger.OnAllKilled(artilleryTeam, CheckAlliedDestruction)
|
||||
end)
|
||||
end
|
||||
|
||||
ReinforceChronoTanks = function(locations)
|
||||
if ChronoTanksReinforced then
|
||||
return
|
||||
end
|
||||
|
||||
ChronoTanksReinforced = true
|
||||
Media.PlaySoundNotification(Greece, "Chronoshift")
|
||||
|
||||
Utils.Do(locations, function(location)
|
||||
local proxy = SpawnMiscActor("powerproxy.chronoshift", GoodGuy, location, DateTime.Seconds(1))
|
||||
local tank = Actor.Create("ctnk", true, { Owner = Greece, Facing = Angle.NorthWest })
|
||||
local payload = { [tank] = location }
|
||||
proxy.Chronoshift(payload)
|
||||
end)
|
||||
end
|
||||
|
||||
ReinforceTanya = function()
|
||||
local path = { WestRoadEntry.Location, TanyaDrop.Location }
|
||||
local plane = Reinforcements.Reinforce(Greece, { "badr.tanya" }, path)[1]
|
||||
local passengers = { TanyaType }
|
||||
|
||||
Trigger.OnAddedToWorld(plane, function()
|
||||
Utils.Do(passengers, function(type)
|
||||
local passenger = Actor.Create(type, false, { Owner = Greece })
|
||||
plane.LoadPassenger(passenger)
|
||||
Trigger.OnKilled(passenger, OnTanyaKilled)
|
||||
Tanya = passenger
|
||||
AnnounceTanyaRules(passenger)
|
||||
end)
|
||||
|
||||
plane.Paradrop(path[2])
|
||||
end)
|
||||
end
|
||||
|
||||
AnnounceTanyaRules = function(tanya)
|
||||
if Difficulty == "easy" then
|
||||
return
|
||||
end
|
||||
|
||||
Trigger.OnAddedToWorld(tanya, function()
|
||||
Trigger.AfterDelay(DateTime.Seconds(1), function()
|
||||
Media.DisplayMessage(UserInterface.GetFluentMessage("tanya-rules-of-engagement"), tanya.TooltipName)
|
||||
Media.PlaySoundNotification(Greece, "AlertBleep")
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
ReinforceLongbows = function()
|
||||
if SoutheastTurret.IsDead then
|
||||
return
|
||||
end
|
||||
|
||||
local goals = { LongbowGoal1, LongbowGoal2, LongbowGoal3 }
|
||||
local spawnOffset = 0
|
||||
|
||||
Utils.Do(goals, function(goal)
|
||||
local entry = { LongbowEntry.Location + CVec.New(spawnOffset, 15) }
|
||||
|
||||
Reinforcements.Reinforce(GoodGuy, { "heli" }, entry, 0, function(helicopter)
|
||||
helicopter.Wait(DateTime.Seconds(1))
|
||||
helicopter.AttackMove(goal.Location)
|
||||
|
||||
-- Original behavior was to fire at the ground until out of ammo.
|
||||
Trigger.OnKilled(SoutheastTurret, function()
|
||||
helicopter.Stop()
|
||||
helicopter.Wait(10)
|
||||
helicopter.Move(LongbowExit.Location, 1)
|
||||
helicopter.Destroy()
|
||||
end)
|
||||
end)
|
||||
|
||||
spawnOffset = spawnOffset + 5
|
||||
end)
|
||||
end
|
||||
|
||||
ReinforceBadGuy = function()
|
||||
-- If ForwardCommand dies early, the General will be busy hunting.
|
||||
if General.IsDead or ForwardCommand.IsDead then
|
||||
return
|
||||
end
|
||||
|
||||
BadGuyReinforced = true
|
||||
Media.PlaySpeechNotification(Greece, "SignalFlareWest")
|
||||
local flare = SpawnFlare(NorthFlare.Location)
|
||||
|
||||
Trigger.OnKilled(General, function()
|
||||
RemoveActor(flare, DateTime.Seconds(30))
|
||||
end)
|
||||
|
||||
local waterCamera = SpawnPlayerCamera(NorthWaterEntry.Location, -1)
|
||||
local boatPath = { NorthWaterEntry.Location, BuilderBeach.Location }
|
||||
local cargo = Reinforcements.ReinforceWithTransport(BadGuy, "lst", { "mcv" }, boatPath, { boatPath[1] })[2]
|
||||
|
||||
Utils.Do(cargo, function(builder)
|
||||
Trigger.OnKilled(builder, CheckNewBase)
|
||||
|
||||
Trigger.OnAddedToWorld(builder, function()
|
||||
local builderCamera = SpawnPlayerCamera(builder.Location, -1, "camera.small")
|
||||
builder.Move(BuilderRally.Location)
|
||||
|
||||
builder.CallFunc(function()
|
||||
RemoveActor(waterCamera)
|
||||
RemoveActor(builderCamera)
|
||||
end)
|
||||
|
||||
builder.Deploy()
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
ReinforceNorthChinook = function()
|
||||
local delay = DateTime.Seconds(4)
|
||||
local camera = SpawnPlayerCamera(NorthChinookUnload.Location, -1, "camera.small", delay + DateTime.Seconds(2))
|
||||
|
||||
Trigger.AfterDelay(delay, function()
|
||||
local transport = Actor.Create("tran.north", true, { Owner = USSR, Location = NorthChinookEntry.Location, Facing = Angle.South })
|
||||
local passengers = transport.Passengers
|
||||
|
||||
transport.UnloadPassengers(NorthChinookUnload.Location)
|
||||
transport.Move(SouthChinookExit.Location)
|
||||
transport.Destroy()
|
||||
|
||||
Trigger.OnPassengerExited(transport, function()
|
||||
if transport.PassengerCount > 0 then
|
||||
return
|
||||
end
|
||||
|
||||
-- Original unload is slow. Mimic the timing with a short pause.
|
||||
Trigger.AfterDelay(DateTime.Seconds(3), function()
|
||||
OrderNorthChinookSoldiers(passengers, camera)
|
||||
end)
|
||||
end)
|
||||
|
||||
Trigger.OnAnyKilled(passengers, function()
|
||||
RemoveActor(camera, DateTime.Seconds(1))
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
OrderNorthChinookSoldiers = function(soldiers, camera)
|
||||
local patrolPath =
|
||||
{
|
||||
VillageNortheast.Location,
|
||||
VillageNorthwest.Location,
|
||||
VillageSouthwest.Location,
|
||||
VillageSoutheast.Location
|
||||
}
|
||||
local liveSoldiers = Utils.Where(soldiers, IsAlive)
|
||||
|
||||
Utils.Do(liveSoldiers, function(soldier)
|
||||
soldier.AttackMove(NorthChinookRally.Location)
|
||||
|
||||
soldier.CallFunc(function()
|
||||
Trigger.AfterDelay(1, function()
|
||||
if not AreAllIdleOrDead(liveSoldiers) then
|
||||
return
|
||||
end
|
||||
RemoveActor(camera, DateTime.Seconds(1))
|
||||
GroupAttackMove(liveSoldiers, VillageBridgeCenter.Location, 2)
|
||||
GroupTightPatrol(liveSoldiers, patrolPath, true)
|
||||
GroupHuntOnDamaged(liveSoldiers, Greece)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
ReinforceVillagePatrol = function()
|
||||
if VillagePatrolSent then
|
||||
return
|
||||
end
|
||||
|
||||
VillagePatrolSent = true
|
||||
|
||||
local path =
|
||||
{
|
||||
VillageSoutheast.Location,
|
||||
VillageSouthwest.Location,
|
||||
VillageNorthwest.Location,
|
||||
VillageNortheast.Location
|
||||
}
|
||||
local types = { "e1", "e1", "e2", "dog" }
|
||||
local origin = { VillagePatrolEntry.Location }
|
||||
local group = Reinforcements.Reinforce(USSR, types, origin, 0)
|
||||
GroupTightPatrol(group, path, true)
|
||||
end
|
||||
|
||||
ReinforceGuardHouse = function(intruderType)
|
||||
if GuardHouse.IsDead then
|
||||
return
|
||||
end
|
||||
|
||||
local goal = GuideBarrelGoal.Location
|
||||
if intruderType == TanyaType then
|
||||
goal = PrisonReveal.Location
|
||||
end
|
||||
|
||||
for i = 1, 4 do
|
||||
Trigger.AfterDelay(i * 5, function()
|
||||
local guard = Actor.Create("e1", true, { Owner = USSR, Location = GuardHouseSpawn.Location, SubCell = 4, Facing = Angle.SouthWest })
|
||||
guard.Move(GuardHouseExit.Location)
|
||||
guard.AttackMove(goal)
|
||||
IdleHunt(guard)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
ReinforceHardTeams = function()
|
||||
if Difficulty ~= "hard" then
|
||||
return
|
||||
end
|
||||
|
||||
ReinforceBaseDefenders()
|
||||
ReinforceNorthBeachGuards()
|
||||
ReinforceV2Team()
|
||||
ReinforceNorthEdgeGuards()
|
||||
PrepareSouthChinook()
|
||||
ReinforceHardDogs()
|
||||
end
|
||||
|
||||
ReinforceBaseDefenders = function()
|
||||
local origin = BadGuyRally.Location + CVec.New(2, 2)
|
||||
local types = { "3tnk", "3tnk" }
|
||||
local defenders = Reinforcements.Reinforce(USSR, types, { origin }, 0, function(actor)
|
||||
actor.Wait(1)
|
||||
actor.Scatter()
|
||||
end)
|
||||
GroupHuntOnDamaged(defenders, Greece)
|
||||
|
||||
local structures = { RoadTurretWest, RoadTurretEast, ForwardPower, ForwardCommand, ForwardTech }
|
||||
Trigger.OnAnyKilled(structures, function()
|
||||
GroupIdleHunt(defenders)
|
||||
end)
|
||||
end
|
||||
|
||||
ReinforceNorthBeachGuards = function()
|
||||
local types = { "e1", "e1", "e2", "e1" }
|
||||
local patrolPath = { VillageNortheast.Location, VillageSouthwest.Location }
|
||||
local soldiers = Reinforcements.Reinforce(USSR, types, { NorthFlare.Location }, 0, function(actor)
|
||||
actor.Scatter()
|
||||
end)
|
||||
|
||||
Trigger.OnEnteredFootprint({ GeneralRally.Location }, function(actor, id)
|
||||
if actor.Type ~= "gnrl" then
|
||||
return
|
||||
end
|
||||
|
||||
Trigger.RemoveFootprintTrigger(id)
|
||||
GroupHuntOnDamaged(soldiers, Greece)
|
||||
|
||||
Utils.Do(soldiers, function(soldier)
|
||||
if soldier.IsDead then
|
||||
return
|
||||
end
|
||||
|
||||
soldier.AttackMove(BadGuyRally.Location)
|
||||
soldier.AttackMove(GuideBarrelGoal.Location)
|
||||
soldier.AttackMove(VillageNorthwest.Location)
|
||||
soldier.Patrol(patrolPath, true)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
ReinforceV2Team = function()
|
||||
local rocket = Actor.Create("v2rl", true, { Owner = USSR, Facing = Angle.West, Location = SamRocketEntry.Location })
|
||||
Reinforcements.Reinforce(USSR, { "e1" }, { SamFenceReveal.Location }, 0, function(actor)
|
||||
actor.Guard(rocket)
|
||||
end)
|
||||
end
|
||||
|
||||
PrepareSouthChinook = function()
|
||||
local startPosition = SouthChinookEntry.CenterPosition + WVec.New(0, 0, Actor.CruiseAltitude("tran"))
|
||||
|
||||
Trigger.OnEnteredProximityTrigger(SouthChinookProximity.CenterPosition, WDist.FromCells(8), function(actor, id)
|
||||
if actor.Type ~= TanyaType or not EscortFinished then
|
||||
return
|
||||
end
|
||||
|
||||
Trigger.RemoveProximityTrigger(id)
|
||||
|
||||
local transport = Actor.Create("tran.south", true, { Owner = USSR, CenterPosition = startPosition, Facing = Angle.East })
|
||||
transport.UnloadPassengers(SouthChinookEntry.Location)
|
||||
transport.Move(SouthChinookExit.Location)
|
||||
transport.Destroy()
|
||||
|
||||
Utils.Do(transport.Passengers, function(passenger)
|
||||
Trigger.OnAddedToWorld(passenger, function()
|
||||
passenger.Wait(DateTime.Seconds(1))
|
||||
IdleHunt(passenger)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
ReinforceNorthEdgeGuards = function()
|
||||
local types = { "e1", "e1", "e2" }
|
||||
local guards = Reinforcements.Reinforce(USSR, types, { NorthEdgeGuardEntry.Location }, 0, function(actor)
|
||||
actor.Scatter()
|
||||
end)
|
||||
GroupHuntOnDamaged(guards, Greece)
|
||||
end
|
||||
|
||||
ReinforceStartSoldiers = function()
|
||||
local teams =
|
||||
{
|
||||
{
|
||||
entry = { WestRoadEntry.Location },
|
||||
types = { "e2", "e2", "e1" }
|
||||
},
|
||||
{
|
||||
entry = { RoadTurretRifle2.Location },
|
||||
types = { "e1", "e2", "e4" }
|
||||
}
|
||||
}
|
||||
|
||||
Utils.Do(teams, function(team)
|
||||
local soldiers = Reinforcements.Reinforce(USSR, team.types, team.entry, 15, function(actor)
|
||||
actor.AttackMove(TanyaDrop.Location)
|
||||
actor.Hunt()
|
||||
end)
|
||||
|
||||
Trigger.OnAnyKilled(soldiers, function()
|
||||
IdleHunt(StartSoldier)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
ReinforceHardDogs = function()
|
||||
local startDog = Actor.Create("dog", true, { Owner = USSR, Location = WestRoadEntry.Location, Facing = Angle.South })
|
||||
startDog.Move(WestRoadRally.Location + CVec.New(-1, 0))
|
||||
PrepareStartDogAttack(startDog)
|
||||
|
||||
local turretDog = Actor.Create("dog.areaguard", true, { Owner = USSR, Location = LongbowGoal2.Location, Facing = Angle.SouthWest })
|
||||
turretDog.AddTag("TurretDog")
|
||||
|
||||
Trigger.OnKilled(turretDog, function()
|
||||
GroupIdleHunt(SoutheastTurretGuards)
|
||||
end)
|
||||
end
|
||||
|
||||
PrepareStartDogAttack = function(dog)
|
||||
-- Tanya will take about 100 ticks/4 seconds to touch the ground.
|
||||
local delay = DateTime.Seconds(5) + 5
|
||||
|
||||
Trigger.OnEnteredFootprint({ TanyaDrop.Location }, function(actor, id)
|
||||
if actor.Type ~= TanyaType then
|
||||
return
|
||||
end
|
||||
|
||||
Trigger.RemoveFootprintTrigger(id)
|
||||
Trigger.AfterDelay(delay, function()
|
||||
if dog.IsDead or actor.IsDead then
|
||||
return
|
||||
end
|
||||
|
||||
dog.Attack(actor)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
Reference in New Issue
Block a user