Add navy orders, fixes to Soviet 06a
This commit is contained in:
@@ -6,29 +6,124 @@
|
||||
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)
|
||||
AlliedInfantryTypes = { "e1", "e1", "e3" }
|
||||
AlliedArmorTypes = { "jeep", "jeep", "1tnk", "1tnk", "2tnk", "2tnk", "arty" }
|
||||
|
||||
ProduceInfantry = function(barracks)
|
||||
if barracks.IsDead or barracks.Owner ~= Greece then
|
||||
return
|
||||
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)
|
||||
Greece.Build(toBuild, function(unit)
|
||||
InfAttack[#InfAttack + 1] = unit[1]
|
||||
|
||||
if #InfAttack >= 10 then
|
||||
SendUnits(InfAttack, path)
|
||||
InfAttack = { }
|
||||
Trigger.AfterDelay(DateTime.Minutes(2), function()
|
||||
ProduceInfantry(barracks)
|
||||
end)
|
||||
else
|
||||
Trigger.AfterDelay(delay, function()
|
||||
ProduceInfantry(barracks)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
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 }
|
||||
ProduceArmor = function(factory)
|
||||
if factory.IsDead or factory.Owner ~= Greece then
|
||||
return
|
||||
elseif IsHarvesterMissing() then
|
||||
ProduceHarvester(factory)
|
||||
return
|
||||
end
|
||||
|
||||
BaseBuildings = { BaseApwr, BaseTent, BaseProc, BaseWeap, BaseApwr2 }
|
||||
local delay = Utils.RandomInteger(DateTime.Seconds(12), DateTime.Seconds(17))
|
||||
local toBuild = { Utils.Random(AlliedArmorTypes) }
|
||||
local path = Utils.Random(AttackPaths)
|
||||
Greece.Build(toBuild, function(unit)
|
||||
ArmorAttack[#ArmorAttack + 1] = unit[1]
|
||||
|
||||
if #ArmorAttack >= 6 then
|
||||
SendUnits(ArmorAttack, path)
|
||||
ArmorAttack = { }
|
||||
Trigger.AfterDelay(DateTime.Minutes(3), function()
|
||||
ProduceArmor(factory)
|
||||
end)
|
||||
else
|
||||
Trigger.AfterDelay(delay, function()
|
||||
ProduceArmor(factory)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
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 i,v in ipairs(BaseBuildings) do
|
||||
if not v.exists then
|
||||
BuildBuilding(v)
|
||||
for _, blueprint in pairs(BaseBlueprints) do
|
||||
if not blueprint.actor then
|
||||
BuildBlueprint(blueprint)
|
||||
return
|
||||
end
|
||||
end
|
||||
@@ -36,82 +131,107 @@ BuildBase = function()
|
||||
Trigger.AfterDelay(DateTime.Seconds(10), BuildBase)
|
||||
end
|
||||
|
||||
BuildBuilding = function(building)
|
||||
Trigger.AfterDelay(Actor.BuildTime(building.type), function()
|
||||
BuildBlueprint = function(blueprint)
|
||||
Trigger.AfterDelay(Actor.BuildTime(blueprint.type), function()
|
||||
if CYard.IsDead or CYard.Owner ~= Greece then
|
||||
return
|
||||
elseif Harvester.IsDead and Greece.Resources <= 299 then
|
||||
elseif GreeceMoney() <= 299 and IsHarvesterMissing() then
|
||||
return
|
||||
end
|
||||
|
||||
local actor = Actor.Create(building.type, true, { Owner = Greece, Location = CYardLocation.Location + building.pos })
|
||||
Greece.Cash = Greece.Cash - building.cost
|
||||
if IsBuildAreaBlocked(Greece, blueprint) then
|
||||
Trigger.AfterDelay(DateTime.Seconds(5), function()
|
||||
BuildBlueprint(blueprint)
|
||||
end)
|
||||
return
|
||||
end
|
||||
|
||||
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)
|
||||
local actor = Actor.Create(blueprint.type, true, { Owner = Greece, Location = blueprint.location })
|
||||
OnBlueprintBuilt(actor, blueprint)
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
local delay = Utils.RandomInteger(DateTime.Seconds(3), DateTime.Seconds(9))
|
||||
local toBuild = { Utils.Random(AlliedInfantryTypes) }
|
||||
local Path = Utils.Random(AttackPaths)
|
||||
Greece.Build(toBuild, function(unit)
|
||||
InfAttack[#InfAttack + 1] = unit[1]
|
||||
ScatterBlockers(player, blockers)
|
||||
return true
|
||||
end
|
||||
|
||||
if #InfAttack >= 10 then
|
||||
SendUnits(InfAttack, Path)
|
||||
InfAttack = { }
|
||||
Trigger.AfterDelay(DateTime.Minutes(2), ProduceInfantry)
|
||||
else
|
||||
Trigger.AfterDelay(delay, ProduceInfantry)
|
||||
-- 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
|
||||
|
||||
ProduceArmor = function()
|
||||
if not BaseWeap.exists then
|
||||
return
|
||||
elseif Harvester.IsDead and Greece.Resources <= 599 then
|
||||
return
|
||||
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
|
||||
|
||||
local delay = Utils.RandomInteger(DateTime.Seconds(12), DateTime.Seconds(17))
|
||||
local toBuild = { Utils.Random(AlliedArmorTypes) }
|
||||
local Path = Utils.Random(AttackPaths)
|
||||
Greece.Build(toBuild, function(unit)
|
||||
ArmorAttack[#ArmorAttack + 1] = unit[1]
|
||||
if repairThreshold then
|
||||
local original = actor.Owner
|
||||
|
||||
if #ArmorAttack >= 6 then
|
||||
SendUnits(ArmorAttack, Path)
|
||||
ArmorAttack = { }
|
||||
Trigger.AfterDelay(DateTime.Minutes(3), ProduceArmor)
|
||||
else
|
||||
Trigger.AfterDelay(delay, ProduceArmor)
|
||||
end
|
||||
end)
|
||||
Trigger.OnDamaged(actor, function()
|
||||
if actor.Owner ~= original or actor.Health > actor.MaxHealth * repairThreshold then
|
||||
return
|
||||
end
|
||||
|
||||
actor.StartBuildingRepairs()
|
||||
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)
|
||||
end)
|
||||
IdleHunt(unit)
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user