--[[ Copyright 2007-2019 The OpenRA Developers (see AUTHORS) This file is part of OpenRA, which is free software. It is made available to you under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. For more information, see COPYING. ]] AttackPaths = { { AttackPath1 }, { AttackPath2 } } GDIBase = { GDICYard, GDIPyle, GDIWeap, GDIHQ, GDIProc, GDINuke1, GDINuke2, GDINuke3, GDIBuilding1, GDIBuilding2, GDIBuilding3, GDIBuilding4, GDIBuilding5, GDIBuilding6, GDIBuilding7, GDIBuilding8, GDIBuilding9, GDIBuilding10, GDIBuilding11 } GDIOrcas = { GDIOrca1, GDIOrca2 } InfantryAttackGroup = { } InfantryGroupSize = 5 InfantryProductionCooldown = DateTime.Minutes(3) InfantryProductionTypes = { "e1", "e1", "e2" } HarvesterProductionType = { "harv" } VehicleAttackGroup = { } VehicleGroupSize = 5 VehicleProductionCooldown = DateTime.Minutes(3) VehicleProductionTypes = { "jeep", "jeep", "mtnk", "mtnk", "mtnk", "msam" } StartingCash = 4000 BaseProc = { type = "proc", pos = CPos.New(54, 10), cost = 1500, exists = true } BaseNuke1 = { type = "nuke", pos = CPos.New(57, 7), cost = 500, exists = true } BaseNuke2 = { type = "nuke", pos = CPos.New(55, 7), cost = 500, exists = true } BaseNuke3 = { type = "nuke", pos = CPos.New(59, 7), cost = 500, exists = true } BaseNuke4 = { type = "nuke", pos = CPos.New(59, 10), cost = 500, exists = true } InfantryProduction = { type = "pyle", pos = CPos.New(49, 4), cost = 500, exists = true } VehicleProduction = { type = "weap", pos = CPos.New(51, 7), cost = 2000, exists = true } BaseBuildings = { BaseProc, BaseNuke1, BaseNuke2, BaseNuke3, BaseNuke4, InfantryProduction, VehicleProduction } AutoGuard = function(guards) Utils.Do(guards, function(guard) Trigger.OnDamaged(guard, function(guard) IdleHunt(guard) end) end) end BuildBase = function(cyard) Utils.Do(BaseBuildings, function(building) if not building.exists and not cyardIsBuilding then BuildBuilding(building, cyard) return end end) Trigger.AfterDelay(DateTime.Seconds(10), function() BuildBase(cyard) end) end BuildBuilding = function(building, cyard) cyardIsBuilding = true Trigger.AfterDelay(Actor.BuildTime(building.type), function() cyardIsBuilding = false if cyard.IsDead or cyard.Owner ~= enemy then return end local actor = Actor.Create(building.type, true, { Owner = enemy, Location = building.pos }) enemy.Cash = enemy.Cash - building.cost building.exists = true if actor.Type == 'pyle' or actor.Type == 'hand' then Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceInfantry(actor) end) elseif actor.Type == 'weap' or actor.Type == 'afld' then Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceVehicle(actor) end) end Trigger.OnKilled(actor, function() building.exists = false end) Trigger.OnDamaged(actor, function(building) if building.Owner == enemy and building.Health < building.MaxHealth * 3/4 then building.StartBuildingRepairs() end end) Trigger.AfterDelay(DateTime.Seconds(10), function() BuildBase(cyard) end) end) end CheckForHarvester = function() local harv = enemy.GetActorsByType("harv") return #harv > 0 end GuardBase = function() Utils.Do(GDIBase, function(building) Trigger.OnDamaged(building, function(guard) Utils.Do(GDIOrcas, function(guard) if not guard.IsDead and not building.IsDead then guard.Guard(building) end end) end) end) end IdleHunt = function(unit) if not unit.IsDead then Trigger.OnIdle(unit, unit.Hunt) end end IdlingUnits = function(enemy) local lazyUnits = enemy.GetGroundAttackers() Utils.Do(lazyUnits, function(unit) IdleHunt(unit) end) end ProduceHarvester = function(building) if not buildingHarvester then buildingHarvester = true building.Build(HarvesterProductionType, function() buildingHarvester = false end) end end ProduceInfantry = function(building) if building.IsDead or building.Owner ~= enemy then return elseif not CheckForHarvester() then Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceInfantry(building) end) end local delay = Utils.RandomInteger(DateTime.Seconds(3), DateTime.Seconds(9)) local toBuild = { Utils.Random(InfantryProductionTypes) } local Path = Utils.Random(AttackPaths) building.Build(toBuild, function(unit) InfantryAttackGroup[#InfantryAttackGroup + 1] = unit[1] if #InfantryAttackGroup >= InfantryGroupSize then SendUnits(InfantryAttackGroup, Path) InfantryAttackGroup = { } Trigger.AfterDelay(InfantryProductionCooldown, function() ProduceInfantry(building) end) else Trigger.AfterDelay(delay, function() ProduceInfantry(building) end) end end) end ProduceVehicle = function(building) if building.IsDead or building.Owner ~= enemy then return elseif not CheckForHarvester() then ProduceHarvester(building) Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceVehicle(building) end) end local delay = Utils.RandomInteger(DateTime.Seconds(12), DateTime.Seconds(17)) local toBuild = { Utils.Random(VehicleProductionTypes) } local Path = Utils.Random(AttackPaths) building.Build(toBuild, function(unit) VehicleAttackGroup[#VehicleAttackGroup + 1] = unit[1] if #VehicleAttackGroup >= VehicleGroupSize then SendUnits(VehicleAttackGroup, Path) VehicleAttackGroup = { } Trigger.AfterDelay(VehicleProductionCooldown, function() ProduceVehicle(building) end) else Trigger.AfterDelay(delay, function() ProduceVehicle(building) 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) end) IdleHunt(unit) end end) end StartAI = function(cyard) Utils.Do(Map.NamedActors, function(actor) if actor.Owner == enemy and actor.HasProperty("StartBuildingRepairs") then Trigger.OnDamaged(actor, function(building) if building.Owner == enemy and building.Health < 3/4 * building.MaxHealth then building.StartBuildingRepairs() end end) end end) enemy.Cash = StartingCash BuildBase(cyard) GuardBase() end Trigger.OnAllKilledOrCaptured(GDIBase, function() IdlingUnits(enemy) end) Trigger.OnKilled(GDIProc, function(building) BaseProc.exists = false end) Trigger.OnKilled(GDINuke1, function(building) BaseNuke1.exists = false end) Trigger.OnKilled(GDINuke2, function(building) BaseNuke2.exists = false end) Trigger.OnKilled(GDINuke3, function(building) BaseNuke3.exists = false end) Trigger.OnKilled(GDINuke4, function(building) BaseNuke4.exists = false end) Trigger.OnKilled(GDIPyle, function(building) InfantryProduction.exists = false end) Trigger.OnKilled(GDIWeap, function(building) VehicleProduction.exists = false end)