module Blubber.Server.ViewPort where
import Data.Map (Map)
import qualified Data.Map as M
import Data.Set (Set)
import qualified Data.Set as S
import Data.Maybe
(
fromJust,
)
import Data.Serialize
(
Serialize,
)
import GHC.Generics
(
Generic,
)
import Blubber.Server.Entity
(
Entity,
mass,
position,
radius,
)
import Blubber.Server.Vector
(
Vector (Vec),
(^-^),
magVec,
vx,
vy,
)
import Blubber.Server.World
(
World,
neutrals,
clamp,
height,
neutrals,
players,
width,
)
data ViewPort = MkViewPort
{viewPos :: Vector
,viewWidth :: Double
,viewHeight :: Double
,visiblePlayers :: Map String Entity
,visibleNeutrals :: [Entity]
} deriving (Eq, Generic, Show)
instance Serialize ViewPort
mkViewPort :: World -> String -> ViewPort
mkViewPort w p =
case M.lookup p (players w) of
Just b -> MkViewPort {viewPos = position e
,viewWidth = wid
,viewHeight = hei
,visiblePlayers =
M.insert (p ++ ": " ++ show (floor (mass e))) b
. M.delete p $ getVisiblePlayers (players w)
(position e)
(radius e)
,visibleNeutrals = S.toList
$ getVisibles (neutrals w)
(position e)
(radius e)
}
Nothing -> worldViewPort w
where e = fromJust (M.lookup p (players w))
wid = radius e * 16
hei = radius e * 9
getVisiblePlayers :: Map String Entity -> Vector -> Double
-> Map String Entity
getVisiblePlayers v pos r = M.filter visibleP v
where visibleP e = magVec (dev e ^-^ Vec (c 16 vx e) (c 9 vy e)) <= radius e
dev = (^-^ pos) . position
c a d e = clamp (((r * a)) / 2) (r * a / 2) (d (dev e))
getVisibles :: Set Entity -> Vector -> Double -> Set Entity
getVisibles v pos r = S.filter visibleP v
where visibleP e = magVec (dev e ^-^ Vec (c 16 vx e) (c 9 vy e)) <= radius e
dev = (^-^ pos) . position
c a d e = clamp (((r * a)) / 2) (r * a / 2) (d (dev e))
worldViewPort :: World -> ViewPort
worldViewPort w = MkViewPort
{viewPos = Vec 0 0
,viewWidth = width w
,viewHeight = height w
,visiblePlayers = players w
,visibleNeutrals = S.elems (neutrals w)
}
viewPort :: World -> String -> ViewPort
viewPort w p = w `mkViewPort` p