36 |
36 |
37 var BestActions: TActions; |
37 var BestActions: TActions; |
38 CanUseAmmo: array [TAmmoType] of boolean; |
38 CanUseAmmo: array [TAmmoType] of boolean; |
39 StopThinking: boolean; |
39 StopThinking: boolean; |
40 StartTicks: Longword; |
40 StartTicks: Longword; |
41 ThinkThread: PSDL_Thread; |
41 ThreadSem: PSDL_Sem; |
42 ThreadLock: PSDL_Mutex; |
|
43 |
42 |
44 procedure FreeActionsList; |
43 procedure FreeActionsList; |
45 begin |
44 begin |
46 AddFileLog('FreeActionsList called'); |
45 AddFileLog('FreeActionsList called'); |
47 if (ThinkThread <> nil) then |
46 |
48 begin |
47 StopThinking:= true; |
49 StopThinking:= true; |
48 SDL_SemWait(ThreadSem); |
50 SDL_WaitThread(ThinkThread, nil); |
49 SDL_SemPost(ThreadSem); |
51 end; |
|
52 SDL_LockMutex(ThreadLock); |
|
53 ThinkThread:= nil; |
|
54 SDL_UnlockMutex(ThreadLock); |
|
55 |
50 |
56 if CurrentHedgehog <> nil then |
51 if CurrentHedgehog <> nil then |
57 with CurrentHedgehog^ do |
52 with CurrentHedgehog^ do |
58 if Gear <> nil then |
53 if Gear <> nil then |
59 if BotLevel <> 0 then |
54 if BotLevel <> 0 then |
110 useThisActions: boolean; |
105 useThisActions: boolean; |
111 begin |
106 begin |
112 BotLevel:= Me^.Hedgehog^.BotLevel; |
107 BotLevel:= Me^.Hedgehog^.BotLevel; |
113 windSpeed:= hwFloat2Float(cWindSpeed); |
108 windSpeed:= hwFloat2Float(cWindSpeed); |
114 useThisActions:= false; |
109 useThisActions:= false; |
|
110 Me^.AIHints:= Me^.AIHints and (not aihAmmosChanged); |
115 |
111 |
116 for i:= 0 to Pred(Targets.Count) do |
112 for i:= 0 to Pred(Targets.Count) do |
117 if (Targets.ar[i].Score >= 0) and (not StopThinking) then |
113 if (Targets.ar[i].Score >= 0) and (not StopThinking) then |
118 begin |
114 begin |
119 with Me^.Hedgehog^ do |
115 with Me^.Hedgehog^ do |
435 switchImmediatelyAvailable:= (CurAmmoGear <> nil) and (CurAmmoGear^.Kind = gtSwitcher); |
431 switchImmediatelyAvailable:= (CurAmmoGear <> nil) and (CurAmmoGear^.Kind = gtSwitcher); |
436 if Me^.Hedgehog^.BotLevel <> 5 then |
432 if Me^.Hedgehog^.BotLevel <> 5 then |
437 switchCount:= HHHasAmmo(PGear(Me)^.Hedgehog^, amSwitch) |
433 switchCount:= HHHasAmmo(PGear(Me)^.Hedgehog^, amSwitch) |
438 else switchCount:= 0; |
434 else switchCount:= 0; |
439 |
435 |
440 if ((Me^.State and gstAttacked) = 0) or isInMultiShoot or bonuses.activity then |
436 if ((Me^.State and gstAttacked) = 0) or isInMultiShoot or bonuses.activity or ((Me^.AIHints and aihAmmosChanged) <> 0) then |
441 if Targets.Count > 0 then |
437 if Targets.Count > 0 then |
442 begin |
438 begin |
443 // iterate over current team hedgehogs |
439 // iterate over current team hedgehogs |
444 repeat |
440 repeat |
445 WalkMe:= CurrentTeam^.Hedgehogs[itHedgehog].Gear^; |
441 WalkMe:= CurrentTeam^.Hedgehogs[itHedgehog].Gear^; |
481 BestActions.Count:= 0; |
477 BestActions.Count:= 0; |
482 |
478 |
483 FillBonuses(false); |
479 FillBonuses(false); |
484 |
480 |
485 // Hog has no idea what to do. Use tardis or skip |
481 // Hog has no idea what to do. Use tardis or skip |
486 if not bonuses.activity then |
482 if (not bonuses.activity) and ((Me^.AIHints and aihAmmosChanged) = 0) then |
487 if (((GameFlags and gfInfAttack) <> 0) or (CurrentHedgehog^.MultiShootAttacks = 0)) and (HHHasAmmo(Me^.Hedgehog^, amTardis) > 0) and (CanUseTardis(Me^.Hedgehog^.Gear)) and (random(4) < 3) then |
483 if (((GameFlags and gfInfAttack) <> 0) or (CurrentHedgehog^.MultiShootAttacks = 0)) and (HHHasAmmo(Me^.Hedgehog^, amTardis) > 0) and (CanUseTardis(Me^.Hedgehog^.Gear)) and (random(4) < 3) then |
488 // Tardis brings hog to a random place. Perfect for clueless AI |
484 // Tardis brings hog to a random place. Perfect for clueless AI |
489 begin |
485 begin |
490 AddAction(BestActions, aia_Weapon, Longword(amTardis), 80, 0, 0); |
486 AddAction(BestActions, aia_Weapon, Longword(amTardis), 80, 0, 0); |
491 AddAction(BestActions, aia_attack, aim_push, 10, 0, 0); |
487 AddAction(BestActions, aia_attack, aim_push, 10, 0, 0); |
492 AddAction(BestActions, aia_attack, aim_release, 10, 0, 0); |
488 AddAction(BestActions, aia_attack, aim_release, 10, 0, 0); |
493 end |
489 end |
494 else |
490 else |
495 AddAction(BestActions, aia_Skip, 0, 250, 0, 0); |
491 AddAction(BestActions, aia_Skip, 0, 250, 0, 0); |
|
492 Me^.AIHints := ME^.AIHints and (not aihAmmosChanged); |
496 end; |
493 end; |
497 |
494 |
498 end else SDL_Delay(100) |
495 end else SDL_Delay(100) |
499 else |
496 else |
500 begin |
497 begin |
520 SDL_Delay(100) |
517 SDL_Delay(100) |
521 end |
518 end |
522 end; |
519 end; |
523 |
520 |
524 Me^.State:= Me^.State and (not gstHHThinking); |
521 Me^.State:= Me^.State and (not gstHHThinking); |
525 SDL_LockMutex(ThreadLock); |
|
526 ThinkThread:= nil; |
|
527 SDL_UnlockMutex(ThreadLock); |
|
528 Think:= 0; |
522 Think:= 0; |
|
523 SDL_SemPost(ThreadSem); |
529 end; |
524 end; |
530 |
525 |
531 procedure StartThink(Me: PGear); |
526 procedure StartThink(Me: PGear); |
|
527 var ThinkThread: PSDL_Thread; |
532 begin |
528 begin |
533 if ((Me^.State and (gstAttacking or gstHHJumping or gstMoving)) <> 0) |
529 if ((Me^.State and (gstAttacking or gstHHJumping or gstMoving)) <> 0) |
534 or isInMultiShoot then |
530 or isInMultiShoot then |
535 exit; |
531 exit; |
536 |
532 |
|
533 SDL_SemWait(ThreadSem); |
537 //DeleteCI(Me); // this will break demo/netplay |
534 //DeleteCI(Me); // this will break demo/netplay |
538 |
535 |
539 Me^.State:= Me^.State or gstHHThinking; |
536 Me^.State:= Me^.State or gstHHThinking; |
540 Me^.Message:= 0; |
537 Me^.Message:= 0; |
541 |
538 |
554 exit |
551 exit |
555 end; |
552 end; |
556 |
553 |
557 FillBonuses(((Me^.State and gstAttacked) <> 0) and (not isInMultiShoot) and ((GameFlags and gfInfAttack) = 0)); |
554 FillBonuses(((Me^.State and gstAttacked) <> 0) and (not isInMultiShoot) and ((GameFlags and gfInfAttack) = 0)); |
558 |
555 |
559 SDL_LockMutex(ThreadLock); |
|
560 ThinkThread:= SDL_CreateThread(@Think, PChar('think'), Me); |
556 ThinkThread:= SDL_CreateThread(@Think, PChar('think'), Me); |
561 SDL_UnlockMutex(ThreadLock); |
557 SDL_DetachThread(ThinkThread); |
562 end; |
558 end; |
563 |
559 |
564 {$IFDEF DEBUGAI} |
560 {$IFDEF DEBUGAI} |
565 var scoreShown: boolean = false; |
561 var scoreShown: boolean = false; |
566 {$ENDIF} |
562 {$ENDIF} |