170 (CurrentHedgehog^.MultiShootAttacks > 0) or // shooting same weapon |
170 (CurrentHedgehog^.MultiShootAttacks > 0) or // shooting same weapon |
171 StopThinking |
171 StopThinking |
172 end |
172 end |
173 end; |
173 end; |
174 |
174 |
175 procedure Walk(Me: PGear); |
175 procedure Walk(Me: PGear; var Actions: TActions); |
176 const FallPixForBranching = cHHRadius * 2 + 8; |
176 const FallPixForBranching = cHHRadius * 2 + 8; |
177 var Actions: TActions; |
177 var |
178 ticks, maxticks, steps, tmp: Longword; |
178 ticks, maxticks, steps, tmp: Longword; |
179 BaseRate, BestRate, Rate: integer; |
179 BaseRate, BestRate, Rate: integer; |
180 GoInfo: TGoInfo; |
180 GoInfo: TGoInfo; |
181 CanGo: boolean; |
181 CanGo: boolean; |
182 AltMe: TGear; |
182 AltMe: TGear; |
183 BotLevel: Byte; |
183 BotLevel: Byte; |
184 a: TAmmoType; |
184 a: TAmmoType; |
185 begin |
185 begin |
186 ticks:= 0; // avoid compiler hint |
186 ticks:= 0; // avoid compiler hint |
187 Actions.Count:= 0; |
|
188 Actions.Pos:= 0; |
|
189 Actions.Score:= 0; |
|
190 Stack.Count:= 0; |
187 Stack.Count:= 0; |
191 |
188 |
192 for a:= Low(TAmmoType) to High(TAmmoType) do |
189 for a:= Low(TAmmoType) to High(TAmmoType) do |
193 CanUseAmmo[a]:= Assigned(AmmoTests[a].proc) and HHHasAmmo(Me^.Hedgehog^, a); |
190 CanUseAmmo[a]:= Assigned(AmmoTests[a].proc) and HHHasAmmo(Me^.Hedgehog^, a); |
194 |
191 |
262 end |
259 end |
263 end; |
260 end; |
264 |
261 |
265 function Think(Me: Pointer): ptrint; |
262 function Think(Me: Pointer): ptrint; |
266 var BackMe, WalkMe: TGear; |
263 var BackMe, WalkMe: TGear; |
267 StartTicks: Longword; |
264 StartTicks, currHedgehogIndex, itHedgehog, switchesNum, i: Longword; |
|
265 switchImmediatelyAvailable, switchAvailable: boolean; |
|
266 Actions: TActions; |
268 begin |
267 begin |
269 InterlockedIncrement(hasThread); |
268 InterlockedIncrement(hasThread); |
270 StartTicks:= GameTicks; |
269 StartTicks:= GameTicks; |
271 BackMe:= PGear(Me)^; |
270 currHedgehogIndex:= CurrentTeam^.CurrHedgehog; |
|
271 itHedgehog:= currHedgehogIndex; |
|
272 switchesNum:= 0; |
|
273 |
|
274 switchImmediatelyAvailable:= (CurAmmoGear <> nil) and (CurAmmoGear^.Kind = gtSwitcher); |
|
275 switchAvailable:= HHHasAmmo(PGear(Me)^.Hedgehog^, amSwitch); |
272 |
276 |
273 if (PGear(Me)^.State and gstAttacked) = 0 then |
277 if (PGear(Me)^.State and gstAttacked) = 0 then |
274 if Targets.Count > 0 then |
278 if Targets.Count > 0 then |
275 begin |
279 begin |
276 WalkMe:= BackMe; |
280 // iterate over current team hedgehogs |
277 Walk(@WalkMe); |
281 repeat |
278 if (StartTicks > GameTicks - 1500) and (not StopThinking) then SDL_Delay(1000); |
282 WalkMe:= CurrentTeam^.Hedgehogs[itHedgehog].Gear^; |
279 if BestActions.Score < -1023 then |
283 |
280 begin |
284 Actions.Count:= 0; |
281 BestActions.Count:= 0; |
285 Actions.Pos:= 0; |
282 AddAction(BestActions, aia_Skip, 0, 250, 0, 0); |
286 Actions.Score:= 0; |
283 end; |
287 if switchesNum > 0 then |
|
288 begin |
|
289 if not switchImmediatelyAvailable then |
|
290 begin |
|
291 // when AI has to use switcher, make it cost smth |
|
292 Actions.Score:= -20000; |
|
293 AddAction(Actions, aia_Weapon, Longword(amSwitch), 300 + random(200), 0, 0); |
|
294 AddAction(Actions, aia_attack, aim_push, 300 + random(300), 0, 0); |
|
295 AddAction(Actions, aia_attack, aim_release, 1, 0, 0); |
|
296 end; |
|
297 for i:= 1 to switchesNum do |
|
298 AddAction(Actions, aia_Switch, 0, 300 + random(200), 0, 0); |
|
299 end; |
|
300 Walk(@WalkMe, Actions); |
|
301 |
|
302 // find another hog in team |
|
303 repeat |
|
304 itHedgehog:= Succ(itHedgehog) mod CurrentTeam^.HedgehogsNumber; |
|
305 until (itHedgehog = currHedgehogIndex) or (CurrentTeam^.Hedgehogs[itHedgehog].Gear <> nil); |
|
306 |
|
307 inc(switchesNum); |
|
308 until (not (switchImmediatelyAvailable or switchAvailable)) |
|
309 or StopThinking |
|
310 or (itHedgehog = currHedgehogIndex); |
|
311 |
|
312 if (StartTicks > GameTicks - 1500) and (not StopThinking) then SDL_Delay(1000); |
|
313 |
|
314 if BestActions.Score < -1023 then |
|
315 begin |
|
316 BestActions.Count:= 0; |
|
317 AddAction(BestActions, aia_Skip, 0, 250, 0, 0); |
|
318 end; |
|
319 |
284 end else |
320 end else |
285 else begin |
321 else begin |
286 while (not StopThinking) and (BestActions.Count = 0) do |
322 BackMe:= PGear(Me)^; |
287 begin |
323 while (not StopThinking) and (BestActions.Count = 0) do |
288 FillBonuses(true); |
324 begin |
289 WalkMe:= BackMe; |
325 FillBonuses(true); |
290 Walk(@WalkMe); |
326 WalkMe:= BackMe; |
291 if not StopThinking then SDL_Delay(100) |
327 Actions.Count:= 0; |
292 end |
328 Actions.Pos:= 0; |
293 end; |
329 Actions.Score:= 0; |
|
330 Walk(@WalkMe, Actions); |
|
331 if not StopThinking then SDL_Delay(100) |
|
332 end |
|
333 end; |
|
334 |
294 PGear(Me)^.State:= PGear(Me)^.State and not gstHHThinking; |
335 PGear(Me)^.State:= PGear(Me)^.State and not gstHHThinking; |
295 Think:= 0; |
336 Think:= 0; |
296 InterlockedDecrement(hasThread) |
337 InterlockedDecrement(hasThread) |
297 end; |
338 end; |
298 |
339 |