AI refactor

This commit is contained in:
2021-05-14 12:04:12 +02:00
parent 2dd3756682
commit 0b26761be5
14 changed files with 282 additions and 762 deletions
+75
View File
@@ -0,0 +1,75 @@
module Dodge.Creature.LtAutoCrit
( ltAutoCrit
) where
import Dodge.Data
import Dodge.Default
import Dodge.Creature.Picture
import Dodge.Creature.Test
import Dodge.Creature.ActionRat
import Dodge.Creature.ChooseTarget
import Dodge.Creature.SetTarget
import Dodge.Creature.Rationality
import Dodge.Creature.AlertLevel
import Dodge.Creature.State
import Dodge.Creature.State.Data
import Dodge.Item.Weapon
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
ltAutoCrit :: Creature
ltAutoCrit = defaultCreature
{ _crPict = basicCrPict red
, _crUpdate = stateUpdate $ impulsiveAI $ composeInternalAIs
[ performActions
, watchUpdateStrat
[ (crHasTargetLOS, \w cr -> StrategyActions (ShootAt 0)
[DoActionIf (not . crIsAiming) DrawWeapon
,DoActionThen
(DoActionWhile crHasTargetLOS $ ArbitraryAction chooseMovement)
(DoImpulses [ChangeStrategy WatchAndWait])
]
)
, (crAwayFromPost, goToPostStrat)
]
, basicPerceptionUpdate [0]
, doStrategyActions
, reloadOverride
, targetYouWhenCognizant
, overrideInternal (onBoth (&&) crHasTarget (crStratConMatches (GetTo (0,0))))
$ \ _ -> crActionPlan . crStrategy .~ WatchAndWait
]
, _crActionPlan = ActionPlan
{ _crImpulse = []
, _crAction = []
, _crStrategy = StrategyActions WatchAndWait [StartSentinelPost]
, _crGoal = []
}
, _crInv = IM.fromList [(0,ltAutoGun),(1,medkit 100)]
, _crInvSel = 0
, _crRad = 10
, _crHP = 500
}
chooseMovement :: Creature -> World -> Action
chooseMovement cr w
| dist cpos p > 200 = DoImpulses [UseItem,TurnToward p 0.05 , MoveForward 3]
| dist cpos p < 80 = DoImpulses [UseItem,TurnToward p 0.05, MoveForward (-3) ]
| errorAngleVV 22 (p' -.- cpos) (unitVectorAtAngle (_crDir cr)) < 0.4
= DoImpulses [UseItem,TurnToward p' 0.01, Move (0,3)]
| otherwise
= DoImpulses [UseItem,TurnToward p' 0.05, Move (0,3)]
where
cpos = _crPos cr
tcr = _creatures w IM.! 0
p = _crPos tcr
v = vNormal $ p -.- cpos
p' = p +.+ 0.5 *.* (v -.- 20 *.* (normalizeV v))
+53 -6
View File
@@ -16,10 +16,13 @@ import Dodge.Item.Weapon
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
@@ -27,7 +30,7 @@ pistolCrit = defaultCreature
, _crUpdate = stateUpdate $ impulsiveAI $ composeInternalAIs
[ performActions
, watchUpdateStrat
[ (crHasTargetLOS, \w cr -> StrategyActions (ShootAt 0) [chooseMovement cr w])
[ (crHasTargetLOS, \w cr -> StrategyActions (ShootAt 0) [DoActionIf (not . crIsAiming) DrawWeapon,chooseMovement cr w])
, (crAwayFromPost, goToPostStrat)
]
, basicPerceptionUpdate [0]
@@ -48,15 +51,58 @@ pistolCrit = defaultCreature
, _crRad = 10
, _crHP = 500
}
chooseMovement :: Creature -> World -> Action
chooseMovement cr w = undefined
chooseMovement cr w = chooseMovement' cr w
`DoActionThen`
DoImpulses [ChangeStrategy WatchAndWait]
retreatAction :: Creature -> Creature -> Action
retreatAction tcr cr =
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 (3,0)] ++ [[Move (3,0),UseItem]])
strafeLeftActions =
DoImpulses [TurnToward yposr (2*pi)]
`DoActionThen`
3
`DoReplicate`
ImpulsesList (replicate 9 [Move (0,3)] ++ [[Move (0,3),UseItem]])
strafeRightActions =
DoImpulses [TurnToward yposl (2*pi)]
`DoActionThen`
3
`DoReplicate`
ImpulsesList (replicate 9 [Move (0,-3)] ++ [[Move (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`
NoAction
3
`DoReplicate`
ImpulsesList (replicate 9 [Move (-3,0)] ++ [[UseItem]])
where
cpos = _crPos cr
tpos = _crPos tcr
@@ -70,3 +116,4 @@ retreatAction tcr cr =
tpos
(tpos +.+ vNormal (cpos -.- tpos))
+6 -1
View File
@@ -137,6 +137,9 @@ performAction cr w ac = case ac of
(imps, Just ac) -> (imps, Just $ DoActionWhilePartial ac f resetAc)
(imps, _) -> (imps, Just $ DoActionWhilePartial resetAc f resetAc)
| otherwise -> performAction cr w partAc
DoActionIf f ac
| f (w,cr) -> performAction cr w ac
| otherwise -> ([],Nothing)
DoActionIfElse ac f ac'
| f (w,cr) -> performAction cr w ac
| otherwise -> performAction cr w ac'
@@ -164,7 +167,9 @@ performAction cr w ac = case ac of
_ -> ([],Nothing)
UseAheadPos f -> performAction cr w (f (_crPos cr +.+ 20 *.* unitVectorAtAngle (_crDir cr)))
ArbitraryAction f -> performAction cr w (f cr w)
DoImpulsesAlongside sideImpulses mainAc -> undefined
DoImpulsesAlongside sideImp mainAc -> case performAction cr w mainAc of
(imp, Just ac) -> (sideImp ++ imp, Just $ DoImpulsesAlongside sideImp ac)
(imp, _) -> (sideImp ++ imp, Nothing)
DoReplicate t ac -> performAction cr w $ DoReplicatePartial ac t ac
DoReplicatePartial _ 0 ac' -> performAction cr w ac'
DoReplicatePartial ac t ac' -> case performAction cr w ac' of
+76
View File
@@ -0,0 +1,76 @@
module Dodge.Creature.SpreadGunCrit
( spreadGunCrit
) where
import Dodge.Data
import Dodge.Default
import Dodge.Creature.Picture
import Dodge.Creature.Test
import Dodge.Creature.ActionRat
import Dodge.Creature.ChooseTarget
import Dodge.Creature.SetTarget
import Dodge.Creature.Rationality
import Dodge.Creature.AlertLevel
import Dodge.Creature.State
import Dodge.Creature.State.Data
import Dodge.Item.Weapon
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
spreadGunCrit :: Creature
spreadGunCrit = defaultCreature
{ _crPict = basicCrPict red
, _crUpdate = stateUpdate $ impulsiveAI $ composeInternalAIs
[ performActions
, watchUpdateStrat
[ (crHasTargetLOS, \w cr -> StrategyActions (ShootAt 0)
[DoActionIf (not . crIsAiming) DrawWeapon
,DoActionThen
(DoActionWhile crHasTargetLOS $ ArbitraryAction chooseMovement)
(DoImpulses [ChangeStrategy WatchAndWait])
]
)
, (crAwayFromPost, goToPostStrat)
]
, basicPerceptionUpdate [0]
, doStrategyActions
, reloadOverride
, targetYouWhenCognizant
, overrideInternal (onBoth (&&) crHasTarget (crStratConMatches (GetTo (0,0))))
$ \ _ -> crActionPlan . crStrategy .~ WatchAndWait
]
, _crActionPlan = ActionPlan
{ _crImpulse = []
, _crAction = []
, _crStrategy = StrategyActions WatchAndWait [StartSentinelPost]
, _crGoal = []
}
, _crInv = IM.fromList [(0,spreadGun),(1,medkit 100)]
, _crInvSel = 0
, _crRad = 10
, _crHP = 500
}
chooseMovement :: Creature -> World -> Action
chooseMovement cr w
| dist cpos p < 30 && safeAngleVV (p -.- cpos) (unitVectorAtAngle (_crDir cr)) > pi
= DoImpulses [UseItem, MoveForward (-3)]
| d < 30 = DoImpulses [UseItem,TurnToward p 0.06]
| d < 60 = DoImpulses [UseItem,TurnToward p 0.06,MoveForward 3]
| d < 100 = DoImpulses [TurnToward p 0.06, MoveForward 3 ]
| d < 200 = DoImpulses [TurnToward p (0.06 + 0.002 *(d-100)), MoveForward 3 ]
| otherwise
= DoImpulses [TurnToward p 0.26, MoveForward 3]
where
d = dist cpos p
cpos = _crPos cr
tcr = _creatures w IM.! 0
p = _crPos tcr
+5
View File
@@ -9,6 +9,7 @@ import Dodge.Creature.Stance.Data
import Picture.Data
import Control.Lens
import qualified Data.Set as S
data CreatureState = CrSt
{ _goals :: [[Impulse]]
@@ -39,6 +40,10 @@ data Faction
| PlayerFaction
deriving (Eq,Show)
data CrGroup
= LoneWolf
| Swarm { _swarm :: S.Set Int }
makeLenses ''CreatureState
makeLenses ''CrSpState
makeLenses ''Impulse
+39
View File
@@ -0,0 +1,39 @@
module Dodge.Creature.SwarmCrit
( swarmCrit
)
where
import Dodge.Data
import Dodge.Default
import Dodge.Creature.Picture
import Dodge.Creature.Test
import Dodge.Creature.ActionRat
import Dodge.Creature.ImpulseRat
import Dodge.Creature.ChooseTarget
import Dodge.Creature.SetTarget
import Dodge.Creature.Rationality
import Dodge.Creature.AlertLevel
import Dodge.Creature.State
import Dodge.Creature.State.Data
import Dodge.Item.Weapon
import Dodge.Item.Consumable
import Dodge.Picture.Layer
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
swarmCrit :: Creature
swarmCrit = defaultCreature
{ _crUpdate = stateUpdate $ meleeCooldown $ impulsiveAI $ chaseTarget targetYouLOS
, _crHP = 1
, _crRad = 4
, _crPict = basicCrPict yellow
, _crInv = IM.empty -- IM.fromList [(0,frontArmour)]
, _crCorpse = onLayer CorpseLayer $ color (greyN 0.5) $ circleSolid 4
, _crFaction = ColorFaction yellow
}