Skip to content

Commit

Permalink
Fix Engineer deaths not counted, add proper TML and SML AI
Browse files Browse the repository at this point in the history
Fixes BaseManager Engineers not decremented if they got either reclaimed or captured, (replaced the 'Death' trigger with the 'Destroyed' trigger, that adds callbacks for being reclaimed and captured as well)

Also added TML and SML AI functions, the AI can now also grab technically unlimited amounts of these to use near a base.
  • Loading branch information
Dhomie authored and Garanas committed Aug 19, 2023
1 parent 4a24475 commit a948a1b
Showing 1 changed file with 90 additions and 31 deletions.
121 changes: 90 additions & 31 deletions lua/AI/OpAI/BaseManagerPlatoonThreads.lua
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ function BaseManagerEngineerPlatoonSplit(platoon)

-- Only add death callback if it hasnt been set yet
if not v.Subtracted then
TriggerFile.CreateUnitDeathTrigger(BaseManagerSingleDestroyed, v)
TriggerFile.CreateUnitDestroyedTrigger(BaseManagerSingleDestroyed, v)
end

-- If the base is building engineers, subtract one from the amount being built
Expand Down Expand Up @@ -109,7 +109,7 @@ function BaseManagerSingleEngineerPlatoon(platoon)
-- Try to build buildings
elseif BMBC.NeedAnyStructure(aiBrain, baseName) and bManager:GetConstructionEngineerCount() < bManager:GetConstructionEngineerMaximum() then
bManager:AddConstructionEngineer(unit)
TriggerFile.CreateUnitDeathTrigger(ConstructionUnitDeath, unit)
TriggerFile.CreateUnitDestroyedTrigger(ConstructionUnitDeath, unit)
BaseManagerEngineerThread(platoon)
bManager:RemoveConstructionEngineer(unit)

Expand Down Expand Up @@ -310,7 +310,7 @@ function ConditionalBuildSuccessful(conditionalUnit)
local waitTime = bManager.ConditionalBuildData.WaitSecondsAfterDeath

-- Register death callback
TriggerFile.CreateUnitDeathTrigger(function(unit)
TriggerFile.CreateUnitDestroyedTrigger(function(unit)
ForkThread(function()
WaitSeconds(waitTime)
ScenarioInfo.ConditionalBuildLocks[selectedBuild.name] = false
Expand Down Expand Up @@ -351,7 +351,7 @@ function AssistConditionalBuild(singleEngineerPlatoon)
local buildIndex = bManager.ConditionalBuildData.Index

-- Register death callback
TriggerFile.CreateUnitDeathTrigger(ConditionalBuilderDead, engineer)
TriggerFile.CreateUnitDestroyedTrigger(ConditionalBuilderDead, engineer)

-- Increment number of units assisting
bManager.ConditionalBuildData.IncrementAssisting()
Expand Down Expand Up @@ -407,7 +407,7 @@ function DoConditionalBuild(singleEngineerPlatoon)
bManager.ConditionalBuildData.WaitSecondsAfterDeath = selectedBuild.data.WaitSecondsAfterDeath or false

-- Register death callback
TriggerFile.CreateUnitDeathTrigger(ConditionalBuilderDead, engineer)
TriggerFile.CreateUnitDestroyedTrigger(ConditionalBuilderDead, engineer)

-- Issue build orders
IssueClearCommands({engineer})
Expand Down Expand Up @@ -515,7 +515,7 @@ function PermanentFactoryAssist(platoon)
local assistFac = false
local unit = platoon:GetPlatoonUnits()[1]

TriggerFile.CreateUnitDeathTrigger(PermanentAssisterDead, unit)
TriggerFile.CreateUnitDestroyedTrigger(PermanentAssisterDead, unit)
while aiBrain:PlatoonExists(platoon) do
-- Get all factories in the base manager
local facs = bManager:GetAllBaseFactories()
Expand Down Expand Up @@ -551,7 +551,7 @@ function PermanentFactoryAssist(platoon)
-- Add to the list of units that are permanently assisting in this base manager
bManager.PermanentAssisters[unit] = true
end
WaitTicks(Random(79, 181))
WaitTicks(Random(80, 180))
end
end

Expand Down Expand Up @@ -677,7 +677,7 @@ function BaseManagerAssistThread(platoon)
end
end
end
local waitTime = Random(5, 17)
local waitTime = Random(5, 20)
WaitTicks(waitTime)

counter = counter + waitTime
Expand Down Expand Up @@ -817,13 +817,6 @@ function BaseManagerEngineerThread(platoon)
error('*AI DEBUG: Missing Base Name or invalid base name for base manager engineer thread', 2)
end

local structurePriTable
if not platoon.PlatoonData.StructurePriorities then
structurePriTable = { 'ALLUNITS' }
else
structurePriTable = platoon.PlatoonData.StructurePriorities
end

-- If there is a construction block use the stuff from here
local buildFunction = BuildBaseManagerStructure

Expand Down Expand Up @@ -1123,22 +1116,39 @@ function BaseManagerScoutingAI(platoon)
end
end

--- Assigns the units of the given platoon into new single unit platoons, and sets the 'BaseManagerTMLAI' as their platoon AI function
--- Also copies over the platoon data, which we require to determine if the unit's BaseManager is allowed to use the TML
---@param platoon Platoon
function BaseManagerTMLPlatoon(platoon)
local aiBrain = platoon:GetBrain()
local TMLs = platoon:GetPlatoonUnits()

if not aiBrain.BaseManagers[platoon.PlatoonData.BaseName] then
aiBrain:DisbandPlatoon(platoon)
end

for _, launcher in TMLs do
if not launcher.Dead then
local launcherPlatoon = aiBrain:MakePlatoon('', '')
aiBrain:AssignUnitsToPlatoon(launcherPlatoon, {launcher}, 'Attack', 'None')
launcherPlatoon.PlatoonData = table.deepcopy(platoon.PlatoonData)
launcherPlatoon:ForkAIThread(BaseManagerTMLAI)
end
end

aiBrain:DisbandPlatoon(platoon)
end

---@param platoon Platoon
function BaseManagerTMLAI(platoon)
local aiBrain = platoon:GetBrain()
local pData = platoon.PlatoonData
local baseName = pData.BaseName
local bManager = aiBrain.BaseManagers[baseName]
local baseName = platoon.PlatoonData.BaseName
local unit = platoon:GetPlatoonUnits()[1]
unit.BaseName = baseName

if not unit then return end

platoon:Stop()
local bp = unit:GetBlueprint()
local weapon = bp.Weapon[1]
local maxRadius = weapon.MaxRadius
local minRadius = weapon.MinRadius
local maxRadius = unit.Blueprint.Weapon[1].MaxRadius

local simpleTargetting = true
if ScenarioInfo.Options.Difficulty == 3 then
Expand All @@ -1152,14 +1162,14 @@ function BaseManagerTMLAI(platoon)
categories.EXPERIMENTAL,
categories.ENERGYPRODUCTION,
categories.STRUCTURE,
categories.TECH3 * categories.MOBILE})
categories.TECH3 * categories.MOBILE}
)

