Add navy orders, fixes to Soviet 06a

This commit is contained in:
JovialFeline
2024-04-11 18:27:45 -04:00
committed by Gustas
parent 81bcff0f8a
commit ff5b5149b3
4 changed files with 508 additions and 239 deletions

View File

@@ -26,10 +26,10 @@ Players:
Faction: allies Faction: allies
PlayerReference@Greece: PlayerReference@Greece:
Name: Greece Name: Greece
Bot: campaign
Faction: allies Faction: allies
Color: E2E6F5 Color: E2E6F5
Enemies: USSR Enemies: USSR
Bot: campaign
PlayerReference@USSR: PlayerReference@USSR:
Name: USSR Name: USSR
AllowBots: False AllowBots: False
@@ -512,34 +512,38 @@ Actors:
Actor155: tc01 Actor155: tc01
Location: 33,1 Location: 33,1
Owner: Neutral Owner: Neutral
Actor156: hbox Hbox1: hbox
Location: 19,23 Location: 19,23
Owner: Greece Owner: Greece
Actor157: hbox Hbox2: hbox
Location: 29,23 Location: 29,23
Owner: Greece Owner: Greece
Actor158: gun Gun3: gun
Location: 20,23 Location: 20,23
Owner: Greece Owner: Greece
Facing: 512 Facing: 512
Actor159: gun TurretFacing: 0
Gun4: gun
Location: 28,23 Location: 28,23
Owner: Greece Owner: Greece
Facing: 512 Facing: 512
Actor163: gap TurretFacing: 0
Gap: gap
Location: 24,22 Location: 24,22
Owner: Greece Owner: Greece
Actor164: syrd Syrd: syrd
Location: 35,14 Location: 35,14
Owner: Greece Owner: Greece
Actor167: gun Gun1: gun
Location: 33,5 Location: 33,5
Owner: Greece Owner: Greece
Facing: 768 Facing: 768
Actor168: gun TurretFacing: 512
Gun2: gun
Location: 33,9 Location: 33,9
Owner: Greece Owner: Greece
Facing: 768 Facing: 768
TurretFacing: 512
Actor169: v07 Actor169: v07
Location: 66,4 Location: 66,4
Owner: Greece Owner: Greece
@@ -557,60 +561,62 @@ Actors:
Actor173: v06 Actor173: v06
Location: 68,4 Location: 68,4
Owner: Greece Owner: Greece
Actor174: powr Powr1: powr
Location: 20,2 Location: 20,2
Owner: Greece Owner: Greece
Actor175: powr Powr2: powr
Location: 25,2 Location: 25,2
Owner: Greece Owner: Greece
Actor179: 2tnk Actor179: 2tnk
Location: 73,35 Location: 73,35
Owner: Greece Owner: Greece
Facing: 640 Facing: 384
Actor180: 2tnk Actor180: 2tnk
Location: 72,34 Location: 72,34
Owner: Greece Owner: Greece
Facing: 640 Facing: 384
Actor181: 2tnk Actor181: 2tnk
Location: 71,33 Location: 71,33
Owner: Greece Owner: Greece
Facing: 640 Facing: 384
Actor182: arty Actor182: arty
Location: 74,33 Location: 74,33
Owner: Greece Owner: Greece
Facing: 640 Facing: 384
Stance: Defend
Actor183: arty Actor183: arty
Location: 73,32 Location: 73,32
Owner: Greece Owner: Greece
Facing: 640 Facing: 384
Stance: Defend
Actor186: 3tnk Actor186: 3tnk
Location: 56,47 Location: 56,47
Owner: USSR Owner: USSR
Facing: 128 Facing: 896
Actor187: 3tnk Actor187: 3tnk
Location: 60,49 Location: 60,49
Owner: USSR Owner: USSR
Facing: 128 Facing: 896
Actor191: v2rl Actor191: v2rl
Location: 57,49 Location: 57,49
Owner: USSR Owner: USSR
Facing: 128 Facing: 896
Actor193: 2tnk Actor193: 2tnk
Location: 73,31 Location: 73,31
Owner: Greece Owner: Greece
Facing: 640 Facing: 384
Actor194: 2tnk Actor194: 2tnk
Location: 75,33 Location: 75,33
Owner: Greece Owner: Greece
Facing: 640 Facing: 384
Actor195: 2tnk Actor195: 2tnk
Location: 85,18 Location: 85,18
Owner: Greece Owner: Greece
Facing: 640 Facing: 384
Actor196: 2tnk Actor196: 2tnk
Location: 88,20 Location: 88,20
Owner: Greece Owner: Greece
Facing: 640 Facing: 384
Actor197: 2tnk Actor197: 2tnk
Location: 22,23 Location: 22,23
Owner: Greece Owner: Greece
@@ -622,11 +628,13 @@ Actors:
Actor199: arty Actor199: arty
Location: 18,23 Location: 18,23
Owner: Greece Owner: Greece
Facing: 384 Facing: 640
Stance: Defend
Actor200: arty Actor200: arty
Location: 30,23 Location: 30,23
Owner: Greece Owner: Greece
Facing: 640 Facing: 384
Stance: Defend
Actor202: 1tnk Actor202: 1tnk
Location: 23,21 Location: 23,21
Owner: Greece Owner: Greece
@@ -638,64 +646,65 @@ Actors:
Actor204: 2tnk Actor204: 2tnk
Location: 40,6 Location: 40,6
Owner: Greece Owner: Greece
Facing: 768 Facing: 256
Actor205: 2tnk Actor205: 2tnk
Location: 40,8 Location: 40,8
Owner: Greece Owner: Greece
Facing: 768 Facing: 256
Actor206: arty Actor206: arty
Location: 40,7 Location: 40,7
Owner: Greece Owner: Greece
Facing: 768 Facing: 256
Stance: Defend
Actor207: 1tnk Actor207: 1tnk
Location: 77,10 Location: 77,10
Owner: Greece Owner: Greece
Facing: 768 Facing: 256
Actor208: 1tnk Actor208: 1tnk
Location: 77,11 Location: 77,11
Owner: Greece Owner: Greece
Facing: 768 Facing: 256
Actor209: 1tnk Actor209: 1tnk
Location: 77,12 Location: 77,12
Owner: Greece Owner: Greece
Facing: 768 Facing: 256
Actor210: ca BridgeBreaker2: ca
Location: 87,29 Location: 87,29
Owner: Greece Owner: Greece
Facing: 896 Facing: 128
Actor211: ca BridgeBreaker1: ca
Location: 87,25 Location: 87,25
Owner: Greece Owner: Greece
Facing: 640 Facing: 384
Actor212: ca ResponseCruiser: ca
Location: 76,22 Location: 76,22
Owner: Greece Owner: Greece
Facing: 896 Facing: 128
Actor213: pt Actor213: pt
Location: 38,4 Location: 38,4
Owner: Greece Owner: Greece
Facing: 768 Facing: 256
Actor214: pt Actor214: pt
Location: 38,10 Location: 38,10
Owner: Greece Owner: Greece
Facing: 768 Facing: 256
Actor215: dd Actor215: dd
Location: 55,15 Location: 55,15
Owner: Greece Owner: Greece
Facing: 768 Facing: 256
Actor216: waypoint waypoint0: waypoint
Location: 39,13 Location: 39,13
Owner: Neutral Owner: Neutral
Actor235: silo Silo4: silo
Owner: Greece Owner: Greece
Location: 26,9 Location: 26,9
Actor236: silo Silo3: silo
Owner: Greece Owner: Greece
Location: 24,9 Location: 24,9
Actor237: silo Silo1: silo
Owner: Greece Owner: Greece
Location: 27,2 Location: 27,2
Actor238: silo Silo2: silo
Owner: Greece Owner: Greece
Location: 27,3 Location: 27,3
waypoint78: waypoint waypoint78: waypoint
@@ -723,7 +732,7 @@ Actors:
APCWaypoint2: waypoint APCWaypoint2: waypoint
Location: 58,51 Location: 58,51
Owner: Neutral Owner: Neutral
Apwr: apwr Apwr1: apwr
Location: 18,12 Location: 18,12
Owner: Greece Owner: Greece
Apwr2: apwr Apwr2: apwr
@@ -735,17 +744,17 @@ Actors:
AttackWaypoint2: waypoint AttackWaypoint2: waypoint
Owner: Neutral Owner: Neutral
Location: 35,30 Location: 35,30
Barr: tent Tent: tent
Location: 29,16 Location: 29,16
Owner: Greece Owner: Greece
BaseAttacker1: 1tnk BaseAttacker1: 1tnk
Location: 76,35 Location: 76,35
Owner: Greece Owner: Greece
Facing: 640 Facing: 384
BaseAttacker2: 1tnk BaseAttacker2: 1tnk
Location: 71,30 Location: 71,30
Owner: Greece Owner: Greece
Facing: 640 Facing: 384
CameraBarrier: camera CameraBarrier: camera
Location: 70,36 Location: 70,36
Owner: Neutral Owner: Neutral
@@ -792,21 +801,21 @@ Actors:
Location: 63,42 Location: 63,42
Owner: Greece Owner: Greece
Health: 28 Health: 28
Facing: 640 Facing: 384
IntroEnemy2: jeep IntroEnemy2: jeep
Location: 64,42 Location: 64,42
Owner: Greece Owner: Greece
Health: 43 Health: 43
Facing: 640 Facing: 384
IntroEnemy3: 1tnk IntroEnemy3: 1tnk
Location: 64,43 Location: 64,43
Owner: Greece Owner: Greece
Health: 50 Health: 50
Facing: 640 Facing: 384
Mcv: mcv Mcv: mcv
Location: 61,45 Location: 61,45
Owner: USSR Owner: USSR
Facing: 384 Facing: 640
McvWaypoint: waypoint McvWaypoint: waypoint
Location: 53,53 Location: 53,53
Owner: Neutral Owner: Neutral
@@ -817,14 +826,26 @@ Actors:
Truck1: truk Truck1: truk
Location: 54,52 Location: 54,52
Owner: USSR Owner: USSR
Facing: 128 Facing: 896
Truck2: truk Truck2: truk
Location: 55,51 Location: 55,51
Owner: USSR Owner: USSR
Facing: 128 Facing: 896
Weap: weap Weap: weap
Location: 22,15 Location: 22,15
Owner: Greece Owner: Greece
NavyPatrol1: waypoint
Owner: Neutral
Location: 35,18
NavyPatrol2: waypoint
Owner: Neutral
Location: 36,10
NavyPatrol3: waypoint
Owner: Neutral
Location: 57,12
NavyPatrol4: waypoint
Owner: Neutral
Location: 76,17
Rules: ra|rules/campaign-rules.yaml, ra|rules/campaign-tooltips.yaml, ra|rules/campaign-palettes.yaml, rules.yaml Rules: ra|rules/campaign-rules.yaml, ra|rules/campaign-tooltips.yaml, ra|rules/campaign-palettes.yaml, rules.yaml

