Tweak creature update

This commit is contained in:
2025-08-06 13:10:37 +01:00
parent af5bdf59b9
commit 9fb7440776
11 changed files with 196 additions and 191 deletions
+11 -93
View File
@@ -1,6 +1,7 @@
module Dodge.Creature.State (
crUpdate,
-- crUpdate,
doDamage,
invItemEffs,
) where
import Control.Applicative
@@ -10,15 +11,10 @@ import Data.Maybe
import Data.Monoid
import Dodge.Base
import Dodge.BaseTriggerType
import Dodge.Corpse.Make
import Dodge.Creature.Action
import Dodge.Creature.Damage
import Dodge.Creature.Impulse.Movement
import Dodge.Creature.State.WalkCycle
import Dodge.Creature.Test
import Dodge.Damage
import Dodge.Data.ComposedItem
import Dodge.Data.Damage.Type
import Dodge.Data.DoubleTree
--import Dodge.Data.DoubleTree
import Dodge.Data.World
@@ -31,100 +27,21 @@ import Dodge.Item.Grammar
import Dodge.Item.HeldOffset
import Dodge.Item.Location
import Dodge.Item.MaxAmmo
import Dodge.Prop.Gib
import Dodge.SoundLogic
import Dodge.Targeting.Draw
import Dodge.Zoning.Creature
import FoldableHelp
import Geometry
import qualified IntMapHelp as IM
import LensHelp
import Picture
import qualified Quaternion as Q
import RandomHelp
import qualified SDL
import Shape
import ShapePicture
-- this can almost certainly be made more efficient
foldCr :: [Creature -> World -> World] -> Creature -> World -> World
foldCr xs cr w = foldl' f w xs
where
f w' g = case w' ^? cWorld . lWorld . creatures . ix (_crID cr) of
Just cr' -> g cr' w'
Nothing -> w'
{- | this seems to work, but I am not sure about the ordering:
previously, the movement was updated before the ai in order to correctly set the oldpos.
This should be made more sensible: should the movement side effects apply to
the creature before or after it has moved?
at what point invSideEffects is applied wrt to when the creature moves
may affect whether the shield moves correctly
-}
crUpdate :: (Creature -> World -> World) -> Creature -> World -> World
crUpdate f =
foldCr
[ doDamage -- these two
, checkDeath -- must be in this order 24/7/22
, updateWalkCycle
, f
, invItemEffs
]
-- I have changed the ordering of item/equipment effects, which may have
-- unforseen consequences, be aware
checkDeath :: Creature -> World -> World
checkDeath cr w
| _crHP cr > 0 =
w
& cWorld . lWorld . creatures . ix (_crID cr) . crDamage .~ []
| _crHP cr <= -200 =
w
& dropAll cr -- the order of
& removecr -- these is important
& stopSoundFrom (CrWeaponSound (_crID cr) 0)
& addCrGibs cr
| _crHP cr > -200 && _crDeathTimer cr < 5 =
w
& cWorld . lWorld . creatures . ix (_crID cr) . crDamage .~ []
& cWorld . lWorld . creatures . ix (_crID cr) . crDeathTimer +~ 1
| otherwise =
w
& dropAll cr -- the order of
& removecr -- these is important
& stopSoundFrom (CrWeaponSound (_crID cr) 0)
& corpseOrGib cr
where
removecr
| _crID cr == 0 = id
-- cWorld . lWorld . creatures . ix (_crID cr) . crHP .~ 0
-- hack to get around player creature being killed but left with more than 0 hp
| otherwise = cWorld . lWorld . creatures . at (_crID cr) .~ Nothing
-- could look at the amount of damage here (given by maxDamage) too
corpseOrGib :: Creature -> World -> World
corpseOrGib cr = case cr ^? crDamage . to maxDamageType . _Just . _1 of
Just CookingDamage -> addcorpse (thecorpse & cpSPic %~ scorchSPic)
Just PoisonDamage -> addcorpse (thecorpse & cpSPic %~ poisonSPic)
Just PhysicalDamage | _crPain cr > 200 -> addCrGibs cr
_ -> addcorpse thecorpse
where
addcorpse ctype = plNew (cWorld . lWorld . corpses) cpID ctype
thecorpse = makeCorpse cr
scorchSPic :: SPic -> SPic
scorchSPic = _1 %~ overColSH (mixColors 0.9 0.1 black . normalizeColor)
poisonSPic :: SPic -> SPic
poisonSPic = _1 %~ overColSH (mixColors 0.5 0.5 green . normalizeColor)
-- reverse keys, otherwise two or more inv items will cause errors
dropAll :: Creature -> World -> World
dropAll cr w = foldl' (flip (dropItem cr)) w . reverse . IM.keys $ _crInv cr
doDamage :: Creature -> World -> World
doDamage cr = applyPastDamages cr . applyCreatureDamage (cr ^. crDamage) cr
doDamage :: Int -> World -> World
doDamage cid w = fromMaybe w $ do
cr <- w ^? cWorld . lWorld . creatures . ix cid
return $ applyPastDamages cr $ applyCreatureDamage (cr ^. crDamage) cr w
-- TODO generalise shake to arbitrary damage amounts
applyPastDamages :: Creature -> World -> World
@@ -141,12 +58,13 @@ applyPastDamages cr w
& randGen .~ g
-- a loop going over all root inventory items
invItemEffs :: Creature -> World -> World
invItemEffs cr =
appEndo $
invItemEffs :: Int -> World -> World
invItemEffs cid w = fromMaybe w $ do
cr <- w ^? cWorld . lWorld . creatures . ix cid
return . appEndo (
foldMap
(reduceLocDT (Endo . invItemLocUpdate cr) . LocDT TopDT)
(invDT' (_crInv cr))
(invDT' (_crInv cr))) $ w
invItemLocUpdate :: Creature -> LocationDT OItem -> World -> World
invItemLocUpdate cr loc w = doAnyEquipmentEffect loc cr $ case itm ^. itType of