while aiBrain:PlatoonExists(platoon) do
if BMBC.TMLsEnabled(aiBrain, baseName) then
local target = false
local blip = false
while unit:GetTacticalSiloAmmoCount() < 1 or not target do
WaitSeconds(7)
WaitSeconds(5)
target = false
while not target do
target = platoon:FindPrioritizedUnit('Attack', 'Enemy', true, unit:GetPosition(), maxRadius)
Expand All @@ -1168,7 +1178,7 @@ function BaseManagerTMLAI(platoon)
break
end

WaitSeconds(3)
WaitSeconds(5)

if not aiBrain:PlatoonExists(platoon) then
return
Expand All @@ -1186,12 +1196,62 @@ function BaseManagerTMLAI(platoon)
end
end
end
WaitSeconds(3)
WaitSeconds(5)
end
end

--- Assigns the units of the given platoon into new single unit platoons, and sets the 'BaseManagerNukeAI' as their platoon AI function
--- Also copies over the platoon data, which we require to determine if the unit's BaseManager is allowed to use the SML
---@param platoon Platoon
function BaseManagerNukePlatoon(platoon)
local aiBrain = platoon:GetBrain()
local SMLs = platoon:GetPlatoonUnits()

if not aiBrain.BaseManagers[platoon.PlatoonData.BaseName] then
aiBrain:DisbandPlatoon(platoon)
end

for _, silo in SMLs do
if not silo.Dead then
local siloPlatoon = aiBrain:MakePlatoon('', '')
aiBrain:AssignUnitsToPlatoon(siloPlatoon, {silo}, 'Support', 'None')
siloPlatoon.PlatoonData = table.deepcopy(platoon.PlatoonData)
siloPlatoon:ForkAIThread(BaseManagerNukeAI)
end
end

aiBrain:DisbandPlatoon(platoon)
end

---@param platoon Platoon
function BaseManagerNukeAI(platoon)
local aiBrain = platoon:GetBrain()
local baseName = platoon.PlatoonData.BaseName
local unit = platoon:GetPlatoonUnits()[1]

if not unit then return end

platoon:Stop()

unit:SetAutoMode(true)
while aiBrain:PlatoonExists(platoon) do
if BMBC.NukesEnabled(aiBrain, baseName) then
while unit:GetNukeSiloAmmoCount() < 1 do
WaitSeconds(15)
if not aiBrain:PlatoonExists(platoon) then
return
end
end

nukePos = AIBehaviors.GetHighestThreatClusterLocation(aiBrain, unit)
if nukePos then
IssueNuke({unit}, nukePos)
WaitSeconds(15)
IssueClearCommands({unit})
end
end
WaitSeconds(10)
end
end

---@param platoon Platoon
Expand Down Expand Up @@ -1220,7 +1280,7 @@ function AMUnlockRatio(platoon)
for _, v in platoon:GetPlatoonUnits() do
if not v.Dead then
v.PlatoonHandle = platoon
TriggerFile.CreateUnitDeathTrigger(callback, v)
TriggerFile.CreateUnitDestroyedTrigger(callback, v)
end
end
end
Expand All @@ -1246,8 +1306,7 @@ function AMUnlockRatioTimer(platoon)
for _, v in platoon:GetPlatoonUnits() do
if not v.Dead then
v.PlatoonHandle = platoon
v:AddOnKilledCallback(callback)
TriggerFile.CreateUnitDeathTrigger(callback, v)
TriggerFile.CreateUnitDestroyedTrigger(callback, v)
end
end
end
Expand Down

0 comments on commit a948a1b

Please sign in to comment.