diff --git a/src/Dodge/Block/Debris.hs b/src/Dodge/Block/Debris.hs index 8baef8aca..6f06717d0 100644 --- a/src/Dodge/Block/Debris.hs +++ b/src/Dodge/Block/Debris.hs @@ -1,12 +1,8 @@ module Dodge.Block.Debris where import Dodge.Material.Sound -import Dodge.Prop.Moving import Dodge.WorldEvent.Sound ---import Dodge.Zone import Dodge.Base import Dodge.Data ---import Dodge.Damage ---import ShapePicture import Shape import Geometry import Color @@ -50,7 +46,7 @@ makeDebris = makeDebrisDirected 1 2 (2*pi) 0 makeDebrisDirectedHeight :: Float -> Float -> Float -> Float -> Float -> Material -> Color -> Point2 -> World -> World makeDebrisDirectedHeight mindist maxdist arcrad dir maxh bm col p w = w - & flip (foldl' (flip $ plNew props pjID)) thedebris + & flip (foldl' (flip $ plNew props prID)) thedebris & randGen .~ newg & originsIDsAt [MaterialSound bm i | i <- [0,1,2]] (destroyMatS bm) p where @@ -62,13 +58,13 @@ makeDebrisDirectedHeight mindist maxdist arcrad dir maxh bm col p w = w spinspeed <- randomR (-0.2,-0.1) & state basedebris <- baseDebris bm return $ basedebris - & pjColor .~ col + & prColor .~ col & prPos .~ p - & pjVel .~ v - & pjQuatSpin .~ Q.axisAngle (vNormal v `v2z` 0) spinspeed - & pjQuat .~ q - & pjVelZ .~ 0 - & pjPosZ .~ h + & prVel .~ v + & prQuatSpin .~ Q.axisAngle (vNormal v `v2z` 0) spinspeed + & prQuat .~ q + & prVelZ .~ 0 + & prPosZ .~ h makeDebrisDirected :: Float -> Float @@ -79,7 +75,7 @@ makeDebrisDirected :: Float -> Point2 -> World -> World makeDebrisDirected mindist maxdist arcrad dir bm col p w = w - & flip (foldl' (flip $ plNew props pjID)) thedebris + & flip (foldl' (flip $ plNew props prID)) thedebris & randGen .~ newg & originsIDsAt [MaterialSound bm i | i <- [0,1,2]] (destroyMatS bm) p where @@ -90,13 +86,13 @@ makeDebrisDirected mindist maxdist arcrad dir bm col p w = w spinspeed <- randomR (-0.2,-0.1) & state basedebris <- baseDebris bm return $ basedebris - & pjColor .~ col + & prColor .~ col & prPos .~ p - & pjVel .~ v - & pjQuatSpin .~ Q.axisAngle (vNormal v `v2z` 0) spinspeed - & pjQuat .~ q - & pjVelZ .~ 0 - & pjPosZ .~ h + & prVel .~ v + & prQuatSpin .~ Q.axisAngle (vNormal v `v2z` 0) spinspeed + & prQuat .~ q + & prVelZ .~ 0 + & prPosZ .~ h debrisSize :: Material -> Float debrisSize mt = case mt of @@ -119,45 +115,45 @@ baseDebris mt = case mt of Metal -> do sh <- jaggedShape return $ metalDebris - & prDraw .~ (`drawMovingShapeCol` sh) + & prDraw .~ PropDrawMovingShapeCol sh Electronics -> baseDebris Metal - Flesh -> baseDebris Dirt <&> pjColor .~ red + Flesh -> baseDebris Dirt <&> prColor .~ red stoneDebris :: Prop stoneDebris = PropZ {_prPos = 0 - ,_pjStartPos = 0 - ,_pjVel = 0 - ,_prDraw = \pr -> drawMovingShapeCol pr (cubeShape 4) - ,_pjID = 0 - ,_pjUpdate = fallSmallBounceDamage - ,_pjPosZ = 10 - ,_pjVelZ = 5 - ,_pjTimer = 20 - ,_pjQuat = Q.axisAngle (V3 1 0 0) 0 - ,_pjQuatSpin = Q.axisAngle (V3 1 1 0) 0.1 - ,_pjColor = greyN 0.5 + ,_prStartPos = 0 + ,_prVel = 0 + ,_prDraw = PropDrawMovingShapeCol (cubeShape 4) + ,_prID = 0 + ,_prUpdate = PropFallSmallBounceDamage + ,_prPosZ = 10 + ,_prVelZ = 5 + ,_prTimer = 20 + ,_prQuat = Q.axisAngle (V3 1 0 0) 0 + ,_prQuatSpin = Q.axisAngle (V3 1 1 0) 0.1 + ,_prColor = greyN 0.5 } dirtDebris :: Prop dirtDebris = stoneDebris - & pjColor .~ dirtColor - & pjUpdate .~ fallSmallBounce + & prColor .~ dirtColor + & prUpdate .~ PropFallSmallBounce dirtColor :: Color dirtColor = V4 (150/256) ( 75/256) 0 ( 250/256) metalDebris :: Prop metalDebris = stoneDebris - & prDraw .~ (\pr -> drawMovingShapeCol pr (shardShape 4)) - & pjUpdate .~ fallSmallBounce + & prDraw .~ PropDrawMovingShapeCol (shardShape 4) + & prUpdate .~ PropFallSmallBounceDamage glassDebris :: Prop glassDebris = stoneDebris - & prDraw .~ (\pr -> drawMovingShapeCol pr (shardShape 4)) - & pjUpdate .~ fallSmallBounce - & pjColor .~ withAlpha 0.5 cyan + & prDraw .~ PropDrawMovingShapeCol (shardShape 4) + & prUpdate .~ PropFallSmallBounce + & prColor .~ withAlpha 0.5 cyan crystalDebris :: Prop crystalDebris = glassDebris - & pjColor .~ withAlpha 0.5 aquamarine + & prColor .~ withAlpha 0.5 aquamarine shardShape :: Float -> Shape shardShape size = translateSHz (-size) $ upperPrismPoly size diff --git a/src/Dodge/Data.hs b/src/Dodge/Data.hs index bca640144..0676803b5 100644 --- a/src/Dodge/Data.hs +++ b/src/Dodge/Data.hs @@ -80,7 +80,13 @@ module Dodge.Data , module Dodge.Data.Laser , module Dodge.Data.TeslaArc , module Dodge.Data.Shockwave + , module Dodge.Data.Prop + , module Dodge.Data.LinearShockwave + , module Dodge.Data.TractorBeam ) where +import Dodge.Data.TractorBeam +import Dodge.Data.LinearShockwave +import Dodge.Data.Prop import Dodge.Data.Shockwave import Dodge.Data.TeslaArc import Dodge.Data.Laser @@ -161,10 +167,7 @@ import Dodge.GameRoom import Color import Data.Tile import MaybeHelp ---import StreamingHelp.Data ---import qualified Data.Vector as V -import qualified Linear.Quaternion as Q import Control.Lens import Control.Monad.State import System.Random @@ -230,6 +233,8 @@ data World = World , _shockwaves :: [Shockwave] , _lasers :: [LaserStart] , _lasersToDraw :: [Laser] + , _linearShockwaves :: IM.IntMap LinearShockwave + , _tractorBeams :: [TractorBeam] , _walls :: IM.IntMap Wall , _wallDamages :: IM.IntMap [Damage] , _doors :: IM.IntMap Door @@ -287,6 +292,7 @@ data World = World , _lSelect :: Point2 , _rSelect :: Point2 } + --deriving (Eq,Ord,Show,Read) data WorldHammer = SubInvHam | DoubleMouseHam @@ -396,72 +402,6 @@ type HitEffect' = Flame -> World -> (World,Maybe Flame) -data Prop - = PropZ - { _prPos :: Point2 - , _pjStartPos :: Point2 - , _pjVel :: Point2 - , _prDraw :: Prop -> SPic - , _pjID :: Int - , _pjUpdate :: Prop -> World -> World - , _pjPosZ :: Float - , _pjVelZ :: Float - , _pjTimer :: Int - , _pjQuat :: Q.Quaternion Float - , _pjQuatSpin :: Q.Quaternion Float - , _pjColor :: Color - } - | Drone - { _prPos :: Point2 - , _pjStartPos :: Point2 - , _pjVel :: Point2 - , _prDraw :: Prop -> SPic - , _pjID :: Int - , _pjUpdate :: Prop -> World -> World - } - | RecursiveProp - { _prPos :: Point2 - , _pjID :: Int - , _pjDraw :: Prop -> SPic - , _pjUpdate :: Prop -> World -> World - , _pjProp :: Prop - } - | ProjectileTimed - { _prPos :: Point2 - , _pjStartPos :: Point2 - , _pjVel :: Point2 - , _prDraw :: Prop -> SPic - , _pjID :: Int - , _pjUpdate :: Prop -> World -> World - , _pjTime :: Int - } - | ShapeProp - { _prPos :: Point2 - , _pjID :: Int - , _pjRot :: Float - , _pjUpdate :: Prop -> World -> World - , _prDraw :: Prop -> SPic - , _prToggle :: Bool - } - | Bomb - { _prPos :: Point2 - , _pjVel :: Point2 - , _pjZ :: Float - , _pjVelZ :: Float - , _prDraw :: Prop -> SPic - , _pjID :: Int - , _pjUpdate :: Prop -> World -> World - , _pjPayload :: Point2 -> World -> World - , _pjTimer :: Int - } - | LinearShockwave - { _prDraw :: Prop -> SPic - , _prPos :: Point2 - , _pjID :: Int - , _pjUpdate :: Prop -> World -> World - , _pjPoints :: [(Point2,Point2)] - , _pjTimer :: Int - } data Either3 a b c = E3x1 a | E3x2 b | E3x3 c data TerminalStatus = TerminalOff | TerminalBusy | TerminalReady deriving (Eq,Ord,Show) @@ -653,7 +593,6 @@ data InPlacement = InPlacement } makeLenses ''World makeLenses ''FloorItem -makeLenses ''Prop makeLenses ''Particle makeLenses ''Door makeLenses ''Terminal diff --git a/src/Dodge/Data/Cloud.hs b/src/Dodge/Data/Cloud.hs index a58f2ace0..2951bb8ad 100644 --- a/src/Dodge/Data/Cloud.hs +++ b/src/Dodge/Data/Cloud.hs @@ -17,7 +17,6 @@ data Cloud = Cloud , _clAlt :: Float , _clTimer :: Int , _clType :: CloudType --- , _clEffect :: Cloud -> World -> World } deriving (Eq,Ord,Show,Read) data CloudType diff --git a/src/Dodge/Data/LinearShockwave.hs b/src/Dodge/Data/LinearShockwave.hs new file mode 100644 index 000000000..755a15ed8 --- /dev/null +++ b/src/Dodge/Data/LinearShockwave.hs @@ -0,0 +1,13 @@ +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE StrictData #-} +module Dodge.Data.LinearShockwave where +import Geometry.Data +import Control.Lens +data LinearShockwave = LinearShockwave + { _lwPos :: Point2 + , _lwID :: Int + , _lwPoints :: [(Point2,Point2)] + , _lwTimer :: Int + } + deriving (Eq,Ord,Show,Read) +makeLenses ''LinearShockwave diff --git a/src/Dodge/Data/Prop.hs b/src/Dodge/Data/Prop.hs new file mode 100644 index 000000000..cf3b64aea --- /dev/null +++ b/src/Dodge/Data/Prop.hs @@ -0,0 +1,65 @@ +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE StrictData #-} +module Dodge.Data.Prop + where +import Dodge.Data.WorldEffect +import Shape.Data +import Color +import qualified Linear.Quaternion as Q +import Geometry.Data +import ShapePicture.Data +import Control.Lens + +data PropDraw = PropDrawSPic SPic + | PropDrawMovingShapeCol Shape + | PropDrawMovingShape PropDraw + | PropDrawFlatTranslate PropDraw + | PropDoubleLampCover Float + | PropVerticalLampCover Float + | PropLampCover Float + | PropDrawToggle PropDraw + | PropDrawGib Float + deriving (Eq,Ord,Show,Read) +data PropUpdate -- = UpdatePropZ + = PropUpdateAnd PropUpdate PropUpdate +-- | UpdateShapeProp + | PropFallSmallBounceDamage + | PropFallSmallBounce + | PropUpdateId + | PropRotate Float + | PropSetToggleAnd WdBl PropUpdate + | PropUpdates [PropUpdate] + | PropUpdateLS Int PrWdLsLs -- Prop -> World -> LightSource -> LightSource + | PropUpdatePosition WdP2f + | PropUpdateWhen WdBl PropUpdate + | PropUpdateIf WdBl PropUpdate PropUpdate + deriving (Eq,Ord,Show,Read) +data PrWdLsLs = PrWdLsId + | PrWdLsSetPosition WdP2f Point3 + | PrWdLsSetColor Point3 + deriving (Eq,Ord,Show,Read) +data Prop + = PropZ + { _prPos :: Point2 + , _prDraw :: PropDraw + , _prUpdate :: PropUpdate + , _prStartPos :: Point2 + , _prVel :: Point2 + , _prID :: Int + , _prPosZ :: Float + , _prVelZ :: Float + , _prTimer :: Int + , _prQuat :: Q.Quaternion Float + , _prQuatSpin :: Q.Quaternion Float + , _prColor :: Color + } + | ShapeProp + { _prPos :: Point2 + , _prDraw :: PropDraw + , _prUpdate :: PropUpdate + , _prID :: Int + , _prRot :: Float + , _prToggle :: Bool + } + deriving (Eq,Ord,Show,Read) +makeLenses ''Prop diff --git a/src/Dodge/Data/TractorBeam.hs b/src/Dodge/Data/TractorBeam.hs new file mode 100644 index 000000000..4ac2cd0ea --- /dev/null +++ b/src/Dodge/Data/TractorBeam.hs @@ -0,0 +1,13 @@ +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE StrictData #-} +module Dodge.Data.TractorBeam where +import Geometry.Data +import Control.Lens +data TractorBeam = TractorBeam + { _tbPos :: Point2 + , _tbStartPos :: Point2 + , _tbVel :: Point2 + , _tbTime :: Int + } + deriving (Eq,Ord,Show,Read) +makeLenses ''TractorBeam diff --git a/src/Dodge/Data/WorldEffect.hs b/src/Dodge/Data/WorldEffect.hs index 62e2a96ff..f18841552 100644 --- a/src/Dodge/Data/WorldEffect.hs +++ b/src/Dodge/Data/WorldEffect.hs @@ -2,7 +2,6 @@ module Dodge.Data.WorldEffect where import Sound.Data import Geometry.Data import Dodge.Data.SoundOrigin - data WorldEffect = NoWorldEffect | SetTrigger Bool Int | WorldEffects [WorldEffect] @@ -21,3 +20,9 @@ data MdWdWd = MdWdId | MdSetLSCol Point3 | MdFlickerUpdate deriving (Eq,Ord,Show,Read) +data WdBl = WdTrig Int + | WdBlDoorMoving Int + deriving (Eq,Ord,Show,Read) +data WdP2f = WdP2f0 + | WdP2fDoorPosition Int + deriving (Eq,Ord,Show,Read) diff --git a/src/Dodge/Default/Prop.hs b/src/Dodge/Default/Prop.hs index 47f27ab87..050de716b 100644 --- a/src/Dodge/Default/Prop.hs +++ b/src/Dodge/Default/Prop.hs @@ -4,18 +4,9 @@ import Geometry defaultProp :: Prop defaultProp = ShapeProp { _prPos = V2 0 0 - , _prDraw = const mempty - , _pjID = 0 - , _pjUpdate = const id - , _prToggle = True - , _pjRot = 0 - } -defaultShapeProp :: Prop -defaultShapeProp = ShapeProp - { _prPos = 0 - , _pjID = 0 - , _pjRot = 0 - , _pjUpdate = const id - , _prDraw = const mempty + , _prDraw = PropDrawSPic mempty + , _prID = 0 + , _prUpdate = PropUpdateId , _prToggle = True + , _prRot = 0 } diff --git a/src/Dodge/Default/World.hs b/src/Dodge/Default/World.hs index 9584286ee..cf9b707a9 100644 --- a/src/Dodge/Default/World.hs +++ b/src/Dodge/Default/World.hs @@ -49,6 +49,8 @@ defaultWorld = World , _shockwaves = [] , _lasers = [] , _lasersToDraw = [] + , _tractorBeams = mempty + , _linearShockwaves = mempty , _walls = IM.empty , _wallDamages = IM.empty , _blocks = IM.empty diff --git a/src/Dodge/Item/Equipment/Booster.hs b/src/Dodge/Item/Equipment/Booster.hs index a576c3f9c..a37f8f0f3 100644 --- a/src/Dodge/Item/Equipment/Booster.hs +++ b/src/Dodge/Item/Equipment/Booster.hs @@ -8,9 +8,6 @@ import Dodge.Default.Weapon import Geometry import qualified IntMapHelp as IM import Picture -import ShapePicture -import ListHelp (safeHead) ---import Shape import Data.Maybe import Control.Lens @@ -60,51 +57,16 @@ addBoostShockwave -> Point2 -> World -> World -addBoostShockwave pjid p v w = w & props %~ +addBoostShockwave pjid p v w = w & linearShockwaves %~ IM.insertWith f pjid thePJ where thePJ = LinearShockwave - { _prDraw = drawBoostShockwave - , _prPos = p - , _pjID = pjid - , _pjUpdate = updateLinearShockwave - , _pjPoints = [(p,v)] - , _pjTimer = maxT + { _lwPos = p + , _lwID = pjid + , _lwPoints = [(p,v)] + , _lwTimer = maxT } - f newVal oldVal = newVal & pjPoints %~ (++ _pjPoints oldVal) - -updateLinearShockwave :: Prop -> World -> World -updateLinearShockwave pj w - | t < 1 = w & props %~ IM.delete pjid - | otherwise = w & props . ix (_pjID pj) . pjTimer -~ 1 - where - pjid = _pjID pj - t = _pjTimer pj - -drawBoostShockwave :: Prop -> SPic -drawBoostShockwave pj = (,) mempty $ setLayer BloomLayer $ setDepth 20 $ pictures $ - theArc ++ - [ lineCol $ zip (reverse lps) $ map (`withAlpha` white) [0,0.05..] - , lineCol $ zip (reverse rps) $ map (`withAlpha` white) [0,0.05..] - ] - where --- drawing half a circle here is not perfect, a slightly smaller arc would fit --- better, but this depends upon the angle formed by the following lines, which --- is not fixed (it varies with speed and angle of last turn) - theArc = maybeToList $ do - (hp,hv) <- safeHead pvs - r <- safeHead xs - return $ color (snd $ last lpairs) $ uncurryV translate hp - $ arc (argV hv - pi/2) (argV hv + pi/2) $ r * magV hv - cols = map (`withAlpha` white) [0,0.05..] - lpairs = zip (reverse lps) cols - pvs = _pjPoints pj - t = _pjTimer pj - xs = take t $ drop (20 - t) [1,1.2..] - lps = zipWith f pvs xs - rps = zipWith g pvs xs - f (p,v) x = p +.+ x *.* vNormal v - g (p,v) x = p -.- x *.* vNormal v + f newVal oldVal = newVal & lwPoints %~ (++ _lwPoints oldVal) maxT :: Int maxT = 20 diff --git a/src/Dodge/Item/Weapon/BatteryGuns.hs b/src/Dodge/Item/Weapon/BatteryGuns.hs index 6a01b3bfd..72b8d8d56 100644 --- a/src/Dodge/Item/Weapon/BatteryGuns.hs +++ b/src/Dodge/Item/Weapon/BatteryGuns.hs @@ -29,15 +29,8 @@ import Dodge.Base --import Dodge.Zone import Geometry import Picture -import ShapePicture import LensHelp ---import Dodge.RandomHelp ---import MonadHelp ---import Data.Maybe ---import Data.List (sortOn) ---import System.Random ---import Data.Tuple import qualified IntMapHelp as IM import qualified Data.Map.Strict as M --import Control.Monad.State @@ -353,8 +346,7 @@ dualRayAt bt itid w col dam phasev pos dir = basicBeamAt itid w col dam phasev p & bmType .~ bt aTractorBeam :: Item -> Creature -> World -> World ---aTractorBeam _ cr w = w & props %~ tractorBeamAt i spos outpos dir power -aTractorBeam _ cr w = w & plNew props pjID (tractorBeamAt spos outpos dir power) +aTractorBeam _ cr w = w & tractorBeams .:~ tractorBeamAt spos outpos dir power where cpos = _crPos cr spos = cpos +.+ (_crRad cr + 10) *.* unitVectorAtAngle dir @@ -363,71 +355,13 @@ aTractorBeam _ cr w = w & plNew props pjID (tractorBeamAt spos outpos dir power) outpos = fst $ collidePointWallsFilterStream (const True) cpos xpos w power = _attractionPower . _itParams $ _crInv cr IM.! crSel cr -tractorBeamAt :: Point2 -> Point2 -> Float -> Point2 -> Prop -tractorBeamAt pos outpos dir power = ProjectileTimed - { _prPos = pos - , _pjStartPos = outpos - , _pjVel = d - , _prDraw = tractorSPic - , _pjID = 0 - , _pjUpdate = updateTractor - , _pjTime = 10 +tractorBeamAt :: Point2 -> Point2 -> Float -> Point2 -> TractorBeam +tractorBeamAt pos outpos dir power = TractorBeam + { _tbPos = pos + , _tbStartPos = outpos + , _tbVel = d + , _tbTime = 10 } where d = unitVectorAtAngle dir * power -{- | -The interaction of this with objects, walls etc needs more thought. -} -updateTractor :: Prop -> World -> World -updateTractor pj w - | _pjTime pj <= 0 = w & props %~ IM.delete i - | otherwise = w - & props . ix i . pjTime -~ 1 - & creatures %~ IM.map (tractCr pullVel pos outpos) - & floorItems %~ IM.map (tractFlIt pullVel pos outpos) - where - i = _pjID pj - pullVel = _pjVel pj - pos = _prPos pj - outpos = _pjStartPos pj -tractFlIt :: Point2 -> Point2 -> Point2 -> FloorItem -> FloorItem -tractFlIt q p1 outpos it - | segOnCirc p1 outpos (_flItPos it) 10 = it & flItPos %~ tractorPullPos q p1 - | otherwise = it - -tractCr :: Point2 -> Point2 -> Point2 -> Creature -> Creature -tractCr q p1 outpos cr - | segOnCirc p1 outpos (_crPos cr) 10 = cr & crPos %~ tractorPullPos q p1 - | otherwise = cr - -tractorPullPos :: Point2 -> Point2 -> Point2 -> Point2 -tractorPullPos q p1 p = p -.- m *.* (0.3/ x' *.* q +.+ g y *.* p4) - where - x' = abs y + 1 - y = errorClosestPointOnLineParam 1 p1 p3 p - m | dist p p1 < 350 = 1 - | otherwise = (400 - dist p p1) / 50 - g x | x > 5 = (10 - x) / 250 - | x > 1 = 0.02 - | x > -1 = x * 0.02 - | x > -5 = -0.02 - | otherwise = (x - 10) / 250 - --p4 = vNormal p5 - p4 = vNormal $ squashNormalizeV q - p3 = p1 +.+ p4 - -tractorSPic :: Prop -> SPic -tractorSPic pj = (,) mempty $ setLayer BloomNoZWrite $ setDepth 20 $ color (withAlpha 0.5 col) $ polygon - [ spos -- not sure if this is anticlockwise... - , spos +.+ size *.* (d +.+ n) - , xpos +.+ size *.* n - , xpos -.- size *.* n - , spos +.+ size *.* (d -.- n) - ] - where - size = fromIntegral (_pjTime pj) - spos = _prPos pj - xpos = _pjStartPos pj - d = squashNormalizeV $ spos -.- xpos - n = vNormal d - col = mixColors 0.5 0.5 white blue diff --git a/src/Dodge/Item/Weapon/Grenade.hs b/src/Dodge/Item/Weapon/Grenade.hs index b68e57318..9f05ff17e 100644 --- a/src/Dodge/Item/Weapon/Grenade.hs +++ b/src/Dodge/Item/Weapon/Grenade.hs @@ -1,15 +1,9 @@ module Dodge.Item.Weapon.Grenade where -import Dodge.Zoning.Wall import Dodge.Data -import Dodge.Base -import Dodge.SoundLogic import Picture import Geometry import ShapePicture import Shape -import qualified IntMapHelp as IM - -import Control.Lens --grenade :: Item --grenade = Item @@ -40,27 +34,27 @@ import Control.Lens -- fuseTime = 50 -- f x = 50 / fromIntegral x -moveGrenade :: Prop -> World -> World -moveGrenade pj w - | _pjTimer pj <= 0 = w - & props %~ IM.delete pID - & _pjPayload pj (_prPos (_props w IM.! pID)) - -- this should maybe - -- be wallsAlongLine - -- or something vvv - | otherwise = case bounceBall 1 oldPos newPos 4 $ wlsNearPoint newPos w of - Nothing -> w & props . ix pID %~ normalUpdate - Just (p,v) -> w - & soundStart (Tap 0) p tapQuietS Nothing - & props . ix pID %~ ( ( prPos .~ p ) . ( pjTimer -~ 1 ) . (pjVel .~ v) ) - where - pID = _pjID pj - normalUpdate = (pjTimer -~ 1) - . (pjZ %~ (max 0 . (+ _pjVelZ pj))) - . (pjVelZ -~ 0.1) - . ( prPos .~ newPos ) - oldPos = _prPos pj - newPos = _pjVel pj +.+ oldPos +--moveGrenade :: Prop -> World -> World +--moveGrenade pj w +-- | _pjTimer pj <= 0 = w +-- & props %~ IM.delete pID +-- & _pjPayload pj (_prPos (_props w IM.! pID)) +-- -- this should maybe +-- -- be wallsAlongLine +-- -- or something vvv +-- | otherwise = case bounceBall 1 oldPos newPos 4 $ wlsNearPoint newPos w of +-- Nothing -> w & props . ix pID %~ normalUpdate +-- Just (p,v) -> w +-- & soundStart (Tap 0) p tapQuietS Nothing +-- & props . ix pID %~ ( ( prPos .~ p ) . ( pjTimer -~ 1 ) . (pjVel .~ v) ) +-- where +-- pID = _pjID pj +-- normalUpdate = (pjTimer -~ 1) +-- . (pjZ %~ (max 0 . (+ _pjVelZ pj))) +-- . (pjVelZ -~ 0.1) +-- . ( prPos .~ newPos ) +-- oldPos = _prPos pj +-- newPos = _pjVel pj +.+ oldPos grenadePic :: Int -> SPic grenadePic time = @@ -72,9 +66,9 @@ grenadePic time = ] ) -grenadeDraw :: Float -> Prop -> SPic -grenadeDraw dir prop = translateSPz (_pjZ prop) $ uncurryV translateSPf (_prPos prop) - $ rotateSP dir $ grenadePic $ _pjTimer prop +--grenadeDraw :: Float -> Prop -> SPic +--grenadeDraw dir prop = translateSPz (_pjZ prop) $ uncurryV translateSPf (_prPos prop) +-- $ rotateSP dir $ grenadePic $ _pjTimer prop --throwGrenade -- :: (Point2 -> World -> World) -- ^ Payload diff --git a/src/Dodge/LinearShockwave/Draw.hs b/src/Dodge/LinearShockwave/Draw.hs new file mode 100644 index 000000000..b7b67eeb8 --- /dev/null +++ b/src/Dodge/LinearShockwave/Draw.hs @@ -0,0 +1,34 @@ +module Dodge.LinearShockwave.Draw + where +import Geometry.Vector +import Geometry.Data +import ListHelp +import Dodge.Data.LinearShockwave +import Picture + +import Data.Maybe + +drawLinearShockwave :: LinearShockwave -> Picture +drawLinearShockwave lw = setLayer BloomLayer $ setDepth 20 $ pictures $ + theArc ++ + [ lineCol $ zip (reverse lps) $ map (`withAlpha` white) [0,0.05..] + , lineCol $ zip (reverse rps) $ map (`withAlpha` white) [0,0.05..] + ] + where +-- drawing half a circle here is not perfect, a slightly smaller arc would fit +-- better, but this depends upon the angle formed by the following lines, which +-- is not fixed (it varies with speed and angle of last turn) + theArc = maybeToList $ do + (hp,hv) <- safeHead pvs + r <- safeHead xs + return $ color (snd $ last lpairs) $ uncurryV translate hp + $ arc (argV hv - pi/2) (argV hv + pi/2) $ r * magV hv + cols = map (`withAlpha` white) [0,0.05..] + lpairs = zip (reverse lps) cols + pvs = _lwPoints lw + t = _lwTimer lw + xs = take t $ drop (20 - t) [1,1.2..] + lps = zipWith f pvs xs + rps = zipWith g pvs xs + f (p,v) x = p +.+ x *.* vNormal v + g (p,v) x = p -.- x *.* vNormal v diff --git a/src/Dodge/LinearShockwave/Update.hs b/src/Dodge/LinearShockwave/Update.hs new file mode 100644 index 000000000..da6e1fb4b --- /dev/null +++ b/src/Dodge/LinearShockwave/Update.hs @@ -0,0 +1,16 @@ +module Dodge.LinearShockwave.Update + where +import Dodge.Data +import qualified IntMapHelp as IM + +import Control.Lens + +updateLinearShockwave :: LinearShockwave -> World -> World +updateLinearShockwave lw w + | t < 1 = w & linearShockwaves %~ IM.delete lwid + | otherwise = w & linearShockwaves . ix lwid . lwTimer -~ 1 + where + lwid = _lwID lw + t = _lwTimer lw + + diff --git a/src/Dodge/Placement/Instance/LightSource.hs b/src/Dodge/Placement/Instance/LightSource.hs index 9d83f3718..04495bbe4 100644 --- a/src/Dodge/Placement/Instance/LightSource.hs +++ b/src/Dodge/Placement/Instance/LightSource.hs @@ -16,36 +16,35 @@ import ShapePicture import Control.Lens import Data.Maybe -propLSThen :: (Prop -> World -> World) - -> (Prop -> World -> LightSource -> LightSource) +propLSThen :: PropUpdate + -> PrWdLsLs --(Prop -> World -> LightSource -> LightSource) -> LightSource -> Prop -> (Placement -> Placement -> Maybe Placement) -- ^ continuation, access to ls and prop placements -> Placement propLSThen propf lsf ls prop cont = pt0 (PutLS ls) - $ \lspl -> Just $ pt0 (PutProp $ prop & pjUpdate .~ theupdate (fromJust $ _plMID lspl)) + $ \lspl -> Just $ pt0 (PutProp $ prop & prUpdate .~ PropUpdates [propf,PropUpdateLS (fromJust $ _plMID lspl) lsf]) + -- theupdate (fromJust $ _plMID lspl)) $ cont lspl where - theupdate lsid pr w = propf pr w & lightSources . ix lsid %~ lsf pr w + --theupdate lsid pr w = propf pr w & lightSources . ix lsid %~ lsf pr w -moveLSThen :: (World -> (Point2,Float)) +moveLSThen :: WdP2f --(World -> (Point2,Float)) -> Point3 -- ^ light source offset -> Shape -> (Placement -> Placement -> Maybe Placement) -> Placement -moveLSThen posf off sh = propLSThen propupdate lsupdate thels theprop +moveLSThen posf off sh = propLSThen (PropUpdatePosition posf) (PrWdLsSetPosition posf off) thels theprop where - propupdate pr w = w - & props . ix (_pjID pr) . prPos .~ fst (posf w) - & props . ix (_pjID pr) . pjRot .~ snd (posf w) - lsupdate _ w = lsParam . lsPos .~ addZ 0 (fst (posf w)) +.+.+ rotate3z (snd (posf w)) off + --lsupdate _ w = lsParam . lsPos .~ addZ 0 (fst (posf w)) +.+.+ rotate3z (snd (posf w)) off thels = defaultLS theprop = ShapeProp { _prPos = 0 - , _pjID = 0 - , _pjRot = 0 - , _pjUpdate = const id - , _prDraw = \pr -> noPic $ uncurryV translateSHf (_prPos pr) $ rotateSH (_pjRot pr) sh + , _prID = 0 + , _prRot = 0 + , _prUpdate = PropUpdateId + --, _prDraw = PropDrawSPic $ noPic $ uncurryV translateSHf (_prPos pr) $ rotateSH (_pjRot pr) sh + , _prDraw = PropDrawFlatTranslate $ PropDrawSPic $ noPic sh , _prToggle = True } diff --git a/src/Dodge/Placement/Instance/LightSource/Cover.hs b/src/Dodge/Placement/Instance/LightSource/Cover.hs index fe7b88418..31a97d40a 100644 --- a/src/Dodge/Placement/Instance/LightSource/Cover.hs +++ b/src/Dodge/Placement/Instance/LightSource/Cover.hs @@ -1,85 +1,35 @@ module Dodge.Placement.Instance.LightSource.Cover where import Dodge.Data -import Dodge.Base import Geometry.Data -import ShapePicture -import Shape -import Geometry import Dodge.Default.Prop - -import Control.Lens - lampCover :: Float -> Prop lampCover h = ShapeProp { _prPos = V2 0 0 - , _pjID = 0 - , _pjRot = 0 - , _pjUpdate = rotateProp 0.15 - , _prDraw = drawLampCover h + , _prID = 0 + , _prRot = 0 + , _prUpdate = PropRotate 0.15 + , _prDraw = PropLampCover h , _prToggle = True } -lampCoverWhen :: (World -> Bool) -> Point2 -> Float -> Prop -lampCoverWhen cond pos h = defaultShapeProp +lampCoverWhen :: WdBl -> Point2 -> Float -> Prop +lampCoverWhen cond pos h = defaultProp { _prPos = pos - , _pjUpdate = setToggle cond `dbArgChain` rotateProp 0.15 - , _prDraw = drawLampCover h + , _prUpdate = PropSetToggleAnd cond (PropRotate 0.15) + , _prDraw = PropLampCover h , _prToggle = True } doubleLampCover :: Float -> Prop -doubleLampCover h = defaultShapeProp +doubleLampCover h = defaultProp { _prPos = V2 0 0 - , _pjUpdate = rotateProp 0.15 - , _prDraw = drawDoubleLampCover h + , _prUpdate = PropRotate 0.15 + , _prDraw = PropDoubleLampCover h } -- on the current (27/9/21) version of shadow stencilling, this glitches -- slightly when the shadow rotates towards the screen verticalLampCover :: Float -> Prop -verticalLampCover h = defaultShapeProp - { _pjUpdate = rotateProp 0.15 - , _prDraw = drawVerticalLampCover h +verticalLampCover h = defaultProp + { _prUpdate = PropRotate 0.15 + , _prDraw = PropVerticalLampCover h } - -rotateProp :: Float -> Prop -> World -> World -rotateProp rotAmount pr w = w - & props . ix (_pjID pr) . pjRot +~ rotAmount - -setToggle :: (World -> Bool) -> Prop -> World -> World -setToggle cond pr w = w & props . ix (_pjID pr) . prToggle .~ cond w - -drawLampCover :: Float -> Prop -> SPic -drawLampCover h pr - | not (_prToggle pr) = mempty - | otherwise = ( translateSHz (h-2.5) . uncurryV translateSHf (_prPos pr) - $ rotateSH (_pjRot pr) $ mconcat - [ translateSHz 1 . upperPrismPoly 1 . reverse $ rectNSWE 3 2 (-1) 3 - , translateSHz 1 . upperPrismPoly 1 . reverse $ rectNSWE 3 (-1) 2 3 - , translateSHz 2 . upperPrismPoly 1 . reverse $ rectNSWE 3 2 (-1) 3 - , translateSHz 2 . upperPrismPoly 1 . reverse $ rectNSWE 3 (-1) 2 3 - , upperPrismPoly 1 [V2 2 2,V2 (-1) 2,V2 2 (-1)] - ] - , mempty - ) - -drawDoubleLampCover :: Float -> Prop -> SPic -drawDoubleLampCover h pr = - ( translateSHz (h-2.5) . uncurryV translateSHf (_prPos pr) - $ rotateSH (_pjRot pr) $ mconcat - [ upperPrismPoly 5 $ reverse $ rectNSWE 6 5 (-6) 6 - , upperPrismPoly 5 $ reverse $ rectNSWE (-5) (-6) (-6) 6 - , upperPrismPoly 1 [V2 0 (-1),V2 6 5,V2 (-6) 5] - , upperPrismPoly 1 [V2 0 1 ,V2 (-6) (-5),V2 6 (-5)] - ] - , mempty - ) - -drawVerticalLampCover :: Float -> Prop -> SPic -drawVerticalLampCover h pr = - ( translateSHz h . uncurryV translateSHf (_prPos pr) - $ rotateSHx (_pjRot pr) $ mconcat - [ - translateSHz (-3) . upperPrismPoly 1 $ reverse $ rectNSWE 2 (-2) (-5) 5 - ] - , mempty - ) diff --git a/src/Dodge/Placement/PlaceSpot.hs b/src/Dodge/Placement/PlaceSpot.hs index d502d293f..08ad9de5d 100644 --- a/src/Dodge/Placement/PlaceSpot.hs +++ b/src/Dodge/Placement/PlaceSpot.hs @@ -86,7 +86,7 @@ placeSpotID :: PlacementSpot -> PSType -> World -> (Int, World) placeSpotID ps pt w = case pt of PutTrigger cnd -> plNewID triggers cnd w PutMod mdi -> plNewUpID modifications mdID mdi w - PutProp prp -> plNewUpID props pjID (mvProp p rot prp) w + PutProp prp -> plNewUpID props prID (mvProp p rot prp) w PutButton bt -> plNewUpID buttons btID (mvButton p rot bt) w PutTerminal tm -> plNewUpID terminals tmID tm w PutFlIt itm -> plNewUpID floorItems flItID (createFlIt p rot itm) w @@ -150,7 +150,7 @@ addPane wl w l = w & plNew walls wlID (wl & wlLine .~ l) -- wlid = IM.newKey (_walls w) mvProp :: Point2 -> Float -> Prop -> Prop -mvProp p a = (pjRot +~ a) . (prPos %~ ( (p +.+) . rotateV a )) +mvProp p a = (prRot +~ a) . (prPos %~ ( (p +.+) . rotateV a )) mvButton :: Point2 -> Float -> Button -> Button mvButton p a = (btRot +~ a) . (btPos %~ ( (p +.+) . rotateV a )) diff --git a/src/Dodge/PrWdLsLs.hs b/src/Dodge/PrWdLsLs.hs new file mode 100644 index 000000000..0024f9160 --- /dev/null +++ b/src/Dodge/PrWdLsLs.hs @@ -0,0 +1,13 @@ +module Dodge.PrWdLsLs + where +import Dodge.WdP2f +import Geometry.Vector3D +import Dodge.Data +import Control.Lens + +doPrWdLsLs :: PrWdLsLs -> Prop -> World -> LightSource -> LightSource +doPrWdLsLs x = case x of + PrWdLsId -> \_ _ -> id + PrWdLsSetPosition y off -> \_ w + -> lsParam . lsPos .~ addZ 0 (fst (doWdP2f y w)) +.+.+ rotate3z (snd (doWdP2f y w)) off + PrWdLsSetColor c -> \_ _ -> lsParam . lsCol .~ c diff --git a/src/Dodge/Prop/Draw.hs b/src/Dodge/Prop/Draw.hs new file mode 100644 index 000000000..6d43fdd01 --- /dev/null +++ b/src/Dodge/Prop/Draw.hs @@ -0,0 +1,87 @@ +module Dodge.Prop.Draw + where +import Geometry.Polygon +import Geometry.Data +import Dodge.Data.Prop +import ShapePicture +import Shape +import Picture +import qualified Quaternion as Q + +drawProp' :: Prop -> SPic +drawProp' pr = drawProp (_prDraw pr) pr + +drawProp :: PropDraw -> Prop -> SPic +drawProp pd = case pd of + PropDrawSPic spic -> const spic + PropDrawMovingShape pd' -> \pr -> drawMovingShape pr (fst $ drawProp pd' pr) + PropDrawMovingShapeCol sh -> \pr -> drawMovingShapeCol pr sh + PropDoubleLampCover h -> drawDoubleLampCover h + PropVerticalLampCover h -> drawVerticalLampCover h + PropLampCover h -> drawLampCover h + PropDrawToggle pd' -> propDrawToggle pd' + PropDrawGib x -> noPic . drawGib x + PropDrawFlatTranslate x -> \pr + -> uncurryV translateSPf (_prPos pr) $ rotateSP (_prRot pr) $ drawProp x pr + +drawGib :: Float -> Prop -> Shape +drawGib x pr = flesh <> skin + where + flesh = colorSH (dark $ dark red) + . translateSHz (negate x) + $ upperPrismPoly (2*x) $ square x + skin = colorSH (_prColor pr) + . translateSH (V3 1 1 (1 - x)) + $ upperPrismPoly (2*x) $ square x + +propDrawToggle :: PropDraw -> Prop -> SPic +propDrawToggle pd pr + | not (_prToggle pr) = mempty + | otherwise = drawProp pd pr + +drawLampCover :: Float -> Prop -> SPic +drawLampCover h pr = ( translateSHz (h-2.5) . uncurryV translateSHf (_prPos pr) + $ rotateSH (_prRot pr) $ mconcat + [ translateSHz 1 . upperPrismPoly 1 . reverse $ rectNSWE 3 2 (-1) 3 + , translateSHz 1 . upperPrismPoly 1 . reverse $ rectNSWE 3 (-1) 2 3 + , translateSHz 2 . upperPrismPoly 1 . reverse $ rectNSWE 3 2 (-1) 3 + , translateSHz 2 . upperPrismPoly 1 . reverse $ rectNSWE 3 (-1) 2 3 + , upperPrismPoly 1 [V2 2 2,V2 (-1) 2,V2 2 (-1)] + ] + , mempty + ) + +drawVerticalLampCover :: Float -> Prop -> SPic +drawVerticalLampCover h pr = + ( translateSHz h . uncurryV translateSHf (_prPos pr) + $ rotateSHx (_prRot pr) $ mconcat + [ + translateSHz (-3) . upperPrismPoly 1 $ reverse $ rectNSWE 2 (-2) (-5) 5 + ] + , mempty + ) + +drawMovingShape :: Prop -> Shape -> SPic +drawMovingShape pr = noPic + . translateSHz (_prPosZ pr) + . uncurryV translateSHf (_prPos pr) + . overPosSH (Q.rotate (_prQuat pr)) + +drawMovingShapeCol :: Prop -> Shape -> SPic +drawMovingShapeCol pr = noPic + . translateSHz (_prPosZ pr) + . uncurryV translateSHf (_prPos pr) + . overPosSH (Q.rotate (_prQuat pr)) + . colorSH (_prColor pr) + +drawDoubleLampCover :: Float -> Prop -> SPic +drawDoubleLampCover h pr = + ( translateSHz (h-2.5) . uncurryV translateSHf (_prPos pr) + $ rotateSH (_prRot pr) $ mconcat + [ upperPrismPoly 5 $ reverse $ rectNSWE 6 5 (-6) 6 + , upperPrismPoly 5 $ reverse $ rectNSWE (-5) (-6) (-6) 6 + , upperPrismPoly 1 [V2 0 (-1),V2 6 5,V2 (-6) 5] + , upperPrismPoly 1 [V2 0 1 ,V2 (-6) (-5),V2 6 (-5)] + ] + , mempty + ) diff --git a/src/Dodge/Prop/Gib.hs b/src/Dodge/Prop/Gib.hs index d233dd7b2..1d2a9d7ff 100644 --- a/src/Dodge/Prop/Gib.hs +++ b/src/Dodge/Prop/Gib.hs @@ -1,16 +1,11 @@ module Dodge.Prop.Gib where -import Dodge.Prop.Moving ---import Dodge.Zone import Dodge.Base import Dodge.Data import Dodge.Damage ---import ShapePicture -import Shape import Geometry import Color import LensHelp import RandomHelp ---import Dodge.Base.NewID import qualified Quaternion as Q import Data.List (zip4) @@ -19,28 +14,18 @@ import Data.Foldable aGib :: Prop aGib = PropZ {_prPos = 0 - ,_pjStartPos = 0 - ,_pjVel = 0 - ,_prDraw = \pr -> drawMovingShape pr (drawGib 3 pr) - ,_pjID = 0 - ,_pjUpdate = fallSmallBounce - ,_pjPosZ = 10 - ,_pjVelZ = 5 - ,_pjTimer = 20 - ,_pjQuat = Q.axisAngle (V3 1 0 0) 0 - ,_pjQuatSpin = Q.axisAngle (V3 1 1 0) 0.1 - ,_pjColor = white + ,_prStartPos = 0 + ,_prVel = 0 + ,_prDraw = PropDrawMovingShape (PropDrawGib 3) + ,_prID = 0 + ,_prUpdate = PropFallSmallBounce + ,_prPosZ = 10 + ,_prVelZ = 5 + ,_prTimer = 20 + ,_prQuat = Q.axisAngle (V3 1 0 0) 0 + ,_prQuatSpin = Q.axisAngle (V3 1 1 0) 0.1 + ,_prColor = white } -drawGib :: Float -> Prop -> Shape -drawGib x pr = flesh <> skin - where - flesh = colorSH (dark $ dark red) - . translateSHz (negate x) - $ upperPrismPoly (2*x) $ square x - skin = colorSH (_pjColor pr) - . translateSH (V3 1 1 (1 - x)) - $ upperPrismPoly (2*x) $ square x - addCrGibs :: Creature -> World -> World addCrGibs cr w = case damageDirection $ _csDamage $ _crState cr of @@ -83,18 +68,18 @@ addGibsAtDir dir minh maxh col p w = foldl' (flip $ addGib4 p col) w (zip4 vels addGib4 :: Point2 -> Color -> (Point2, Float, Q.Quaternion Float, Float) -> World -> World -addGib4 p col (v,zs,q,h) = plNew props pjID (aGib & prPos .~ p +.+ (5 *.* normalizeV v) - & pjColor .~ col - & pjVel .~ v - & pjQuatSpin .~ Q.axisAngle (vNormal v `v2z` 0) (-0.1) - & pjQuat .~ q - & pjVelZ .~ zs - & pjPosZ .~ h +addGib4 p col (v,zs,q,h) = plNew props prID (aGib & prPos .~ p +.+ (5 *.* normalizeV v) + & prColor .~ col + & prVel .~ v + & prQuatSpin .~ Q.axisAngle (vNormal v `v2z` 0) (-0.1) + & prQuat .~ q + & prVelZ .~ zs + & prPosZ .~ h ) addGibAt :: Float -> Color -> Point2 -> World -> World addGibAt h col p w = w - & plNew props pjID gib + & plNew props prID gib & randGen .~ newg where (gib,newg) = runState f $ _randGen w @@ -106,16 +91,16 @@ addGibAt h col p w = w let v = s *.* dir return $ aGib & prPos .~ p - & pjColor .~ col - & pjVel .~ v - & pjQuatSpin .~ Q.axisAngle (vNormal v `v2z` 0) (-0.1) - & pjQuat .~ q - & pjVelZ .~ zs - & pjPosZ .~ h + & prColor .~ col + & prVel .~ v + & prQuatSpin .~ Q.axisAngle (vNormal v `v2z` 0) (-0.1) + & prQuat .~ q + & prVelZ .~ zs + & prPosZ .~ h addGibAtDir :: Float -> Float -> Color -> Point2 -> World -> World addGibAtDir dir h col p w = w - & plNew props pjID gib + & plNew props prID gib & randGen .~ newg where (gib,newg) = runState f $ _randGen w @@ -126,9 +111,9 @@ addGibAtDir dir h col p w = w let v = s *.* unitVectorAtAngle dir return $ aGib & prPos .~ p - & pjColor .~ col - & pjVel .~ v - & pjQuatSpin .~ Q.axisAngle (vNormal v `v2z` 0) (-0.1) - & pjQuat .~ q - & pjVelZ .~ zs - & pjPosZ .~ h + & prColor .~ col + & prVel .~ v + & prQuatSpin .~ Q.axisAngle (vNormal v `v2z` 0) (-0.1) + & prQuat .~ q + & prVelZ .~ zs + & prPosZ .~ h diff --git a/src/Dodge/Prop/Moving.hs b/src/Dodge/Prop/Moving.hs index 59f79a825..ecd81bdb3 100644 --- a/src/Dodge/Prop/Moving.hs +++ b/src/Dodge/Prop/Moving.hs @@ -1,77 +1,52 @@ module Dodge.Prop.Moving - ( drawMovingShape - , drawMovingShapeCol - , fallSmallBounceDamage + ( fallSmallBounceDamage , fallSmallBounce ) where ---import Dodge.Zone import Dodge.Base import Dodge.Data ---import Dodge.Damage -import ShapePicture -import Shape import Geometry ---import Color import LensHelp ---import RandomHelp ---import Dodge.Base.NewID - -import qualified Quaternion as Q ---import Data.List (zip4) --- fallSmallBounceDamage :: Prop -> World -> World fallSmallBounceDamage pr w = w & dodamage - & props . ix (_pjID pr) %~ fallSmallBounce' w + & props . ix (_prID pr) %~ fallSmallBounce' w where p = _prPos pr - v = _pjVel pr + v = _prVel pr dodamage - | _pjPosZ pr < 25 = creatures %~ fmap dodamage' + | _prPosZ pr < 25 = creatures %~ fmap dodamage' | otherwise = id dodamage' cr | dist (_crPos cr) p < _crRad cr + 5 = cr & crState . csDamage - .:~ Damage CRUSHING (floor . (*10) . max 0 . subtract 5 . abs $ _pjVelZ pr) (p -.- v) p (p +.+ v) NoDamageEffect + .:~ Damage CRUSHING (floor . (*10) . max 0 . subtract 5 . abs $ _prVelZ pr) (p -.- v) p (p +.+ v) NoDamageEffect | otherwise = cr fallSmallBounce :: Prop -> World -> World fallSmallBounce pr w = w - & props . ix (_pjID pr) %~ fallSmallBounce' w + & props . ix (_prID pr) %~ fallSmallBounce' w fallSmallBounce' :: World -> Prop -> Prop fallSmallBounce' w pr | newposz < 0 && velz < (-2) = pr - & pjVelZ %~ ((*0.5) . negate) + & prVelZ %~ ((*0.5) . negate) -- & pjPos +~ (0.5*.* vel) & updateWithVel (0.5 *.* vel) - & pjVel %~ (0.5 *.*) + & prVel %~ (0.5 *.*) -- & pjPos +~ (0.5*.* vel) - | newposz < 0 = pr & pjUpdate .~ const id - & pjZ .~ 0 + | newposz < 0 = pr & prUpdate .~ PropUpdateId + & prPosZ .~ 0 -- & pjQuat *~ (_pjQuatSpin pr) | otherwise = pr - & pjVelZ -~ 1 - & pjPosZ +~ velz + & prVelZ -~ 1 + & prPosZ +~ velz & updateWithVel vel - & pjQuat *~ _pjQuatSpin pr + & prQuat *~ _prQuatSpin pr where - newposz = _pjPosZ pr + velz - velz = _pjVelZ pr - vel = _pjVel pr + newposz = _prPosZ pr + velz + velz = _prVelZ pr + vel = _prVel pr pos = _prPos pr updateWithVel v = case bouncePoint (const True) 0.5 pos (pos + v) w of Nothing -> prPos +~ v - Just (p,v') -> (prPos .~ p) . (pjVel .~ v') + Just (p,v') -> (prPos .~ p) . (prVel .~ v') -drawMovingShape :: Prop -> Shape -> SPic -drawMovingShape pr = noPic - . translateSHz (_pjPosZ pr) - . uncurryV translateSHf (_prPos pr) - . overPosSH (Q.rotate (_pjQuat pr)) - -drawMovingShapeCol :: Prop -> Shape -> SPic -drawMovingShapeCol pr = noPic - . translateSHz (_pjPosZ pr) - . uncurryV translateSHf (_prPos pr) - . overPosSH (Q.rotate (_pjQuat pr)) - . colorSH (_pjColor pr) diff --git a/src/Dodge/Prop/Update.hs b/src/Dodge/Prop/Update.hs new file mode 100644 index 000000000..8fe322ea7 --- /dev/null +++ b/src/Dodge/Prop/Update.hs @@ -0,0 +1,53 @@ +module Dodge.Prop.Update + where +import Dodge.WdP2f +import Dodge.PrWdLsLs +import Dodge.WorldBool +import Dodge.Data +import Dodge.Prop.Moving + +import Data.Foldable +import Control.Lens + +updateProp :: Prop -> World -> World +updateProp pr = case _prUpdate pr of + PropFallSmallBounceDamage -> fallSmallBounceDamage pr + PropFallSmallBounce -> fallSmallBounce pr + PropUpdateId -> id + PropRotate x -> rotateProp x pr + PropSetToggleAnd wb pu -> propSetToggleAnd wb pu pr + PropUpdates pus -> doPropUpdates pr pus + PropUpdateLS lsid x -> \w -> w & lightSources . ix lsid %~ doPrWdLsLs x pr w + PropUpdatePosition x -> propUpdatePosition x pr + PropUpdateWhen t x -> propUpdateIf t x PropUpdateId pr + PropUpdateAnd x y -> doPropUpdates pr [x,y] + PropUpdateIf t x y -> propUpdateIf t x y pr + +propUpdateIf :: WdBl -> PropUpdate -> PropUpdate -> Prop -> World -> World +propUpdateIf wb x y pr w + | doWdBl wb w = updateProp (pr & prUpdate .~ x) w + | otherwise = updateProp (pr & prUpdate .~ y) w + + + +propUpdatePosition :: WdP2f -> Prop -> World -> World +propUpdatePosition x pr w = w + & props . ix (_prID pr) . prPos .~ fst (doWdP2f x w) + & props . ix (_prID pr) . prRot .~ snd (doWdP2f x w) + +doPropUpdates :: Prop -> [PropUpdate] -> World -> World +doPropUpdates pr pus w = foldl' f w pus + where + f w' pu = updateProp (pr & prUpdate .~ pu) w' + +propSetToggleAnd :: WdBl -> PropUpdate -> Prop -> World -> World +propSetToggleAnd wb pu pr = setToggle (doWdBl wb) pr . updateProp (pr & prUpdate .~ pu) + -- fugly + +setToggle :: (World -> Bool) -> Prop -> World -> World +setToggle cond pr w = w & props . ix (_prID pr) . prToggle .~ cond w + +rotateProp :: Float -> Prop -> World -> World +rotateProp rotAmount pr w = w + & props . ix (_prID pr) . prRot +~ rotAmount + diff --git a/src/Dodge/Render/ShapePicture.hs b/src/Dodge/Render/ShapePicture.hs index 98011cfb8..bc957750a 100644 --- a/src/Dodge/Render/ShapePicture.hs +++ b/src/Dodge/Render/ShapePicture.hs @@ -1,6 +1,9 @@ module Dodge.Render.ShapePicture ( worldSPic ) where +import Dodge.LinearShockwave.Draw +import Dodge.Prop.Draw +import Dodge.TractorBeam.Draw import Dodge.Shockwave.Draw import Dodge.Tesla.Arc.Draw import Dodge.Laser.Draw @@ -62,7 +65,7 @@ singleSPic = id worldSPic :: Configuration -> World -> SPic worldSPic cfig w = singleSPic (mempty, extraPics cfig w) - <> foldup (dbArg _prDraw) (filtOn _prPos _props) + <> foldup drawProp' (filtOn _prPos _props) <> foldup drawProjectile (filtOn _prjPos _projectiles) <> foldup (shiftDraw _blPos _blDir _blDraw) (filtOn _blPos _blocks) <> foldup (shiftDraw _fsPos _fsDir (const _fsSPic)) (filtOn _fsPos _foregroundShapes) @@ -129,6 +132,8 @@ cullPoint cfig w p extraPics :: Configuration -> World -> Picture extraPics cfig w = pictures (_decorations w) + <> concatMapPic drawTractorBeam (_tractorBeams w) + <> concatMapPic drawLinearShockwave (_linearShockwaves w) <> concatMapPic drawShockwave (_shockwaves w) <> concatMapPic drawLaser (_lasersToDraw w) <> concatMapPic drawTeslaArc (_teslaArcs w) diff --git a/src/Dodge/Room/LongDoor.hs b/src/Dodge/Room/LongDoor.hs index 388a6bb8f..a5a2e3e64 100644 --- a/src/Dodge/Room/LongDoor.hs +++ b/src/Dodge/Room/LongDoor.hs @@ -6,7 +6,6 @@ import Dodge.Data import Dodge.Default.Door import Dodge.Cleat import Dodge.RoomLink -import Dodge.Base import Dodge.Tree import Dodge.Default.Room import Dodge.LevelGen.Data @@ -49,7 +48,7 @@ twinSlowDoorRoom w h x = defaultRoom $ \btid -> jsps0J (PutSlideDr (thedoor btid) thewall DoorObstacle 1 (V2 x 1) (V2 x h)) $ ps0 (PutSlideDr (thedoor btid) thewall DoorObstacle 1 (V2 (-x) 1) (V2 (-x) h)) $ \did -> jps0' (PutLS (lsColPos (V3 0.75 0 0) (V3 0 (h-1) lampheight))) - $ \lspl -> jsps0 $ PutProp $ addColorChange (fromJust $ _plMID lspl) did $ lampCoverWhen (drmoving did) (V2 0 (h-1)) lampheight + $ \lspl -> jsps0 $ PutProp $ addColorChange (fromJust $ _plMID lspl) did $ lampCoverWhen (WdBlDoorMoving did) (V2 0 (h-1)) lampheight ] , _rmBound = ps , _rmName = "twinSlowDoorRoom" @@ -58,13 +57,9 @@ twinSlowDoorRoom w h x = defaultRoom where thewall = switchWallCol red wlSpeed = 0.5 - addColorChange lsid drid = over pjUpdate $ dbArgChain $ const f - where - f u | _drStatus (_doors u IM.! drid) == DoorHalfway - = u & updatelscol (V3 8 0 0) - | otherwise = u & updatelscol 0.7 - updatelscol c = lightSources . ix lsid . lsParam . lsCol .~ c - drmoving i w' = DoorHalfway == _drStatus (_doors w' IM.! i) + addColorChange lsid drid = over prUpdate $ PropUpdateAnd $ PropUpdateIf (WdBlDoorMoving drid) + (PropUpdateLS lsid (PrWdLsSetColor (V3 8 0 0))) + (PropUpdateLS lsid (PrWdLsSetColor 0.7)) lampheight = 41 ps = [rectNSWE h 0 (-w) w @@ -107,7 +102,7 @@ addButtonSlowDoor x h rm = do openDoorBound = reverse $ rectNSWE (h + 5) (h - 5) (3*x/2) (-x/2) belowH y = (sndV2 . fst) y < h - 40 aboveH y = (sndV2 . fst) y > h + 40 - amountedlight dr xoff mpl = Just . moveLSThen (getdoorpos (fromJust $ _plMID dr)) + amountedlight dr xoff mpl = Just . moveLSThen (WdP2fDoorPosition (fromJust $ _plMID dr)) (V3 15 xoff 89) (aShape (V2 15 0) (V3 15 xoff 90)) $ \plls plpr -> Just $ ptCont (PutWorldUpdate (const $ setmount dr plls plpr)) $ const mpl @@ -126,8 +121,6 @@ addButtonSlowDoor x h rm = do $ amountedlight dr2 50 $ amountedlight dr2 (-50) Nothing - getdoorpos drid w = let Just (a,b) = w ^? doors . ix drid . drPos - in (b, argV (a-.-b)) col = dim $ light red cond' btid w = w ^? buttons . ix btid . btState /= Just BtOff diff --git a/src/Dodge/TractorBeam/Draw.hs b/src/Dodge/TractorBeam/Draw.hs new file mode 100644 index 000000000..f232aad81 --- /dev/null +++ b/src/Dodge/TractorBeam/Draw.hs @@ -0,0 +1,24 @@ +module Dodge.TractorBeam.Draw + where +import Dodge.Data.TractorBeam +import Geometry +import Picture + +drawTractorBeam :: TractorBeam -> Picture +drawTractorBeam = tractorSPic + +tractorSPic :: TractorBeam -> Picture +tractorSPic pj = setLayer BloomNoZWrite $ setDepth 20 $ color (withAlpha 0.5 col) $ polygon + [ spos -- not sure if this is anticlockwise... + , spos +.+ size *.* (d +.+ n) + , xpos +.+ size *.* n + , xpos -.- size *.* n + , spos +.+ size *.* (d -.- n) + ] + where + size = fromIntegral (_tbTime pj) + spos = _tbPos pj + xpos = _tbStartPos pj + d = squashNormalizeV $ spos -.- xpos + n = vNormal d + col = mixColors 0.5 0.5 white blue diff --git a/src/Dodge/TractorBeam/Update.hs b/src/Dodge/TractorBeam/Update.hs new file mode 100644 index 000000000..9e7618ff4 --- /dev/null +++ b/src/Dodge/TractorBeam/Update.hs @@ -0,0 +1,45 @@ +module Dodge.TractorBeam.Update + where +import Geometry +import Dodge.Data +import qualified IntMapHelp as IM +import Control.Lens + +updateTractorBeam :: World -> TractorBeam -> (World, Maybe TractorBeam) +updateTractorBeam w pj + | _tbTime pj <= 0 = (w, Nothing) + | otherwise = (w + & creatures %~ IM.map (tractCr pullVel pos outpos) + & floorItems %~ IM.map (tractFlIt pullVel pos outpos) + , Just (pj & tbTime -~ 1)) + where + pullVel = _tbVel pj + pos = _tbPos pj + outpos = _tbStartPos pj + +tractFlIt :: Point2 -> Point2 -> Point2 -> FloorItem -> FloorItem +tractFlIt q p1 outpos it + | segOnCirc p1 outpos (_flItPos it) 10 = it & flItPos %~ tractorPullPos q p1 + | otherwise = it + +tractCr :: Point2 -> Point2 -> Point2 -> Creature -> Creature +tractCr q p1 outpos cr + | segOnCirc p1 outpos (_crPos cr) 10 = cr & crPos %~ tractorPullPos q p1 + | otherwise = cr + +tractorPullPos :: Point2 -> Point2 -> Point2 -> Point2 +tractorPullPos q p1 p = p -.- m *.* (0.3/ x' *.* q +.+ g y *.* p4) + where + x' = abs y + 1 + y = errorClosestPointOnLineParam 1 p1 p3 p + m | dist p p1 < 350 = 1 + | otherwise = (400 - dist p p1) / 50 + g x | x > 5 = (10 - x) / 250 + | x > 1 = 0.02 + | x > -1 = x * 0.02 + | x > -5 = -0.02 + | otherwise = (x - 10) / 250 + --p4 = vNormal p5 + p4 = vNormal $ squashNormalizeV q + p3 = p1 +.+ p4 + diff --git a/src/Dodge/Update.hs b/src/Dodge/Update.hs index e9fc5f8e1..4210655a7 100644 --- a/src/Dodge/Update.hs +++ b/src/Dodge/Update.hs @@ -4,6 +4,9 @@ Module : Dodge.Update Description : Simulation update -} module Dodge.Update ( updateUniverse ) where +import Dodge.TractorBeam.Update +import Dodge.Prop.Update +import Dodge.LinearShockwave.Update import Dodge.Shockwave.Update import Dodge.Tesla.Arc import Dodge.Laser.Update @@ -61,7 +64,7 @@ updateUniverse u = case _menuLayers u of (OptionScreen {_scOptionFlag = GameOverOptions} : _) -> u & uvWorld %~ ( updateParticles . (radarBlips .~ []) - . updateIMl _props _pjUpdate +-- . updateIMl _props _pjUpdate . updateLightSources . updateClouds ) (_ : _) -> u @@ -100,7 +103,9 @@ functionalUpdate w = checkEndGame . over uvWorld updateBeams . over uvWorld updateLasers . over uvWorld updateTeslaArcs - . over uvWorld (updateIMl _props _pjUpdate ) + . over uvWorld updateTractorBeams + . over uvWorld (updateIMl' _linearShockwaves updateLinearShockwave) + . over uvWorld (updateIMl' _props updateProp ) . over uvWorld (updateIMl' _projectiles updateProjectile) . over uvWorld updateLightSources . over uvWorld updateClouds @@ -238,6 +243,11 @@ updateTeslaArcs w = w' & teslaArcs .~ catMaybes newtas where (w',newtas) = mapAccumR moveTeslaArc w $ _teslaArcs w +updateTractorBeams :: World -> World +updateTractorBeams w = w' & tractorBeams .~ catMaybes newtas + where + (w',newtas) = mapAccumR updateTractorBeam w $ _tractorBeams w + {- Apply internal particle updates, delete 'Nothing's. -} updateBullets :: World -> World diff --git a/src/Dodge/WdP2.hs b/src/Dodge/WdP2.hs new file mode 100644 index 000000000..ea64cfff8 --- /dev/null +++ b/src/Dodge/WdP2.hs @@ -0,0 +1 @@ +module Dodge.WdP2 where diff --git a/src/Dodge/WdP2f.hs b/src/Dodge/WdP2f.hs new file mode 100644 index 000000000..dcf97361c --- /dev/null +++ b/src/Dodge/WdP2f.hs @@ -0,0 +1,12 @@ +module Dodge.WdP2f + where +import Geometry.Vector +import Dodge.Data +import Geometry.Data +import Control.Lens + +doWdP2f :: WdP2f -> World -> (Point2,Float) +doWdP2f x = case x of + WdP2f0 -> const (0,0) + WdP2fDoorPosition drid -> \w -> let Just (a,b) = w ^? doors . ix drid . drPos + in (b, argV (a-.-b)) diff --git a/src/Dodge/WorldBool.hs b/src/Dodge/WorldBool.hs new file mode 100644 index 000000000..c095d5cf5 --- /dev/null +++ b/src/Dodge/WorldBool.hs @@ -0,0 +1,12 @@ +module Dodge.WorldBool + where +import Dodge.Data +import Data.Maybe +import Control.Lens + +doWdBl :: WdBl -> World -> Bool +doWdBl wb w = case wb of + WdTrig i -> fromMaybe False $ w ^? triggers . ix i + WdBlDoorMoving i -> fromMaybe False $ do + dr <- w ^? doors . ix i + return (DoorHalfway == _drStatus dr) diff --git a/src/Shape/Data.hs b/src/Shape/Data.hs index 5f6625a78..b06c75f4c 100644 --- a/src/Shape/Data.hs +++ b/src/Shape/Data.hs @@ -32,17 +32,17 @@ data ShapeObj = ShapeObj { _shType :: ShapeType , _shVs :: [ShapeV] } - deriving () + deriving (Eq,Ord,Show,Read) newtype ShapeType = TopPrism Int - deriving (Eq,Ord,Show) + deriving (Eq,Ord,Show,Read) -- edges are given by four consecutive points data ShapeV = ShapeV {_svPos :: Point3 ,_svCol :: Point4 } - deriving (Eq,Ord,Show) + deriving (Eq,Ord,Show,Read) pairToSV :: (Point3,Point4) -> ShapeV {-# INLINE pairToSV #-} pairToSV = uncurry ShapeV