diff -r c4fd2813b127 -r d92eeb468dad hedgewars/uAI.pas --- a/hedgewars/uAI.pas Wed Jul 31 23:14:27 2019 +0200 +++ b/hedgewars/uAI.pas Fri Jul 03 23:51:47 2020 +0200 @@ -38,20 +38,15 @@ CanUseAmmo: array [TAmmoType] of boolean; StopThinking: boolean; StartTicks: Longword; - ThinkThread: PSDL_Thread; - ThreadLock: PSDL_Mutex; + ThreadSem: PSDL_Sem; procedure FreeActionsList; begin AddFileLog('FreeActionsList called'); - if (ThinkThread <> nil) then - begin - StopThinking:= true; - SDL_WaitThread(ThinkThread, nil); - end; - SDL_LockMutex(ThreadLock); - ThinkThread:= nil; - SDL_UnlockMutex(ThreadLock); + + StopThinking:= true; + SDL_SemWait(ThreadSem); + SDL_SemPost(ThreadSem); if CurrentHedgehog <> nil then with CurrentHedgehog^ do @@ -112,6 +107,7 @@ BotLevel:= Me^.Hedgehog^.BotLevel; windSpeed:= hwFloat2Float(cWindSpeed); useThisActions:= false; +Me^.AIHints:= Me^.AIHints and (not aihAmmosChanged); for i:= 0 to Pred(Targets.Count) do if (Targets.ar[i].Score >= 0) and (not StopThinking) then @@ -437,7 +433,7 @@ switchCount:= HHHasAmmo(PGear(Me)^.Hedgehog^, amSwitch) else switchCount:= 0; -if ((Me^.State and gstAttacked) = 0) or isInMultiShoot or bonuses.activity then +if ((Me^.State and gstAttacked) = 0) or isInMultiShoot or bonuses.activity or ((Me^.AIHints and aihAmmosChanged) <> 0) then if Targets.Count > 0 then begin // iterate over current team hedgehogs @@ -483,7 +479,7 @@ FillBonuses(false); // Hog has no idea what to do. Use tardis or skip - if not bonuses.activity then + if (not bonuses.activity) and ((Me^.AIHints and aihAmmosChanged) = 0) then 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 // Tardis brings hog to a random place. Perfect for clueless AI begin @@ -493,6 +489,7 @@ end else AddAction(BestActions, aia_Skip, 0, 250, 0, 0); + Me^.AIHints := ME^.AIHints and (not aihAmmosChanged); end; end else SDL_Delay(100) @@ -522,18 +519,18 @@ end; Me^.State:= Me^.State and (not gstHHThinking); -SDL_LockMutex(ThreadLock); -ThinkThread:= nil; -SDL_UnlockMutex(ThreadLock); Think:= 0; +SDL_SemPost(ThreadSem); end; procedure StartThink(Me: PGear); +var ThinkThread: PSDL_Thread; begin if ((Me^.State and (gstAttacking or gstHHJumping or gstMoving)) <> 0) or isInMultiShoot then exit; +SDL_SemWait(ThreadSem); //DeleteCI(Me); // this will break demo/netplay Me^.State:= Me^.State or gstHHThinking; @@ -556,9 +553,8 @@ FillBonuses(((Me^.State and gstAttacked) <> 0) and (not isInMultiShoot) and ((GameFlags and gfInfAttack) = 0)); -SDL_LockMutex(ThreadLock); ThinkThread:= SDL_CreateThread(@Think, PChar('think'), Me); -SDL_UnlockMutex(ThreadLock); +SDL_DetachThread(ThinkThread); end; {$IFDEF DEBUGAI} @@ -610,14 +606,13 @@ procedure initModule; begin StartTicks:= 0; - ThinkThread:= nil; - ThreadLock:= SDL_CreateMutex(); + ThreadSem:= SDL_CreateSemaphore(1); end; procedure freeModule; begin FreeActionsList(); - SDL_DestroyMutex(ThreadLock); + SDL_DestroySemaphore(ThreadSem); end; end.