View File

@@ -6,112 +6,232 @@
the License, or (at your option) any later version. For more the License, or (at your option) any later version. For more
information, see COPYING. information, see COPYING.
]] ]]
IdlingUnits = function() InfAttack = { }
local lazyUnits = Greece.GetGroundAttackers() ArmorAttack = { }
AttackPaths = { { AttackWaypoint1.Location }, { AttackWaypoint2.Location } }
Utils.Do(lazyUnits, function(unit) AlliedInfantryTypes = { "e1", "e1", "e3" }
Trigger.OnDamaged(unit, function() AlliedArmorTypes = { "jeep", "jeep", "1tnk", "1tnk", "2tnk", "2tnk", "arty" }
Trigger.ClearAll(unit)
Trigger.AfterDelay(0, function() IdleHunt(unit) end)
end)
end)
end
BaseApwr = { type = "apwr", pos = CVec.New(-13, 7), cost = 500, exists = true } ProduceInfantry = function(barracks)
BaseTent = { type = "tent", pos = CVec.New(-2, 12), cost = 400, exists = true } if barracks.IsDead or barracks.Owner ~= Greece then
BaseProc = { type = "proc", pos = CVec.New(-7, 5), cost = 1400, exists = true }
BaseWeap = { type = "weap", pos = CVec.New(-9, 11), cost = 2000, exists = true }
BaseApwr2 = { type = "apwr", pos = CVec.New(-4, 1), cost = 500, exists = true }
BaseBuildings = { BaseApwr, BaseTent, BaseProc, BaseWeap, BaseApwr2 }
BuildBase = function()
for i,v in ipairs(BaseBuildings) do
if not v.exists then
BuildBuilding(v)
return return
end elseif GreeceMoney() <= 299 and IsHarvesterMissing() then
end
Trigger.AfterDelay(DateTime.Seconds(10), BuildBase)
end
BuildBuilding = function(building)
Trigger.AfterDelay(Actor.BuildTime(building.type), function()
if CYard.IsDead or CYard.Owner ~= Greece then
return
elseif Harvester.IsDead and Greece.Resources <= 299 then
return
end
local actor = Actor.Create(building.type, true, { Owner = Greece, Location = CYardLocation.Location + building.pos })
Greece.Cash = Greece.Cash - building.cost
building.exists = true
Trigger.OnKilled(actor, function() building.exists = false end)
Trigger.OnDamaged(actor, function(building)
if building.Owner == Greece and building.Health < building.MaxHealth * 3/4 then
building.StartBuildingRepairs()
end
end)
Trigger.AfterDelay(DateTime.Seconds(10), BuildBase)
end)
end
ProduceInfantry = function()
if not BaseTent.exists then
return
elseif Harvester.IsDead and Greece.Resources <= 299 then
return return
end end
local delay = Utils.RandomInteger(DateTime.Seconds(3), DateTime.Seconds(9)) local delay = Utils.RandomInteger(DateTime.Seconds(3), DateTime.Seconds(9))
local toBuild = { Utils.Random(AlliedInfantryTypes) } local toBuild = { Utils.Random(AlliedInfantryTypes) }
local Path = Utils.Random(AttackPaths) local path = Utils.Random(AttackPaths)
Greece.Build(toBuild, function(unit) Greece.Build(toBuild, function(unit)
InfAttack[#InfAttack + 1] = unit[1] InfAttack[#InfAttack + 1] = unit[1]
if #InfAttack >= 10 then if #InfAttack >= 10 then
SendUnits(InfAttack, Path) SendUnits(InfAttack, path)
InfAttack = { } InfAttack = { }
Trigger.AfterDelay(DateTime.Minutes(2), ProduceInfantry) Trigger.AfterDelay(DateTime.Minutes(2), function()
ProduceInfantry(barracks)
end)
else else
Trigger.AfterDelay(delay, ProduceInfantry) Trigger.AfterDelay(delay, function()
ProduceInfantry(barracks)
end)
end end
end) end)
end end
ProduceArmor = function() ProduceArmor = function(factory)
if not BaseWeap.exists then if factory.IsDead or factory.Owner ~= Greece then
return return
elseif Harvester.IsDead and Greece.Resources <= 599 then elseif IsHarvesterMissing() then
ProduceHarvester(factory)
return return
end end
local delay = Utils.RandomInteger(DateTime.Seconds(12), DateTime.Seconds(17)) local delay = Utils.RandomInteger(DateTime.Seconds(12), DateTime.Seconds(17))
local toBuild = { Utils.Random(AlliedArmorTypes) } local toBuild = { Utils.Random(AlliedArmorTypes) }
local Path = Utils.Random(AttackPaths) local path = Utils.Random(AttackPaths)
Greece.Build(toBuild, function(unit) Greece.Build(toBuild, function(unit)
ArmorAttack[#ArmorAttack + 1] = unit[1] ArmorAttack[#ArmorAttack + 1] = unit[1]
if #ArmorAttack >= 6 then if #ArmorAttack >= 6 then
SendUnits(ArmorAttack, Path) SendUnits(ArmorAttack, path)
ArmorAttack = { } ArmorAttack = { }
Trigger.AfterDelay(DateTime.Minutes(3), ProduceArmor) Trigger.AfterDelay(DateTime.Minutes(3), function()
ProduceArmor(factory)
end)
else else
Trigger.AfterDelay(delay, ProduceArmor) Trigger.AfterDelay(delay, function()
ProduceArmor(factory)
end)
end end
end) end)
end end
SendUnits = function(units, waypoints) ProduceHarvester = function(factory)
Utils.Do(units, function(unit) if GreeceMoney() < Actor.Cost("harv") then
if not unit.IsDead then return
Utils.Do(waypoints, function(waypoint) end
unit.AttackMove(waypoint.Location)
local toBuild = { "harv" }
Greece.Build(toBuild, function(unit)
unit.FindResources()
ProduceArmor(factory)
end) end)
end
SendUnits = function(units, path)
Utils.Do(units, function(unit)
if unit.IsDead then
return
end
unit.Patrol(path, false)
IdleHunt(unit) IdleHunt(unit)
end)
end
IsHarvesterMissing = function()
return #Greece.GetActorsByType("harv") == 0
end
GreeceMoney = function()
return Greece.Cash + Greece.Resources
end
BaseBlueprints =
{
{ type = "apwr", actor = Apwr1, cost = 500, shape = { 3, 3 }, location = CPos.New(18, 12) },
{ type = "apwr", actor = Apwr2, cost = 500, shape = { 3, 3 }, location = CPos.New(27, 6) },
{ type = "tent", actor = Tent, cost = 400, shape = { 2, 3 }, location = CPos.New(29, 16), onBuilt = ProduceInfantry },
{ type = "proc", actor = Proc, cost = 1400, shape = { 3, 4 }, location = CPos.New(24, 9) },
{ type = "weap", actor = Weap, cost = 2000, shape = { 3, 3 }, location = CPos.New(22, 15), onBuilt = ProduceArmor },
{ type = "powr", actor = Powr1, cost = 300, shape = { 2, 3 }, location = CPos.New(20, 2) },
{ type = "powr", actor = Powr2, cost = 300, shape = { 2, 3 }, location = CPos.New(25, 2) },
{ type = "gun", actor = Gun4, cost = 800, shape = { 1, 1 }, location = CPos.New(28, 23) },
{ type = "hbox", actor = Hbox2, cost = 600, shape = { 1, 1 }, location = CPos.New(29, 23) },
{ type = "gun", actor = Gun3, cost = 800, shape = { 1, 1 }, location = CPos.New(20, 23) },
{ type = "hbox", actor = Hbox1, cost = 600, shape = { 1, 1 }, location = CPos.New(19, 23) },
{ type = "gap", actor = Gap, cost = 800, shape = { 1, 1 }, location = CPos.New(24, 22) }
}
--[[
Similar to the original CnC/RA [BASE] and [STRUCTURES] .INI sections.
Check a list every so often and (re)build structures missing from
that list, in order, if circumstances allow for it.
]]
BuildBase = function()
for _, blueprint in pairs(BaseBlueprints) do
if not blueprint.actor then
BuildBlueprint(blueprint)
return
end
end
Trigger.AfterDelay(DateTime.Seconds(10), BuildBase)
end
BuildBlueprint = function(blueprint)
Trigger.AfterDelay(Actor.BuildTime(blueprint.type), function()
if CYard.IsDead or CYard.Owner ~= Greece then
return
elseif GreeceMoney() <= 299 and IsHarvesterMissing() then
return
end
if IsBuildAreaBlocked(Greece, blueprint) then
Trigger.AfterDelay(DateTime.Seconds(5), function()
BuildBlueprint(blueprint)
end)
return
end
local actor = Actor.Create(blueprint.type, true, { Owner = Greece, Location = blueprint.location })
OnBlueprintBuilt(actor, blueprint)
Trigger.AfterDelay(DateTime.Seconds(10), BuildBase)
end)
end
OnBlueprintBuilt = function(actor, blueprint)
Greece.Cash = Greece.Cash - blueprint.cost
blueprint.actor = actor
MaintainBuilding(actor, blueprint, 0.75)
if blueprint.onBuilt then
-- Build() will not work properly on producers if immediately called.
Trigger.AfterDelay(1, function()
blueprint.onBuilt(actor)
end)
end
end
IsBuildAreaBlocked = function(player, blueprint)
local nw, se = blueprint.northwestEdge, blueprint.southeastEdge
local blockers = Map.ActorsInBox(nw, se, function(actor)
return actor.CenterPosition.Z == 0 and actor.HasProperty("Health") and not IsOwnedSilo(player, actor)
end)
if #blockers == 0 then
return false
end
ScatterBlockers(player, blockers)
return true
end
-- This is used to disregard silos inside the refinery rebuild area.
IsOwnedSilo = function(player, actor)
return actor.Type == "silo" and actor.Owner == player
end
ScatterBlockers = function(player, actors)
Utils.Do(actors, function(actor)
if actor.IsIdle and actor.Owner == player and actor.HasProperty("Scatter") then
actor.Scatter()
end end
end) end)
end end
BeginBaseMaintenance = function()
Utils.Do(BaseBlueprints, function(blueprint)
MaintainBuilding(blueprint.actor, blueprint)
end)
Utils.Do(Greece.GetActors(), function(actor)
if actor.HasProperty("StartBuildingRepairs") then
MaintainBuilding(actor, nil, 0.75)
end
end)
end
MaintainBuilding = function(actor, blueprint, repairThreshold)
if blueprint then
Trigger.OnKilled(actor, function() blueprint.actor = nil end)
Trigger.OnSold(actor, function() blueprint.actor = nil end)
if not blueprint.northwestEdge then
PrepareBlueprintEdges(blueprint)
end
end
if repairThreshold then
local original = actor.Owner
Trigger.OnDamaged(actor, function()
if actor.Owner ~= original or actor.Health > actor.MaxHealth * repairThreshold then
return
end
actor.StartBuildingRepairs()
end)
end
end
PrepareBlueprintEdges = function(blueprint)
local shapeX, shapeY = blueprint.shape[1], blueprint.shape[2]
local northwestEdge = Map.CenterOfCell(blueprint.location) + WVec.New(-512, -512, 0)
local southeastEdge = northwestEdge + WVec.New(shapeX * 1024, shapeY * 1024, 0)
blueprint.northwestEdge = northwestEdge
blueprint.southeastEdge = southeastEdge
end

View File

@@ -44,8 +44,11 @@ EnemyPaths =
} }
Wave = 0 Wave = 0
SendEnemies = function() SendReinforcements = function()
Trigger.AfterDelay(EnemyAttackDelay[Difficulty], function() Trigger.AfterDelay(EnemyAttackDelay[Difficulty], function()
if Dome.IsDead or Dome.Owner ~= Greece then
return
end
Wave = Wave + 1 Wave = Wave + 1
if Wave > 3 then if Wave > 3 then
@@ -60,8 +63,6 @@ SendEnemies = function()
Utils.Do(units, IdleHunt) Utils.Do(units, IdleHunt)
end end
if not Dome.IsDead then SendReinforcements()
SendEnemies()
end
end) end)
end end

