From f0da9b5f8cdcb3b1e03b54153cc2e71da41d49e5 Mon Sep 17 00:00:00 2001 From: justin Date: Sun, 12 Apr 2026 13:44:05 +0100 Subject: [PATCH] Allow slimes to recombine --- src/Dodge/Creature/ChaseCrit.hs | 2 +- src/Dodge/Creature/Update.hs | 31 ++++++++++++++++++++++--------- src/Dodge/Data/Creature/Misc.hs | 1 + src/Dodge/TestString.hs | 3 +++ src/Dodge/Update.hs | 19 +++++++++++++++++++ 5 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src/Dodge/Creature/ChaseCrit.hs b/src/Dodge/Creature/ChaseCrit.hs index 1f3937340..35de0512c 100644 --- a/src/Dodge/Creature/ChaseCrit.hs +++ b/src/Dodge/Creature/ChaseCrit.hs @@ -66,7 +66,7 @@ slimeCrit :: Creature slimeCrit = defaultCreature & crName .~ "slimeCrit" & crHP .~ HP 1000 - & crType .~ SlimeCrit 40 (V2 30 0) False + & crType .~ SlimeCrit 40 (V2 30 0) False True & crFaction .~ ColorFaction (light green) & crPerception . cpVision . viFOV .~ FloatFOV pi diff --git a/src/Dodge/Creature/Update.hs b/src/Dodge/Creature/Update.hs index 895e6c880..8f8296f93 100644 --- a/src/Dodge/Creature/Update.hs +++ b/src/Dodge/Creature/Update.hs @@ -2,7 +2,7 @@ module Dodge.Creature.Update (updateCreature) where -import Dodge.Base.Collide +import Dodge.WorldEvent.ThingsHit import Dodge.Creature.Radius import Color import Control.Monad @@ -82,23 +82,32 @@ slimeCritUpdate cid w | otherwise = w & cWorld . lWorld . creatures . ix cid .~ mvslime & cWorld . lWorld . creatures . ix cid . crDamage .~ [] + & cWorld . lWorld . creatures . ix cid . crDir .~ d + & cWorld . lWorld . creatures . ix cid . crType . slimeResetDir .~ rb' + & randGen .~ g where txy = w ^?! cWorld . lWorld . creatures . ix 0 . crPos . _xy cr = w ^?! cWorld . lWorld . creatures . ix cid cxy = cr ^. crPos . _xy - mvslime - | hasLOS cxy txy w = mvslime' - | otherwise = cr - mvslime' = cr & crType . slimeCompression .~ p' + x - -- & crPos . _xy +~ g (x) - & crPos . _xy +~ 0.1 *^ normalize (txy-cxy) + rb = cr ^?! crType . slimeResetDir + (d,rb',g) + | isWalkable cxy txy w && distance cxy txy < 50 + r + , rb == cr ^?! crType . slimeIsCompressing + = (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') - & crDir .~ argV (txy-cxy) -- g | cr ^?! crType . slimeIsCompressing = negate -- | otherwise = id s | cr ^?! crType . slimeIsCompressing = 2/3 | otherwise = 1.5 - f | abs (norm v - norm p') < 0.1 = not + f | abs (norm v - norm p') < 0.2 = not | otherwise = id v = (s * r) *^ unitVectorAtAngle (cr ^. crDir) r = crRad (cr ^. crType) @@ -123,9 +132,13 @@ splitSlimeCrit p v cr = do return (cr' & crPos . _xy .~ mp + r1 *^ normalize (mp - cxy) & crType . slimeRad .~ r1 & crType . slimeCompression .~ V2 r1 0 + & crDir .~ argV (mp - cxy) + & crType . slimeResetDir .~ not (cr ^?! crType . slimeIsCompressing) ,cr' & crPos . _xy .~ mp - r2 *^ normalize (mp - cxy) & crType . slimeRad .~ r2 & crType . slimeCompression .~ V2 r2 0 + & crDir .~ argV (cxy - mp) + & crType . slimeResetDir .~ not (cr ^?! crType . slimeIsCompressing) ) where cxy = cr ^. crPos . _xy diff --git a/src/Dodge/Data/Creature/Misc.hs b/src/Dodge/Data/Creature/Misc.hs index 952f7b1a5..00b834866 100644 --- a/src/Dodge/Data/Creature/Misc.hs +++ b/src/Dodge/Data/Creature/Misc.hs @@ -74,6 +74,7 @@ data CreatureType { _slimeRad :: Float , _slimeCompression :: Point2 , _slimeIsCompressing :: Bool + , _slimeResetDir :: Bool } | SwarmCrit | AutoCrit diff --git a/src/Dodge/TestString.hs b/src/Dodge/TestString.hs index 9ad67bc6f..b9829c1ed 100644 --- a/src/Dodge/TestString.hs +++ b/src/Dodge/TestString.hs @@ -2,6 +2,7 @@ module Dodge.TestString where +import Dodge.Creature.Radius import AesonHelp import qualified Control.Foldl as L import Control.Lens @@ -43,6 +44,8 @@ tocrs = uvWorld . cWorld . lWorld . creatures testStringInit :: Universe -> [String] testStringInit u = u ^.. tocrs . ix 1 . crPos . _xy . to show <> u ^.. tocrs . ix 1 . crType . slimeCompression . to show + <> u ^.. tocrs . ix 1 . crType . slimeCompression . to norm . to show + <> u ^.. tocrs . ix 1 . crType . to crRad . to show <> u ^.. tocrs . ix 1 . crType . slimeIsCompressing . to show <> u ^.. tocrs . ix 1 . crDir . to show <> u ^.. tocrs . ix 1 . crDamage . to show diff --git a/src/Dodge/Update.hs b/src/Dodge/Update.hs index d70708a27..661985ac1 100644 --- a/src/Dodge/Update.hs +++ b/src/Dodge/Update.hs @@ -1000,6 +1000,9 @@ crCrSpring c1 c2 | vec == V2 0 0 = id | diff >= comRad = id | diffheight = id + | SlimeCrit{} <- c1 ^. crType + , SlimeCrit{} <- c2 ^. crType + , id2 > id1 = fuseSlimes c1 c2 | otherwise = cWorld . lWorld . creatures %~ ( olap c1 c2 . olap' c2 c1) where z c = c ^. crPos . _z @@ -1018,6 +1021,22 @@ crCrSpring c1 c2 overlap c = ((comRad - diff) * crMass (_crType c) * 0.5 / massT) *^ signorm vec massT = crMass (_crType c1) + crMass (_crType c2) +fuseSlimes :: Creature -> Creature -> World -> World +fuseSlimes c1 c2 = (cWorld . lWorld . creatures . ix i1 .~ c) + . (cWorld . lWorld . creatures . at i2 .~ Nothing) + where + i1 = c1 ^. crID + i2 = c2 ^. crID + c = c1 & crType . slimeRad .~ r + & crType . slimeCompression .~ V2 r 0 + & crPos . _xy .~ (r1/(r1+r2)) *^ xy1 + (r2/(r1+r2)) *^ xy2 + xy1 = c1 ^. crPos . _xy + xy2 = c2 ^. crPos . _xy + r1 = c1 ^?! crType . slimeRad + r2 = c2 ^?! crType . slimeRad + r = sqrt (r1*r1 + r2*r2) + + updateDelayedEvents :: World -> World updateDelayedEvents w = let (neww, newde) = mapAccumR f w (w ^. cWorld . lWorld . delayedEvents)