Files
loop/src/Dodge/Render/ShapePicture.hs
T
2023-05-20 15:06:05 +01:00

174 lines
5.8 KiB
Haskell

module Dodge.Render.ShapePicture (
worldSPic,
) where
import Dodge.Render.List
import Control.Lens
import Control.Monad (guard)
import Data.Foldable
import Data.Maybe
import Dodge.Base
import Dodge.Creature.Picture
import Dodge.Data.Universe
import Dodge.Debug.Picture
import Dodge.Draw
import Dodge.Flare
import Dodge.RadarBlip
import Dodge.Render.Picture
import Geometry
import qualified IntMapHelp as IM
import Picture
import Shape
import ShapePicture
worldSPic :: Configuration -> Universe -> SPic
worldSPic cfig u =
(mempty, extraPics cfig u)
<> foldup drawProp' (filtOn _prPos _props)
<> foldup drawProjectile (filtOn _prjPos _projectiles)
<> foldup (shiftDraw _blPos _blDir (drawBlock . _blDraw)) (filtOn _blPos _blocks)
<> foldup (shiftDraw _fsPos _fsDir (const _fsSPic)) (filtOn _fsPos _foregroundShapes)
<> foldup (shiftDraw' _cpPos _cpDir _cpSPic) (filtOn _cpPos _corpses)
<> foldup drawCreature (filtOn _crPos _creatures)
<> foldup floorItemSPic (filtOn _flItPos _floorItems)
<> foldup btSPic (filtOn _btPos _buttons)
<> foldup mcSPic (filtOn _mcPos _machines)
<> aimDelaySweep w
<> anyTargeting cfig w
where
w = _uvWorld u
foldup = foldMap'
filtOn f g = IM.filter (pointIsClose . f) (g (_lWorld (_cWorld w)))
pointIsClose = cullPoint cfig w
aimDelaySweep :: World -> SPic
aimDelaySweep w = fromMaybe mempty $ do
cr <- w ^? cWorld . lWorld . creatures . ix 0
aimstatus <- cr ^? crStance . posture
guard (aimstatus == Aiming)
return $ noShape $ drawSweep cr w
drawSweep :: Creature -> World -> Picture
drawSweep cr w = fromMaybe mempty $ do
a <- safeArgV (mwp -.- p)
let a'
| a - cdir > pi = cdir + 2 * pi
| a - cdir < - pi = cdir - 2 * pi
| otherwise = cdir
return $
setLayer FixedCoordLayer $
uncurryV translate (worldPosToScreen campos p) $
arcFull (a - rot) 10 white (a' - rot) 1 white (5 + dist mwp p * campos ^. camZoom) white
where
cdir = _crDir cr
rot = campos ^. camRot
p = _crPos cr
campos = w ^. wCam
theinput = w ^. input
mwp = mouseWorldPos theinput campos
anyTargeting :: Configuration -> World -> SPic
anyTargeting cfig w = fromMaybe mempty $ do
tt <- cr ^? crTargeting . ctType . _Just
return $ noShape $ drawTargeting tt cr cfig w
where
cr = you w
drawCreature :: Creature -> SPic
drawCreature cr = case _crType cr of
Humanoid{} -> basicCrPict cr
Barreloid{} ->
picAtCrPos1
( setDepth 20 $
fold
[ color orange $ circleSolid 10
, setDepth 0.049 . color (greyN 0.5) $ circleSolid 8
, color (greyN 0.5) $ circleSolid 8
]
)
cr
Lampoid{_lampHeight = h} -> uncurryV translateSPxy (_crPos cr) $ lampCrSPic h
NonDrawnCreature -> mempty
lampCrSPic :: Float -> SPic
lampCrSPic h =
( colorSH blue . upperBox Small Typical h $ rectWH 5 5
, setLayer BloomLayer (setDepth h . color white $ circleSolid 3)
)
picAtCrPos1 :: Picture -> Creature -> SPic
--{-# INLINE picAtCrPos #-}
picAtCrPos1 thePic cr = (,) mempty $ tranRot (_crPos cr) (_crDir cr) thePic
shiftDraw :: (a -> Point2) -> (a -> Float) -> (a -> a -> SPic) -> a -> SPic
shiftDraw fpos fdir fdraw x =
uncurryV translateSPxy (fpos x)
. rotateSP (fdir x)
$ fdraw x x
shiftDraw' :: (a -> Point2) -> (a -> Float) -> (a -> SPic) -> a -> SPic
shiftDraw' fpos fdir fdraw x =
uncurryV translateSPxy (fpos x)
. rotateSP (fdir x)
$ fdraw x
cullPoint :: Configuration -> World -> Point2 -> Bool
cullPoint cfig w p
| debugOn Close_shape_culling cfig = pointInPolygon p (w ^. wCam . camBoundBox)
| otherwise = dist (w ^. wCam . camCenter) p < (w ^. wCam . camViewDistance)
extraPics :: Configuration -> Universe -> Picture
extraPics cfig u =
fold (_decorations lw)
<> setLayer FixedCoordLayer (fixedCoordPictures u)
<> foldMap drawTractorBeam (_tractorBeams lw)
<> foldMap drawLinearShockwave (_linearShockwaves lw)
<> foldMap drawShockwave (_shockwaves lw)
<> foldMap drawLaser (_lasersToDraw lw)
<> foldMap drawTeslaArc (_teslaArcs lw)
<> foldMap drawRadarSweep (_radarSweeps lw)
<> foldMap drawFlame (_flames lw)
<> foldMap drawEnergyBall (_energyBalls lw)
<> foldMap drawSpark (_sparks lw)
<> foldMap drawBul (_bullets lw)
<> foldMap drawBlip (_radarBlips lw)
<> foldMap drawFlare (_flares lw)
<> foldMap (dbArg (drawBeam . _bmDraw)) (_positronBeams $ _beams lw)
<> foldMap (dbArg (drawBeam . _bmDraw)) (_electronBeams $ _beams lw)
<> foldMap (dbArg (drawLightSource . _lsPict)) (_lightSources lw)
<> testPic cfig w
<> foldMap ppDraw (_pressPlates lw)
<> viewClipBounds cfig w
<> debugDraw cfig w
<> foldMap (`_debugPic` u) (_uvDebug u)
<> setLayer FixedCoordLayer
(toTopLeft cfig . translate (1.3* halfWidth cfig) 0
. drawList
. take 50 . drop (u ^. uvDebugMessageOffset)
. map text $ foldMap (`_debugMessage` u) (_uvDebug u))
where
w = u ^. uvWorld
lw = w ^. cWorld . lWorld
testPic :: Configuration -> World -> Picture
testPic _ _ = mempty
ppDraw :: PressPlate -> Picture
ppDraw c = uncurryV translate (_ppPos c) $ rotate (_ppRot c) (_ppPict c)
floorItemSPic :: FloorItem -> SPic
floorItemSPic flit =
uncurryV translateSPxy (_flItPos flit) $
rotateSP (_flItRot flit) (itemSPic (_flIt flit))
btSPic :: Button -> SPic
btSPic bt =
uncurryV translateSPxy (_btPos bt) $
rotateSP (_btRot bt) (drawButton (_btPict bt) bt)
mcSPic :: Machine -> SPic
mcSPic mc =
uncurryV translateSPxy (_mcPos mc) $
rotateSP (_mcDir mc) (drawMachine mc)