View File

@@ -6,146 +6,273 @@
the License, or (at your option) any later version. For more the License, or (at your option) any later version. For more
information, see COPYING. information, see COPYING.
]] ]]
ArmorAttack = { } Trigger.OnRemovedFromWorld(Mcv, function()
AttackPaths = { { AttackWaypoint1 }, { AttackWaypoint2 } } if McvDeployed or Mcv.IsDead then
BaseAttackers = { BaseAttacker1, BaseAttacker2 } return
InfAttack = { }
IntroAttackers = { IntroEnemy1, IntroEnemy2, IntroEnemy3 }
Trucks = { Truck1, Truck2 }
AlliedInfantryTypes = { "e1", "e1", "e3" }
AlliedArmorTypes = { "jeep", "jeep", "1tnk", "1tnk", "2tnk", "2tnk", "arty" }
SovietReinforcements1 = { "e6", "e6", "e6", "e6", "e6" }
SovietReinforcements2 = { "e4", "e4", "e2", "e2", "e2" }
SovietReinforcements1Waypoints = { McvWaypoint.Location, APCWaypoint1.Location }
SovietReinforcements2Waypoints = { McvWaypoint.Location, APCWaypoint2.Location }
TruckGoalTrigger = { CPos.New(83, 7), CPos.New(83, 8), CPos.New(83, 9), CPos.New(83, 10), CPos.New(84, 10), CPos.New(84, 11), CPos.New(84, 12), CPos.New(85, 12), CPos.New(86, 12), CPos.New(87, 12), CPos.New(87, 13), CPos.New(88, 13), CPos.New(89, 13), CPos.New(90, 13), CPos.New(90, 14), CPos.New(90, 15), CPos.New(91, 15), CPos.New(92, 15), CPos.New(93, 15), CPos.New(94, 15) }
CameraBarrierTrigger = { CPos.New(65, 39), CPos.New(65, 40), CPos.New(66, 40), CPos.New(66, 41), CPos.New(67, 41), CPos.New(67, 42), CPos.New(68, 42), CPos.New(68, 43), CPos.New(68, 44) }
CameraBaseTrigger = { CPos.New(53, 42), CPos.New(54, 42), CPos.New(54, 41), CPos.New(55, 41), CPos.New(56, 41), CPos.New(56, 40), CPos.New(57, 40), CPos.New(57, 39), CPos.New(58, 39), CPos.New(59, 39), CPos.New(59, 38), CPos.New(60, 38), CPos.New(61, 38) }
Trigger.OnEnteredFootprint(TruckGoalTrigger, function(a, id)
if not TruckGoalTriggered and a.Owner == USSR and a.Type == "truk" then
TruckGoalTriggered = true
USSR.MarkCompletedObjective(SovietObjective)
USSR.MarkCompletedObjective(SaveAllTrucks)
end end
end)
Trigger.OnEnteredFootprint(CameraBarrierTrigger, function(a, id) McvDeployed = true
if not CameraBarrierTriggered and a.Owner == USSR then BuildBase()
CameraBarrierTriggered = true SendReinforcements()
local cameraBarrier = Actor.Create("camera", true, { Owner = USSR, Location = CameraBarrier.Location })
Trigger.AfterDelay(DateTime.Seconds(15), function() Trigger.AfterDelay(DateTime.Minutes(1), function()
cameraBarrier.Destroy() ProduceInfantry(Tent)
end)
Trigger.AfterDelay(DateTime.Minutes(2), function()
ProduceArmor(Weap)
end)
local baseAttackers = { BaseAttacker1, BaseAttacker2 }
Trigger.AfterDelay(DateTime.Minutes(2), function()
Utils.Do(baseAttackers, IdleHunt)
end) end)
end
end) end)
Trigger.OnEnteredFootprint(CameraBaseTrigger, function(a, id) PrepareReveals = function()
if not CameraBaseTriggered and a.Owner == USSR then local cameraBarrierCells = { CPos.New(65, 39), CPos.New(65, 40), CPos.New(66, 40), CPos.New(66, 41), CPos.New(67, 41), CPos.New(67, 42), CPos.New(68, 42), CPos.New(68, 43), CPos.New(68, 44) }
CameraBaseTriggered = true local cameraBaseCells = { CPos.New(53, 42), CPos.New(54, 42), CPos.New(54, 41), CPos.New(55, 41), CPos.New(56, 41), CPos.New(56, 40), CPos.New(57, 40), CPos.New(57, 39), CPos.New(58, 39), CPos.New(59, 39), CPos.New(59, 38), CPos.New(60, 38), CPos.New(61, 38) }
local cameraBarrierTriggered = false
local cameraBaseTriggered = false
Trigger.OnEnteredFootprint(cameraBarrierCells, function(a, id)
if cameraBarrierTriggered or a.Owner ~= USSR then
return
end
cameraBarrierTriggered = true
Trigger.RemoveFootprintTrigger(id)
local cameraBarrier = Actor.Create("camera", true, { Owner = USSR, Location = CameraBarrier.Location })
Trigger.AfterDelay(DateTime.Seconds(12), cameraBarrier.Destroy)
end)
Trigger.OnEnteredFootprint(cameraBaseCells, function(a, id)
if cameraBaseTriggered or a.Owner ~= USSR then
return
end
cameraBaseTriggered = true
Trigger.RemoveFootprintTrigger(id)
local cameraBase1 = Actor.Create("camera", true, { Owner = USSR, Location = CameraBase1.Location }) local cameraBase1 = Actor.Create("camera", true, { Owner = USSR, Location = CameraBase1.Location })
local cameraBase2 = Actor.Create("camera", true, { Owner = USSR, Location = CameraBase2.Location }) local cameraBase2 = Actor.Create("camera", true, { Owner = USSR, Location = CameraBase2.Location })
local cameraBase3 = Actor.Create("camera", true, { Owner = USSR, Location = CameraBase3.Location }) local cameraBase3 = Actor.Create("camera", true, { Owner = USSR, Location = CameraBase3.Location })
local cameraBase4 = Actor.Create("camera", true, { Owner = USSR, Location = CameraBase4.Location }) local cameraBase4 = Actor.Create("camera", true, { Owner = USSR, Location = CameraBase4.Location })
Trigger.AfterDelay(DateTime.Minutes(1), function() Trigger.AfterDelay(DateTime.Minutes(1), function()
cameraBase1.Destroy() cameraBase1.Destroy()
cameraBase2.Destroy() cameraBase2.Destroy()
cameraBase3.Destroy() cameraBase3.Destroy()
cameraBase4.Destroy() cameraBase4.Destroy()
end) end)
end)
end
PrepareResponseCruiser = function()
local responseBuildings = { Apwr1, Apwr2, Powr1, Powr2, Weap, Tent }
local responseOrdered = false
Utils.Do(responseBuildings, function(building)
Trigger.OnDamaged(building, function()
if responseOrdered or USSR.IsObjectiveCompleted(DisruptDome) then
return
end end
end)
Trigger.OnAllKilled(Trucks, function() responseOrdered = true
Greece.MarkCompletedObjective(AlliedObjective) OrderResponseCruiser()
end) end)
end)
end
Trigger.OnAnyKilled(Trucks, function() OrderResponseCruiser = function()
USSR.MarkFailedObjective(SaveAllTrucks) if ResponseCruiser.IsDead then
end) return
end
Trigger.OnKilled(Apwr, function() Trigger.OnIdle(ResponseCruiser, function()
BaseApwr.exists = false ResponseCruiser.AttackMove(waypoint0.Location, 2)
end) end)
Trigger.OnKilled(Barr, function() Trigger.OnDamaged(ResponseCruiser, function(_, attacker)
BaseTent.exists = false if attacker.IsDead or not ResponseCruiser.CanTarget(attacker) then
end) return
end
Trigger.OnKilled(Proc, function() ResponseCruiser.Attack(attacker)
BaseProc.exists = false ResponseCruiser.Scatter()
end) end)
end
Trigger.OnKilled(Weap, function() PrepareBridgeBreakers = function()
BaseWeap.exists = false local target = Map.ActorsInCircle(waypoint78.CenterPosition, WDist.New(1536), function(actor)
end) return actor.Type == "br3"
end)[1]
Trigger.OnKilled(Apwr2, function() if not target then
BaseApwr2.exists = false Media.Debug("No bridge segment found.")
end) return
end
Trigger.OnKilledOrCaptured(Dome, function() local orderSent = false
Trigger.AfterDelay(DateTime.Seconds(30), function()
orderSent = true
OrderBridgeBreakers(target)
end)
local bridgeEntryCells = { CPos.New(75, 30), CPos.New(76, 30), CPos.New(77, 30) }
Trigger.OnEnteredFootprint(bridgeEntryCells, function(a, id)
if a.Owner ~= USSR then
return
end
Trigger.RemoveFootprintTrigger(id)
if not orderSent then
OrderBridgeBreakers(target, "with bridge reveal")
end
end)
end
OrderBridgeBreakers = function(target, reveal)
if target.IsDead then
return
end
local breakers = { BridgeBreaker1, BridgeBreaker2 }
Utils.Do(breakers, function(breaker)
if breaker.IsDead then
return
end
breaker.Stop()
breaker.Attack(target, true, true)
end)
if not reveal then
return
end
local camera = Actor.Create("camera", true, { Owner = USSR, Location = target.Location })
Trigger.OnKilled(target, function()
Trigger.AfterDelay(DateTime.Seconds(2), camera.Destroy)
end)
end
PrepareObjectives = function()
InitObjectives(USSR)
KillTrucks = AddPrimaryObjective(Greece, "")
EscortConvoy = AddPrimaryObjective(USSR, "escort-convoy")
DisruptDome = AddSecondaryObjective(USSR, "destroy-capture-radar-dome-reinforcements")
SaveAllTrucks = AddSecondaryObjective(USSR, "keep-trucks-alive")
Trigger.OnKilledOrCaptured(Dome, function()
-- Let the capture notification play first.
Trigger.AfterDelay(DateTime.Seconds(2), function() Trigger.AfterDelay(DateTime.Seconds(2), function()
USSR.MarkCompletedObjective(SovietObjective2) USSR.MarkCompletedObjective(DisruptDome)
Media.PlaySpeechNotification(USSR, "ObjectiveMet") Media.PlaySpeechNotification(USSR, "ObjectiveMet")
end) end)
end) end)
end
-- Activate the AI once the player deployed the Mcv PrepareTrucks = function()
Trigger.OnRemovedFromWorld(Mcv, function() local trucks = { Truck1, Truck2 }
if not McvDeployed then local goalCells = { CPos.New(83, 7), CPos.New(83, 8), CPos.New(83, 9), CPos.New(83, 10), CPos.New(84, 10), CPos.New(84, 11), CPos.New(84, 12), CPos.New(85, 12), CPos.New(86, 12), CPos.New(87, 12), CPos.New(87, 13), CPos.New(88, 13), CPos.New(89, 13), CPos.New(90, 13), CPos.New(90, 14), CPos.New(90, 15), CPos.New(91, 15), CPos.New(92, 15), CPos.New(93, 15), CPos.New(94, 15) }
McvDeployed = true
BuildBase() local goalTriggered = false
SendEnemies() Trigger.OnEnteredFootprint(goalCells, function(a)
Trigger.AfterDelay(DateTime.Minutes(1), ProduceInfantry) if not goalTriggered and a.Owner == USSR and a.Type == "truk" then
Trigger.AfterDelay(DateTime.Minutes(2), ProduceArmor) goalTriggered = true
Trigger.AfterDelay(DateTime.Minutes(2), function() USSR.MarkCompletedObjective(EscortConvoy)
Utils.Do(BaseAttackers, function(actor) USSR.MarkCompletedObjective(SaveAllTrucks)
IdleHunt(actor)
end)
end)
end end
end) end)
Trigger.OnAllKilled(trucks, function()
Greece.MarkCompletedObjective(KillTrucks)
end)
Trigger.OnAnyKilled(trucks, function()
USSR.MarkFailedObjective(SaveAllTrucks)
end)
end
BeginIntro = function()
local introAttackers = { IntroEnemy1, IntroEnemy2, IntroEnemy3 }
local sovietReinforcements1 = { "e6", "e6", "e6", "e6", "e6" }
local sovietReinforcements2 = { "e4", "e4", "e2", "e2", "e2" }
local sovietReinforcements1Path = { McvWaypoint.Location, APCWaypoint1.Location }
local sovietReinforcements2Path = { McvWaypoint.Location, APCWaypoint2.Location }
Mcv.Move(McvWaypoint.Location)
Utils.Do(introAttackers, IdleHunt)
Reinforcements.ReinforceWithTransport(USSR, "apc", sovietReinforcements1, sovietReinforcements1Path)
Reinforcements.ReinforceWithTransport(USSR, "apc", sovietReinforcements2, sovietReinforcements2Path)
end
PrepareIdleGuards = function()
local lazyUnits = Utils.Where(Greece.GetGroundAttackers(), function(unit)
return unit.Type ~= "ca" and unit.Type ~= "arty"
end)
Utils.Do(lazyUnits, function(unit)
local triggered = false
Trigger.OnDamaged(unit, function()
if triggered then
return
end
triggered = true
IdleHunt(unit)
end)
end)
end
WorldLoaded = function() WorldLoaded = function()
USSR = Player.GetPlayer("USSR") USSR = Player.GetPlayer("USSR")
Greece = Player.GetPlayer("Greece") Greece = Player.GetPlayer("Greece")
PrepareReveals()
PrepareObjectives()
Camera.Position = CameraStart.CenterPosition Camera.Position = CameraStart.CenterPosition
Mcv.Move(McvWaypoint.Location)
Harvester.FindResources() Harvester.FindResources()
Utils.Do(IntroAttackers, function(actor) BeginBaseMaintenance()
IdleHunt(actor)
end)
Utils.Do(Map.NamedActors, function(actor) if Difficulty ~= "easy" then
if actor.Owner == Greece and actor.HasProperty("StartBuildingRepairs") then PrepareResponseCruiser()
Trigger.OnDamaged(actor, function(building) Trigger.AfterDelay(1, PrepareBridgeBreakers)
if building.Owner == Greece and building.Health < 3/4 * building.MaxHealth then
building.StartBuildingRepairs()
end end
end)
if Difficulty == "hard" then
BuildNavyPatrol()
end end
PrepareTrucks()
BeginIntro()
PrepareIdleGuards()
end
BuildNavyPatrol = function()
local types = { "dd", "dd" }
local patrolPath = { NavyPatrol1.Location, NavyPatrol2.Location, NavyPatrol3.Location, NavyPatrol4.Location }
Greece.Build(types, function(units)
Utils.Do(units, function(u)
u.Patrol(patrolPath, true, 100)
end) end)
Reinforcements.ReinforceWithTransport(USSR, "apc", SovietReinforcements1, SovietReinforcements1Waypoints) Trigger.OnAllKilled(units, function()
Reinforcements.ReinforceWithTransport(USSR, "apc", SovietReinforcements2, SovietReinforcements2Waypoints) if not Greece.HasPrerequisites({ "syrd", "dome" }) then
return
end
InitObjectives(USSR) BuildNavyPatrol()
end)
AlliedObjective = AddPrimaryObjective(Greece, "") end)
SovietObjective = AddPrimaryObjective(USSR, "escort-convoy")
SovietObjective2 = AddSecondaryObjective(USSR, "destroy-capture-radar-dome-reinforcements")
SaveAllTrucks = AddSecondaryObjective(USSR, "keep-trucks-alive")
end end
Tick = function() Tick = function()
if USSR.HasNoRequiredUnits() then if USSR.HasNoRequiredUnits() then
Greece.MarkCompletedObjective(AlliedObjective) Greece.MarkCompletedObjective(KillTrucks)
end end
if Greece.Resources >= Greece.ResourceCapacity * 0.75 then if Greece.Resources >= Greece.ResourceCapacity * 0.75 then