Work on slime crit split/combining
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
module Dodge.Creature.Update (updateCreature) where
|
||||
|
||||
import Dodge.WorldEvent.ThingsHit
|
||||
--import Dodge.WorldEvent.ThingsHit
|
||||
import Color
|
||||
import Control.Monad
|
||||
import qualified IntMapHelp as IM
|
||||
@@ -78,47 +78,48 @@ slimeCritUpdate cid w
|
||||
let cid' = IM.newKey $ w ^. cWorld . lWorld . creatures
|
||||
in w & cWorld . lWorld . creatures . ix cid .~ cr1
|
||||
& 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
|
||||
& 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
|
||||
& cWorld . lWorld . creatures . ix cid %~ doSlimeRadChange
|
||||
& tocr %~ doSlimeRadChange
|
||||
& tocr . crType . slimeSplitTimer %~ (max 0 . subtract 1)
|
||||
where
|
||||
txy = w ^?! cWorld . lWorld . creatures . ix 0 . crPos . _xy
|
||||
tocr = cWorld . lWorld . creatures . ix cid
|
||||
cr = w ^?! cWorld . lWorld . creatures . ix cid
|
||||
cxy = cr ^. crPos . _xy
|
||||
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')
|
||||
-- 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
|
||||
v = 0.1 *^ normalize p
|
||||
mvslime = cr & crType . slimeCompression +~ f v
|
||||
& crPos . _xy +~ v
|
||||
& crType . slimeIsCompressing %~ f'
|
||||
f | t = negate
|
||||
| otherwise = id
|
||||
v = (s * r) *^ unitVectorAtAngle (cr ^. crDir)
|
||||
--r = crRad (cr ^. crType)
|
||||
f' | norm p > 3*r/2 = const True
|
||||
| otherwise = id
|
||||
t = cr ^?! crType . slimeIsCompressing
|
||||
r = cr ^?! crType . slimeRad
|
||||
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)
|
||||
| dot p (-v) > dot p (vNormal v) && dot p (-v) > dot p (-vNormal v) = (-p, id)
|
||||
| dot p (vNormal v) > dot p (-vNormal v) = ((r*r/norm p) *^ normalize (vNormal p), not)
|
||||
| otherwise = (-(r*r/norm p) *^ normalize (vNormal p), not)
|
||||
x = 0.1 *^ normalize (v - p')
|
||||
|
||||
setSlimeDir :: Int -> Creature -> World -> State StdGen World
|
||||
setSlimeDir cid cr w = do
|
||||
i <- state $ randomR (0,1)
|
||||
d <- state $ randomR (0,2*pi)
|
||||
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 = crType . slimeRadWobble %~ f
|
||||
@@ -136,23 +137,23 @@ splitSlimeCrit p v cr = do
|
||||
a2 = pi*r*r - a1
|
||||
r1 = sqrt (a1/pi)
|
||||
r2 = sqrt (a2/pi)
|
||||
-- guard $ r1 > 5 && r2 > 5
|
||||
return (cr' & crPos . _xy .~ mp + (r1 + 0.5) *^ normalize (mp - cxy)
|
||||
mvdir = normalize (vNormal v)
|
||||
return (cr' & crPos . _xy .~ mp + (r1 + 0.51) *^ mvdir
|
||||
& crType . slimeRad .~ r1
|
||||
& crType . slimeCompression .~ rotateV (argV (mp-cxy)) (V2 r1 0)
|
||||
& crDir .~ argV (mp - cxy)
|
||||
& crType . slimeResetDir .~ not (cr ^?! crType . slimeIsCompressing)
|
||||
,cr' & crPos . _xy .~ mp - (r2 + 0.5) *^ normalize (mp - cxy)
|
||||
& crType . slimeCompression .~ rotateV (argV mvdir) (V2 r1 0)
|
||||
& crDir .~ argV mvdir
|
||||
,cr' & crPos . _xy .~ mp - (r2 + 0.51) *^ normalize mvdir
|
||||
& crType . slimeRad .~ r2
|
||||
& crType . slimeCompression .~ rotateV (argV (cxy-mp)) (V2 r2 0)
|
||||
& crDir .~ argV (cxy - mp)
|
||||
& crType . slimeResetDir .~ not (cr ^?! crType . slimeIsCompressing)
|
||||
& crType . slimeCompression .~ rotateV (argV (-mvdir)) (V2 r2 0)
|
||||
& crDir .~ argV (-mvdir)
|
||||
)
|
||||
where
|
||||
cxy = cr ^. crPos . _xy
|
||||
r = cr ^?! crType . slimeRad
|
||||
cr' = cr & crDamage .~ []
|
||||
& crType . slimeRadWobble .~ 0
|
||||
& crType . slimeSplitTimer .~ 10
|
||||
& crType . slimeIsCompressing .~ False
|
||||
|
||||
-- h is the height of the segment, ie r - distance to center
|
||||
segmentArea :: Float -> Float -> Float
|
||||
|
||||
Reference in New Issue
Block a user