Add concept of GameRoom, check viewing distance based on rooms
This commit is contained in:
+72
-53
@@ -14,6 +14,8 @@ import Dodge.Base.Collide
|
||||
import Dodge.Config.KeyConfig
|
||||
import Dodge.Item.Attachment.Data
|
||||
import Geometry
|
||||
import Geometry.ConvexPoly
|
||||
import Dodge.GameRoom
|
||||
|
||||
import qualified Data.List.NonEmpty as NEL
|
||||
import Control.Lens
|
||||
@@ -24,14 +26,16 @@ import qualified Data.IntMap.Strict as IM
|
||||
import qualified SDL
|
||||
import Data.Monoid
|
||||
import Data.Semigroup
|
||||
import qualified Control.Foldl as L
|
||||
{- Update the screen camera rotation and position, including any in rold scope/remote camera modifiers;
|
||||
update where your avatar's view is from. -}
|
||||
updateCamera :: World -> World
|
||||
updateCamera = rotCam . moveCamera . updateScopeZoom
|
||||
{- Updte the center of the screen camera center and where your avatar's view is from in world. -}
|
||||
moveCamera :: World -> World
|
||||
moveCamera w = w & cameraCenter .~ idealPos
|
||||
& cameraViewFrom .~ sightFrom
|
||||
moveCamera w = w
|
||||
& cameraCenter .~ idealPos
|
||||
& cameraViewFrom .~ sightFrom
|
||||
where
|
||||
aimRangeFactor
|
||||
| _cameraZoom w == 0 = 0
|
||||
@@ -40,17 +44,13 @@ moveCamera w = w & cameraCenter .~ idealPos
|
||||
| SDL.ButtonRight `S.member` _mouseButtons w = 1
|
||||
| otherwise = 0
|
||||
ypos = _crPos $ you w
|
||||
--idealOffset = rotateV (_cameraRot w) (aimRangeFactor * aimingMult *.* _mousePos w)
|
||||
--currentOffset = currentPos -.- camCenter
|
||||
idealPos = camCenter +.+ rotateV (_cameraRot w)
|
||||
(aimRangeFactor * aimingMult *.* _mousePos w)
|
||||
--currentPos = _cameraCenter w
|
||||
camCenter = ypos +.+ scope
|
||||
isCam :: Bool
|
||||
isCam = fromMaybe False $ yourItem w ^? itAttachment . _Just . scopeIsCamera
|
||||
scope = fromMaybe (V2 0 0) $ yourItem w ^? itAttachment . _Just . scopePos
|
||||
idealPos = camCenter
|
||||
+.+ rotateV (_cameraRot w) (aimRangeFactor * aimingMult *.* _mousePos w)
|
||||
camCenter = ypos +.+ scopeOffset
|
||||
scopeOffset = fromMaybe (V2 0 0) $ yourItem w ^? itAttachment . scopePos
|
||||
sightFrom
|
||||
| isCam = camCenter
|
||||
| fromMaybe False $ yourItem w ^? itAttachment . scopeIsCamera
|
||||
= camCenter
|
||||
| otherwise = ypos
|
||||
|
||||
updateScopeZoom :: World -> World
|
||||
@@ -59,49 +59,50 @@ updateScopeZoom w
|
||||
Just x
|
||||
| x > 9 -> zoomInLongGun $ zoomInLongGun
|
||||
$ w & creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0))
|
||||
. itAttachment . _Just . scopeZoomChange -~ 2
|
||||
. itAttachment . scopeZoomChange -~ 2
|
||||
| x > 0 -> zoomInLongGun
|
||||
$ w & creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0))
|
||||
. itAttachment . _Just . scopeZoomChange -~ 1
|
||||
. itAttachment . scopeZoomChange -~ 1
|
||||
| x < -9 -> zoomOutLongGun $ zoomOutLongGun
|
||||
$ w & creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0))
|
||||
. itAttachment . _Just . scopeZoomChange +~ 2
|
||||
. itAttachment . scopeZoomChange +~ 2
|
||||
| x < 0 -> zoomOutLongGun $ zoomOutLongGun
|
||||
$ w & creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0))
|
||||
. itAttachment . _Just . scopeZoomChange +~ 1
|
||||
. itAttachment . scopeZoomChange +~ 1
|
||||
| otherwise -> w
|
||||
_ -> w
|
||||
| otherwise = w & creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0))
|
||||
. itAttachment . _Just %~ updateScope
|
||||
where scppoint = creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0))
|
||||
. itAttachment . _Just . scopeZoomChange
|
||||
updateScope (ItScope _ _ _ bl) = ItScope (V2 0 0) 0 1 bl
|
||||
updateScope otherAtt = otherAtt
|
||||
. itAttachment %~ updateScope
|
||||
where
|
||||
scppoint = creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0))
|
||||
. itAttachment . scopeZoomChange
|
||||
updateScope (ItScope _ _ _ bl) = ItScope (V2 0 0) 0 1 bl
|
||||
updateScope otherAtt = otherAtt
|
||||
|
||||
zoomSpeed :: Float
|
||||
zoomSpeed = 39/40
|
||||
|
||||
zoomInLongGun :: World -> World
|
||||
zoomInLongGun w
|
||||
| currentZoom < 8 = over (wpPointer . itAttachment . _Just . scopePos)
|
||||
| currentZoom < 8 = over (wpPointer . itAttachment . scopePos)
|
||||
(\p -> p +.+ (4-(4*zoomSpeed)) / currentZoom *.* mousep)
|
||||
$ over (wpPointer . itAttachment . _Just . scopeZoom) (/ zoomSpeed)
|
||||
$ over (wpPointer . itAttachment . scopeZoom) (/ zoomSpeed)
|
||||
w
|
||||
| otherwise = w
|
||||
where
|
||||
wpPointer = creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0))
|
||||
wp = _crInv (_creatures w IM.! 0) IM.! _crInvSel (_creatures w IM.! 0)
|
||||
Just currentZoom = wp ^? itAttachment . _Just . scopeZoom
|
||||
Just currentZoom = wp ^? itAttachment . scopeZoom
|
||||
mousep = rotateV (_cameraRot w) $ _mousePos w
|
||||
|
||||
zoomOutLongGun :: World -> World
|
||||
zoomOutLongGun w
|
||||
| currentZoom > 0.5 = over (wpPointer . itAttachment . _Just . scopeZoom) (* zoomSpeed) w
|
||||
| currentZoom > 0.5 = over (wpPointer . itAttachment . scopeZoom) (* zoomSpeed) w
|
||||
| otherwise = w
|
||||
where
|
||||
wpPointer = creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0))
|
||||
wp = _crInv (_creatures w IM.! 0) IM.! _crInvSel (_creatures w IM.! 0)
|
||||
Just currentZoom = wp ^? itAttachment . _Just . scopeZoom
|
||||
Just currentZoom = wp ^? itAttachment . scopeZoom
|
||||
--currentCursorDisplacement = fromJust $ _itAttachment wp
|
||||
|
||||
rotCam :: World -> World
|
||||
@@ -115,13 +116,13 @@ rotateCameraL w
|
||||
| rotateCameraPlusKey (_keyConfig w) `S.member` _keys w
|
||||
= w & cameraRot +~ 0.015
|
||||
& creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0))
|
||||
. itAttachment . _Just . scopePos %~ rotateV 0.015
|
||||
. itAttachment . scopePos %~ rotateV 0.015
|
||||
| otherwise = w
|
||||
rotateCameraR :: World -> World
|
||||
rotateCameraR w | rotateCameraMinusKey (_keyConfig w) `S.member` _keys w
|
||||
= w & cameraRot -~ 0.015
|
||||
& creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0))
|
||||
. itAttachment . _Just . scopePos %~ rotateV (-0.015)
|
||||
. itAttachment . scopePos %~ rotateV (-0.015)
|
||||
| otherwise = w
|
||||
zoomCamIn :: World -> World
|
||||
zoomCamIn w | zoomInKey (_keyConfig w) `S.member` _keys w
|
||||
@@ -132,38 +133,64 @@ zoomCamOut w | zoomOutKey (_keyConfig w) `S.member` _keys w
|
||||
= w {_cameraZoom = max (_cameraZoom w - 0.01) 0.01}
|
||||
| otherwise = w
|
||||
|
||||
{-
|
||||
Automatically sets the zoom of the camera according to the surrounding walls.
|
||||
-}
|
||||
zoomFromItem
|
||||
:: ItZoom
|
||||
-> Float -- ^ Furthest viewable distance
|
||||
-> Float
|
||||
zoomFromItem ItZoom {_itZoomMax = zMax, _itZoomMin = zMin, _itZoomFac = zFac}
|
||||
= min zMax . max zMin . (zFac *)
|
||||
zoomNoItem
|
||||
:: Float -- ^ Furthest viewable distance
|
||||
-> Float
|
||||
zoomNoItem = min 20 . max 0.2
|
||||
{- Automatically sets the zoom of the camera according to the surrounding walls. -}
|
||||
autoZoomCam :: World -> World
|
||||
autoZoomCam w = over cameraZoom changeZoom w
|
||||
where
|
||||
camPos = _cameraViewFrom w
|
||||
wallZoom = farWallDist camPos w
|
||||
idealZoom | SDL.ButtonRight `S.member` _mouseButtons w
|
||||
= scZoom *
|
||||
min (fromMaybe 20 $ yourItem w ^? itZoom . itAimZoomMax)
|
||||
( max (fromMaybe 0.2 $ yourItem w ^? itZoom . itAimZoomMin)
|
||||
(wallZoom * fromMaybe 1 (yourItem w ^? itZoom . itAimZoomFac))
|
||||
)
|
||||
| otherwise
|
||||
= min (fromMaybe 20 $ yourItem w ^? itZoom . itZoomMax)
|
||||
$ max (fromMaybe 0.2 (yourItem w ^? itZoom . itZoomMin))
|
||||
(wallZoom * fromMaybe 1 (yourItem w ^? itZoom . itZoomFac))
|
||||
wallZoom = farWallDist' camPos w
|
||||
idealZoom
|
||||
| SDL.ButtonRight `S.member` _mouseButtons w
|
||||
= theScopeZoom * maybe zoomNoItem zoomFromItem (yourItem w ^? itAimZoom) wallZoom
|
||||
| otherwise
|
||||
= maybe zoomNoItem zoomFromItem (yourItem w ^? itZoom) wallZoom
|
||||
changeZoom curZoom
|
||||
| curZoom > idealZoom + 0.01 = ((zoomOutSpeed-1)*curZoom + idealZoom) / zoomOutSpeed
|
||||
| curZoom < idealZoom - 0.01 = ((zoomInSpeed-1)*curZoom + idealZoom) / zoomInSpeed
|
||||
| curZoom < idealZoom - 0.01 = ((zoomInSpeed -1)*curZoom + idealZoom) / zoomInSpeed
|
||||
| otherwise = idealZoom
|
||||
-- these speeds are inverted, larger means slower
|
||||
zoomInSpeed = 25
|
||||
zoomOutSpeed = 15
|
||||
scZoom = fromMaybe 1 $ yourItem w ^? itAttachment . _Just . scopeZoom
|
||||
theScopeZoom = fromMaybe 1 $ yourItem w ^? itAttachment . scopeZoom
|
||||
|
||||
farWallDist' :: Point2 -> World -> Float
|
||||
farWallDist' p w = (winFac /) $ fromMaybe 800 $ L.fold L.maximum vdists
|
||||
where
|
||||
hw = halfWidth w
|
||||
hh = halfHeight w
|
||||
winFac = min hw hh
|
||||
vdists = map (flip (collideDirectionIndirect 800 p) wos)
|
||||
vps
|
||||
vps = concatMap _grViewpoints grs
|
||||
grs = filter (pointInOrOnPolygon p . _grBound) (_gameRooms w)
|
||||
wos = wallsOnScreen w
|
||||
|
||||
|
||||
-- | Find the furthest viewable distance from a given point in the world
|
||||
farWallDist :: Point2 -> World -> Float
|
||||
--{-# INLINE farWallDist #-}
|
||||
farWallDist cpos w = getMin . uncurry (<>) $ bimap (toScale hw) (toScale hh) $ sconcat $ NEL.map distsMaybeTo viewTestValues
|
||||
farWallDist cpos w
|
||||
= getMin
|
||||
. uncurry (<>)
|
||||
$ bimap (toScale hw) (toScale hh)
|
||||
$ sconcat
|
||||
$ NEL.map distsMaybeTo viewTestValues
|
||||
where
|
||||
wos = wallsOnScreen w
|
||||
camRot = _cameraRot w
|
||||
hw = halfWidth w
|
||||
hh = halfHeight w
|
||||
toScale x = Min . (x /) . (+ 50) . maybe maxViewDistance getMax . getAp
|
||||
distsMaybeTo x = (valueAtWidth x,valueAtHeight x)
|
||||
valueAtHeight h = cpiv (cpos +.+ x) <> cpiv (cpos -.- x)
|
||||
where
|
||||
@@ -177,17 +204,9 @@ farWallDist cpos w = getMin . uncurry (<>) $ bimap (toScale hw) (toScale hh) $ s
|
||||
cpih p = Ap $ Max . verSize <$> collidePointIndirect cpos p wos
|
||||
verSize = abs . dotV rh . (-.- cpos)
|
||||
rh = rotateV camRot (V2 0 1)
|
||||
wos = wallsOnScreen w
|
||||
camRot = _cameraRot w
|
||||
hw = halfWidth w
|
||||
hh = halfHeight w
|
||||
toScale x = Min . (x /) . (+ 50) . maybe maxViewDistance getMax . getAp
|
||||
|
||||
viewTestValues :: NEL.NonEmpty Float
|
||||
viewTestValues = NEL.fromList [-maxViewDistance,negate $ 0.75*maxViewDistance..maxViewDistance]
|
||||
|
||||
maxViewDistance :: Float
|
||||
maxViewDistance = 800
|
||||
|
||||
--dirRays :: Float -> [Point2]
|
||||
--dirRays dir = take 11 $ iterate (rotateV (0.5 * pi / 10)) $ rotateV (dir-pi*0.25) (600,0)
|
||||
|
||||
Reference in New Issue
Block a user