module Dodge.Creature.PistolCrit ( pistolCrit ) where import Dodge.Data import Dodge.Default import Dodge.Creature.Picture import Dodge.Creature.Test import Dodge.Creature.Impulse import Dodge.Creature.Action import Dodge.Creature.Volition import Dodge.Creature.Strategy import Dodge.Creature.ReaderUpdate --import Dodge.Creature.ChooseTarget import Dodge.Creature.Perception import Dodge.Creature.State --import Dodge.Creature.State.Data import Dodge.Item.Weapon.BulletGuns import Dodge.Item.Consumable import Geometry import Picture import Dodge.RandomHelp import Data.Maybe import qualified Data.IntMap.Strict as IM import Control.Lens import Control.Monad.State --import System.Random pistolCrit :: Creature pistolCrit = defaultCreature { _crPict = basicCrPict red , _crUpdate = stateUpdate $ impulsiveAIR $ performActionsR >=> watchUpdateStratR [ (crHasTargetLOS, \w cr -> StrategyActions (ShootAt 0) [DoActionIf (not . crIsAiming) drawWeapon,chooseMovement cr w]) , (crAwayFromPost, goToPostStrat) ] >=> perceptionUpdate [0] >=> doStrategyActionsR >=> reloadOverrideR >=> targetYouWhenCognizantR >=> overrideInternalRRR (\cr -> (&&) <$> crHasTargetR cr <*> crStratConMatchesR (GetTo (V2 0 0)) cr) (pure . (crActionPlan . crStrategy .~ WatchAndWait)) , _crActionPlan = ActionPlan { _crImpulse = [] , _crAction = [] , _crStrategy = StrategyActions WatchAndWait [StartSentinelPost] , _crGoal = [] } , _crInv = IM.fromList [(0,pistol),(1,medkit 100)] , _crInvSel = 0 , _crRad = 10 , _crHP = 500 } chooseMovement :: Creature -> World -> Action chooseMovement cr w = chooseMovement' cr w `DoActionThen` DoImpulses [ChangeStrategy WatchAndWait] chooseMovement' :: Creature -> World -> Action chooseMovement' cr w = takeOneWeighted [chargeProb,retreatProb,strafeProb,strafeProb] [chargeActions ,retreatActions ycr cr ,strafeLeftActions ,strafeRightActions ] & evalState $ g where g = _randGen w cpos = _crPos cr ycr = _creatures w IM.! 0 ypos = _crPos ycr chargeProb | dist cpos ypos > 300 = 5 | dist cpos ypos > 150 = 1 | otherwise = 0 strafeProb | dist cpos ypos > 150 = 1 | otherwise = 0 retreatProb | dist cpos ypos < 200 = 1 :: Float | otherwise = 0 chargeActions = [TurnToward ypos 0.1] `DoImpulsesAlongside` 3 `DoReplicate` ImpulsesList (replicate 9 [Move (V2 3 0)] ++ [[Move (V2 3 0),UseItem]]) strafeLeftActions = DoImpulses [TurnToward yposr (2*pi)] `DoActionThen` 3 `DoReplicate` ImpulsesList (replicate 9 [Move (V2 0 3)] ++ [[Move (V2 0 3),UseItem]]) strafeRightActions = DoImpulses [TurnToward yposl (2*pi)] `DoActionThen` 3 `DoReplicate` ImpulsesList (replicate 9 [Move (V2 0 (-3))] ++ [[Move (V2 0 (-3)),UseItem]]) yposl = ypos -.- 100 *.* vNormal (normalizeV $ ypos -.- cpos) yposr = ypos +.+ 100 *.* vNormal (normalizeV $ ypos -.- cpos) retreatActions :: Creature -> Creature -> Action retreatActions tcr cr = [TurnToward retreatOffset 0.2] `DoImpulsesAlongside` 3 `DoReplicate` ImpulsesList (replicate 9 [Move (V2 (-3) 0)] ++ [[UseItem]]) where cpos = _crPos cr tpos = _crPos tcr retreatOffset = let a | dist cpos tpos < 50 = 0 | isLeftOfA (_crDir cr) (argV $ tpos -.- cpos) = -0.7 | otherwise = 0.7 in fromMaybe tpos $ intersectLineLine' cpos (cpos +.+ rotateV a (tpos -.- cpos)) tpos (tpos +.+ vNormal (cpos -.- tpos))