Allow slimes to recombine

This commit is contained in:
2026-04-12 13:44:05 +01:00
parent d075880248
commit f0da9b5f8c
5 changed files with 46 additions and 10 deletions
+1 -1
View File
@@ -66,7 +66,7 @@ slimeCrit :: Creature
slimeCrit = defaultCreature slimeCrit = defaultCreature
& crName .~ "slimeCrit" & crName .~ "slimeCrit"
& crHP .~ HP 1000 & crHP .~ HP 1000
& crType .~ SlimeCrit 40 (V2 30 0) False & crType .~ SlimeCrit 40 (V2 30 0) False True
& crFaction .~ ColorFaction (light green) & crFaction .~ ColorFaction (light green)
& crPerception . cpVision . viFOV .~ FloatFOV pi & crPerception . cpVision . viFOV .~ FloatFOV pi
+22 -9
View File
@@ -2,7 +2,7 @@
module Dodge.Creature.Update (updateCreature) where module Dodge.Creature.Update (updateCreature) where
import Dodge.Base.Collide import Dodge.WorldEvent.ThingsHit
import Dodge.Creature.Radius import Dodge.Creature.Radius
import Color import Color
import Control.Monad import Control.Monad
@@ -82,23 +82,32 @@ slimeCritUpdate cid w
| otherwise = w | otherwise = 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
& cWorld . lWorld . creatures . ix cid . crType . slimeResetDir .~ rb'
& randGen .~ g
where where
txy = w ^?! cWorld . lWorld . creatures . ix 0 . crPos . _xy txy = w ^?! cWorld . lWorld . creatures . ix 0 . crPos . _xy
cr = w ^?! cWorld . lWorld . creatures . ix cid cr = w ^?! cWorld . lWorld . creatures . ix cid
cxy = cr ^. crPos . _xy cxy = cr ^. crPos . _xy
mvslime rb = cr ^?! crType . slimeResetDir
| hasLOS cxy txy w = mvslime' (d,rb',g)
| otherwise = cr | isWalkable cxy txy w && distance cxy txy < 50 + r
mvslime' = cr & crType . slimeCompression .~ p' + x , rb == cr ^?! crType . slimeIsCompressing
-- & crPos . _xy +~ g (x) = (argV (txy-cxy), rb, w ^. randGen)
& crPos . _xy +~ 0.1 *^ normalize (txy-cxy) | 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') & crType . slimeIsCompressing %~ (f . f')
& crDir .~ argV (txy-cxy)
-- g | cr ^?! crType . slimeIsCompressing = negate -- g | cr ^?! crType . slimeIsCompressing = negate
-- | otherwise = id -- | otherwise = id
s | cr ^?! crType . slimeIsCompressing = 2/3 s | cr ^?! crType . slimeIsCompressing = 2/3
| otherwise = 1.5 | otherwise = 1.5
f | abs (norm v - norm p') < 0.1 = not f | abs (norm v - norm p') < 0.2 = not
| otherwise = id | otherwise = id
v = (s * r) *^ unitVectorAtAngle (cr ^. crDir) v = (s * r) *^ unitVectorAtAngle (cr ^. crDir)
r = crRad (cr ^. crType) r = crRad (cr ^. crType)
@@ -123,9 +132,13 @@ splitSlimeCrit p v cr = do
return (cr' & crPos . _xy .~ mp + r1 *^ normalize (mp - cxy) return (cr' & crPos . _xy .~ mp + r1 *^ normalize (mp - cxy)
& crType . slimeRad .~ r1 & crType . slimeRad .~ r1
& crType . slimeCompression .~ V2 r1 0 & crType . slimeCompression .~ V2 r1 0
& crDir .~ argV (mp - cxy)
& crType . slimeResetDir .~ not (cr ^?! crType . slimeIsCompressing)
,cr' & crPos . _xy .~ mp - r2 *^ normalize (mp - cxy) ,cr' & crPos . _xy .~ mp - r2 *^ normalize (mp - cxy)
& crType . slimeRad .~ r2 & crType . slimeRad .~ r2
& crType . slimeCompression .~ V2 r2 0 & crType . slimeCompression .~ V2 r2 0
& crDir .~ argV (cxy - mp)
& crType . slimeResetDir .~ not (cr ^?! crType . slimeIsCompressing)
) )
where where
cxy = cr ^. crPos . _xy cxy = cr ^. crPos . _xy
+1
View File
@@ -74,6 +74,7 @@ data CreatureType
{ _slimeRad :: Float { _slimeRad :: Float
, _slimeCompression :: Point2 , _slimeCompression :: Point2
, _slimeIsCompressing :: Bool , _slimeIsCompressing :: Bool
, _slimeResetDir :: Bool
} }
| SwarmCrit | SwarmCrit
| AutoCrit | AutoCrit
+3
View File
@@ -2,6 +2,7 @@
module Dodge.TestString where module Dodge.TestString where
import Dodge.Creature.Radius
import AesonHelp import AesonHelp
import qualified Control.Foldl as L import qualified Control.Foldl as L
import Control.Lens import Control.Lens
@@ -43,6 +44,8 @@ tocrs = uvWorld . cWorld . lWorld . creatures
testStringInit :: Universe -> [String] testStringInit :: Universe -> [String]
testStringInit u = u ^.. tocrs . ix 1 . crPos . _xy . to show 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 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 . 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
+19
View File
@@ -1000,6 +1000,9 @@ crCrSpring c1 c2
| vec == V2 0 0 = id | vec == V2 0 0 = id
| diff >= comRad = id | diff >= comRad = id
| diffheight = id | diffheight = id
| SlimeCrit{} <- c1 ^. crType
, SlimeCrit{} <- c2 ^. crType
, id2 > id1 = fuseSlimes c1 c2
| 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
@@ -1018,6 +1021,22 @@ crCrSpring c1 c2
overlap c = ((comRad - diff) * crMass (_crType c) * 0.5 / massT) *^ signorm vec overlap c = ((comRad - diff) * crMass (_crType c) * 0.5 / massT) *^ signorm vec
massT = crMass (_crType c1) + crMass (_crType c2) 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 :: World -> World
updateDelayedEvents w = updateDelayedEvents w =
let (neww, newde) = mapAccumR f w (w ^. cWorld . lWorld . delayedEvents) let (neww, newde) = mapAccumR f w (w ^. cWorld . lWorld . delayedEvents)