forked from FAForever/fa
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPlatoonFormManager.lua
More file actions
179 lines (150 loc) · 6.93 KB
/
PlatoonFormManager.lua
File metadata and controls
179 lines (150 loc) · 6.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#***************************************************************************
#*
#** File : /lua/sim/BuilderManager.lua
#**
#** Summary : Manage builders
#**
#** Copyright © 2005 Gas Powered Games, Inc. All rights reserved.
#****************************************************************************
local BuilderManager = import('/lua/sim/BuilderManager.lua').BuilderManager
local AIUtils = import('/lua/ai/aiutilities.lua')
local Builder = import('/lua/sim/Builder.lua')
local AIBuildUnits = import('/lua/ai/aibuildunits.lua')
PlatoonFormManager = Class(BuilderManager) {
Create = function(self, brain, lType, location, radius)
BuilderManager.Create(self,brain)
if not lType or not location or not radius then
error('*PLATOOM FORM MANAGER ERROR: Invalid parameters; requires locationType, location, and radius')
return false
end
self.Location = location
self.Radius = radius
self.LocationType= lType
self:AddBuilderType('Any')
self.BuilderCheckInterval = 5
end,
AddBuilder = function(self, builderData, locationType, builderType)
local newBuilder = Builder.CreatePlatoonBuilder(self.Brain, builderData, locationType)
self:AddInstancedBuilder(newBuilder, builderType)
return newBuilder
end,
GetPlatoonTemplate = function(self, templateName)
local templateData = PlatoonTemplates[templateName]
if not templateData then
error('*AI ERROR: Invalid platoon template named - ' .. templateName)
end
local template = {}
if templateData.GlobalSquads then
template = {
templateData.Name,
templateData.Plan,
unpack(templateData.GlobalSquads)
}
else
template = {
templateData.Name,
templateData.Plan,
}
for k,v in templateData.FactionSquads do
table.insert(template, unpack(v))
end
end
return template
end,
GetUnitsBeingBuilt = function(self, buildingCategory, builderCategory)
local position = self.Location
local radius = self.Radius
local filterUnits = AIUtils.GetOwnUnitsAroundPoint(self.Brain, builderCategory, position, radius)
local retUnits = {}
for k,v in filterUnits do
# Make sure the unit is building or upgrading
if not v:IsUnitState('Building') and not v:IsUnitState('Upgrading') then
continue
end
# Engineer doesn't want to be assisted
if v.DesiresAssist == false then
continue
end
# Check for unit being built compatibility
local beingBuiltUnit = v.UnitBeingBuilt
if not beingBuiltUnit or not EntityCategoryContains(buildingCategory, beingBuiltUnit) then
continue
end
# Engineer doesn't want any more assistance
if v.NumAssistees and table.getn(v:GetGuards()) >= v.NumAssistees then
continue
end
# Check if valid economy exists for this assist
# Unit had not problems; add to possible list
table.insert(retUnits, v)
end
return retUnits
end,
ManagerLoopBody = function(self,builder,bType)
BuilderManager.ManagerLoopBody(self,builder,bType)
# Try to form all builders that pass
if self.Brain.BuilderManagers[self.LocationType] and builder.Priority >= 1 and builder:CheckInstanceCount() then
local personality = self.Brain:GetPersonality()
local poolPlatoon = self.Brain:GetPlatoonUniquelyNamed('ArmyPool')
local template = self:GetPlatoonTemplate(builder:GetPlatoonTemplate())
builder:FormDebug()
local radius = self.Radius
if builder:GetFormRadius() then radius = builder:GetFormRadius() end
if not template or not self.Location or not radius then
if type(template) != 'table' or type(template[1]) != 'string' or type(template[2]) != 'string' then
WARN('*Platoon Form: Could not find template named: ' .. builder:GetPlatoonTemplate())
return
end
WARN('*Platoon Form: Could not find template named: ' .. builder:GetPlatoonTemplate())
return
end
local formIt = poolPlatoon:CanFormPlatoon(template, personality:GetPlatoonSize(), self.Location, radius)
if formIt and builder:GetBuilderStatus() then
local hndl = poolPlatoon:FormPlatoon(template, personality:GetPlatoonSize(), self.Location, radius)
#LOG('*AI DEBUG: ARMY ', repr(self.Brain:GetArmyIndex()),': Platoon Form Manager Forming - ',repr(builder.BuilderName),': Location = ',self.LocationType)
#LOG('*AI DEBUG: ARMY ', repr(self.Brain:GetArmyIndex()),': Platoon Form Manager - Platoon Size = ', table.getn(hndl:GetPlatoonUnits()))
hndl.PlanName = template[2]
#If we have specific AI, fork that AI thread
if builder:GetPlatoonAIFunction() then
hndl:StopAI()
local aiFunc = builder:GetPlatoonAIFunction()
hndl:ForkAIThread(import(aiFunc[1])[aiFunc[2]])
end
if builder:GetPlatoonAIPlan() then
hndl.PlanName = builder:GetPlatoonAIPlan()
hndl:SetAIPlan(hndl.PlanName)
end
#If we have additional threads to fork on the platoon, do that as well.
if builder:GetPlatoonAddPlans() then
for papk, papv in builder:GetPlatoonAddPlans() do
hndl:ForkThread(hndl[papv])
end
end
if builder:GetPlatoonAddFunctions() then
for pafk, pafv in builder:GetPlatoonAddFunctions() do
hndl:ForkThread(import(pafv[1])[pafv[2]])
end
end
if builder:GetPlatoonAddBehaviors() then
for pafk, pafv in builder:GetPlatoonAddBehaviors() do
hndl:ForkThread(import('/lua/ai/AIBehaviors.lua')[pafv])
end
end
hndl.Priority = builder.Priority
hndl.BuilderName = builder.BuilderName
hndl:SetPlatoonData(builder:GetBuilderData(self.LocationType))
for k,v in hndl:GetPlatoonUnits() do
if not v.PlatoonPlanName then
v.PlatoonHandle = hndl
end
end
builder:StoreHandle(hndl)
end
end
end,
}
function CreatePlatoonFormManager(brain, lType, location, radius)
local pfm = PlatoonFormManager()
pfm:Create(brain, lType, location, radius)
return pfm
end