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:
268
mods/ra/maps/siberian-conflict-1-fresh-tracks/fresh-tracks.lua
Normal file
268
mods/ra/maps/siberian-conflict-1-fresh-tracks/fresh-tracks.lua
Normal file
@@ -0,0 +1,268 @@
|
||||
--[[
|
||||
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.
|
||||
]]
|
||||
TimerTicks = DateTime.Minutes(8)
|
||||
Squad1 = { FirstSquad1, FirstSquad2, FirstSquad3 }
|
||||
Squad2 = { SecondSquad1, SecondSquad2, SecondSquad3 }
|
||||
PatrolMammothPath = { Patrol1.Location, Patrol2.Location, Patrol3.Location, Patrol4.Location, Patrol5.Location, Patrol6.Location, Patrol7.Location }
|
||||
ConvoyEscape = { CPos.New(113, 42), CPos.New(117, 71) }
|
||||
|
||||
ConvoyUnits =
|
||||
{
|
||||
easy = { { "e2", "e2", "e2", "truk", "truk", "truk" }, { "3tnk", "3tnk", "truk", "truk", "truk" } },
|
||||
normal = { { "3tnk", "3tnk", "3tnk", "truk", "truk", "truk" }, { "3tnk", "v2rl", "e2", "e1", "e1", "truk", "truk", "truk" } },
|
||||
hard = { { "3tnk", "3tnk", "3tnk", "3tnk", "truk", "truk", "truk" }, { "3tnk", "v2rl", "v2rl", "e1", "e1", "e4", "e4", "truk", "truk", "truk", "4tnk" }, { "ttnk", "ttnk", "ttnk", "shok", "shok", "shok", "shok", "truk", "truk", "truk" } }
|
||||
}
|
||||
|
||||
BaseConvoyUnits = { "3tnk", "ttnk", "ttnk", "ttnk", "truk", "truk", "truk" }
|
||||
FinalConvoyUnits = { "3tnk", "3tnk", "3tnk", "3tnk", "truk", "truk", "truk", "4tnk" }
|
||||
|
||||
AttackPaths =
|
||||
{
|
||||
{ ExitNorth.Location },
|
||||
{ ExitEast.Location },
|
||||
{ AttackEntry1.Location },
|
||||
{ AttackEntry2.Location }
|
||||
}
|
||||
|
||||
AttackWaveUnits = { { "3tnk", "3tnk" }, { "e1", "e1", "e1", "e2", "e2", "e4", "e4" }, { "shok", "shok", "shok", "shok", "shok" }, { "ttnk", "ttnk" }, { "4tnk", "e1", "e1", "e2" }, { "v2rl", "v2rl", "ftrk", "ftrk", "ftrk" } }
|
||||
|
||||
ConvoyPaths =
|
||||
{
|
||||
{ NorthwestEntry.Location, NorthwestPath1.Location, NorthwestBridge.Location, Patrol7.Location, Patrol6.Location, NortheastBridge.Location, NorthwestPath3.Location, ExitNorth.Location },
|
||||
{ CenterEntry.Location, CenterPath1.Location, CenterPath2.Location, Patrol1.Location, Patrol7.Location, Patrol6.Location, NortheastBridge.Location, NorthwestPath3.Location, ExitNorth.Location },
|
||||
{ CenterEntry.Location, CenterPath1.Location, CenterPath2.Location, Patrol1.Location, Patrol2.Location, SouthPath2.Location, SoutheastBridge.Location, SouthPath3.Location, ExitEast.Location },
|
||||
{ SouthEntry.Location, SouthPath1.Location, Patrol2.Location, SouthPath2.Location, SoutheastBridge.Location, SouthPath3.Location, ExitEast.Location }
|
||||
}
|
||||
|
||||
BaseConvoyPath = { BaseEntry.Location, BasePath1.Location, CenterPath2.Location, Patrol1.Location, Patrol7.Location, Patrol6.Location, NortheastBridge.Location, NorthwestPath3.Location, ExitNorth.Location }
|
||||
FinalConvoyPath = { NorthEntry.Location, Patrol7.Location, Patrol6.Location, Patrol5.Location, FinalConvoy1.Location, ExitEast.Location }
|
||||
|
||||
OpeningMoves = function()
|
||||
Utils.Do(Squad1, function(actor)
|
||||
actor.AttackMove(AlliedBase.Location)
|
||||
end)
|
||||
|
||||
Utils.Do(Squad2, function(actor)
|
||||
actor.AttackMove(AlliedBase.Location)
|
||||
end)
|
||||
|
||||
PatrolMammoth.Patrol(PatrolMammothPath, true, 10)
|
||||
end
|
||||
|
||||
AttackWaveDelays =
|
||||
{
|
||||
easy = { DateTime.Seconds(40), DateTime.Seconds(80) },
|
||||
normal = { DateTime.Seconds(30), DateTime.Seconds(60) },
|
||||
hard = { DateTime.Seconds(20), DateTime.Seconds(40) }
|
||||
}
|
||||
|
||||
AttackWaves = function()
|
||||
local attackpath = Utils.Random(AttackPaths)
|
||||
local attackers = Reinforcements.Reinforce(USSR, Utils.Random(AttackWaveUnits), { attackpath[1] })
|
||||
Utils.Do(attackers, function(unit)
|
||||
Trigger.OnAddedToWorld(unit, function()
|
||||
unit.AttackMove(AlliedBase.Location)
|
||||
IdleHunt(unit)
|
||||
end)
|
||||
end)
|
||||
|
||||
Trigger.AfterDelay(Utils.RandomInteger(AttackWaveDelay[1], AttackWaveDelay[2]), AttackWaves)
|
||||
end
|
||||
|
||||
ConvoyWaves =
|
||||
{
|
||||
easy = 2,
|
||||
normal = 3,
|
||||
hard = 4
|
||||
}
|
||||
ConvoysPassed = 0
|
||||
|
||||
SendConvoys = function()
|
||||
ConvoysSent = true
|
||||
Media.PlaySpeechNotification(Allies, "ConvoyApproaching")
|
||||
local path = Utils.Random(ConvoyPaths)
|
||||
local units = Reinforcements.Reinforce(USSR, Utils.Random(ConvoyUnits), { path[1] })
|
||||
local lastWaypoint = path[#path]
|
||||
Utils.Do(units, function(unit)
|
||||
Trigger.OnAddedToWorld(unit, function()
|
||||
if unit.Type == "truk" then
|
||||
Utils.Do(path, function(waypoint)
|
||||
unit.Move(waypoint)
|
||||
end)
|
||||
|
||||
Trigger.OnIdle(unit, function()
|
||||
unit.Move(lastWaypoint)
|
||||
end)
|
||||
else
|
||||
unit.Patrol(path)
|
||||
Trigger.OnIdle(unit, function()
|
||||
unit.AttackMove(lastWaypoint)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
ConvoysPassed = ConvoysPassed + 1
|
||||
if ConvoysPassed <= ConvoyWaves[Difficulty] then
|
||||
Trigger.AfterDelay(DateTime.Seconds(90), SendConvoys)
|
||||
else
|
||||
FinalTrucks()
|
||||
end
|
||||
end
|
||||
|
||||
FinalTrucks = function()
|
||||
Trigger.AfterDelay(DateTime.Minutes(1), function()
|
||||
Media.PlaySpeechNotification(Allies, "ConvoyApproaching")
|
||||
local basePath = BaseConvoyPath
|
||||
local baseWaypoint = basePath[#basePath]
|
||||
local baseConvoy = Reinforcements.Reinforce(USSR, BaseConvoyUnits, { basePath[1] })
|
||||
Utils.Do(baseConvoy, function(unit)
|
||||
Trigger.OnAddedToWorld(unit, function()
|
||||
Utils.Do(basePath, function(waypoint)
|
||||
unit.Move(waypoint)
|
||||
end)
|
||||
|
||||
Trigger.OnIdle(unit, function()
|
||||
unit.Move(baseWaypoint)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
Trigger.AfterDelay(DateTime.Minutes(2), function()
|
||||
Media.PlaySpeechNotification(Allies, "ConvoyApproaching")
|
||||
local finalPath = FinalConvoyPath
|
||||
local finalWaypoint = finalPath[#finalPath]
|
||||
local finalConvoy = Reinforcements.Reinforce(USSR, FinalConvoyUnits, { finalPath[1] })
|
||||
Utils.Do(finalConvoy, function(unit)
|
||||
Trigger.OnAddedToWorld(unit, function()
|
||||
Utils.Do(finalPath, function(waypoint)
|
||||
unit.Move(waypoint)
|
||||
end)
|
||||
|
||||
Trigger.OnIdle(unit, function()
|
||||
unit.Move(finalWaypoint)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
Trigger.OnAllKilled(Utils.Where(finalConvoy, function(a) return a.Type == "truk" end), function()
|
||||
Allies.MarkCompletedObjective(StopTrucks)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
ConvoyExit = function()
|
||||
Trigger.OnEnteredFootprint(ConvoyEscape, function(actor, id)
|
||||
if actor.Owner == USSR and actor.Type == "truk" then
|
||||
actor.Stop()
|
||||
actor.Destroy()
|
||||
Allies.MarkFailedObjective(StopTrucks)
|
||||
elseif actor.Owner == USSR and actor.Type ~= "truk" then
|
||||
actor.Stop()
|
||||
actor.Destroy()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
BridgeTriggers = function()
|
||||
Trigger.OnKilled(BridgeBarrel1, function()
|
||||
local theNorthEastBridge = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Type == "bridge2" end)[1]
|
||||
if not theNorthEastBridge.IsDead then
|
||||
theNorthEastBridge.Kill()
|
||||
end
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(BridgeBarrel2, function()
|
||||
local theNorthwestBridge = Map.ActorsInBox(NorthwestPath1.CenterPosition, NorthEntry.CenterPosition, function(self) return self.Type == "bridge1" end)[1]
|
||||
if not theNorthwestBridge.IsDead then
|
||||
theNorthwestBridge.Kill()
|
||||
end
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(BridgeBarrel3, function()
|
||||
local theSoutheastBridge = Map.ActorsInBox(SoutheastBridge.CenterPosition, SouthPath3.CenterPosition, function(self) return self.Type == "bridge1" end)[1]
|
||||
if not theSoutheastBridge.IsDead then
|
||||
theSoutheastBridge.Kill()
|
||||
end
|
||||
end)
|
||||
|
||||
AllThreeBridges = Utils.Where(Map.ActorsInWorld, function(actor)
|
||||
return
|
||||
actor.Type == "bridge1" or
|
||||
actor.Type == "bridge2"
|
||||
end)
|
||||
|
||||
Trigger.OnAllKilled(AllThreeBridges, function()
|
||||
Allies.MarkCompletedObjective(DestroyBridges)
|
||||
end)
|
||||
end
|
||||
|
||||
FirstTrucksEntering = UserInterface.GetFluentMessage("first-trucks-entering")
|
||||
FinishTimer = function()
|
||||
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(FirstTrucksEntering, c) end)
|
||||
end
|
||||
Trigger.AfterDelay(DateTime.Seconds(6), function() UserInterface.SetMissionText("") end)
|
||||
end
|
||||
|
||||
Ticked = TimerTicks
|
||||
ConvoysSent = false
|
||||
Tick = function()
|
||||
if Ticked > 0 then
|
||||
if (Ticked % DateTime.Seconds(1)) == 0 then
|
||||
Timer = UserInterface.GetFluentMessage("first-trucks-arrive-in", { ["time"] = Utils.FormatTime(Ticked) })
|
||||
UserInterface.SetMissionText(Timer, TimerColor)
|
||||
end
|
||||
Ticked = Ticked - 1
|
||||
elseif Ticked == 0 and not ConvoysSent then
|
||||
SendConvoys()
|
||||
FinishTimer()
|
||||
end
|
||||
|
||||
if Allies.HasNoRequiredUnits() then
|
||||
USSR.MarkCompletedObjective(SovietObj)
|
||||
end
|
||||
end
|
||||
|
||||
WorldLoaded = function()
|
||||
Allies = Player.GetPlayer("Allies")
|
||||
USSR = Player.GetPlayer("USSR")
|
||||
|
||||
SovietObj = AddPrimaryObjective(USSR, "")
|
||||
StopTrucks = AddPrimaryObjective(Allies, "destroy-soviet-convoy")
|
||||
DestroyBridges = AddSecondaryObjective(Allies, "destroy-bridges-slow-convoy")
|
||||
|
||||
InitObjectives(Allies)
|
||||
|
||||
Trigger.AfterDelay(DateTime.Minutes(3), function()
|
||||
Media.PlaySpeechNotification(Allies, "WarningFiveMinutesRemaining")
|
||||
end)
|
||||
Trigger.AfterDelay(DateTime.Minutes(5), function()
|
||||
Media.PlaySpeechNotification(Allies, "WarningThreeMinutesRemaining")
|
||||
end)
|
||||
Trigger.AfterDelay(DateTime.Minutes(7), function()
|
||||
Media.PlaySpeechNotification(Allies, "WarningOneMinuteRemaining")
|
||||
end)
|
||||
|
||||
Camera.Position = AlliedBase.CenterPosition
|
||||
TimerColor = Allies.Color
|
||||
OpeningMoves()
|
||||
Trigger.AfterDelay(DateTime.Seconds(30), AttackWaves)
|
||||
ConvoyExit()
|
||||
BridgeTriggers()
|
||||
|
||||
ConvoyUnits = ConvoyUnits[Difficulty]
|
||||
AttackWaveDelay = AttackWaveDelays[Difficulty]
|
||||
end
|
||||
Reference in New Issue
Block a user