Main update loop executed every frame.
128{
129 BWAPI::Unit dt = darkTemplar;
130
131 if (state == State::Done || !dt || !dt->exists())
132 {
133 return;
134 }
135
136 if (!enemyMainPos.isValid() && commanderRef)
137 {
138 const auto& e = commanderRef->enemy();
139 if (e.main.has_value())
140 {
142 }
143 }
144
145 switch (state)
146 {
147 case State::Idle:
148 {
149 state = enemyMainPos.isValid() ? State::MoveToEnemyMain : State::WaitEnemyMain;
150 break;
151 }
152
153 case State::WaitEnemyMain:
154 {
155 if (enemyMainPos.isValid())
156 {
157 state = State::MoveToEnemyMain;
158 }
159 break;
160 }
161
162 case State::MoveToEnemyMain:
163 {
164 if (enemyMainPos.isValid() && dt->getDistance(enemyMainPos) <= kMainPriorityRadiusPx)
165 {
166 lockedTargetId = -1;
167 state = State::AttackEnemyMain;
168 break;
169 }
170
171 if (manager)
172 {
173 auto nat = manager->getEnemyNatural();
174 if (nat.has_value())
175 {
176 state = State::ApproachNatural;
177 break;
178 }
179 }
180
182
183 if (!target || !target->exists())
184 {
186
187 if (target && target->exists())
188 {
189 lockedTargetId = target->getID();
190 }
191 else
192 {
193 lockedTargetId = -1;
194 }
195 }
196
197 if (target && target->exists())
198 {
199 if (dt->getOrderTarget() != target)
200 {
201 dt->attack(target);
202 }
203 }
204 else if (dt->getDistance(enemyMainPos) > kArriveDistPx)
205 {
206 if (dt->getLastCommandFrame() < BWAPI::Broodwar->getFrameCount() - kMoveCooldownFrames)
207 {
208 dt->attack(enemyMainPos);
209 }
210 }
211 else
212 {
213 state = State::ApproachNatural;
214 }
215
216 break;
217 }
218
219 case State::ApproachNatural:
220 {
222
223 if (!approachPos.isValid())
224 {
225 if (enemyMainPos.isValid())
226 {
227 approachPos = enemyMainPos;
228 }
229 else
230 {
231 break;
232 }
233 }
234
235 const int dist = dt->getDistance(approachPos);
236
237 const int mainPriorityRadius = 10 * 32;
238
239 if (enemyMainPos.isValid() && dt->getDistance(enemyMainPos) <= mainPriorityRadius)
240 {
241 lockedTargetId = -1;
242 state = State::AttackEnemyMain;
243 break;
244 }
245
247
248 if (!target || !target->exists())
249 {
251
252 if (target && target->exists())
253 {
254 lockedTargetId = target->getID();
255 }
256 else
257 {
258 lockedTargetId = -1;
259 }
260 }
261
262 if (target && target->exists())
263 {
264 if (dt->getOrderTarget() != target)
265 {
266 dt->attack(target);
267 }
268 }
269 else if (dt->getLastCommandFrame() < BWAPI::Broodwar->getFrameCount() - kMoveCooldownFrames)
270 {
271 dt->attack(approachPos);
272 }
273
274 break;
275 }
276
277 case State::AttackEnemyMain:
278 {
280
281 if (!target || !target->exists())
282 {
284
285 if (target && target->exists())
286 {
287 lockedTargetId = target->getID();
288 }
289 else
290 {
291 lockedTargetId = -1;
292 }
293 }
294
295 if (target && target->exists())
296 {
297 if (dt->getOrderTarget() != target)
298 {
299 dt->attack(target);
300 }
301 }
302 else
303 {
305 }
306 break;
307 }
308
309 case State::Done:
310 default:
311 {
312 break;
313 }
314 }
315}
BWAPI::Position getNaturalApproachPosition() const
Returns the preferred approach position near the enemy natural.
void setEnemyMain(const BWAPI::TilePosition &tp)
Sets the enemy main base location and updates behavior state.
BWAPI::Unit findApproachTarget(BWAPI::Unit dt) const
Finds a nearby target to attack while approaching the enemy base.
BWAPI::Unit pickTargetFor(BWAPI::Unit dt) const
Selects the highest priority target inside the enemy base.
void issueMove(BWAPI::Unit unit, const BWAPI::Position &p, bool force=false)
Issues a movement command with cooldown control.