Add navy orders, fixes to Soviet 06a
This commit is contained in:
@@ -26,10 +26,10 @@ Players:
|
||||
Faction: allies
|
||||
PlayerReference@Greece:
|
||||
Name: Greece
|
||||
Bot: campaign
|
||||
Faction: allies
|
||||
Color: E2E6F5
|
||||
Enemies: USSR
|
||||
Bot: campaign
|
||||
PlayerReference@USSR:
|
||||
Name: USSR
|
||||
AllowBots: False
|
||||
@@ -512,34 +512,38 @@ Actors:
|
||||
Actor155: tc01
|
||||
Location: 33,1
|
||||
Owner: Neutral
|
||||
Actor156: hbox
|
||||
Hbox1: hbox
|
||||
Location: 19,23
|
||||
Owner: Greece
|
||||
Actor157: hbox
|
||||
Hbox2: hbox
|
||||
Location: 29,23
|
||||
Owner: Greece
|
||||
Actor158: gun
|
||||
Gun3: gun
|
||||
Location: 20,23
|
||||
Owner: Greece
|
||||
Facing: 512
|
||||
Actor159: gun
|
||||
TurretFacing: 0
|
||||
Gun4: gun
|
||||
Location: 28,23
|
||||
Owner: Greece
|
||||
Facing: 512
|
||||
Actor163: gap
|
||||
TurretFacing: 0
|
||||
Gap: gap
|
||||
Location: 24,22
|
||||
Owner: Greece
|
||||
Actor164: syrd
|
||||
Syrd: syrd
|
||||
Location: 35,14
|
||||
Owner: Greece
|
||||
Actor167: gun
|
||||
Gun1: gun
|
||||
Location: 33,5
|
||||
Owner: Greece
|
||||
Facing: 768
|
||||
Actor168: gun
|
||||
TurretFacing: 512
|
||||
Gun2: gun
|
||||
Location: 33,9
|
||||
Owner: Greece
|
||||
Facing: 768
|
||||
TurretFacing: 512
|
||||
Actor169: v07
|
||||
Location: 66,4
|
||||
Owner: Greece
|
||||
@@ -557,60 +561,62 @@ Actors:
|
||||
Actor173: v06
|
||||
Location: 68,4
|
||||
Owner: Greece
|
||||
Actor174: powr
|
||||
Powr1: powr
|
||||
Location: 20,2
|
||||
Owner: Greece
|
||||
Actor175: powr
|
||||
Powr2: powr
|
||||
Location: 25,2
|
||||
Owner: Greece
|
||||
Actor179: 2tnk
|
||||
Location: 73,35
|
||||
Owner: Greece
|
||||
Facing: 640
|
||||
Facing: 384
|
||||
Actor180: 2tnk
|
||||
Location: 72,34
|
||||
Owner: Greece
|
||||
Facing: 640
|
||||
Facing: 384
|
||||
Actor181: 2tnk
|
||||
Location: 71,33
|
||||
Owner: Greece
|
||||
Facing: 640
|
||||
Facing: 384
|
||||
Actor182: arty
|
||||
Location: 74,33
|
||||
Owner: Greece
|
||||
Facing: 640
|
||||
Facing: 384
|
||||
Stance: Defend
|
||||
Actor183: arty
|
||||
Location: 73,32
|
||||
Owner: Greece
|
||||
Facing: 640
|
||||
Facing: 384
|
||||
Stance: Defend
|
||||
Actor186: 3tnk
|
||||
Location: 56,47
|
||||
Owner: USSR
|
||||
Facing: 128
|
||||
Facing: 896
|
||||
Actor187: 3tnk
|
||||
Location: 60,49
|
||||
Owner: USSR
|
||||
Facing: 128
|
||||
Facing: 896
|
||||
Actor191: v2rl
|
||||
Location: 57,49
|
||||
Owner: USSR
|
||||
Facing: 128
|
||||
Facing: 896
|
||||
Actor193: 2tnk
|
||||
Location: 73,31
|
||||
Owner: Greece
|
||||
Facing: 640
|
||||
Facing: 384
|
||||
Actor194: 2tnk
|
||||
Location: 75,33
|
||||
Owner: Greece
|
||||
Facing: 640
|
||||
Facing: 384
|
||||
Actor195: 2tnk
|
||||
Location: 85,18
|
||||
Owner: Greece
|
||||
Facing: 640
|
||||
Facing: 384
|
||||
Actor196: 2tnk
|
||||
Location: 88,20
|
||||
Owner: Greece
|
||||
Facing: 640
|
||||
Facing: 384
|
||||
Actor197: 2tnk
|
||||
Location: 22,23
|
||||
Owner: Greece
|
||||
@@ -622,11 +628,13 @@ Actors:
|
||||
Actor199: arty
|
||||
Location: 18,23
|
||||
Owner: Greece
|
||||
Facing: 384
|
||||
Facing: 640
|
||||
Stance: Defend
|
||||
Actor200: arty
|
||||
Location: 30,23
|
||||
Owner: Greece
|
||||
Facing: 640
|
||||
Facing: 384
|
||||
Stance: Defend
|
||||
Actor202: 1tnk
|
||||
Location: 23,21
|
||||
Owner: Greece
|
||||
@@ -638,64 +646,65 @@ Actors:
|
||||
Actor204: 2tnk
|
||||
Location: 40,6
|
||||
Owner: Greece
|
||||
Facing: 768
|
||||
Facing: 256
|
||||
Actor205: 2tnk
|
||||
Location: 40,8
|
||||
Owner: Greece
|
||||
Facing: 768
|
||||
Facing: 256
|
||||
Actor206: arty
|
||||
Location: 40,7
|
||||
Owner: Greece
|
||||
Facing: 768
|
||||
Facing: 256
|
||||
Stance: Defend
|
||||
Actor207: 1tnk
|
||||
Location: 77,10
|
||||
Owner: Greece
|
||||
Facing: 768
|
||||
Facing: 256
|
||||
Actor208: 1tnk
|
||||
Location: 77,11
|
||||
Owner: Greece
|
||||
Facing: 768
|
||||
Facing: 256
|
||||
Actor209: 1tnk
|
||||
Location: 77,12
|
||||
Owner: Greece
|
||||
Facing: 768
|
||||
Actor210: ca
|
||||
Facing: 256
|
||||
BridgeBreaker2: ca
|
||||
Location: 87,29
|
||||
Owner: Greece
|
||||
Facing: 896
|
||||
Actor211: ca
|
||||
Facing: 128
|
||||
BridgeBreaker1: ca
|
||||
Location: 87,25
|
||||
Owner: Greece
|
||||
Facing: 640
|
||||
Actor212: ca
|
||||
Facing: 384
|
||||
ResponseCruiser: ca
|
||||
Location: 76,22
|
||||
Owner: Greece
|
||||
Facing: 896
|
||||
Facing: 128
|
||||
Actor213: pt
|
||||
Location: 38,4
|
||||
Owner: Greece
|
||||
Facing: 768
|
||||
Facing: 256
|
||||
Actor214: pt
|
||||
Location: 38,10
|
||||
Owner: Greece
|
||||
Facing: 768
|
||||
Facing: 256
|
||||
Actor215: dd
|
||||
Location: 55,15
|
||||
Owner: Greece
|
||||
Facing: 768
|
||||
Actor216: waypoint
|
||||
Facing: 256
|
||||
waypoint0: waypoint
|
||||
Location: 39,13
|
||||
Owner: Neutral
|
||||
Actor235: silo
|
||||
Silo4: silo
|
||||
Owner: Greece
|
||||
Location: 26,9
|
||||
Actor236: silo
|
||||
Silo3: silo
|
||||
Owner: Greece
|
||||
Location: 24,9
|
||||
Actor237: silo
|
||||
Silo1: silo
|
||||
Owner: Greece
|
||||
Location: 27,2
|
||||
Actor238: silo
|
||||
Silo2: silo
|
||||
Owner: Greece
|
||||
Location: 27,3
|
||||
waypoint78: waypoint
|
||||
@@ -723,7 +732,7 @@ Actors:
|
||||
APCWaypoint2: waypoint
|
||||
Location: 58,51
|
||||
Owner: Neutral
|
||||
Apwr: apwr
|
||||
Apwr1: apwr
|
||||
Location: 18,12
|
||||
Owner: Greece
|
||||
Apwr2: apwr
|
||||
@@ -735,17 +744,17 @@ Actors:
|
||||
AttackWaypoint2: waypoint
|
||||
Owner: Neutral
|
||||
Location: 35,30
|
||||
Barr: tent
|
||||
Tent: tent
|
||||
Location: 29,16
|
||||
Owner: Greece
|
||||
BaseAttacker1: 1tnk
|
||||
Location: 76,35
|
||||
Owner: Greece
|
||||
Facing: 640
|
||||
Facing: 384
|
||||
BaseAttacker2: 1tnk
|
||||
Location: 71,30
|
||||
Owner: Greece
|
||||
Facing: 640
|
||||
Facing: 384
|
||||
CameraBarrier: camera
|
||||
Location: 70,36
|
||||
Owner: Neutral
|
||||
@@ -792,21 +801,21 @@ Actors:
|
||||
Location: 63,42
|
||||
Owner: Greece
|
||||
Health: 28
|
||||
Facing: 640
|
||||
Facing: 384
|
||||
IntroEnemy2: jeep
|
||||
Location: 64,42
|
||||
Owner: Greece
|
||||
Health: 43
|
||||
Facing: 640
|
||||
Facing: 384
|
||||
IntroEnemy3: 1tnk
|
||||
Location: 64,43
|
||||
Owner: Greece
|
||||
Health: 50
|
||||
Facing: 640
|
||||
Facing: 384
|
||||
Mcv: mcv
|
||||
Location: 61,45
|
||||
Owner: USSR
|
||||
Facing: 384
|
||||
Facing: 640
|
||||
McvWaypoint: waypoint
|
||||
Location: 53,53
|
||||
Owner: Neutral
|
||||
@@ -817,14 +826,26 @@ Actors:
|
||||
Truck1: truk
|
||||
Location: 54,52
|
||||
Owner: USSR
|
||||
Facing: 128
|
||||
Facing: 896
|
||||
Truck2: truk
|
||||
Location: 55,51
|
||||
Owner: USSR
|
||||
Facing: 128
|
||||
Facing: 896
|
||||
Weap: weap
|
||||
Location: 22,15
|
||||
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
|
||||
|
||||
|
||||
@@ -6,112 +6,232 @@
|
||||
the License, or (at your option) any later version. For more
|
||||
information, see COPYING.
|
||||
]]
|
||||
IdlingUnits = function()
|
||||
local lazyUnits = Greece.GetGroundAttackers()
|
||||
InfAttack = { }
|
||||
ArmorAttack = { }
|
||||
AttackPaths = { { AttackWaypoint1.Location }, { AttackWaypoint2.Location } }
|
||||
|
||||
Utils.Do(lazyUnits, function(unit)
|
||||
Trigger.OnDamaged(unit, function()
|
||||
Trigger.ClearAll(unit)
|
||||
Trigger.AfterDelay(0, function() IdleHunt(unit) end)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
AlliedInfantryTypes = { "e1", "e1", "e3" }
|
||||
AlliedArmorTypes = { "jeep", "jeep", "1tnk", "1tnk", "2tnk", "2tnk", "arty" }
|
||||
|
||||
BaseApwr = { type = "apwr", pos = CVec.New(-13, 7), cost = 500, exists = true }
|
||||
BaseTent = { type = "tent", pos = CVec.New(-2, 12), cost = 400, exists = true }
|
||||
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)
|
||||
ProduceInfantry = function(barracks)
|
||||
if barracks.IsDead or barracks.Owner ~= Greece then
|
||||
return
|
||||
end
|
||||
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
|
||||
elseif GreeceMoney() <= 299 and IsHarvesterMissing() then
|
||||
return
|
||||
end
|
||||
|
||||
local delay = Utils.RandomInteger(DateTime.Seconds(3), DateTime.Seconds(9))
|
||||
local toBuild = { Utils.Random(AlliedInfantryTypes) }
|
||||
local Path = Utils.Random(AttackPaths)
|
||||
local path = Utils.Random(AttackPaths)
|
||||
Greece.Build(toBuild, function(unit)
|
||||
InfAttack[#InfAttack + 1] = unit[1]
|
||||
|
||||
if #InfAttack >= 10 then
|
||||
SendUnits(InfAttack, Path)
|
||||
SendUnits(InfAttack, path)
|
||||
InfAttack = { }
|
||||
Trigger.AfterDelay(DateTime.Minutes(2), ProduceInfantry)
|
||||
Trigger.AfterDelay(DateTime.Minutes(2), function()
|
||||
ProduceInfantry(barracks)
|
||||
end)
|
||||
else
|
||||
Trigger.AfterDelay(delay, ProduceInfantry)
|
||||
Trigger.AfterDelay(delay, function()
|
||||
ProduceInfantry(barracks)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
ProduceArmor = function()
|
||||
if not BaseWeap.exists then
|
||||
ProduceArmor = function(factory)
|
||||
if factory.IsDead or factory.Owner ~= Greece then
|
||||
return
|
||||
elseif Harvester.IsDead and Greece.Resources <= 599 then
|
||||
elseif IsHarvesterMissing() then
|
||||
ProduceHarvester(factory)
|
||||
return
|
||||
end
|
||||
|
||||
local delay = Utils.RandomInteger(DateTime.Seconds(12), DateTime.Seconds(17))
|
||||
local toBuild = { Utils.Random(AlliedArmorTypes) }
|
||||
local Path = Utils.Random(AttackPaths)
|
||||
local path = Utils.Random(AttackPaths)
|
||||
Greece.Build(toBuild, function(unit)
|
||||
ArmorAttack[#ArmorAttack + 1] = unit[1]
|
||||
|
||||
if #ArmorAttack >= 6 then
|
||||
SendUnits(ArmorAttack, Path)
|
||||
SendUnits(ArmorAttack, path)
|
||||
ArmorAttack = { }
|
||||
Trigger.AfterDelay(DateTime.Minutes(3), ProduceArmor)
|
||||
Trigger.AfterDelay(DateTime.Minutes(3), function()
|
||||
ProduceArmor(factory)
|
||||
end)
|
||||
else
|
||||
Trigger.AfterDelay(delay, ProduceArmor)
|
||||
Trigger.AfterDelay(delay, function()
|
||||
ProduceArmor(factory)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
SendUnits = function(units, waypoints)
|
||||
Utils.Do(units, function(unit)
|
||||
if not unit.IsDead then
|
||||
Utils.Do(waypoints, function(waypoint)
|
||||
unit.AttackMove(waypoint.Location)
|
||||
ProduceHarvester = function(factory)
|
||||
if GreeceMoney() < Actor.Cost("harv") then
|
||||
return
|
||||
end
|
||||
|
||||
local toBuild = { "harv" }
|
||||
Greece.Build(toBuild, function(unit)
|
||||
unit.FindResources()
|
||||
ProduceArmor(factory)
|
||||
end)
|
||||
end
|
||||
|
||||
SendUnits = function(units, path)
|
||||
Utils.Do(units, function(unit)
|
||||
if unit.IsDead then
|
||||
return
|
||||
end
|
||||
|
||||
unit.Patrol(path, false)
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
@@ -44,8 +44,11 @@ EnemyPaths =
|
||||
}
|
||||
|
||||
Wave = 0
|
||||
SendEnemies = function()
|
||||
SendReinforcements = function()
|
||||
Trigger.AfterDelay(EnemyAttackDelay[Difficulty], function()
|
||||
if Dome.IsDead or Dome.Owner ~= Greece then
|
||||
return
|
||||
end
|
||||
|
||||
Wave = Wave + 1
|
||||
if Wave > 3 then
|
||||
@@ -60,8 +63,6 @@ SendEnemies = function()
|
||||
Utils.Do(units, IdleHunt)
|
||||
end
|
||||
|
||||
if not Dome.IsDead then
|
||||
SendEnemies()
|
||||
end
|
||||
SendReinforcements()
|
||||
end)
|
||||
end
|
||||
|
||||
@@ -6,146 +6,273 @@
|
||||
the License, or (at your option) any later version. For more
|
||||
information, see COPYING.
|
||||
]]
|
||||
ArmorAttack = { }
|
||||
AttackPaths = { { AttackWaypoint1 }, { AttackWaypoint2 } }
|
||||
BaseAttackers = { BaseAttacker1, BaseAttacker2 }
|
||||
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)
|
||||
Trigger.OnRemovedFromWorld(Mcv, function()
|
||||
if McvDeployed or Mcv.IsDead then
|
||||
return
|
||||
end
|
||||
end)
|
||||
|
||||
Trigger.OnEnteredFootprint(CameraBarrierTrigger, function(a, id)
|
||||
if not CameraBarrierTriggered and a.Owner == USSR then
|
||||
CameraBarrierTriggered = true
|
||||
local cameraBarrier = Actor.Create("camera", true, { Owner = USSR, Location = CameraBarrier.Location })
|
||||
Trigger.AfterDelay(DateTime.Seconds(15), function()
|
||||
cameraBarrier.Destroy()
|
||||
McvDeployed = true
|
||||
BuildBase()
|
||||
SendReinforcements()
|
||||
|
||||
Trigger.AfterDelay(DateTime.Minutes(1), function()
|
||||
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)
|
||||
|
||||
Trigger.OnEnteredFootprint(CameraBaseTrigger, function(a, id)
|
||||
if not CameraBaseTriggered and a.Owner == USSR then
|
||||
CameraBaseTriggered = true
|
||||
PrepareReveals = function()
|
||||
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) }
|
||||
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 cameraBase2 = Actor.Create("camera", true, { Owner = USSR, Location = CameraBase2.Location })
|
||||
local cameraBase3 = Actor.Create("camera", true, { Owner = USSR, Location = CameraBase3.Location })
|
||||
local cameraBase4 = Actor.Create("camera", true, { Owner = USSR, Location = CameraBase4.Location })
|
||||
|
||||
Trigger.AfterDelay(DateTime.Minutes(1), function()
|
||||
cameraBase1.Destroy()
|
||||
cameraBase2.Destroy()
|
||||
cameraBase3.Destroy()
|
||||
cameraBase4.Destroy()
|
||||
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)
|
||||
|
||||
Trigger.OnAllKilled(Trucks, function()
|
||||
Greece.MarkCompletedObjective(AlliedObjective)
|
||||
end)
|
||||
responseOrdered = true
|
||||
OrderResponseCruiser()
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
Trigger.OnAnyKilled(Trucks, function()
|
||||
USSR.MarkFailedObjective(SaveAllTrucks)
|
||||
end)
|
||||
OrderResponseCruiser = function()
|
||||
if ResponseCruiser.IsDead then
|
||||
return
|
||||
end
|
||||
|
||||
Trigger.OnKilled(Apwr, function()
|
||||
BaseApwr.exists = false
|
||||
end)
|
||||
Trigger.OnIdle(ResponseCruiser, function()
|
||||
ResponseCruiser.AttackMove(waypoint0.Location, 2)
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(Barr, function()
|
||||
BaseTent.exists = false
|
||||
end)
|
||||
Trigger.OnDamaged(ResponseCruiser, function(_, attacker)
|
||||
if attacker.IsDead or not ResponseCruiser.CanTarget(attacker) then
|
||||
return
|
||||
end
|
||||
|
||||
Trigger.OnKilled(Proc, function()
|
||||
BaseProc.exists = false
|
||||
end)
|
||||
ResponseCruiser.Attack(attacker)
|
||||
ResponseCruiser.Scatter()
|
||||
end)
|
||||
end
|
||||
|
||||
Trigger.OnKilled(Weap, function()
|
||||
BaseWeap.exists = false
|
||||
end)
|
||||
PrepareBridgeBreakers = function()
|
||||
local target = Map.ActorsInCircle(waypoint78.CenterPosition, WDist.New(1536), function(actor)
|
||||
return actor.Type == "br3"
|
||||
end)[1]
|
||||
|
||||
Trigger.OnKilled(Apwr2, function()
|
||||
BaseApwr2.exists = false
|
||||
end)
|
||||
if not target then
|
||||
Media.Debug("No bridge segment found.")
|
||||
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()
|
||||
USSR.MarkCompletedObjective(SovietObjective2)
|
||||
USSR.MarkCompletedObjective(DisruptDome)
|
||||
Media.PlaySpeechNotification(USSR, "ObjectiveMet")
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
-- Activate the AI once the player deployed the Mcv
|
||||
Trigger.OnRemovedFromWorld(Mcv, function()
|
||||
if not McvDeployed then
|
||||
McvDeployed = true
|
||||
BuildBase()
|
||||
SendEnemies()
|
||||
Trigger.AfterDelay(DateTime.Minutes(1), ProduceInfantry)
|
||||
Trigger.AfterDelay(DateTime.Minutes(2), ProduceArmor)
|
||||
Trigger.AfterDelay(DateTime.Minutes(2), function()
|
||||
Utils.Do(BaseAttackers, function(actor)
|
||||
IdleHunt(actor)
|
||||
end)
|
||||
end)
|
||||
PrepareTrucks = function()
|
||||
local trucks = { Truck1, Truck2 }
|
||||
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) }
|
||||
|
||||
local goalTriggered = false
|
||||
Trigger.OnEnteredFootprint(goalCells, function(a)
|
||||
if not goalTriggered and a.Owner == USSR and a.Type == "truk" then
|
||||
goalTriggered = true
|
||||
USSR.MarkCompletedObjective(EscortConvoy)
|
||||
USSR.MarkCompletedObjective(SaveAllTrucks)
|
||||
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()
|
||||
USSR = Player.GetPlayer("USSR")
|
||||
Greece = Player.GetPlayer("Greece")
|
||||
|
||||
PrepareReveals()
|
||||
PrepareObjectives()
|
||||
Camera.Position = CameraStart.CenterPosition
|
||||
|
||||
Mcv.Move(McvWaypoint.Location)
|
||||
Harvester.FindResources()
|
||||
Utils.Do(IntroAttackers, function(actor)
|
||||
IdleHunt(actor)
|
||||
end)
|
||||
BeginBaseMaintenance()
|
||||
|
||||
Utils.Do(Map.NamedActors, function(actor)
|
||||
if actor.Owner == Greece and actor.HasProperty("StartBuildingRepairs") then
|
||||
Trigger.OnDamaged(actor, function(building)
|
||||
if building.Owner == Greece and building.Health < 3/4 * building.MaxHealth then
|
||||
building.StartBuildingRepairs()
|
||||
if Difficulty ~= "easy" then
|
||||
PrepareResponseCruiser()
|
||||
Trigger.AfterDelay(1, PrepareBridgeBreakers)
|
||||
end
|
||||
end)
|
||||
|
||||
if Difficulty == "hard" then
|
||||
BuildNavyPatrol()
|
||||
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)
|
||||
|
||||
Reinforcements.ReinforceWithTransport(USSR, "apc", SovietReinforcements1, SovietReinforcements1Waypoints)
|
||||
Reinforcements.ReinforceWithTransport(USSR, "apc", SovietReinforcements2, SovietReinforcements2Waypoints)
|
||||
Trigger.OnAllKilled(units, function()
|
||||
if not Greece.HasPrerequisites({ "syrd", "dome" }) then
|
||||
return
|
||||
end
|
||||
|
||||
InitObjectives(USSR)
|
||||
|
||||
AlliedObjective = AddPrimaryObjective(Greece, "")
|
||||
SovietObjective = AddPrimaryObjective(USSR, "escort-convoy")
|
||||
SovietObjective2 = AddSecondaryObjective(USSR, "destroy-capture-radar-dome-reinforcements")
|
||||
SaveAllTrucks = AddSecondaryObjective(USSR, "keep-trucks-alive")
|
||||
BuildNavyPatrol()
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
Tick = function()
|
||||
if USSR.HasNoRequiredUnits() then
|
||||
Greece.MarkCompletedObjective(AlliedObjective)
|
||||
Greece.MarkCompletedObjective(KillTrucks)
|
||||
end
|
||||
|
||||
if Greece.Resources >= Greece.ResourceCapacity * 0.75 then
|
||||
|
||||
Reference in New Issue
Block a user