234 lines
7.7 KiB
Haskell
234 lines
7.7 KiB
Haskell
module Dodge.Render.ShapePicture
|
|
( worldSPic
|
|
) where
|
|
import Dodge.ShortShow
|
|
import Dodge.CullBox
|
|
import Dodge.Config.Data
|
|
import Dodge.Render.InfoBox
|
|
import Dodge.Debug.Picture
|
|
import Dodge.Picture.SizeInvariant
|
|
import Dodge.Data
|
|
import Dodge.Base
|
|
--import Dodge.Base.Window
|
|
import Dodge.SoundLogic.LoadSound
|
|
import Dodge.Graph
|
|
import Dodge.GameRoom
|
|
import Dodge.Update.Camera
|
|
import Dodge.Item.Draw
|
|
--import Dodge.Zone
|
|
import Geometry
|
|
import ShapePicture
|
|
import Shape
|
|
import Picture
|
|
import Sound.Data
|
|
import Geometry.ConvexPoly
|
|
|
|
import qualified Data.IntMap.Strict as IM -- Lazy?
|
|
import qualified Data.Map.Strict as M
|
|
import Control.Lens
|
|
import Data.Maybe
|
|
|
|
-- TODO only filter out shapes outside the range of the furthest shown light source
|
|
worldSPic :: Configuration -> World -> SPic
|
|
worldSPic cfig w =
|
|
(extraShapes w, extraPics cfig w)
|
|
<> foldMap (dbArg _prDraw) (filtOn _prPos _props)
|
|
<> foldMap (dbArg _blDraw) (filtOn _blPos _blocks)
|
|
<> foldMap (dbArg _cpPict) (filtOn _cpPos _corpses)
|
|
<> foldMap ((($ w) . ($ cfig)) . dbArg _crPict) (filtOn _crPos _creatures)
|
|
<> foldMap floorItemSPic (filtOn _flItPos _floorItems)
|
|
<> foldMap btSPic (filtOn _btPos _buttons)
|
|
<> foldMap mcSPic (filtOn _mcPos _machines)
|
|
where
|
|
filtOn f g = IM.filter (pointIsClose . f) (g w)
|
|
--pointIsClose p = dist camCen p < _viewDistance w
|
|
pointIsClose = cullPoint w
|
|
camCen = _cameraCenter w
|
|
|
|
cullPoint :: World -> Point2 -> Bool
|
|
cullPoint w p = pointInPolygon p (_boundBox w)
|
|
|
|
extraShapes :: World -> Shape
|
|
extraShapes = _foregroundShape
|
|
|
|
-- TODO filter out pictures not in the frame
|
|
extraPics :: Configuration -> World -> Picture
|
|
extraPics cfig w = pictures (_decorations w)
|
|
<> concatMapPic (dbArg _ptDraw) (_particles w)
|
|
<> concatMapPic (dbArg _bmDraw) (_positronBeams $ _beams w)
|
|
<> concatMapPic (dbArg _bmDraw) (_electronBeams $ _beams w)
|
|
<> concatMapPic (dbArg _lsPict) (_lightSources w)
|
|
<> testPic cfig w
|
|
<> _debugPicture w
|
|
<> concatMapPic clDraw (_clouds w )
|
|
<> concatMapPic ppDraw (_pressPlates w )
|
|
<> soundPics cfig w
|
|
<> viewBoundaries cfig w
|
|
<> viewClipBounds cfig w
|
|
<> drawMousePosition cfig w
|
|
<> drawWallIDs cfig w
|
|
<> drawPathing cfig w
|
|
<> drawCrInfo cfig w
|
|
|
|
testPic :: Configuration -> World -> Picture
|
|
testPic cfig w = setLayer DebugLayer $ color green $ line $ (x:xs) ++ [x]
|
|
where
|
|
(x:xs) = cullBox cfig w
|
|
|
|
clDraw :: Cloud -> Picture
|
|
clDraw c = translate3 (_clPos c) (_clPict c c)
|
|
ppDraw :: PressPlate -> Picture
|
|
ppDraw c = uncurryV translate (_ppPos c) $ rotate (_ppRot c) (_ppPict c)
|
|
|
|
floorItemSPic :: FloorItem -> SPic
|
|
floorItemSPic flit = uncurryV translateSPf (_flItPos flit)
|
|
$ rotateSP (_flItRot flit) (itSPic (_flIt flit))
|
|
|
|
btSPic :: Button -> SPic
|
|
btSPic bt = uncurryV translateSPf (_btPos bt)
|
|
$ rotateSP (_btRot bt) (_btPict bt bt)
|
|
mcSPic :: Machine -> SPic
|
|
mcSPic bt = uncurryV translateSPf (_mcPos bt)
|
|
$ rotateSP (_mcDir bt) (_mcDraw bt bt)
|
|
|
|
soundPics :: Configuration -> World -> Picture
|
|
soundPics cfig w
|
|
| _debug_show_sound cfig = pictures $ M.map (soundPic cfig w) $ _playingSounds w
|
|
| otherwise = []
|
|
|
|
soundPic :: Configuration -> World -> Sound -> Picture
|
|
soundPic cfig w s = fixedSizePicClampArrow 50 50 thePic p cfig w
|
|
where
|
|
p = _soundPos s
|
|
thePic
|
|
= rotate (_cameraRot w)
|
|
. scale theScale theScale
|
|
. centerText
|
|
. soundToOnomato
|
|
$ _soundChunkID s
|
|
theScale = 0.15 * f (_soundVolume s * 0.0001)
|
|
f x = 1 - 0.5 * (1 - x)
|
|
|
|
drawMousePosition :: Configuration -> World -> Picture
|
|
drawMousePosition cfig w
|
|
| not $ _debug_mouse_position cfig = mempty
|
|
| otherwise
|
|
= setLayer FixedCoordLayer . winScale cfig
|
|
. uncurryV translate p
|
|
. scale 0.1 0.1
|
|
. text
|
|
$ shortPoint2 mwp
|
|
where
|
|
p = worldPosToScreen w mwp
|
|
mwp = mouseWorldPos w
|
|
|
|
drawWallIDs :: Configuration -> World -> Picture
|
|
drawWallIDs cfig w
|
|
| _debug_walls cfig = setLayer FixedCoordLayer
|
|
$ foldMap f (_walls w)
|
|
| otherwise = mempty
|
|
where
|
|
f wl
|
|
| dist (_crPos $ you w) (fst (_wlLine wl)) > 200 = mempty -- this should be improved with a better "on screen test"
|
|
| otherwise = winScale cfig
|
|
. uncurryV translate p
|
|
. scale 0.1 0.1
|
|
. text
|
|
$ show $ _wlID wl
|
|
where
|
|
p = worldPosToScreen w $ 0.5 *.* uncurry (+.+) (_wlLine wl)
|
|
|
|
drawPathing :: Configuration -> World -> Picture
|
|
drawPathing cfig w
|
|
| _debug_pathing cfig
|
|
= setLayer DebugLayer $
|
|
(color green . pictures . map (thickLine 5 . tflat2) $ graphToEdges gr)
|
|
<> concatMap dispInc (graphToIncidence gr)
|
|
| otherwise = []
|
|
where
|
|
dispInc (p,n) = setDepth 2 . uncurryV translate p . scale 0.1 0.1 $ text $ show n
|
|
gr = _pathGraph w
|
|
|
|
crDisplayInfo :: Configuration -> World -> Creature -> Maybe (Point2,[String])
|
|
crDisplayInfo cfig w cr
|
|
| _crID cr == 0 = Nothing
|
|
| crOnScreen = Just (_crPos cr, catMaybes
|
|
-- [fmap show $ ap ^? crGoal
|
|
[fmap show $ cr ^? crHP
|
|
,fmap show $ ap ^? crStrategy
|
|
,fmap show $ cr ^? crPos
|
|
,fmap show $ cr ^? crPerception . crAwakeLevel
|
|
-- ,fmap show $ cr ^? crOldPos
|
|
,fmap show $ ap ^? crAction
|
|
,fmap show $ ap ^? crImpulse
|
|
]
|
|
)
|
|
| otherwise = Nothing
|
|
where
|
|
ap = _crActionPlan cr
|
|
crOnScreen = pointOnScreen cfig w $ _crPos cr
|
|
|
|
drawCrInfo :: Configuration -> World -> Picture
|
|
drawCrInfo cfig w
|
|
| _debug_cr_status cfig = setLayer FixedCoordLayer
|
|
$ renderInfoListsAt (2*hw - 400) 0 cfig w
|
|
$ mapMaybe (crDisplayInfo cfig w) $ IM.elems $ _creatures w
|
|
| otherwise = mempty
|
|
where
|
|
hw = halfWidth cfig
|
|
|
|
viewBoundaries :: Configuration -> World -> Picture
|
|
viewBoundaries cfig w
|
|
| _debug_view_boundaries cfig
|
|
= setLayer DebugLayer $ color green (concatMap (polygonWire . _grBound) grs)
|
|
<> color yellow (concatMap (\q -> line [p,q]) $ farWallPoints p w)
|
|
| otherwise = []
|
|
where
|
|
p = _crPos $ you w
|
|
grs = filter (pointInOrOnPolygon p . _grBound) (_gameRooms w)
|
|
|
|
viewClipBounds :: Configuration -> World -> Picture
|
|
viewClipBounds cfig w
|
|
| _debug_view_clip_bounds cfig == AllRoomClipBoundaries
|
|
= setLayer DebugLayer $ color green $ concatMap (polygonWire . _cpPoints) (_roomClipping w)
|
|
| _debug_view_clip_bounds cfig == IntersectingRoomClipBoundaries
|
|
= setLayer DebugLayer $ f (_roomClipping w)
|
|
| otherwise = []
|
|
where
|
|
f (x:xs) = g x xs <> f xs
|
|
f [] = mempty
|
|
g x (y:ys) | convexPolysOverlap x y = color green (polygonWire $ _cpPoints x)
|
|
<> color yellow (polygonWire $ _cpPoints y)
|
|
<> g x ys
|
|
| otherwise = g x ys
|
|
g _ [] = mempty
|
|
|
|
--wallFloorsToDraw :: World -> [Wall]
|
|
--wallFloorsToDraw w = filter isVisible $ IM.elems $ wallsOnScreen w
|
|
-- where
|
|
-- onScreen wall = uncurry (lineOnScreen w) $ _wlLine wall
|
|
-- isVisible wl
|
|
-- | wl ^? wlDraw == Just False = False
|
|
-- | otherwise = onScreen wl
|
|
--
|
|
--lineOnScreen :: World -> Point2 -> Point2 -> Bool
|
|
--lineOnScreen w p1 p2 = pointInPolygon p1 sp
|
|
-- || pointInPolygon p2 sp
|
|
-- || any (isJust . uncurry (intersectSegSeg p1 p2)) sps
|
|
-- where
|
|
-- sp = screenPolygon w
|
|
-- sps = zip sp (tail sp ++ [head sp])
|
|
--
|
|
--drawWallFloor :: Wall -> Picture
|
|
--drawWallFloor wl = if _wlOpacity wl == SeeThrough
|
|
-- then setDepth 0.9 . color c $ polygon [x,x +.+ n2,y+.+n2, y]
|
|
-- else blank
|
|
-- where
|
|
-- (x,y) = _wlLine wl
|
|
-- c = _wlColor wl
|
|
-- n2 = 15 *.* (vNormal . errorNormalizeVDR $ y -.- x)
|
|
--
|
|
--errorNormalizeVDR :: Point2 -> Point2
|
|
--errorNormalizeVDR (V2 0 0) = error "problem with function: errorNormalizeVDR in DodgeRendering"
|
|
--errorNormalizeVDR p = normalizeV p
|