Files
loop/src/Dodge/Debug.hs
T

333 lines
11 KiB
Haskell

{-# LANGUAGE LambdaCase #-}
module Dodge.Debug (debugEvents, drawDebug) where
import Dodge.Base.Coordinate
import Dodge.Zoning.Creature
import Dodge.Creature.Radius
import Geometry.Data
import Dodge.Render.Label
import Dodge.HeldUse
import Dodge.DoubleTree
import Dodge.Item.Grammar
import NewInt
import AesonHelp
import Control.Lens
import Control.Monad
import qualified Data.IntMap.Strict as IM
import qualified Data.Map.Strict as M
import Data.Maybe
import qualified Data.Set as S
import Dodge.Base.Window
import Dodge.Data.Universe
import Dodge.Debug.Picture
import Linear
import Padding
import Picture.Base
import qualified SDL
import System.Hclip
import Text.Read
import Data.List (sortOn)
debugEvents :: Universe -> Universe
debugEvents u = case dbools ^. at Display_debug of
Nothing -> u & uvDebug .~ mempty
Just () ->
S.foldr debugEvent (u & uvDebug .~ mempty) dbools
& overDebugEvent
where
dbools = u ^. uvConfig . debug_booleans
overDebugEvent :: Universe -> Universe
overDebugEvent u = fromMaybe u $ do
OverDebug db i <- u ^? uvWorld . input . mouseContext
f <- u ^? uvDebug . ix db . ix i . debugFunction
return $ f u
debugEvent :: DebugBool -> Universe -> Universe
debugEvent db u = u & uvDebug . at db .~ debugItem db u
& debugEvent' db
-- possibly don't want this running when the game is paused/not running normally
-- note this happens before functionalUpdate
debugEvent' :: DebugBool -> Universe -> Universe
debugEvent' = \case
Collision_test -> id
Circ_collision_test -> id
Show_walls_near_point_cursor -> id
Show_walls_near_segment -> id
Display_debug -> id
Noclip -> id
Remove_LOS -> id
Cull_more_lights -> id
Close_shape_culling -> id
Bound_box_screen -> id
Show_ms_frame -> id
View_gr_boundaries -> id
View_rm_boundaries -> id
Show_bound_box -> id
Show_wall_search_rays -> id
Show_dda_test -> id
Show_far_wall_detect -> id
Show_walls_near_you -> id
Show_zone_near_point_cursor -> id
Show_zone_circ -> id
Inspect_wall -> id
Cr_awareness -> id
Show_sound -> id
Cr_status -> id
Mouse_position -> id
Walls_info -> id
Pathing -> id
Show_path_between -> id
Show_writable_values -> id
Show_mouse_click_pos -> id
Debug_get -> id
Debug_put -> id
Muzzle_positions -> id
Show_cr_hitboxes -> id
Clipboard_cr -> clipboardCr
clipboardCr :: Universe -> Universe
clipboardCr u = fromMaybe u $ do
guard (u ^. uvWorld . input . mouseButtons . at SDL.ButtonLeft == Just 0)
return $ u & uvIOEffects %~ (\m u' -> setClipboard s >> m u')
where
s = unlines . prettyShort $ closestCrToMouse $ u ^. uvWorld
debugItem :: DebugBool -> Universe -> Maybe [DebugItem]
debugItem = \case
Collision_test -> mempty
Circ_collision_test -> mempty
Show_walls_near_point_cursor -> mempty
Show_walls_near_segment -> mempty
Display_debug -> mempty
Noclip -> mempty
Remove_LOS -> mempty
Cull_more_lights -> mempty
Close_shape_culling -> mempty
Bound_box_screen -> mempty
Show_ms_frame -> mempty
View_gr_boundaries -> mempty
View_rm_boundaries -> mempty
Show_bound_box -> mempty
Show_wall_search_rays -> mempty
Show_dda_test -> mempty
Show_far_wall_detect -> mempty
Show_walls_near_you -> mempty
Show_zone_near_point_cursor -> mempty
Show_zone_circ -> mempty
Inspect_wall -> mempty
Cr_awareness -> mempty
Show_sound -> mempty
Cr_status -> drawCrInfo'
Mouse_position -> mempty
Walls_info -> mempty
Pathing -> mempty
Show_path_between -> Just . return . debugShowPath
Show_writable_values -> debugWritableValues
Show_mouse_click_pos -> debugMouseClickPos
Debug_get -> doDebugGet
Debug_put -> debugPutItems
Muzzle_positions -> mempty
Show_cr_hitboxes -> mempty
Clipboard_cr -> mempty
debugGet :: Universe -> [String]
debugGet u = foldMap getPretty $ u ^. uvWorld . cWorld . lWorld . shockwaves
debugPutItems :: Universe -> Maybe [DebugItem]
debugPutItems u = Just $ f <$> [0..debugPutN]
where
f i = DebugItem (g i) (doDebugPut i) -- (uvIOEffects %~ doDebugPut i)
g i = fromMaybe "Not assigned" $ u ^? uvDebugPut . ix i
debugPutN :: Int
debugPutN = 5
doDebugPut :: Int -> Universe -> Universe
doDebugPut i u
| u ^. uvWorld . input . mouseButtons . at SDL.ButtonLeft == Just 0 = u
& uvIOEffects %~ \ f u' -> do
s <- getClipboard
f $ u' & uvDebugPut . at i ?~ s
| otherwise = u
debugPutDraw :: IM.IntMap String -> Universe -> Picture
debugPutDraw _ _ = mempty
doDebugGet :: Universe -> Maybe [DebugItem]
doDebugGet u =
Just $ f <$> debugGet u
where
f s = DebugItem s (setClip s)
debugShowPath :: Universe -> DebugItem
debugShowPath u =
DebugItem (u ^. uvDebugPathShowType . to show) f
where
f u' = fromMaybe u' $ do
guard (u ^. uvWorld . input . mouseButtons . at SDL.ButtonLeft == Just 0)
return (u' & uvDebugPathShowType %~ succB)
succB :: (Eq a, Bounded a, Enum a) => a -> a
succB x
| x == maxBound = minBound
| otherwise = succ x
debugWritableValues :: Universe -> Maybe [DebugItem]
debugWritableValues u =
Just $
mapMaybe f
[ (uvDebugV2_1, uvDebugV2_1)
, (uvDebugV2_2, uvDebugV2_2)
]
where
f (gt, st) = do
s <- u ^? gt
return $ DebugItem (show s) (applyClip st)
applyClip ::
Read b =>
((a -> Identity b) -> Universe -> Identity Universe) ->
Universe ->
Universe
applyClip l u' = fromMaybe u' $ do
guard (u' ^. uvWorld . input . mouseButtons . at SDL.ButtonLeft == Just 0)
return $ u' & uvIOEffects %~ f
where
f g u = do
s <- getClipboard
case readMaybe s of
Just x -> g (u & l .~ x)
Nothing -> g u
debugMouseClickPos :: Universe -> Maybe [DebugItem]
debugMouseClickPos u =
Just $
mapMaybe
f
[ uvWorld . input . clickPos . at SDL.ButtonLeft
, uvWorld . input . clickPos . at SDL.ButtonRight
, uvWorld . input . heldPos . at SDL.ButtonLeft
, uvWorld . input . heldPos . at SDL.ButtonRight
, uvWorld . input . clickWorldPos . at SDL.ButtonLeft
, uvWorld . input . clickWorldPos . at SDL.ButtonRight
, uvWorld . input . heldWorldPos . at SDL.ButtonLeft
, uvWorld . input . heldWorldPos . at SDL.ButtonRight
]
where
f l = do
s <- show <$> u ^. l
return $ DebugItem s (setClip s)
drawCrInfo' :: Universe -> Maybe [DebugItem]
drawCrInfo' u = case drawCrInfo u of
[] -> Nothing
xs -> Just xs
drawCrInfo :: Universe -> [DebugItem]
drawCrInfo u = foldMap f . IM.elems $ w ^. cWorld . lWorld . creatures
where
w = u ^. uvWorld
g ls x = do
rs <- show <$> x
return $ DebugItem ((rightPad 7 '.' ls ++ "...") ++ rs) (setClip rs)
f cr = fromMaybe [] $ do
guard $
pointIsOnScreen (u ^. uvConfig) (w ^. wCam) (cr ^. crPos . _xy)
&& cr ^. crID /= 0
Just $
catMaybes
[ g "crID" $ cr ^? crID
, g "crHP" $ cr ^? crHP . _HP
, g "crStrategy" $ cr ^? crActionPlan . apStrategy
, g "crPos" $ cr ^? crPos . _xy
, g "cpVigilance" $ cr ^? crPerception . cpVigilance
, g "crAction" $ cr ^? crActionPlan . apAction
-- , g "crImpulse" $ cr ^? crActionPlan . apImpulse
, g "crName" $ cr ^? crName
, g "crIntention" $ cr ^? crIntention
]
setClip :: String -> Universe -> Universe
setClip s u = fromMaybe u $ do
guard (u ^. uvWorld . input . mouseButtons . at SDL.ButtonLeft == Just 0)
return $ u & uvIOEffects %~ (\m u' -> setClipboard s >> m u')
--closestCreatureID :: Universe -> Maybe Int
--closestCreatureID u =
-- fmap (_crID . snd) . listToMaybe
-- . sortOn (Down . dist mwp . fst)
-- . crsHitRadial mwp 100
-- $ _uvWorld u
-- where
-- mwp = mouseWorldPos (u ^. uvWorld . input) (u ^. uvWorld . wCam)
drawDebug :: Universe -> DebugBool -> Picture
drawDebug u = \case
Debug_put -> debugPutDraw (u ^. uvDebugPut) u
Debug_get -> mempty
Collision_test -> drawCollisionTest $ _uvWorld u
Circ_collision_test -> drawCircCollisionTest $ _uvWorld u
Show_walls_near_point_cursor -> drawWallsNearCursor $ _uvWorld u
Show_walls_near_segment -> drawWallsNearSegment $ _uvWorld u
Display_debug -> mempty
Noclip -> mempty
Remove_LOS -> mempty
Cull_more_lights -> mempty
Close_shape_culling -> mempty
Bound_box_screen -> mempty
Show_ms_frame -> mempty
View_gr_boundaries -> viewGameRoomBoundaries $ _uvWorld u
View_rm_boundaries -> viewRoomBoundaries $ _uvWorld u
Show_bound_box -> drawBoundingBox $ _uvWorld u
Show_wall_search_rays -> drawWallSearchRays $ _uvWorld u
Show_dda_test -> drawDDATest $ _uvWorld u
Show_far_wall_detect -> drawFarWallDetect $ _uvWorld u
Show_walls_near_you -> drawWallsNearYou $ _uvWorld u
Show_zone_near_point_cursor -> drawZoneNearPointCursor $ _uvWorld u
Show_zone_circ -> drawZoneCirc $ _uvWorld u
Inspect_wall -> drawInspectWalls $ _uvWorld u
Cr_awareness -> drawCreatureDisplayTexts $ _uvWorld u
Show_sound ->
fold $
M.map (soundPic (u ^. uvConfig) (u ^. uvWorld)) $ u ^. uvWorld . playingSounds
Cr_status -> mempty
Mouse_position -> drawMousePosition $ _uvWorld u
Walls_info -> drawWlIDs $ _uvWorld u
Pathing -> drawPathing (u ^. uvConfig) (u ^. uvWorld)
Show_path_between -> drawPathBetween u
Show_writable_values -> mempty
Show_mouse_click_pos -> mempty
Muzzle_positions -> showMuzzlePositions u
Show_cr_hitboxes -> foldMap drawCreatureRad (u ^. uvWorld . cWorld . lWorld . creatures)
Clipboard_cr -> foldMap drawCreatureRad (closestCrToMouse $ u^.uvWorld)
closestCrToMouse :: World -> Maybe Creature
closestCrToMouse w = listToMaybe . sortOn (distance mwp . (^. crPos . _xy))
$ crsNearPoint mwp w
where
mwp = mouseWorldPos (w^.input) (w^.wCam)
drawCreatureRad :: Creature -> Picture
drawCreatureRad cr = setLayer DebugLayer
. translate3 (cr ^. crPos)
. color orange
$ circle (crRad (cr ^. crType))
showMuzzlePositions :: Universe -> Picture
showMuzzlePositions u = fold $ do
cr <- u ^? uvWorld . cWorld . lWorld . creatures . ix 0
invid <- u ^?uvWorld.hud . manObject . imRootSelectedItem . unNInt
--revise1 invid <- cr ^? crManipulation . manObject . imRootSelectedItem . unNInt
loc <- invIndents ((\k -> u ^?! uvWorld . cWorld . lWorld . items . ix k) <$> _crInv cr)
^? ix invid . _2
return . color red $ setLayer DebugLayer $ reduceLocDT (f cr) loc
where
f cr loc = foldMap (g . muzzlePos (u^.uvWorld) loc cr) (itemMuzzles loc)
where
g :: Point3Q -> Picture
g pq = translate3 (pq ^. _1) $ crossPic 5