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

@@ -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