406 lines
13 KiB
Lua
406 lines
13 KiB
Lua
FrenchSquad = { "2tnk", "2tnk", "mcv" }
|
|
|
|
TimerTicks = DateTime.Minutes(10)
|
|
AttackTicks = DateTime.Seconds(52)
|
|
AttackAtFrame = DateTime.Seconds(18)
|
|
AttackAtFrameIncrement = DateTime.Seconds(18)
|
|
Producing = true
|
|
SpawningInfantry = true
|
|
ProduceAtFrame = DateTime.Seconds(12)
|
|
ProduceAtFrameIncrement = DateTime.Seconds(12)
|
|
SovietGroupSize = 4
|
|
SovietAttackGroupSize = 7
|
|
|
|
InfantryGuards = { }
|
|
HarvGuards = { HarvGuard1, HarvGuard2, HarvGuard3 }
|
|
SovietPlatoonUnits = { "e1", "e1", "e2", "e4", "e4", "e1", "e1", "e2", "e4", "e4" }
|
|
SovietTanks = { "3tnk", "3tnk", "3tnk" }
|
|
SovietVehicles = { "3tnk", "3tnk", "v2rl" }
|
|
SovietInfantry = { "e1", "e4", "e2" }
|
|
SovietEntryPoints = { SovietEntry1, SovietEntry2, SovietEntry3 }
|
|
SovietRallyPoints = { SovietRally2, SovietRally4, SovietRally5, SovietRally6 }
|
|
NewSovietEntryPoints = { SovietParaDropEntry, SovietEntry3 }
|
|
NewSovietRallyPoints = { SovietRally3, SovietRally4, SovietRally8 }
|
|
|
|
ParaWaves =
|
|
{
|
|
{ delay = AttackTicks, type = "SovietSquad", target = SovietRally5 },
|
|
{ delay = 0, type = "SovietSquad", target = SovietRally6 },
|
|
{ delay = AttackTicks * 2, type = "SovietSquad", target = SovietParaDrop3 },
|
|
{ delay = 0, type = "SovietPlatoonUnits", target = SovietRally5 },
|
|
{ delay = 0, type = "SovietPlatoonUnits", target = SovietRally6 },
|
|
{ delay = 0, type = "SovietSquad", target = SovietRally2 },
|
|
{ delay = AttackTicks * 2, type = "SovietSquad", target = SovietParaDrop2 },
|
|
{ delay = AttackTicks * 2, type = "SovietSquad", target = SovietParaDrop1 },
|
|
{ delay = AttackTicks * 3, type = "SovietSquad", target = SovietParaDrop1 }
|
|
}
|
|
|
|
IdleHunt = function(unit)
|
|
Trigger.OnIdle(unit, function(a)
|
|
if a.IsInWorld then
|
|
a.Hunt()
|
|
end
|
|
end)
|
|
end
|
|
|
|
GuardHarvester = function(unit, harvester)
|
|
if not unit.IsDead then
|
|
unit.Stop()
|
|
|
|
local start = unit.Location
|
|
if not harvester.IsDead then
|
|
unit.AttackMove(harvester.Location)
|
|
else
|
|
unit.Hunt()
|
|
end
|
|
|
|
Trigger.OnIdle(unit, function()
|
|
if unit.Location == start then
|
|
Trigger.ClearAll(unit)
|
|
else
|
|
unit.AttackMove(start)
|
|
end
|
|
end)
|
|
|
|
Trigger.OnCapture(unit, function()
|
|
Trigger.ClearAll(unit)
|
|
end)
|
|
end
|
|
end
|
|
|
|
ticked = TimerTicks
|
|
Tick = function()
|
|
if soviets.HasNoRequiredUnits() then
|
|
if DestroyObj then
|
|
allies.MarkCompletedObjective(DestroyObj)
|
|
else
|
|
DestroyObj = allies.AddPrimaryObjective("Destroy all Soviet forces in the area.")
|
|
allies.MarkCompletedObjective(DestroyObj)
|
|
end
|
|
end
|
|
|
|
if allies.HasNoRequiredUnits() then
|
|
soviets.MarkCompletedObjective(SovietObj)
|
|
end
|
|
|
|
if soviets.Resources > soviets.ResourceCapacity / 2 then
|
|
soviets.Resources = soviets.ResourceCapacity / 2
|
|
end
|
|
|
|
if DateTime.GameTime == ProduceAtFrame then
|
|
if SpawningInfantry then
|
|
ProduceAtFrame = ProduceAtFrame + ProduceAtFrameIncrement
|
|
ProduceAtFrameIncrement = ProduceAtFrameIncrement * 2 - 5
|
|
SpawnSovietInfantry()
|
|
end
|
|
end
|
|
|
|
if DateTime.GameTime == AttackAtFrame then
|
|
AttackAtFrame = AttackAtFrame + AttackAtFrameIncrement
|
|
AttackAtFrameIncrement = AttackAtFrameIncrement * 2 - 5
|
|
if Producing then
|
|
SpawnSovietVehicle(SovietEntryPoints, SovietRallyPoints)
|
|
else
|
|
SpawnSovietVehicle(NewSovietEntryPoints, NewSovietRallyPoints)
|
|
end
|
|
end
|
|
|
|
if DateTime.Minutes(5) == ticked then
|
|
Media.PlaySpeechNotification(allies, "WarningFiveMinutesRemaining")
|
|
InitCountDown()
|
|
end
|
|
|
|
if ticked > 0 then
|
|
UserInterface.SetMissionText("Soviet reinforcements arrive in " .. Utils.FormatTime(ticked), TimerColor)
|
|
ticked = ticked - 1
|
|
elseif ticked == 0 then
|
|
FinishTimer()
|
|
ticked = ticked - 1
|
|
end
|
|
end
|
|
|
|
SendSovietParadrops = function(table)
|
|
local paraproxy = Actor.Create(table.type, false, { Owner = soviets })
|
|
units = paraproxy.SendParatroopers(table.target.CenterPosition)
|
|
Utils.Do(units, function(unit) IdleHunt(unit) end)
|
|
paraproxy.Destroy()
|
|
end
|
|
|
|
SpawnSovietInfantry = function()
|
|
soviets.Build({ Utils.Random(SovietInfantry) }, function(units)
|
|
IdleHunt(units[1])
|
|
end)
|
|
end
|
|
|
|
SpawnSovietVehicle = function(spawnpoints, rallypoints)
|
|
local route = Utils.RandomInteger(1, #spawnpoints + 1)
|
|
local rally = Utils.RandomInteger(1, #rallypoints + 1)
|
|
local unit = Reinforcements.Reinforce(soviets, { Utils.Random(SovietVehicles) }, { spawnpoints[route].Location })[1]
|
|
unit.AttackMove(rallypoints[rally].Location)
|
|
IdleHunt(unit)
|
|
|
|
Trigger.OnCapture(unit, function()
|
|
Trigger.ClearAll(unit)
|
|
end)
|
|
end
|
|
|
|
SpawnAndAttack = function(types, entry)
|
|
local units = Reinforcements.Reinforce(soviets, types, { entry })
|
|
Utils.Do(units, function(unit)
|
|
IdleHunt(unit)
|
|
|
|
Trigger.OnCapture(unit, function()
|
|
Trigger.ClearAll(unit)
|
|
end)
|
|
end)
|
|
return units
|
|
end
|
|
|
|
SendFrenchReinforcements = function()
|
|
local camera = Actor.Create("camera", true, { Owner = allies, Location = SovietRally1.Location })
|
|
Beacon.New(allies, FranceEntry.CenterPosition - WVec.New(0, 3 * 1024, 0))
|
|
Media.PlaySpeechNotification(allies, "AlliedReinforcementsArrived")
|
|
Reinforcements.Reinforce(allies, FrenchSquad, { FranceEntry.Location, FranceRally.Location })
|
|
Trigger.AfterDelay(DateTime.Seconds(3), function() camera.Destroy() end)
|
|
end
|
|
|
|
FrenchReinforcements = function()
|
|
Camera.Position = SovietRally1.CenterPosition
|
|
|
|
if drum1.IsDead or drum2.IsDead or drum3.IsDead then
|
|
SendFrenchReinforcements()
|
|
return
|
|
end
|
|
|
|
powerproxy = Actor.Create("powerproxy.parabombs", false, { Owner = allies })
|
|
powerproxy.SendAirstrike(drum1.CenterPosition, false, Facing.NorthEast + 4)
|
|
powerproxy.SendAirstrike(drum2.CenterPosition, false, Facing.NorthEast)
|
|
powerproxy.SendAirstrike(drum3.CenterPosition, false, Facing.NorthEast - 4)
|
|
powerproxy.Destroy()
|
|
|
|
Trigger.AfterDelay(DateTime.Seconds(3), function()
|
|
SendFrenchReinforcements()
|
|
end)
|
|
end
|
|
|
|
FinalAttack = function()
|
|
local units1 = SpawnAndAttack(SovietTanks, SovietEntry1.Location)
|
|
local units2 = SpawnAndAttack(SovietTanks, SovietEntry1.Location)
|
|
local units3 = SpawnAndAttack(SovietTanks, SovietEntry2.Location)
|
|
local units4 = SpawnAndAttack(SovietPlatoonUnits, SovietEntry1.Location)
|
|
local units5 = SpawnAndAttack(SovietPlatoonUnits, SovietEntry2.Location)
|
|
|
|
local units = { }
|
|
local insert = function(table)
|
|
local count = #units
|
|
Utils.Do(table, function(unit)
|
|
units[count] = unit
|
|
count = count + 1
|
|
end)
|
|
end
|
|
|
|
insert(units1)
|
|
insert(units2)
|
|
insert(units3)
|
|
insert(units4)
|
|
insert(units5)
|
|
|
|
Trigger.OnAllKilledOrCaptured(units, function()
|
|
if not DestroyObj then
|
|
Media.DisplayMessage("Excellent work Commander! We have reinforced our position enough to initiate a counter-attack.", "Incoming Report")
|
|
DestroyObj = allies.AddPrimaryObjective("Destroy the remaining Soviet forces in the area.")
|
|
end
|
|
allies.MarkCompletedObjective(SurviveObj)
|
|
end)
|
|
end
|
|
|
|
FinishTimer = function()
|
|
for i = 0, 9, 1 do
|
|
local c = TimerColor
|
|
if i % 2 == 0 then
|
|
c = HSLColor.White
|
|
end
|
|
|
|
Trigger.AfterDelay(DateTime.Seconds(i), function() UserInterface.SetMissionText("Soviet reinforcements have arrived!", c) end)
|
|
end
|
|
Trigger.AfterDelay(DateTime.Seconds(10), function() UserInterface.SetMissionText("") end)
|
|
end
|
|
|
|
wave = 1
|
|
SendParadrops = function()
|
|
SendSovietParadrops(ParaWaves[wave])
|
|
|
|
wave = wave + 1
|
|
if wave > #ParaWaves then
|
|
Trigger.AfterDelay(AttackTicks, FrenchReinforcements)
|
|
else
|
|
Trigger.AfterDelay(ParaWaves[wave].delay, SendParadrops)
|
|
end
|
|
end
|
|
|
|
SetupBridges = function()
|
|
local count = 0
|
|
local counter = function()
|
|
count = count + 1
|
|
if count == 2 then
|
|
allies.MarkCompletedObjective(RepairBridges)
|
|
end
|
|
end
|
|
|
|
Media.DisplayMessage("Commander! The Soviets destroyed the bridges to disable our reinforcements. Repair them for additional reinforcements.", "Incoming Report")
|
|
RepairBridges = allies.AddSecondaryObjective("Repair the two southern bridges.")
|
|
|
|
local bridgeA = Map.ActorsInCircle(BrokenBridge1.CenterPosition, WDist.FromCells(1), function(self) return self.Type == "bridge1" end)
|
|
local bridgeB = Map.ActorsInCircle(BrokenBridge2.CenterPosition, WDist.FromCells(1), function(self) return self.Type == "bridge1" end)
|
|
|
|
Utils.Do(bridgeA, function(bridge)
|
|
Trigger.OnDamaged(bridge, function()
|
|
Utils.Do(bridgeA, function(self) Trigger.ClearAll(self) end)
|
|
Media.PlaySpeechNotification(allies, "AlliedReinforcementsArrived")
|
|
Reinforcements.Reinforce(allies, { "1tnk", "2tnk", "2tnk" }, { ReinforcementsEntry1.Location, ReinforcementsRally1.Location })
|
|
counter()
|
|
end)
|
|
end)
|
|
Utils.Do(bridgeB, function(bridge)
|
|
Trigger.OnDamaged(bridge, function()
|
|
Utils.Do(bridgeB, function(self) Trigger.ClearAll(self) end)
|
|
Media.PlaySpeechNotification(allies, "AlliedReinforcementsArrived")
|
|
Reinforcements.Reinforce(allies, { "jeep", "1tnk", "1tnk" }, { ReinforcementsEntry2.Location, ReinforcementsRally2.Location })
|
|
counter()
|
|
end)
|
|
end)
|
|
end
|
|
|
|
InitCountDown = function()
|
|
Trigger.AfterDelay(DateTime.Minutes(1), function() Media.PlaySpeechNotification(allies, "WarningFourMinutesRemaining") end)
|
|
Trigger.AfterDelay(DateTime.Minutes(2), function() Media.PlaySpeechNotification(allies, "WarningThreeMinutesRemaining") end)
|
|
Trigger.AfterDelay(DateTime.Minutes(3), function() Media.PlaySpeechNotification(allies, "WarningTwoMinutesRemaining") end)
|
|
Trigger.AfterDelay(DateTime.Minutes(4), function() Media.PlaySpeechNotification(allies, "WarningOneMinuteRemaining") end)
|
|
end
|
|
|
|
InitObjectives = function()
|
|
Trigger.OnObjectiveAdded(allies, function(p, id)
|
|
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
|
|
end)
|
|
|
|
SurviveObj = allies.AddPrimaryObjective("Enforce your position and hold-out the onslaught.")
|
|
SovietObj = soviets.AddPrimaryObjective("Eliminate all Allied forces.")
|
|
|
|
Trigger.AfterDelay(DateTime.Seconds(15), function()
|
|
SetupBridges()
|
|
end)
|
|
|
|
Trigger.OnObjectiveCompleted(allies, function(p, id)
|
|
Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed")
|
|
end)
|
|
Trigger.OnObjectiveFailed(allies, function(p, id)
|
|
Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed")
|
|
end)
|
|
|
|
Trigger.OnPlayerLost(allies, function()
|
|
Media.PlaySpeechNotification(allies, "Lose")
|
|
end)
|
|
Trigger.OnPlayerWon(allies, function()
|
|
Media.PlaySpeechNotification(allies, "Win")
|
|
Media.DisplayMessage("We have destroyed the remaining Soviet presence!", "Incoming Report")
|
|
end)
|
|
end
|
|
|
|
InitMission = function()
|
|
Camera.Position = AlliesBase.CenterPosition
|
|
TimerColor = HSLColor.Red
|
|
|
|
Trigger.AfterDelay(DateTime.Seconds(1), function() Media.PlaySpeechNotification(allies, "MissionTimerInitialised") end)
|
|
|
|
Trigger.AfterDelay(TimerTicks, function()
|
|
Media.DisplayMessage("The Soviet reinforcements are approaching!", "Incoming Report")
|
|
Media.PlaySpeechNotification(allies, "SovietReinforcementsArrived")
|
|
SpawnSovietVehicle(NewSovietEntryPoints, NewSovietRallyPoints)
|
|
FinalAttack()
|
|
Producing = false
|
|
end)
|
|
|
|
Trigger.AfterDelay(AttackTicks, SendParadrops)
|
|
|
|
Trigger.OnKilled(drum1, function() --Kill the remaining stuff from FrenchReinforcements
|
|
if not boom2.IsDead then boom2.Kill() end
|
|
if not boom4.IsDead then boom4.Kill() end
|
|
if not drum2.IsDead then drum2.Kill() end
|
|
if not drum3.IsDead then drum3.Kill() end
|
|
end)
|
|
Trigger.OnKilled(drum2, function()
|
|
if not boom1.IsDead then boom1.Kill() end
|
|
if not boom5.IsDead then boom5.Kill() end
|
|
Trigger.AfterDelay(DateTime.Seconds(1), function() if not drum1.IsDead then drum1.Kill() end end)
|
|
end)
|
|
Trigger.OnKilled(drum3, function()
|
|
if not boom1.IsDead then boom1.Kill() end
|
|
if not boom3.IsDead then boom3.Kill() end
|
|
Trigger.AfterDelay(DateTime.Seconds(1), function() if not drum1.IsDead then drum1.Kill() end end)
|
|
end)
|
|
end
|
|
|
|
SetupSoviets = function()
|
|
Barrack1.IsPrimaryBuilding = true
|
|
Barrack1.RallyPoint = SovietRally.Location
|
|
Trigger.OnKilledOrCaptured(Barrack1, function()
|
|
SpawningInfantry = false
|
|
end)
|
|
|
|
Harvester1.FindResources()
|
|
Trigger.OnDamaged(Harvester1, function()
|
|
Utils.Do(HarvGuards, function(unit)
|
|
GuardHarvester(unit, Harvester1)
|
|
end)
|
|
end)
|
|
Trigger.OnCapture(Harvester1, function()
|
|
Trigger.ClearAll(Harvester1)
|
|
end)
|
|
|
|
Harvester2.FindResources()
|
|
Trigger.OnDamaged(Harvester2, function()
|
|
Utils.Do(InfantryGuards, function(unit) GuardHarvester(unit, Harvester2) end)
|
|
|
|
local toBuild = { }
|
|
for i = 1, 6, 1 do
|
|
toBuild[i] = Utils.Random(SovietInfantry)
|
|
end
|
|
|
|
soviets.Build(toBuild, function(units)
|
|
Utils.Do(units, function(unit)
|
|
InfantryGuards[#InfantryGuards + 1] = unit
|
|
GuardHarvester(unit, Harvester2)
|
|
end)
|
|
end)
|
|
end)
|
|
Trigger.OnCapture(Harvester2, function()
|
|
Trigger.ClearAll(Harvester2)
|
|
end)
|
|
|
|
Trigger.AfterDelay(0, function()
|
|
local buildings = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(self) return self.Owner == soviets and self.HasProperty("StartBuildingRepairs") end)
|
|
Utils.Do(buildings, function(actor)
|
|
Trigger.OnDamaged(actor, function(building)
|
|
if building.Owner == soviets and building.Health < building.MaxHealth * 3/4 then
|
|
building.StartBuildingRepairs()
|
|
end
|
|
end)
|
|
end)
|
|
|
|
local units = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(self) return self.Owner == soviets and self.HasProperty("AutoTarget") end)
|
|
Utils.Do(units, function(unit)
|
|
unit.Stance = "Defend"
|
|
end)
|
|
end)
|
|
end
|
|
|
|
WorldLoaded = function()
|
|
|
|
allies = Player.GetPlayer("Allies")
|
|
soviets = Player.GetPlayer("Soviets")
|
|
|
|
InitObjectives()
|
|
InitMission()
|
|
SetupSoviets()
|
|
end
|