29 procedure FreeActionsList; |
29 procedure FreeActionsList; |
30 |
30 |
31 implementation |
31 implementation |
32 uses uConsts, SDLh, uAIMisc, uAIAmmoTests, uAIActions, |
32 uses uConsts, SDLh, uAIMisc, uAIAmmoTests, uAIActions, |
33 uAmmos, SysUtils{$IFNDEF USE_SDLTHREADS} {$IFDEF UNIX}, cthreads{$ENDIF} {$ENDIF}, uTypes, |
33 uAmmos, SysUtils{$IFNDEF USE_SDLTHREADS} {$IFDEF UNIX}, cthreads{$ENDIF} {$ENDIF}, uTypes, |
34 uVariables, uCommands, uUtils, uDebug; |
34 uVariables, uCommands, uUtils, uDebug, uAILandMarks; |
35 |
35 |
36 var BestActions: TActions; |
36 var BestActions: TActions; |
37 CanUseAmmo: array [TAmmoType] of boolean; |
37 CanUseAmmo: array [TAmmoType] of boolean; |
38 StopThinking: boolean; |
38 StopThinking: boolean; |
39 {$IFDEF USE_SDLTHREADS} |
39 {$IFDEF USE_SDLTHREADS} |
189 if (Ammoz[a].Ammo.Propz and ammoprop_AttackingPut) = 0 then |
189 if (Ammoz[a].Ammo.Propz and ammoprop_AttackingPut) = 0 then |
190 begin |
190 begin |
191 AddAction(BestActions, aia_attack, aim_push, 650 + random(300), 0, 0); |
191 AddAction(BestActions, aia_attack, aim_push, 650 + random(300), 0, 0); |
192 AddAction(BestActions, aia_attack, aim_release, ap.Power, 0, 0); |
192 AddAction(BestActions, aia_attack, aim_release, ap.Power, 0, 0); |
193 end; |
193 end; |
194 |
194 |
|
195 if (Ammoz[a].Ammo.Propz and ammoprop_Track) <> 0 then |
|
196 begin |
|
197 AddAction(BestActions, aia_waitAmmoXY, 0, 12, ap.ExplX, ap.ExplY); |
|
198 AddAction(BestActions, aia_attack, aim_push, 1, 0, 0); |
|
199 AddAction(BestActions, aia_attack, aim_release, 7, 0, 0); |
|
200 end; |
|
201 |
195 if ap.ExplR > 0 then |
202 if ap.ExplR > 0 then |
196 AddAction(BestActions, aia_AwareExpl, ap.ExplR, 10, ap.ExplX, ap.ExplY); |
203 AddAction(BestActions, aia_AwareExpl, ap.ExplR, 10, ap.ExplX, ap.ExplY); |
197 end |
204 end |
198 end; |
205 end; |
199 if a = High(TAmmoType) then |
206 if a = High(TAmmoType) then |
203 or StopThinking |
210 or StopThinking |
204 end |
211 end |
205 end; |
212 end; |
206 |
213 |
207 procedure Walk(Me: PGear; var Actions: TActions); |
214 procedure Walk(Me: PGear; var Actions: TActions); |
208 const FallPixForBranching = cHHRadius * 2 + 8; |
215 const FallPixForBranching = cHHRadius; |
209 var |
216 var |
210 ticks, maxticks, steps, tmp: Longword; |
217 ticks, maxticks, steps, tmp: Longword; |
211 BaseRate, BestRate, Rate: integer; |
218 BaseRate, BestRate, Rate: integer; |
212 GoInfo: TGoInfo; |
219 GoInfo: TGoInfo; |
213 CanGo: boolean; |
220 CanGo: boolean; |
266 if ticks > maxticks then |
273 if ticks > maxticks then |
267 break; |
274 break; |
268 |
275 |
269 if (BotLevel < 5) and (GoInfo.JumpType = jmpHJump) then // hjump support |
276 if (BotLevel < 5) and (GoInfo.JumpType = jmpHJump) then // hjump support |
270 if Push(ticks, Actions, AltMe, Me^.Message) then |
277 if Push(ticks, Actions, AltMe, Me^.Message) then |
|
278 begin |
271 with Stack.States[Pred(Stack.Count)] do |
279 with Stack.States[Pred(Stack.Count)] do |
272 begin |
280 begin |
273 if Me^.dX.isNegative then |
281 if Me^.dX.isNegative then |
274 AddAction(MadeActions, aia_LookRight, 0, 200, 0, 0) |
282 AddAction(MadeActions, aia_LookRight, 0, 200, 0, 0) |
275 else |
283 else |
281 if Me^.dX.isNegative then |
289 if Me^.dX.isNegative then |
282 AddAction(MadeActions, aia_LookLeft, 0, 200, 0, 0) |
290 AddAction(MadeActions, aia_LookLeft, 0, 200, 0, 0) |
283 else |
291 else |
284 AddAction(MadeActions, aia_LookRight, 0, 200, 0, 0); |
292 AddAction(MadeActions, aia_LookRight, 0, 200, 0, 0); |
285 end; |
293 end; |
|
294 |
|
295 // check if we could go backwards and maybe ljump over a gap after this hjump |
|
296 Push(ticks, Stack.States[Pred(Stack.Count)].MadeActions, AltMe, Me^.Message xor 3) |
|
297 end; |
286 if (BotLevel < 3) and (GoInfo.JumpType = jmpLJump) then // ljump support |
298 if (BotLevel < 3) and (GoInfo.JumpType = jmpLJump) then // ljump support |
287 begin |
299 begin |
288 // push current position so we proceed from it after checking jump opportunities |
300 // at final check where we go after jump walking backward |
|
301 if Push(ticks, Actions, AltMe, Me^.Message xor 3) then |
|
302 with Stack.States[Pred(Stack.Count)] do |
|
303 AddAction(MadeActions, aia_LJump, 0, 305 + random(50), 0, 0); |
|
304 |
|
305 // push current position so we proceed from it after checking jump+forward walk opportunities |
289 if CanGo then Push(ticks, Actions, Me^, Me^.Message); |
306 if CanGo then Push(ticks, Actions, Me^, Me^.Message); |
290 // first check where we go after jump |
307 |
|
308 // first check where we go after jump walking forward |
291 if Push(ticks, Actions, AltMe, Me^.Message) then |
309 if Push(ticks, Actions, AltMe, Me^.Message) then |
292 with Stack.States[Pred(Stack.Count)] do |
310 with Stack.States[Pred(Stack.Count)] do |
293 AddAction(MadeActions, aia_LJump, 0, 305 + random(50), 0, 0); |
311 AddAction(MadeActions, aia_LJump, 0, 305 + random(50), 0, 0); |
294 break |
312 break |
295 end; |
313 end; |
308 BestRate:= Rate; |
326 BestRate:= Rate; |
309 Me^.State:= Me^.State or gstAttacked // we have better place, go there and do not use ammo |
327 Me^.State:= Me^.State or gstAttacked // we have better place, go there and do not use ammo |
310 end |
328 end |
311 else if Rate < BestRate then |
329 else if Rate < BestRate then |
312 break; |
330 break; |
|
331 |
313 if ((Me^.State and gstAttacked) = 0) and ((steps mod 4) = 0) then |
332 if ((Me^.State and gstAttacked) = 0) and ((steps mod 4) = 0) then |
|
333 begin |
|
334 if (steps > 4) and checkMark(hwRound(Me^.X), hwRound(Me^.Y), markWasHere) then |
|
335 break; |
|
336 addMark(hwRound(Me^.X), hwRound(Me^.Y), markWasHere); |
|
337 |
314 TestAmmos(Actions, Me, true); |
338 TestAmmos(Actions, Me, true); |
|
339 end; |
|
340 |
315 if GoInfo.FallPix >= FallPixForBranching then |
341 if GoInfo.FallPix >= FallPixForBranching then |
316 Push(ticks, Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right |
342 Push(ticks, Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right |
317 end {while}; |
343 end {while}; |
318 |
344 |
319 if BestRate > BaseRate then |
345 if BestRate > BaseRate then |
334 currHedgehogIndex:= CurrentTeam^.CurrHedgehog; |
360 currHedgehogIndex:= CurrentTeam^.CurrHedgehog; |
335 itHedgehog:= currHedgehogIndex; |
361 itHedgehog:= currHedgehogIndex; |
336 switchesNum:= 0; |
362 switchesNum:= 0; |
337 |
363 |
338 switchImmediatelyAvailable:= (CurAmmoGear <> nil) and (CurAmmoGear^.Kind = gtSwitcher); |
364 switchImmediatelyAvailable:= (CurAmmoGear <> nil) and (CurAmmoGear^.Kind = gtSwitcher); |
339 switchCount:= HHHasAmmo(PGear(Me)^.Hedgehog^, amSwitch); |
365 if PGear(Me)^.Hedgehog^.BotLevel <> 5 then |
|
366 switchCount:= HHHasAmmo(PGear(Me)^.Hedgehog^, amSwitch) |
|
367 else switchCount:= 0; |
340 |
368 |
341 if (PGear(Me)^.State and gstAttacked) = 0 then |
369 if (PGear(Me)^.State and gstAttacked) = 0 then |
342 if Targets.Count > 0 then |
370 if Targets.Count > 0 then |
343 begin |
371 begin |
344 // iterate over current team hedgehogs |
372 // iterate over current team hedgehogs |
399 if not StopThinking then |
432 if not StopThinking then |
400 SDL_Delay(100) |
433 SDL_Delay(100) |
401 end |
434 end |
402 end; |
435 end; |
403 |
436 |
404 PGear(Me)^.State:= PGear(Me)^.State and not gstHHThinking; |
437 PGear(Me)^.State:= PGear(Me)^.State and (not gstHHThinking); |
405 Think:= 0; |
438 Think:= 0; |
406 InterlockedDecrement(hasThread) |
439 InterlockedDecrement(hasThread) |
407 end; |
440 end; |
408 |
441 |
409 procedure StartThink(Me: PGear); |
442 procedure StartThink(Me: PGear); |
410 begin |
443 begin |
411 if ((Me^.State and (gstAttacking or gstHHJumping or gstMoving)) <> 0) |
444 if ((Me^.State and (gstAttacking or gstHHJumping or gstMoving)) <> 0) |
412 or isInMultiShoot then |
445 or isInMultiShoot then |
413 exit; |
446 exit; |
414 |
447 |
415 //DeleteCI(Me); // this might break demo |
448 //DeleteCI(Me); // this will break demo/netplay |
|
449 clearAllMarks; |
|
450 |
416 Me^.State:= Me^.State or gstHHThinking; |
451 Me^.State:= Me^.State or gstHHThinking; |
417 Me^.Message:= 0; |
452 Me^.Message:= 0; |
418 |
453 |
419 BestActions.Count:= 0; |
454 BestActions.Count:= 0; |
420 BestActions.Pos:= 0; |
455 BestActions.Pos:= 0; |
467 StartThink(Gear); |
502 StartThink(Gear); |
468 StartTicks:= GameTicks |
503 StartTicks:= GameTicks |
469 |
504 |
470 end else |
505 end else |
471 begin |
506 begin |
472 (* |
507 {if not scoreShown then |
473 if not scoreShown then |
|
474 begin |
508 begin |
475 if BestActions.Score > 0 then ParseCommand('/say Expected score = ' + inttostr(BestActions.Score div 1024), true); |
509 if BestActions.Score > 0 then ParseCommand('/say Expected score = ' + inttostr(BestActions.Score div 1024), true); |
476 scoreShown:= true |
510 scoreShown:= true |
477 end;*) |
511 end;} |
478 ProcessAction(BestActions, Gear) |
512 ProcessAction(BestActions, Gear) |
479 end |
513 end |
480 else if ((GameTicks - StartTicks) > cMaxAIThinkTime) |
514 else if ((GameTicks - StartTicks) > cMaxAIThinkTime) |
481 or (TurnTimeLeft <= cStopThinkTime) then |
515 or (TurnTimeLeft <= cStopThinkTime) then |
482 StopThinking:= true |
516 StopThinking:= true |