Files
OpenRA/mods/cnc/maps/eviction-notice/eviction-notice-AI.lua

408 lines
13 KiB
Lua

--[[
Copyright (c) The OpenRA Developers and Contributors
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.
]]
GDInuke1 = { type = "nuk2", pos = CPos.New(6,3), blocked = false }
GDIproc1 = { type = "proc", pos = CPos.New(8,12), blocked = false }
GDIpyle = { type = "pyle", pos = CPos.New(17,4), blocked = false }
GDIweap = { type = "weap", pos = CPos.New(10,9), blocked = false }
GDIproc2 = { type = "proc", pos = CPos.New(12,3), blocked = false }
GDInuke2 = { type = "nuk2", pos = CPos.New(4,11), blocked = false }
GDInuke3 = { type = "nuk2", pos = CPos.New(3,14), blocked = false }
GDIdef1 = { type = "atwr", pos = CPos.New(8,5), blocked = false }
GDIdef2 = { type = "atwr", pos = CPos.New(6,10), blocked = false }
GDIdef3 = { type = "atwr", pos = CPos.New(6,16), blocked = false }
GDIdef4 = { type = "gtwr", pos = CPos.New(9,8), blocked = false }
GDInuke4 = { type = "nuk2", pos = CPos.New(13,12), blocked = false }
GDIdef5 = { type = "atwr", pos = CPos.New(15,10), blocked = false }
GDIdef6 = { type = "atwr", pos = CPos.New(13,16), blocked = false }
GDInuke5 = { type = "nuk2", pos = CPos.New(11,14), blocked = false }
GDIsilo1 = { type = "silo", pos = CPos.New(3,6), blocked = false }
GDIsilo2 = { type = "silo", pos = CPos.New(5,17), blocked = false }
GDIdef7 = { type = "atwr", pos = CPos.New(19,5), blocked = false }
GDIdef8 = { type = "atwr", pos = CPos.New(10,21), blocked = false }
GDIsilo3 = { type = "silo", pos = CPos.New(17,2), blocked = false }
GDIsilo4 = { type = "silo", pos = CPos.New(9,17), blocked = false }
GDIdef9 = { type = "atwr", pos = CPos.New(18,20), blocked = false }
GDIhpad1 = { type = "hpad", pos = CPos.New(3,18), blocked = false }
GDIBase = { GDINuke1, GDIPyle, GDIWeap, GDINuke2, GDINuke3, GDIDef1, GDIDef2, GDIDef3, GDIDef4,
GDINuke4, GDIDef5, GDIDef6, GDINuke5, GDISilo1, GDISilo2, GDIDef7, GDIDef8, GDISilo3, GDISilo4, GDIDef9 }
GDIRebuildList = { GDInuke1, GDIproc1, GDIpyle, GDIweap, GDIproc2, GDInuke2, GDInuke3, GDIdef1, GDIdef2, GDIdef3, GDIdef4,
GDInuke4, GDIdef5, GDIdef6, GDInuke5, GDIsilo1, GDIsilo2, GDIdef7, GDIdef8, GDIsilo3, GDIsilo4, GDIdef9 }
BSizes = { nuk2 = CVec.New(2,3), proc = CVec.New(3,4), pyle = CVec.New(2,3), weap = CVec.New(3,3), atwr = CVec.New(1,1), gtwr = CVec.New(1,1), silo = CVec.New(2,1), hpad = CVec.New(2,2) }
ProductionBuildings = { infantry = GDIPyle, vehicle = GDIWeap, aircraft = GDICYard }
ProductionQueue = { infantry = { }, vehicle = { }, aircraft = { } }
NewTeam = { }
TeamJob = "attack"
AT1 = { "e2", "e2", "e2", "e3", "e3", "vehicle", "jeep", "jeep", "apc" }
AT2 = { "e2", "e2", "e2", "e3", "e3", "e1", "e1", "e1", "e1" }
AT3 = { "vehicle", "mtnk", "mtnk", "jeep", "jeep" }
AT4 = { "e3", "e3", "e1", "e1", "e1", "vehicle", "mtnk", "mtnk", "msam" }
AT5 = { "vehicle", "jeep", "jeep", "jeep", "apc", "apc" }
AT6 = { "e3", "e3", "e1", "e1", "e1", "vehicle", "htnk" }
AT7 = { "vehicle", "htnk", "htnk", "mtnk" }
AT8 = { "vehicle", "htnk", "htnk", "msam" }
AT9 = { "vehicle", "mtnk", "msam", "apc", "apc" }
AT10 = { "e2", "e2", "e2", "e2", "e2", "e2", "e2", "e2", "e2", "e2" }
OT1 = { "aircraft", "orca", "orca" }
OT2 = { "aircraft", "orca", "orca", "orca", "orca" }
AttackTeams = { AT1, AT2, AT3, AT4, AT5, AT6, AT7, AT8, AT9, AT10 }
PT1 = { "vehicle", "htnk" }
PT2 = { "vehicle", "mtnk", "mtnk" }
PT3 = { "e2", "e2", "e2", "e3", "e3" }
PatrolTeams = { PT1, PT2, PT3 }
DT1 = { "vehicle", "mtnk", "mtnk", "msam", "msam" }
DT2 = { "e3", "e3", "e1", "e1", "e1", "vehicle", "mtnk", "mtnk", "msam" }
DT3 = { "vehicle", "htnk", "htnk", "msam" }
DefenseTeams = { DT1, DT2, DT3 }
AddOrcasTo = { AT1, AT2, AT5, AT6, AT9, DT1, DT2, DT3 }
AP1 = { waypoint5.Location, waypoint9.Location, waypoint8.Location, waypoint13.Location }
AP2 = { waypoint2.Location, waypoint5.Location, waypoint4.Location, waypoint6.Location }
AP3 = { waypoint2.Location, waypoint3.Location, waypoint4.Location, waypoint6.Location }
AP4 = { waypoint5.Location, waypoint9.Location, waypoint14.Location, PlayerStart.Location, waypoint13.Location }
AP5 = { waypoint5.Location, waypoint9.Location, waypoint6.Location }
AttackPaths = { AP1, AP2, AP3, AP4, AP5 }
InitAi = function()
if Difficulty == "hard" then
PBDelay = 115
PUDelay = 30
ICDelay = 800
ProdCDSecs = 30
GDI.Resources = 10000
MinHarvs = 3
ProcUpgrade = "AIHProcUpgrade"
CivsBuildingsToDestroy = 8
end
if Difficulty == "normal" then
PBDelay = 140
PUDelay = 50
ICDelay = 1000
ProdCDSecs = 40
GDI.Resources = 7000
MinHarvs = 2
ProcUpgrade = "AINProcUpgrade"
CivsBuildingsToDestroy = 11
end
if Difficulty == "easy" then
PBDelay = 180
PUDelay = 70
ICDelay = 1200
ProdCDSecs = 50
GDI.Resources = 5000
MinHarvs = 2
Nod.Resources = 3000
CivsBuildingsToDestroy = 13
end
RepairNamedActors(GDI, 0.75)
SetAutoRebuild()
Trigger.OnKilled(GDIPyle, function()
ProductionQueue["infantry"] = { }
end)
Trigger.OnKilled(GDIWeap, function()
ProductionQueue["vehicle"] = { }
end)
if ProcUpgrade then
ProcUpg = Actor.Create(ProcUpgrade, true, { Owner = GDI })
end
Trigger.AfterDelay(DateTime.Seconds(PBDelay), function()
CheckBase()
Trigger.AfterDelay(DateTime.Seconds(PUDelay), function()
ProduceUnits()
ReduceProdCD()
end)
Trigger.AfterDelay(DateTime.Seconds(ICDelay), function()
FireIonCannon(270)
end)
if not GDIAdvComCenter.IsDead then
IonCannonOnline = true
Media.DisplayMessage(UserInterface.GetFluentMessage("destroy-ion-cannon-advice"))
DestroyIonCannon = AddSecondaryObjective(Nod, "quickly-destroy-ion-cannon")
end
end)
end
ReduceProdCD = function()
Trigger.AfterDelay(DateTime.Minutes(2), function()
ProdCDSecs = ProdCDSecs - 1
if ProdCDSecs > 10 then
ReduceProdCD()
end
end)
end
PrepareOrcas = function()
table.insert(GDIRebuildList, 11, GDIhpad1)
Utils.Do(AddOrcasTo, function(t)
Utils.Do(OT1, function(u)
table.insert(t, u)
end)
end)
table.insert(AttackTeams, OT2)
table.insert(PatrolTeams, OT1)
end
--Building logic
SetAutoRebuild = function()
Utils.Do(GDIBase, function(b)
Trigger.OnKilled(b, CheckBase)
end)
end
CheckBase = function()
if GDICYard.IsDead then return end
for i = 1, #GDIRebuildList do
if GDIRebuildList[i].blocked then
CheckBuildablePlace(GDIRebuildList[i])
else
local building = GDI.GetActorsByType(GDIRebuildList[i].type)
if #building < 1 then
BuildBuilding(GDIRebuildList[i], GDICYard)
return
end
for ii = 1, #building do
if not building[ii].IsDead and building[ii].Location == GDIRebuildList[i].pos then
break
end
if ii == #building then
BuildBuilding(GDIRebuildList[i], GDICYard)
return
end
end
end
end
if not CheckProgrammed then
CheckProgrammed = true
Trigger.AfterDelay(250, function()
CheckProgrammed = false
CheckBase()
end)
end
end
CheckBuildablePlace = function(b)
local actors = Map.ActorsInBox(WPos.New(b.pos.X * 1024, b.pos.Y * 1024, 0), WPos.New((b.pos.X + BSizes[b.type].X) * 1024, (b.pos.Y + BSizes[b.type].Y) * 1024, 0), function(a) return a.Owner == Nod end)
if #actors > 0 then
b.blocked = true
return false
else
b.blocked = false
return true
end
end
BuildBuilding = function(building, cyard)
if CyardIsBuilding or GDI.Resources < Actor.Cost(building.type) then
if Dontspam == true then
return
end
Dontspam = true
Trigger.AfterDelay(DateTime.Seconds(10), function()
Dontspam = false
CheckBase()
end)
return
end
CyardIsBuilding = true
GDI.Resources = GDI.Resources - Actor.Cost(building.type)
Trigger.AfterDelay(Actor.BuildTime(building.type), function()
CyardIsBuilding = false
if cyard.IsDead or cyard.Owner ~= GDI then
GDI.Resources = GDI.Resources + Actor.Cost(building.type)
return
end
if CheckBuildablePlace(building) == false then
CheckBase()
return
end
local newbuilding = Actor.Create(building.type, true, { Owner = GDI, Location = building.pos })
Trigger.OnKilled(newbuilding, function() CheckBase() end)
RepairBuilding(GDI, newbuilding, 0.75)
GuardBuilding(newbuilding)
if newbuilding.Type == "pyle" then
ProductionBuildings["infantry"] = newbuilding
Trigger.OnKilled(newbuilding, function() ProductionQueue["infantry"] = { } end)
RestartUnitProduction()
elseif newbuilding.Type == "weap" then
ProductionBuildings["vehicle"] = newbuilding
Trigger.OnKilled(newbuilding, function() ProductionQueue["vehicle"] = { } end)
RestartUnitProduction()
NeedHarv = false
elseif newbuilding.Type == "hpad" then
ProductionBuildings["aircraft"] = newbuilding
Trigger.OnKilled(newbuilding, function() ProductionQueue["aircraft"] = { } end)
RestartUnitProduction()
end
Trigger.AfterDelay(50, CheckBase)
end)
end
--Units production logic
UniqueTeamsQueue = { }
ProdCooldown = false
CheckProduction = function()
if #GDI.GetActorsByType("proc") < 1 and GDI.Resources < 6000 then
Trigger.AfterDelay(250, CheckProduction)
return
elseif ProductionBuildings["infantry"].IsDead and ProductionBuildings["vehicle"].IsDead and ProductionBuildings["aircraft"].IsDead then
return
elseif not ProductionBuildings["vehicle"].IsDead and CheckForHarvester() then
NeedHarv = true
ProductionBuildings["vehicle"].Build( { "harv" }, function()
CheckProduction()
Trigger.AfterDelay(DateTime.Seconds(5), function()
if not ProductionBuildings["vehicle"].IsDead then
ProductionBuildings["vehicle"].Build( { "harv" } )
end
end)
end)
return
end
NeedHarv = false
if #ProductionQueue["infantry"] + #ProductionQueue["vehicle"] + #ProductionQueue["aircraft"] < 1 and Producing then
Producing = false
end
if ProdCooldown or GDI.Resources < 4000 then
RestartUnitProduction()
else
ProduceUnits()
end
end
ProduceUnits = function()
if NeedHarv then
RestartUnitProduction()
return
end
if not Producing then
NewTeam = { }
CreateUnitsGroup()
if #ProductionQueue["infantry"] + #ProductionQueue["vehicle"] + #ProductionQueue["aircraft"] > 0 then
Producing = true
else
RestartUnitProduction()
return
end
end
if #ProductionQueue["infantry"] > 0 and not ProductionBuildings["infantry"].IsDead and not ProductionBuildings["infantry"].IsProducing("e2") then
ProductionBuildings["infantry"].Build( { ProductionQueue["infantry"][1] }, function(u)
table.insert(NewTeam, u[1])
table.remove(ProductionQueue["infantry"], 1)
CheckTeamCompleted()
end)
end
if #ProductionQueue["vehicle"] > 0 and not ProductionBuildings["vehicle"].IsDead and not ProductionBuildings["vehicle"].IsProducing("mtnk") then
ProductionBuildings["vehicle"].Build( { ProductionQueue["vehicle"][1] }, function(u)
table.insert(NewTeam, u[1])
table.remove(ProductionQueue["vehicle"], 1)
CheckTeamCompleted()
end)
end
if #ProductionQueue["aircraft"] > 0 and not ProductionBuildings["aircraft"].IsDead and not ProductionBuildings["aircraft"].IsProducing("orca") then
ProductionBuildings["aircraft"].Build( { ProductionQueue["aircraft"][1] }, function(u)
table.insert(NewTeam, u[1])
table.remove(ProductionQueue["aircraft"], 1)
CheckTeamCompleted()
end)
end
RestartUnitProduction()
end
CheckTeamCompleted = function()
if #ProductionQueue["infantry"] + #ProductionQueue["vehicle"] + #ProductionQueue["aircraft"] < 1 and #NewTeam > 0 then
NewTeam = Utils.Where(NewTeam, function(u) return not u.IsDead end)
if TeamJob == "attack" then
SendAttackGroup(NewTeam)
elseif TeamJob == "patrol" then
TeamJob = "attack"
PatrolTeam = NewTeam
StartPatrol()
elseif TeamJob == "defend" then
TeamJob = "attack"
BaseDefenseTeam = NewTeam
StartGuard()
end
Producing = false
ProdCooldown = true
NewTeam = { }
Trigger.AfterDelay(DateTime.Seconds(ProdCDSecs), function() ProdCooldown = false end)
else
ProduceUnits()
end
end
SendAttackGroup = function(team)
MoveAsGroup(team, Utils.Random(AttackPaths), 1, false)
end
CreateUnitsGroup = function()
local team = AttackTeams
if #UniqueTeamsQueue > 0 then
team = UniqueTeamsQueue[1].team
TeamJob = UniqueTeamsQueue[1].job
table.remove(UniqueTeamsQueue, 1)
end
local pb = "infantry"
Utils.Do(Utils.Random(team), function(u)
if u == "vehicle" or u == "aircraft" then
pb = u
elseif ProductionBuildings[pb] and not ProductionBuildings[pb].IsDead and ProductionBuildings[pb].Owner == GDI then
table.insert(ProductionQueue[pb], u)
end
end)
end
RestartUnitProduction = function()
if not Restarting then
Restarting = true
else
return
end
Trigger.AfterDelay(DateTime.Seconds(5), function()
Restarting = false
CheckProduction()
end)
end
CheckForHarvester = function()
local harv = GDI.GetActorsByType("harv")
return #harv < MinHarvs
end