Make creature update an external function

This commit is contained in:
2022-07-20 01:22:17 +01:00
parent db44d5d6ce
commit 1f79fe157f
31 changed files with 562 additions and 462 deletions
+2 -21
View File
@@ -4,36 +4,16 @@ module Dodge.Creature.ArmourChase
) where
import Dodge.Data
import Dodge.Default
--import Dodge.Creature.State
import Dodge.Creature.Update
import Dodge.Creature.ChaseCrit
--import Dodge.Creature.ChainUpdates
import Dodge.Creature.ReaderUpdate
import Dodge.Creature.Perception
--import Dodge.Creature.Impulse
import Dodge.Creature.Action
import Dodge.Item.Equipment
import Dodge.Item.Consumable
--import Picture
import qualified Data.IntMap.Strict as IM
import Control.Lens
flockArmourChaseCrit :: Creature
flockArmourChaseCrit = defaultCreature
{ _crUpdate = defaultImpulsive
[ watchUpdateStrat []
, const doStrategyActions
, performActions
, targetYouWhenCognizant
, setTargetMv (\_ -> _targetCr . _crIntention)
, flockACC
, perceptionUpdate [0]
, goToTarget
, const overrideMeleeCloseTarget
, const (crMeleeCooldown %~ max 0 . subtract 1)
]
, _crName = "armourChaseCrit"
{ _crName = "armourChaseCrit"
, _crHP = 300
, _crInv = IM.fromList
[(0,frontArmour)
@@ -49,6 +29,7 @@ flockArmourChaseCrit = defaultCreature
, _crGroup = ShieldGroup
, _crMvType = defaultChaseMvType
}
& crType . humanoidAI .~ FlockArmourChaseAI
armourChaseCrit :: Creature
armourChaseCrit = chaseCrit
{ _crName = "armourChaseCrit"
+3 -12
View File
@@ -3,28 +3,19 @@ module Dodge.Creature.AutoCrit
) where
import Dodge.Data
import Dodge.Default
import Dodge.Creature.Update
import Dodge.Creature.SentinelAI
--import Dodge.Creature.ChooseTarget
--import Dodge.Creature.Impulse
--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
autoCrit :: Creature
autoCrit = defaultCreature
{ _crUpdate = defaultImpulsive [sentinelAI]
, _crInv = IM.fromList [(0,autoGun),(1,medkit 100)]
{ _crInv = IM.fromList [(0,autoGun),(1,medkit 100)]
, _crRad = 10
, _crHP = 300
, _crMvType = defaultAimMvType
}
& crType . skinUpper .~ light4 red
& crType . humanoidAI .~ AutoAI
+2 -20
View File
@@ -6,18 +6,11 @@ module Dodge.Creature.ChaseCrit
import Dodge.Data
import Dodge.Default
import Dodge.Creature.Picture
import Dodge.Creature.Update
import Dodge.Creature.ReaderUpdate
import Dodge.Creature.Action
import Dodge.Creature.Perception
import Dodge.Item.Consumable
import Dodge.Item.Equipment
import Dodge.SoundLogic
--import Geometry
import Picture
--import Dodge.RandomHelp
--import Data.Maybe
import qualified Data.IntMap.Strict as IM
import Control.Lens
--import System.Random
@@ -37,19 +30,7 @@ invisibleChaseCrit = chaseCrit
& crInvEquipped . at 0 ?~ OnLeftWrist
chaseCrit :: Creature
chaseCrit = defaultCreature
{ _crUpdate = defaultImpulsive
[ const doStrategyActions
, performActions
, const overrideMeleeCloseTarget
, const setViewPos
, setMvPos
, chaseCritMv
, chaseCritPerceptionUpdate [0]
, targetYouWhenCognizant
, const searchIfDamaged
, const (crMeleeCooldown %~ max 0 . subtract 1)
]
, _crName = "chaseCrit"
{ _crName = "chaseCrit"
, _crHP = 150
, _crInv = IM.fromList [(0,medkit 200)]
, _crMeleeCooldown = 0
@@ -66,3 +47,4 @@ chaseCrit = defaultCreature
] 50 0
, _crMvType = defaultChaseMvType
}
& crType . humanoidAI .~ ChaseAI
+4 -59
View File
@@ -9,23 +9,14 @@ module Dodge.Creature.Inanimate
) where
import Dodge.Data
import Dodge.Creature.Lamp
import Dodge.WorldEvent.Explosion
import Dodge.Spark
import Dodge.Default
import Dodge.Creature.State
import qualified IntMapHelp as IM
import Geometry
import Dodge.SoundLogic
import LensHelp
import System.Random
import Data.List
barrel :: Creature
barrel = defaultInanimate
{ _crUpdate = updateBarrel
, _crHP = 500
, _crType = Barreloid
{ _crHP = 500
, _crType = Barreloid PlainBarrel
, _crState = defaultState
{_csSpState = Barrel []
}
@@ -34,57 +25,11 @@ barrel = defaultInanimate
explosiveBarrel :: Creature
explosiveBarrel = defaultInanimate
{ _crUpdate = updateExpBarrel
, _crHP = 400
, _crType = Barreloid
{ _crHP = 400
, _crType = Barreloid ExplosiveBarrel
, _crState = defaultState
{_csSpState = Barrel []
}
, _crInv = IM.empty -- IM.fromList [(0,frontArmour)]
}
& crMaterial .~ Crystal
updateBarrel :: Creature -> World -> World
updateBarrel cr
| _crHP cr > 0 = doDamage cr
| otherwise = creatures . at (_crID cr) .~ Nothing
-- should generate the sparks externally using new random generators
updateExpBarrel :: Creature -> World -> World
updateExpBarrel cr w
| _crHP cr > 0 = foldr ($) (hiss w & creatures . at (_crID cr) .~ newCr) pierceSparks
| otherwise = makeExplosionAt (_crPos cr) $ stopSounds w & creatures . at (_crID cr) .~ Nothing
where
g = _randGen w
damages = _csDamage $ _crState cr
pierceSparks :: [World -> World]
pierceSparks
= zipWith3 (\p a -> createBarrelSpark (_crPos cr +.+ p) (a + argV p))
poss as colids
as = randomRs (-0.7,0.7) g
colids = randomRs (0,11) g
poss = _piercedPoints $ _csSpState $ _crState cr
newCr = Just $ applyFuseDamage $ set (crState . csDamage) [] $ damToExpBarrel damages cr
applyFuseDamage cr' = cr' & crHP %~
subtract (length . _piercedPoints . _csSpState $ _crState cr')
hiss | null poss = id
| otherwise = soundMultiFrom [BarrelHiss 0,BarrelHiss 1] (_crPos cr) foamSprayLoopS (Just 1)
stopSounds = stopSoundFrom (BarrelHiss 0) . stopSoundFrom (BarrelHiss 1)
damToExpBarrel :: [Damage] -> Creature -> Creature
damToExpBarrel ds cr = foldr damToExpBarrel' (foldr damToExpBarrel' cr pierceDam) otherDam
where
(pierceDam,otherDam) = partition isPierce ds
isPierce Damage{_dmType = PIERCING{}} = True
isPierce _ = False
damToExpBarrel' :: Damage -> Creature -> Creature
damToExpBarrel' dm cr = case _dmType dm of
PIERCING -> over (crState . csSpState . piercedPoints) ((:) $ int -.- _crPos cr)
$ cr & crHP -~ div amount 200
POISONDAM -> cr
SPARKING -> cr
-- PUSHDAM -> cr LensHelp.& crPos .+.+~ (1 / _crMass cr *.* _dePushBack (_dmEffect dm))
_ -> cr LensHelp.& crHP -~ amount
where
amount = _dmAmount dm
int = _dmAt dm
+3 -34
View File
@@ -3,48 +3,17 @@ module Dodge.Creature.Lamp
, colorLamp
) where
import Dodge.Data
import Dodge.Material.Sound
import Dodge.Default
import Dodge.LightSource
import Dodge.WorldEvent.Flash
import Dodge.WorldEvent.Sound
import Dodge.Creature.State
import Geometry
import qualified IntMapHelp as IM
import LensHelp
import Geometry.Data
colorLamp
:: Point3 -- color of lamp
-> Float -- height of lamp
-> Creature
colorLamp col h = defaultInanimate
{ _crUpdate = initialiseColorLamp col h
, _crHP = 100
, _crType = Lampoid h
{ _crHP = 100
, _crType = Lampoid h col Nothing
, _crRad = 3
, _crMass = 3
}
lamp :: Float -> Creature
lamp = colorLamp 0.75
initialiseColorLamp :: Point3 -> Float -> Creature -> World -> World
initialiseColorLamp col h cr w = w
& lightSources . at lsid ?~ lsColPosID col (addZ h $ _crPos cr) lsid
& creatures . ix (_crID cr) . crUpdate .~ updateLamp h lsid
where
lsid = IM.newKey $ _lightSources w
updateLamp :: Float -> Int -> Creature -> World -> World
updateLamp h i cr w
| _crHP cr < 0 = w
& explosionFlashAt cpos
& originsIDsAt [MaterialSound Glass n | n <- [0,1,2]] (destroyMatS Glass) cpos
& lightSources . at i .~ Nothing
& creatures . at cid .~ Nothing
| otherwise = w
& lightSources . ix i . lsParam . lsPos .~ addZ h cpos
& doDamage cr
where
cpos = _crPos cr
cid = _crID cr
+2 -53
View File
@@ -4,18 +4,7 @@ module Dodge.Creature.LauncherCrit
where
import Dodge.Data
import Dodge.Default
--import Dodge.Creature.ChainUpdates
import Dodge.Creature.Test
import Dodge.Creature.Volition
import Dodge.Creature.Strategy
import Dodge.Creature.ReaderUpdate
import Dodge.Creature.Perception
--import Dodge.Creature.State
import Dodge.Creature.Update
import Dodge.Item.Weapon.Launcher
--import Dodge.Creature.Impulse
import Dodge.Creature.Action
import Geometry.Data
import Picture
import qualified Data.IntMap.Strict as IM
@@ -23,53 +12,13 @@ import Control.Lens
launcherCrit :: Creature
launcherCrit = defaultCreature
{ _crUpdate = defaultImpulsive
[ performActions
, watchUpdateStrat
[ (crHasTargetLOS, \_ _ -> StrategyActions (ShootAt 0) [retreatFire])
, (const crAwayFromPost, const goToPostStrat)
]
, perceptionUpdate [0]
, const doStrategyActions
, const reloadOverride
, targetYouWhenCognizant
, const $ overrideInternal
(\cr -> crHasTarget cr && crStratConMatches (GetTo (V2 0 0)) cr)
(crActionPlan . apStrategy .~ WatchAndWait)
]
, _crInv = IM.fromList [(0,launcher)]
{ _crInv = IM.fromList [(0,launcher)]
, _crRad = 10
, _crState = defaultState
, _crHP = 300
}
& crType . skinUpper .~ light4 red
& crType . humanoidAI .~ LauncherAI
retreatFire :: Action
retreatFire = ImpulsesList ( [ UseItem ] : replicate 20 [ Turn 0.16 ])
`DoActionThen`
holsterWeapon
`DoActionThen`
ImpulsesList ( replicate 30 [ MoveForward 3 ])
`DoActionThen`
drawWeapon
`DoActionThen`
ImpulsesList ( [UseItem] : replicate 20 [ Turn $ negate 0.16 ] )
`DoActionThen`
holsterWeapon
`DoActionThen`
ImpulsesList ( replicate 15 [ MoveForward 3 ] )
`DoActionThen`
drawWeapon
`DoActionThen`
ImpulsesList (
replicate 100 [UseItem, ImpulseUseTarget $ \tcr -> TurnToward (_crPos tcr) (pi/16) ] )
`DoActionThen`
20
`WaitThen`
holsterWeapon
`DoActionThen`
ImpulsesList ( replicate 15 [ MoveForward 3 ] )
`DoActionThen`
DoImpulses [ChangeStrategy WatchAndWait]
+2 -44
View File
@@ -3,17 +3,8 @@ module Dodge.Creature.LtAutoCrit
) where
import Dodge.Data
import Dodge.Default
import Dodge.Creature.Update
import Dodge.Creature.Action
import Dodge.Creature.Test
import Dodge.Creature.Volition
import Dodge.Creature.Strategy
--import Dodge.Creature.ChooseTarget
import Dodge.Creature.ReaderUpdate
import Dodge.Creature.Perception
import Dodge.Item.Weapon.BulletGuns
import Dodge.Item.Consumable
import Geometry
import Picture
import qualified Data.IntMap.Strict as IM
@@ -21,43 +12,10 @@ import Control.Lens
ltAutoCrit :: Creature
ltAutoCrit = defaultCreature
{ _crUpdate = defaultImpulsive
[ performActions
, watchUpdateStrat
[ (crHasTargetLOS, \_ _ -> StrategyActions (ShootAt 0)
[DoActionIf (const $ not . crIsAiming) drawWeapon
,DoActionThen
(DoActionWhile crHasTargetLOS $ ArbitraryAction chooseMovement)
(DoImpulses [ChangeStrategy WatchAndWait])
]
)
, (const crAwayFromPost, const goToPostStrat)
]
, perceptionUpdate [0]
, const doStrategyActions
, const reloadOverride
, targetYouWhenCognizant
, const $ overrideInternal
(\cr -> crHasTarget cr && crStratConMatches (GetTo (V2 0 0)) cr)
(crActionPlan . apStrategy .~ WatchAndWait)
]
, _crInv = IM.fromList [(0,autoPistol),(1,medkit 100)]
{ _crInv = IM.fromList [(0,autoPistol),(1,medkit 100)]
, _crRad = 10
, _crHP = 500
}
& crType . humanoidAI .~ LtAutoAI
& crType . skinUpper .~ light4 red
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 (V2 0 3)]
| otherwise
= DoImpulses [UseItem,TurnToward p' 0.05, Move (V2 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)
+2 -90
View File
@@ -3,109 +3,21 @@ module Dodge.Creature.PistolCrit
) where
import Dodge.Data
import Dodge.Default
import Dodge.Creature.Update
import Dodge.Creature.Test
import Dodge.Creature.Action
import Dodge.Creature.Volition
import Dodge.Creature.Strategy
import Dodge.Creature.ReaderUpdate
import Dodge.Creature.Perception
--import Dodge.Creature.State.Data
import Dodge.Item.Weapon.BulletGuns
import Dodge.Item.Consumable
import Geometry
import Picture
import RandomHelp
import Data.Maybe
import qualified Data.IntMap.Strict as IM
import Control.Lens
pistolCrit :: Creature
pistolCrit = defaultCreature
{ _crUpdate = defaultImpulsive
[ performActions
, watchUpdateStrat
[ (crHasTargetLOS, \w cr -> StrategyActions (ShootAt 0)
[DoActionIf (const $ not . crIsAiming) drawWeapon,chooseMovement cr w])
, (const crAwayFromPost, const goToPostStrat)
]
, perceptionUpdate [0]
, const doStrategyActions
, const reloadOverride
, targetYouWhenCognizant
, const $ overrideInternal
(\cr -> crHasTarget cr && crStratConMatches (GetTo (V2 0 0)) cr)
(crActionPlan . apStrategy .~ WatchAndWait)
]
, _crInv = IM.fromList [(0,pistol),(1,medkit 100)]
{ _crInv = IM.fromList [(0,pistol),(1,medkit 100)]
, _crRad = 10
, _crHP = 500
}
& crType . humanoidAI .~ PistolAI
& crType . skinUpper .~ light4 red
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))
+2 -47
View File
@@ -3,64 +3,19 @@ module Dodge.Creature.SpreadGunCrit
) where
import Dodge.Data
import Dodge.Default
import Dodge.Creature.Update
import Dodge.Creature.Test
import Dodge.Creature.Action
import Dodge.Creature.Volition
import Dodge.Creature.Strategy
import Dodge.Creature.ReaderUpdate
import Dodge.Creature.Perception
--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
spreadGunCrit :: Creature
spreadGunCrit = defaultCreature
{ _crUpdate = defaultImpulsive
[performActions
,watchUpdateStrat
[ (crHasTargetLOS, \_ _ -> StrategyActions (ShootAt 0)
[DoActionIf (const $ not . crIsAiming) drawWeapon
,DoActionThen
(DoActionWhile crHasTargetLOS $ ArbitraryAction chooseMovement)
(DoImpulses [ChangeStrategy WatchAndWait])
]
)
, (const crAwayFromPost, const goToPostStrat)
]
,perceptionUpdate [0]
,const doStrategyActions
,const reloadOverride
,targetYouWhenCognizant
,const $ overrideInternal
(\cr -> crHasTarget cr && crStratConMatches (GetTo (V2 0 0)) cr)
(\ cr -> cr & crActionPlan . apStrategy .~ WatchAndWait)
]
, _crInv = IM.fromList [(0,bangStick 6),(1,medkit 100)]
{ _crInv = IM.fromList [(0,bangStick 6),(1,medkit 100)]
, _crRad = 10
, _crHP = 500
}
& crType . humanoidAI .~ SpreadGunAI
& crType . skinUpper .~ light4 red
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
+1 -2
View File
@@ -62,8 +62,7 @@ checkDeath cr w
& corpseOrGib cr
where
removecr
| _crID cr == 0 = (creatures . ix (_crID cr) . crUpdate .~ const id)
. (creatures . ix (_crID cr) . crType .~ NonDrawnCreature)
| _crID cr == 0 = (creatures . ix (_crID cr) . crType .~ NonDrawnCreature)
. (creatures . ix (_crID cr) . crHP .~ 0)
-- hack to get around player creature being killed but left with more than 0 hp
| otherwise = creatures . at (_crID cr) .~ Nothing
+2 -18
View File
@@ -4,30 +4,13 @@ module Dodge.Creature.SwarmCrit
import Dodge.Data
import Dodge.Default
import Dodge.Creature.Picture
import Dodge.Creature.Update
--import Dodge.Creature.ChainUpdates
import Dodge.Creature.Boid
import Dodge.Creature.ReaderUpdate
import Dodge.Creature.Perception
--import Dodge.Creature.Impulse
--import Dodge.Creature.State
import Picture
import Control.Lens
swarmCrit :: Creature
swarmCrit = defaultCreature
{ _crUpdate = defaultImpulsive
[ flockToPointUsing' (encircleDistP 100) (meleeHeadingMove 0.1 0.1 (pi/4) 3.9)
, const (crMeleeCooldown %~ max 0 . subtract 1)
, perceptionUpdate [0]
, const doStrategyActions
, targetYouWhenCognizant
]
-- , doStrategyActions
-- , targetYouWhenCognizant
, _crHP = 1
{ _crHP = 1
, _crRad = 2
, _crMass = 2
, _crCorpse = basicCrCorpse
@@ -35,6 +18,7 @@ swarmCrit = defaultCreature
, _crMeleeCooldown = 0
}
& crType . skinUpper .~ light4 yellow
& crType . humanoidAI .~ SwarmAI
--swarmCritMoveFunc :: Creature -> Point2 -> Creature -> Point2
--swarmCritMoveFunc tcr cenp cr
+13
View File
@@ -3,10 +3,23 @@ import Dodge.Data
import Dodge.Creature.State
import Dodge.Creature.Impulse
import Dodge.Creature.ChainUpdates
import Dodge.Lampoid
import Dodge.Humanoid
import Dodge.Turretoid
import Dodge.Barreloid
import LensHelp
import System.Random
updateCreature :: Creature -> World -> World
updateCreature cr = case _crType cr of
Lampoid{} -> updateLampoid cr
Humanoid{} -> updateHumanoid cr
Turretoid{} -> updateTurretoid cr
Barreloid{} -> updateBarreloid cr
NonDrawnCreature -> id
-- bit of a hack to get new random generators after each creature's update
defaultImpulsive :: [World -> Creature -> Creature]
-> Creature -> World -> World