Work on slime crit split/combining

This commit is contained in:
2026-04-15 20:54:26 +01:00
parent 02e26c368c
commit c3d9a24735
11 changed files with 430 additions and 583 deletions
-5
View File
@@ -3,8 +3,6 @@ module Dodge.Creature (
module Dodge.Creature.ChaseCrit, module Dodge.Creature.ChaseCrit,
module Dodge.Creature.Inanimate, module Dodge.Creature.Inanimate,
launcherCrit, launcherCrit,
-- pistolCrit,
ltAutoCrit,
spreadGunCrit, spreadGunCrit,
autoCrit, autoCrit,
armourChaseCrit, armourChaseCrit,
@@ -13,7 +11,6 @@ module Dodge.Creature (
module Dodge.Creature.Impulse, module Dodge.Creature.Impulse,
module Dodge.Creature.Perception, module Dodge.Creature.Perception,
module Dodge.Creature.ReaderUpdate, module Dodge.Creature.ReaderUpdate,
module Dodge.Creature.SentinelAI,
module Dodge.Creature.State, module Dodge.Creature.State,
module Dodge.Creature.Strategy, module Dodge.Creature.Strategy,
module Dodge.Creature.Test, module Dodge.Creature.Test,
@@ -34,10 +31,8 @@ import Dodge.Creature.ChaseCrit
import Dodge.Creature.Impulse import Dodge.Creature.Impulse
import Dodge.Creature.Inanimate import Dodge.Creature.Inanimate
import Dodge.Creature.LauncherCrit import Dodge.Creature.LauncherCrit
import Dodge.Creature.LtAutoCrit
import Dodge.Creature.Perception import Dodge.Creature.Perception
import Dodge.Creature.ReaderUpdate import Dodge.Creature.ReaderUpdate
import Dodge.Creature.SentinelAI
import Dodge.Creature.SpreadGunCrit import Dodge.Creature.SpreadGunCrit
import Dodge.Creature.State import Dodge.Creature.State
import Dodge.Creature.Strategy import Dodge.Creature.Strategy
+3 -1
View File
@@ -66,11 +66,13 @@ slimeCrit :: Creature
slimeCrit = defaultCreature slimeCrit = defaultCreature
& crName .~ "slimeCrit" & crName .~ "slimeCrit"
& crHP .~ HP 1000 & crHP .~ HP 1000
& crType .~ SlimeCrit 40 0 0 (V2 50 0) False True & crType .~ SlimeCrit r 0 0 (V2 r 0) False
& crFaction .~ ColorFaction (light green) & crFaction .~ ColorFaction (light green)
& crPerception . cpVision . viFOV .~ FloatFOV pi & crPerception . cpVision . viFOV .~ FloatFOV pi
& crActionPlan .~ SlimeIntelligence & crActionPlan .~ SlimeIntelligence
& crStance . carriage .~ Crawling & crStance . carriage .~ Crawling
where
r = 50
hoverCrit :: Creature hoverCrit :: Creature
hoverCrit = hoverCrit =
-20
View File
@@ -1,20 +0,0 @@
module Dodge.Creature.LtAutoCrit (
ltAutoCrit,
) where
--import Control.Lens
import Dodge.Data.Creature
import Dodge.Default
--import Dodge.Item.Held.Stick
--import qualified IntMapHelp as IM
--import Picture
ltAutoCrit :: Creature
ltAutoCrit =
defaultCreature
{ --_crInv = IM.fromList [(0, autoPistol)]
_crHP = HP 500
}
-- & crType .~ LtAutoCrit
-- & crType . humanoidAI .~ LtAutoAI
-- & crType . skinUpper .~ lightx4 red
-135
View File
@@ -1,135 +0,0 @@
module Dodge.Creature.SentinelAI (
sentinelAI,
sentinelFireType,
sentinelExtraWatchUpdate,
) where
--import Control.Lens
import Data.Maybe
--import Dodge.Creature.Action
--import Dodge.Creature.ChainUpdates
--import Dodge.Creature.Perception
--import Dodge.Creature.ReaderUpdate
--import Dodge.Creature.Strategy
import Dodge.Creature.Test
import Dodge.Creature.Volition
import Dodge.Data.CreatureEffect
import Dodge.Data.World
import Geometry.Data
sentinelAI :: World -> Creature -> Creature
--sentinelAI w =
sentinelAI =
sentinelExtraWatchUpdate
[
( crHasTargetLOS
, \_ cr ->
StrategyActions
(ShootAt (fromJust $ tcid cr))
[ DoActionIf
(WdCrNegate $ WdCrBlfromCrBl CrIsAiming)
(drawWeapon `DoActionThen` (50 `WaitThen` NoAction))
`DoActionThen` lostest
`DoActionWhile` advanceShoot
`DoActionThen` 75
`DoReplicate` advanceShoot
`DoActionThen` DoImpulses [ChangeStrategy WatchAndWait]
, AimAt{_targetID = fromJust $ tcid cr, _targetSeenAt = V2 0 0}
]
)
]
where
advanceShoot = DoImpulses [UseItem, MoveForward 3]
tcid cr = _targetCr (_crIntention cr)
lostest = WdCrLOSTarget -- w' cr = maybe False (\cid -> canSee (_crID cr) cid w') (tcid cr)
--chainCreatureUpdates :: [World -> Creature -> Creature] -> World -> Creature -> Creature
--chainCreatureUpdates ls w cr = foldr (\f -> f w) cr ls
sentinelFireType :: (Int -> Action) -> World -> Creature -> Creature
sentinelFireType _ = undefined
--sentinelFireType f =
-- chainCreatureUpdates
-- [ watchUpdateStrat
-- [
-- ( crHasTargetLOS
-- , \_ _ ->
-- StrategyActions
-- (ShootAt 0)
-- [ drawwp `DoActionThen` f 0 `DoActionThen` DoImpulses [ChangeStrategy WatchAndWait]
-- , aiming
-- ]
-- )
-- , (const crAwayFromPost, const goToPostStrat)
-- ]
-- , perceptionUpdate [0]
-- , -- , Left $ perceptionUp 0
-- const doStrategyActions
-- , targetYouWhenCognizant
-- , const $
-- overrideInternal
-- (\cr -> crHasTarget cr && crStratConMatches (GetTo (V2 0 0)) cr)
-- (crActionPlan . apStrategy .~ WatchAndWait)
-- ]
-- where
-- drawwp = DoActionIfElse NoAction (WdCrBlfromCrBl CrIsAiming) (DoActionThen drawWeapon (WaitThen 50 NoAction))
-- aiming =
-- AimAt
-- { _targetID = 0
-- , _targetSeenAt = V2 0 0 -- hack
-- }
sentinelExtraWatchUpdate ::
[(World -> Creature -> Bool, World -> Creature -> Strategy)] ->
World ->
Creature ->
Creature
sentinelExtraWatchUpdate _ = undefined
--sentinelExtraWatchUpdate xs =
-- chainCreatureUpdates
-- [ watchUpdateStrat
-- (xs ++ [(const crAwayFromPost, const goToPostStrat)])
-- , perceptionUpdate [0]
-- , const doStrategyActions
-- , targetYouWhenCognizant
-- , const $
-- overrideInternal
-- (\cr -> crHasTarget cr && crStratConMatches (GetTo (V2 0 0)) cr)
-- (crActionPlan . apStrategy .~ WatchAndWait)
-- ]
--shootAtAdvance :: Int -> [Action]
--shootAtAdvance tcid =
-- [ DoActionIfElse NoAction crIsAiming (DoActionThen drawWeapon (WaitThen 50 NoAction))
-- `DoActionThen`
-- lostest `DoActionWhile`
-- advanceShoot `DoActionThen`
-- 75 `DoReplicate`
-- advanceShoot `DoActionThen`
-- DoImpulses [ChangeStrategy WatchAndWait]
-- , AimAt
-- { _targetID = tcid
-- , _targetSeenAt = V2 0 0 -- hack
-- }
-- ]
-- where
-- lostest (w,cr') = canSee (_crID cr') tcid w
-- advanceShoot = ImpulsesList [[UseItem, MoveForward 3]]
--
--shootAtWhileContinueTime :: Int -> World -> Creature -> Strategy
--shootAtWhileContinueTime tcid _ _ = StrategyActions (ShootAt tcid)
-- [ DoActionIfElse NoAction crIsAiming (DoActionThen drawWeapon (WaitThen 50 NoAction))
-- `DoActionThen`
-- lostest `DoActionWhile`
-- advanceShoot `DoActionThen`
-- 75 `DoReplicate`
-- advanceShoot `DoActionThen`
-- DoImpulses [ChangeStrategy WatchAndWait]
-- , AimAt
-- { _targetID = tcid
-- , _targetSeenAt = V2 0 0 -- hack
-- }
-- ]
-- where
-- lostest (w,cr') = canSee (_crID cr') tcid w
-- advanceShoot = ImpulsesList [[UseItem, MoveForward 3]]
+44 -43
View File
@@ -2,7 +2,7 @@
module Dodge.Creature.Update (updateCreature) where module Dodge.Creature.Update (updateCreature) where
import Dodge.WorldEvent.ThingsHit --import Dodge.WorldEvent.ThingsHit
import Color import Color
import Control.Monad import Control.Monad
import qualified IntMapHelp as IM import qualified IntMapHelp as IM
@@ -78,47 +78,48 @@ slimeCritUpdate cid w
let cid' = IM.newKey $ w ^. cWorld . lWorld . creatures let cid' = IM.newKey $ w ^. cWorld . lWorld . creatures
in w & cWorld . lWorld . creatures . ix cid .~ cr1 in w & cWorld . lWorld . creatures . ix cid .~ cr1
& cWorld . lWorld . creatures . at cid' ?~ (cr2 & crID .~ cid') & cWorld . lWorld . creatures . at cid' ?~ (cr2 & crID .~ cid')
| (cr ^?! crType . slimeIsCompressing) && r > norm p
= let (w',g) = runState (setSlimeDir cid (cr & crDamage .~ []) w) (w ^. randGen)
in w' & randGen .~ g
| otherwise = updateCarriage cid $ w | otherwise = updateCarriage cid $ w
& cWorld . lWorld . creatures . ix cid .~ mvslime & cWorld . lWorld . creatures . ix cid .~ mvslime
& cWorld . lWorld . creatures . ix cid . crDamage .~ [] & cWorld . lWorld . creatures . ix cid . crDamage .~ []
& cWorld . lWorld . creatures . ix cid . crDir .~ d & tocr %~ doSlimeRadChange
& cWorld . lWorld . creatures . ix cid . crType . slimeResetDir .~ rb' & tocr . crType . slimeSplitTimer %~ (max 0 . subtract 1)
& randGen .~ g
& cWorld . lWorld . creatures . ix cid %~ doSlimeRadChange
where where
txy = w ^?! cWorld . lWorld . creatures . ix 0 . crPos . _xy tocr = cWorld . lWorld . creatures . ix cid
cr = w ^?! cWorld . lWorld . creatures . ix cid cr = w ^?! cWorld . lWorld . creatures . ix cid
cxy = cr ^. crPos . _xy v = 0.1 *^ normalize p
rb = cr ^?! crType . slimeResetDir mvslime = cr & crType . slimeCompression +~ f v
(d,rb',g) & crPos . _xy +~ v
| isWalkable cxy txy w && distance cxy txy < 50 + r & crType . slimeIsCompressing %~ f'
, rb == cr ^?! crType . slimeIsCompressing f | t = negate
= (argV (txy-cxy), rb, w ^. randGen)
| abs (norm p - r) < 0.1
, rb == cr ^?! crType . slimeIsCompressing
= let (d',g') = randomR (0, 2* pi) (w ^. randGen)
in (d',not rb, g')
| otherwise = (cr ^. crDir, rb, w ^. randGen)
mvslime = cr & crType . slimeCompression .~ p' + x
-- & crPos . _xy +~ 0.1 *^ normalize (txy-cxy)
& crPos . _xy +~ 0.1 *^ unitVectorAtAngle d
& crType . slimeIsCompressing %~ (f . f')
-- g | cr ^?! crType . slimeIsCompressing = negate
-- | otherwise = id
s | cr ^?! crType . slimeIsCompressing = 2/3
| otherwise = 1.5
f | abs (norm v - norm p') < 0.2 = not
| otherwise = id | otherwise = id
v = (s * r) *^ unitVectorAtAngle (cr ^. crDir) f' | norm p > 3*r/2 = const True
--r = crRad (cr ^. crType) | otherwise = id
t = cr ^?! crType . slimeIsCompressing
r = cr ^?! crType . slimeRad r = cr ^?! crType . slimeRad
p = cr ^?! crType . slimeCompression p = cr ^?! crType . slimeCompression
(p',f')
| dot p v > 0 && dot p v > dot p (vNormal v) && dot p v > dot p (-vNormal v) = (p, id) setSlimeDir :: Int -> Creature -> World -> State StdGen World
| dot p (-v) > dot p (vNormal v) && dot p (-v) > dot p (-vNormal v) = (-p, id) setSlimeDir cid cr w = do
| dot p (vNormal v) > dot p (-vNormal v) = ((r*r/norm p) *^ normalize (vNormal p), not) i <- state $ randomR (0,1)
| otherwise = (-(r*r/norm p) *^ normalize (vNormal p), not) d <- state $ randomR (0,2*pi)
x = 0.1 *^ normalize (v - p') if i < (r - 11) / 50
then do
x <- randInCirc 1
let (cr1,cr2) = splitSlimeCrit (x + cxy) (unitVectorAtAngle d) cr ^?! _Just
cid' = IM.newKey $ w ^. cWorld . lWorld . creatures
return $ w & tocr .~ cr1
& tocr' cid' ?~ (cr2 & crID .~ cid')
else return $ w & tocr . crType . slimeCompression .~ r *^ unitVectorAtAngle d
& tocr . crType . slimeIsCompressing .~ False
where
tocr = cWorld . lWorld . creatures . ix cid
tocr' i = cWorld . lWorld . creatures . at i
cxy = cr ^. crPos . _xy
r = cr ^?! crType . slimeRad
doSlimeRadChange :: Creature -> Creature doSlimeRadChange :: Creature -> Creature
doSlimeRadChange = crType . slimeRadWobble %~ f doSlimeRadChange = crType . slimeRadWobble %~ f
@@ -136,23 +137,23 @@ splitSlimeCrit p v cr = do
a2 = pi*r*r - a1 a2 = pi*r*r - a1
r1 = sqrt (a1/pi) r1 = sqrt (a1/pi)
r2 = sqrt (a2/pi) r2 = sqrt (a2/pi)
-- guard $ r1 > 5 && r2 > 5 mvdir = normalize (vNormal v)
return (cr' & crPos . _xy .~ mp + (r1 + 0.5) *^ normalize (mp - cxy) return (cr' & crPos . _xy .~ mp + (r1 + 0.51) *^ mvdir
& crType . slimeRad .~ r1 & crType . slimeRad .~ r1
& crType . slimeCompression .~ rotateV (argV (mp-cxy)) (V2 r1 0) & crType . slimeCompression .~ rotateV (argV mvdir) (V2 r1 0)
& crDir .~ argV (mp - cxy) & crDir .~ argV mvdir
& crType . slimeResetDir .~ not (cr ^?! crType . slimeIsCompressing) ,cr' & crPos . _xy .~ mp - (r2 + 0.51) *^ normalize mvdir
,cr' & crPos . _xy .~ mp - (r2 + 0.5) *^ normalize (mp - cxy)
& crType . slimeRad .~ r2 & crType . slimeRad .~ r2
& crType . slimeCompression .~ rotateV (argV (cxy-mp)) (V2 r2 0) & crType . slimeCompression .~ rotateV (argV (-mvdir)) (V2 r2 0)
& crDir .~ argV (cxy - mp) & crDir .~ argV (-mvdir)
& crType . slimeResetDir .~ not (cr ^?! crType . slimeIsCompressing)
) )
where where
cxy = cr ^. crPos . _xy cxy = cr ^. crPos . _xy
r = cr ^?! crType . slimeRad r = cr ^?! crType . slimeRad
cr' = cr & crDamage .~ [] cr' = cr & crDamage .~ []
& crType . slimeRadWobble .~ 0 & crType . slimeRadWobble .~ 0
& crType . slimeSplitTimer .~ 10
& crType . slimeIsCompressing .~ False
-- h is the height of the segment, ie r - distance to center -- h is the height of the segment, ie r - distance to center
segmentArea :: Float -> Float -> Float segmentArea :: Float -> Float -> Float
-1
View File
@@ -76,7 +76,6 @@ data CreatureType
, _slimeSplitTimer :: Int , _slimeSplitTimer :: Int
, _slimeCompression :: Point2 , _slimeCompression :: Point2
, _slimeIsCompressing :: Bool , _slimeIsCompressing :: Bool
, _slimeResetDir :: Bool
} }
| SwarmCrit | SwarmCrit
| AutoCrit | AutoCrit
+1 -2
View File
@@ -2,13 +2,12 @@ module Dodge.Item.Held.BatteryGuns (
teslaCoil, teslaCoil,
laser, laser,
tractorGun, tractorGun,
compass, compass, -- this should be elsewhere
) where ) where
import Control.Lens import Control.Lens
import Dodge.Data.Item import Dodge.Data.Item
import Dodge.Default.Item import Dodge.Default.Item
--import Geometry.Data
teslaCoil :: Item teslaCoil :: Item
teslaCoil = teslaCoil =
+7 -5
View File
@@ -57,15 +57,17 @@ tutAnoTree = do
foldMTRS foldMTRS
[ tToBTree "TutStartRez" . return . cleatOnward <$> tutRezBox [ tToBTree "TutStartRez" . return . cleatOnward <$> tutRezBox
, corDoor , corDoor
, tToBTree "" . return . cleatOnward <$> xChasm 200 200 --, tToBTree "" . return . cleatOnward <$> (xChasm 200 200
, tToBTree "" . return . cleatOnward <$> (roomRectAutoLights 200 200
<&> rmPmnts .:~ (sps0 (PutCrit slimeCrit) & plSpot . psPos .~ V2 100 100))
-- , tToBTree "" . return . cleatOnward <$> (cChasm -- , tToBTree "" . return . cleatOnward <$> (cChasm
-- <&> rmPmnts .:~ (sps0 (PutCrit slimeCrit) & plSpot . psPos .~ V2 100 20)) -- <&> rmPmnts .:~ (sps0 (PutCrit slimeCrit) & plSpot . psPos .~ V2 100 20))
-- , corDoor -- , corDoor
-- , loadAmmoTut -- , loadAmmoTut
, corDoor --a , corDoor
, chasmSpitTerminal --a , chasmSpitTerminal
, corDoor --a , corDoor
, tutHub --a , tutHub
--b , corDoor --b , corDoor
--b , tToBTree "slowCrush" . return . cleatOnward <$> pushCaverns --b , tToBTree "slowCrush" . return . cleatOnward <$> pushCaverns
--b , corDoor --b , corDoor
+1
View File
@@ -51,6 +51,7 @@ testStringInit u = u ^.. tocrs . ix 1 . crPos . _xy . to show
<> u ^.. tocrs . ix 1 . crType . slimeIsCompressing . to show <> u ^.. tocrs . ix 1 . crType . slimeIsCompressing . to show
<> u ^.. tocrs . ix 1 . crDir . to show <> u ^.. tocrs . ix 1 . crDir . to show
<> u ^.. tocrs . ix 1 . crDamage . to show <> u ^.. tocrs . ix 1 . crDamage . to show
<> u ^.. tocrs . each . crType . to crRad . to show
-- <> u ^.. tocrs . each . crID . to show -- <> u ^.. tocrs . each . crID . to show
-- where -- where
-- tocr = uvWorld . cWorld . lWorld . creatures . ix 0 -- tocr = uvWorld . cWorld . lWorld . creatures . ix 0
+9 -10
View File
@@ -1004,11 +1004,11 @@ crCrSpring c1 c2
, SlimeCrit{} <- c2 ^. crType , SlimeCrit{} <- c2 ^. crType
, id2 > id1 , id2 > id1
, distance xy1 xy2 < abs (r1 - r2) + 1 = fuseSlimes c1 c2 , distance xy1 xy2 < abs (r1 - r2) + 1 = fuseSlimes c1 c2
| SlimeCrit{} <- c1 ^. crType = | Just t <- c1 ^? crType . slimeSplitTimer
--cWorld . lWorld . creatures %~ (rolap c1 c2 . rolap' c2 c1) , t <= 0 =
cWorld . lWorld . creatures %~ (rolap . rolap') cWorld . lWorld . creatures %~ (rolap . rolap')
| SlimeCrit{} <- c1 ^. crType = id
| SlimeCrit{} <- c2 ^. crType = id | SlimeCrit{} <- c2 ^. crType = id
-- cWorld . lWorld . creatures %~ ( rolap c1 c2 . rolap' c2 c1)
| otherwise = cWorld . lWorld . creatures %~ ( olap c1 c2 . olap' c2 c1) | otherwise = cWorld . lWorld . creatures %~ ( olap c1 c2 . olap' c2 c1)
where where
z c = c ^. crPos . _z z c = c ^. crPos . _z
@@ -1037,20 +1037,19 @@ crCrSpring c1 c2
m2 = crMass $ c2 ^. crType m2 = crMass $ c2 ^. crType
fuseSlimes :: Creature -> Creature -> World -> World fuseSlimes :: Creature -> Creature -> World -> World
fuseSlimes c1 c2 = (cWorld . lWorld . creatures . ix mini .~ (c & crID .~ mini)) fuseSlimes c1 c2 = (cWorld . lWorld . creatures . ix mini .~ c)
. (cWorld . lWorld . creatures . at maxi .~ Nothing) . (cWorld . lWorld . creatures . at maxi .~ Nothing)
where where
c' | c1 ^?! crType . slimeRad > c2 ^?! crType . slimeRad = c1
| otherwise = c2
mini = min i1 i2 mini = min i1 i2
maxi = max i1 i2 maxi = max i1 i2
i1 = c1 ^. crID i1 = c1 ^. crID
i2 = c2 ^. crID i2 = c2 ^. crID
c = c1 & crType . slimeRad .~ r c = c' & crType . slimeRad .~ r
& crType . slimeRadWobble +~ r - max r1 r2 & crType . slimeRadWobble +~ r - max r1 r2
& crType . slimeCompression .~ V2 r 0 & crType . slimeCompression %~ ((r/max r1 r2) *^)
-- & crPos . _xy .~ (r1/(r1+r2)) *^ xy1 + (r2/(r1+r2)) *^ xy2 & crID .~ mini
& crPos . _xy .~ if r1 > r2 then xy1 else xy2
xy1 = c1 ^. crPos . _xy
xy2 = c2 ^. crPos . _xy
r1 = c1 ^?! crType . slimeRad r1 = c1 ^?! crType . slimeRad
r2 = c2 ^?! crType . slimeRad r2 = c2 ^?! crType . slimeRad
r = sqrt (r1*r1 + r2*r2) r = sqrt (r1*r1 + r2*r2)
+365 -361
View File
File diff suppressed because it is too large Load Diff