Cleanup warnings

This commit is contained in:
2021-05-17 22:39:18 +02:00
parent d7fcdbf550
commit 69f915a894
102 changed files with 1243 additions and 1185 deletions
+38 -13
View File
@@ -14,19 +14,19 @@ import Dodge.Data
import Dodge.Base.Zone import Dodge.Base.Zone
import Dodge.Base.Window import Dodge.Base.Window
import Dodge.Base.Collide import Dodge.Base.Collide
import Dodge.Config.Data --import Dodge.Config.Data
import Geometry import Geometry
import Picture import Picture
import Control.Lens import Control.Lens
import Control.Monad.State --import Control.Monad.State
import Data.List import Data.List
import Data.Function --import Data.Function
import Data.Maybe import Data.Maybe
import Data.Bifunctor --import Data.Bifunctor
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import qualified Data.IntSet as IS --import qualified Data.IntSet as IS
import qualified Data.Set as S --import qualified Data.Set as S
leftPad :: Int -> a -> [a] -> [a] leftPad :: Int -> a -> [a] -> [a]
leftPad i x xs = reverse $ take i $ reverse (take i xs) ++ repeat x leftPad i x xs = reverse $ take i $ reverse (take i xs) ++ repeat x
@@ -44,10 +44,11 @@ midPadL i x xs ys = take j (xs ++ repeat x) ++ ys
where where
j = i - length ys j = i - length ys
{- | Implementation copied from
- https://hackage.haskell.org/package/utility-ht-0.0.16/docs/src/Data.List.HT.Private.html#takeUntil
-}
takeUntil :: (a -> Bool) -> [a] -> [a] takeUntil :: (a -> Bool) -> [a] -> [a]
takeUntil f ps = case break f ps of takeUntil p = foldr (\x xs -> x : if p x then [] else xs) []
(xs,[]) -> xs
(xs, y:_ ) -> xs ++ [y]
you :: World -> Creature you :: World -> Creature
you w = _creatures w IM.! _yourID w you w = _creatures w IM.! _yourID w
@@ -63,6 +64,12 @@ crItem w cid = _crInv cr IM.! _crInvSel cr
where where
cr = _creatures w IM.! cid cr = _creatures w IM.! cid
yourItemRef
:: Applicative f
=> World
-> (Item -> f Item)
-> World
-> f World
yourItemRef w = creatures . ix (_yourID w) . crInv . ix (_crInvSel (you w)) yourItemRef w = creatures . ix (_yourID w) . crInv . ix (_crInvSel (you w))
wallNormal :: Wall -> Point2 wallNormal :: Wall -> Point2
@@ -189,7 +196,7 @@ insertNewKey x m = case IM.lookupMax m of
reflectPointCreature :: Point2 -> Point2 -> Creature -> Maybe (Point2, Point2, Int) reflectPointCreature :: Point2 -> Point2 -> Creature -> Maybe (Point2, Point2, Int)
reflectPointCreature p1 p2 cr = case collidePointCirc p1 p2 (_crRad cr) (_crPos cr) of reflectPointCreature p1 p2 cr = case collidePointCirc p1 p2 (_crRad cr) (_crPos cr) of
Nothing -> Nothing Nothing -> Nothing
Just p3 -> Just Just _ -> Just
( p1 ( p1
, errorNormalizeV 35 (ssaTriPoint p2 (_crPos cr) p1 (_crRad cr) -.- _crPos cr) , errorNormalizeV 35 (ssaTriPoint p2 (_crPos cr) p1 (_crRad cr) -.- _crPos cr)
+.+ (_crPos cr -.- _crOldPos cr) +.+ (_crPos cr -.- _crOldPos cr)
@@ -212,7 +219,7 @@ reflectCircCreature
-> Maybe (Point2, Point2, Int) -> Maybe (Point2, Point2, Int)
reflectCircCreature rad p1 p2 cr = case collidePointCirc p1 p2 (rad + _crRad cr) (_crPos cr) of reflectCircCreature rad p1 p2 cr = case collidePointCirc p1 p2 (rad + _crRad cr) (_crPos cr) of
Nothing -> Nothing Nothing -> Nothing
Just p3 -> Just Just _ -> Just
( p1 ( p1
, errorNormalizeV 37 (ssaTriPoint p2 (_crPos cr) p1 (_crRad cr) -.- _crPos cr) , errorNormalizeV 37 (ssaTriPoint p2 (_crPos cr) p1 (_crRad cr) -.- _crPos cr)
+.+ (_crPos cr -.- _crOldPos cr) +.+ (_crPos cr -.- _crOldPos cr)
@@ -234,7 +241,9 @@ reflectCircCreatures rad p1 p2 cs
f (a,_,_) = magV (a -.- p1) f (a,_,_) = magV (a -.- p1)
-- | collides a point with forcefields -- | collides a point with forcefields
-- if found, returns point of collision, deflection if required, and the id -- if found, returns point of collision, deflection if required, and the id
collidePointFFs :: a
collidePointFFs = undefined collidePointFFs = undefined
collidePointFF :: a
collidePointFF = undefined collidePointFF = undefined
-- --
--collidePointFFs :: Point2 -> Point2 -> StdGen -> IM.IntMap ForceField --collidePointFFs :: Point2 -> Point2 -> StdGen -> IM.IntMap ForceField
@@ -380,11 +389,16 @@ circOnSomeWall p rad w
. IM.elems . IM.elems
$ wallsNearPoint p w $ wallsNearPoint p w
{- | Test whether there is a creature of weight 4 or greater near a line. -} {- | Test whether there is a creature of weight 4 or greater near a line. -}
isHeavyCrNearLine :: Float -> [Point2] -> World -> Bool isHeavyCrNearLine
:: Float
-> [Point2]
-> World
-> Bool
isHeavyCrNearLine d (p1:p2:_) w isHeavyCrNearLine d (p1:p2:_) w
= any (\c -> circOnSeg p1 p2 (_crPos c) (d + _crRad c)) = any (\c -> circOnSeg p1 p2 (_crPos c) (d + _crRad c))
. IM.filter (\cr -> _crMass cr > 4) . IM.filter (\cr -> _crMass cr > 4)
$ _creatures w $ _creatures w
isHeavyCrNearLine _ _ _ = error "Testing whether creature is near empty line"
{- | Adds the distance to the creature radius, tests whether the center is in {- | Adds the distance to the creature radius, tests whether the center is in
the circle of this size centered at the point -} the circle of this size centered at the point -}
crsNearPoint :: Float -> Point2 -> World -> Bool crsNearPoint :: Float -> Point2 -> World -> Bool
@@ -505,7 +519,8 @@ isAnimate cr = case _crActionPlan cr of
Inanimate -> False Inanimate -> False
_ -> True _ -> True
sigmoid x = x/sqrt(1+x^2) sigmoid :: Floating a => a -> a
sigmoid x = x/sqrt(1+x^(2::Int))
{- | In order to force a list, apply with seq. -} {- | In order to force a list, apply with seq. -}
forceSpine :: [a] -> () forceSpine :: [a] -> ()
@@ -514,3 +529,13 @@ forceSpine = foldr (const id) ()
forceList :: [a] -> [a] forceList :: [a] -> [a]
forceList l = seq (forceSpine l) l forceList l = seq (forceSpine l) l
normalizeAnglePi :: Float -> Float
normalizeAnglePi angle
| normalizeAngle angle > pi = normalizeAngle angle - 2*pi
| otherwise = normalizeAngle angle
-- | Taken from online, splits a list into its even and odd elements
evenOddSplit :: [a] -> ([a],[a])
evenOddSplit = foldr f ([],[])
where
f a (ls,rs) = (rs, a : ls)
+3 -6
View File
@@ -103,21 +103,19 @@ hasLOSIndirect p1 p2 w = case collidePointIndirect p1 p2 $ wallsAlongLine p1 p2
Nothing -> True Nothing -> True
isWalkable :: Point2 -> Point2 -> World -> Bool isWalkable :: Point2 -> Point2 -> World -> Bool
isWalkable p1 p2 w = not $ collidePointWalkable p1 p2 nearbyWalls isWalkable p1 p2 w = not
where $ collidePointWalkable p1 p2
nearbyWalls = wallsAlongLine p1 p2 w $ wallsAlongLine p1 p2 w
canSee :: Int -> Int -> World -> Bool canSee :: Int -> Int -> World -> Bool
canSee i j w = hasLOS p1 p2 w canSee i j w = hasLOS p1 p2 w
where where
p1 = _crPos (_creatures w IM.! i) p1 = _crPos (_creatures w IM.! i)
p2 = _crPos (_creatures w IM.! j) p2 = _crPos (_creatures w IM.! j)
nearbyWalls = wallsAlongLine p1 p2 w
canSeePoint :: Int -> Point2 -> World -> Bool canSeePoint :: Int -> Point2 -> World -> Bool
canSeePoint i p w = hasLOS p1 p w canSeePoint i p w = hasLOS p1 p w
where where
nearbyWalls = wallsAlongLine p1 p w
p1 = _crPos (_creatures w IM.! i) p1 = _crPos (_creatures w IM.! i)
pathToPointFireable :: Int -> Point2 -> World -> Bool pathToPointFireable :: Int -> Point2 -> World -> Bool
@@ -133,7 +131,6 @@ canSeePointAll i targPos w
= all (flip (canSeePoint i) w . (\p -> targPos +.+ radius *.* p)) [(1,0),(0,1),(-1,0),(0,-1)] = all (flip (canSeePoint i) w . (\p -> targPos +.+ radius *.* p)) [(1,0),(0,1),(-1,0),(0,-1)]
where where
cr = _creatures w IM.! i cr = _creatures w IM.! i
cpos = _crPos cr
radius = _crRad cr radius = _crRad cr
canSeeAny :: Int -> Int -> World -> Bool canSeeAny :: Int -> Int -> World -> Bool
+2 -1
View File
@@ -10,6 +10,7 @@ screenPolygon w = [tr,tl,bl,br]
where where
scRot = rotateV (_cameraRot w) scRot = rotateV (_cameraRot w)
scZoom p | _cameraZoom w /= 0 = (1/_cameraZoom w) *.* p scZoom p | _cameraZoom w /= 0 = (1/_cameraZoom w) *.* p
| otherwise = p
scTran p = p +.+ _cameraCenter w scTran p = p +.+ _cameraCenter w
tr = scTran $ scRot $ scZoom ( halfWidth w, halfHeight w) tr = scTran $ scRot $ scZoom ( halfWidth w, halfHeight w)
tl = scTran $ scRot $ scZoom (-halfWidth w, halfHeight w) tl = scTran $ scRot $ scZoom (-halfWidth w, halfHeight w)
@@ -19,6 +20,6 @@ screenPolygon w = [tr,tl,bl,br]
halfWidth,halfHeight :: World -> Float halfWidth,halfHeight :: World -> Float
halfWidth w = getWindowX w / 2 halfWidth w = getWindowX w / 2
halfHeight w = getWindowY w / 2 halfHeight w = getWindowY w / 2
getWindowX ,getWindowY :: World -> Float
getWindowX = _windowX . _config getWindowX = _windowX . _config
getWindowY = _windowY . _config getWindowY = _windowY . _config
+2 -4
View File
@@ -14,11 +14,8 @@ module Dodge.Config.Data (
) where ) where
import Data.Aeson import Data.Aeson
import Foreign.C.Types
import GHC.Generics import GHC.Generics
import qualified GHC.Int --import System.Directory
import qualified SDL
import System.Directory
import Control.Lens import Control.Lens
data Configuration = Configuration data Configuration = Configuration
@@ -39,6 +36,7 @@ instance ToJSON Configuration where
instance FromJSON Configuration instance FromJSON Configuration
defaultConfig :: Configuration
defaultConfig = Configuration defaultConfig = Configuration
{ _volume_master = 1 { _volume_master = 1
, _volume_sound = 1 , _volume_sound = 1
+85 -82
View File
@@ -2,14 +2,13 @@
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
module Dodge.Config.KeyConfig module Dodge.Config.KeyConfig
where where
import Data.Aeson --import Data.Aeson
import Foreign.C.Types --import Foreign.C.Types
import GHC.Generics import GHC.Generics
import qualified GHC.Int --import qualified GHC.Int
import qualified SDL import qualified SDL
import qualified SDL.Internal.Numbered --import qualified SDL.Internal.Numbered
--import System.Directory
import System.Directory
data KeyConfig = KeyConfig data KeyConfig = KeyConfig
{ moveUpBinding :: Int, { moveUpBinding :: Int,
@@ -51,6 +50,7 @@ data KeyConfigSDL = KeyConfigSDL
} }
deriving (Generic, Show) deriving (Generic, Show)
defaultKeyConfigSDL :: KeyConfigSDL
defaultKeyConfigSDL = defaultKeyConfigSDL =
KeyConfigSDL KeyConfigSDL
{ moveUpKey = SDL.ScancodeW, { moveUpKey = SDL.ScancodeW,
@@ -71,82 +71,85 @@ defaultKeyConfigSDL =
newKey = SDL.ScancodeN newKey = SDL.ScancodeN
} }
instance ToJSON KeyConfig where --instance ToJSON KeyConfig where
toEncoding = genericToEncoding defaultOptions -- toEncoding = genericToEncoding defaultOptions
--
instance FromJSON KeyConfig where --instance FromJSON KeyConfig where
parseJSON = withObject "KeyConfig" $ \o -> do -- parseJSON = withObject "KeyConfig" $ \o -> do
moveUpBinding <- o .:? "moveUp" .!= 119 -- moveUpBinding <- o .:? "moveUp" .!= 119
moveDownBinding <- o .:? "moveDown" .!= 115 -- moveDownBinding <- o .:? "moveDown" .!= 115
moveLeftBinding <- o .:? "moveLeft" .!= 97 -- moveLeftBinding <- o .:? "moveLeft" .!= 97
moveRightBinding <- o .:? "moveRight" .!= 100 -- moveRightBinding <- o .:? "moveRight" .!= 100
pauseBinding <- o .:? "pause" .!= 112 -- pauseBinding <- o .:? "pause" .!= 112
escapeBinding <- o .:? "escape" .!= 27 -- escapeBinding <- o .:? "escape" .!= 27
dropItemBinding <- o .:? "dropItem" .!= 102 -- dropItemBinding <- o .:? "dropItem" .!= 102
toggleMapBinding <- o .:? "toggleMap" .!= 109 -- toggleMapBinding <- o .:? "toggleMap" .!= 109
reloadBinding <- o .:? "reload" .!= 114 -- reloadBinding <- o .:? "reload" .!= 114
testEventBinding <- o .:? "testEvent" .!= 116 -- testEventBinding <- o .:? "testEvent" .!= 116
spaceActionBinding <- o .:? "spaceAction" .!= 32 -- spaceActionBinding <- o .:? "spaceAction" .!= 32
rotateCameraPlusBinding <- o .:? "rotateCameraPlus" .!= 113 -- rotateCameraPlusBinding <- o .:? "rotateCameraPlus" .!= 113
rotateCameraMinusBinding <- o .:? "rotateCameraMinus" .!= 101 -- rotateCameraMinusBinding <- o .:? "rotateCameraMinus" .!= 101
zoomInBinding <- o .:? "zoomIn" .!= 106 -- zoomInBinding <- o .:? "zoomIn" .!= 106
zoomOutBinding <- o .:? "zoomOut" .!= 107 -- zoomOutBinding <- o .:? "zoomOut" .!= 107
newBinding <- o .:? "new" .!= 110 -- newBinding <- o .:? "new" .!= 110
return -- return
KeyConfig -- KeyConfig
{ moveUpBinding = moveUpBinding, -- { moveUpBinding = moveUpBinding,
moveDownBinding = moveDownBinding, -- moveDownBinding = moveDownBinding,
moveLeftBinding = moveLeftBinding, -- moveLeftBinding = moveLeftBinding,
moveRightBinding = moveRightBinding, -- moveRightBinding = moveRightBinding,
pauseBinding = pauseBinding, -- pauseBinding = pauseBinding,
escapeBinding = escapeBinding, -- escapeBinding = escapeBinding,
dropItemBinding = dropItemBinding, -- dropItemBinding = dropItemBinding,
toggleMapBinding = toggleMapBinding, -- toggleMapBinding = toggleMapBinding,
reloadBinding = reloadBinding, -- reloadBinding = reloadBinding,
testEventBinding = testEventBinding, -- testEventBinding = testEventBinding,
spaceActionBinding = spaceActionBinding, -- spaceActionBinding = spaceActionBinding,
rotateCameraPlusBinding = rotateCameraPlusBinding, -- rotateCameraPlusBinding = rotateCameraPlusBinding,
rotateCameraMinusBinding = rotateCameraMinusBinding, -- rotateCameraMinusBinding = rotateCameraMinusBinding,
zoomInBinding = zoomInBinding, -- zoomInBinding = zoomInBinding,
zoomOutBinding = zoomOutBinding, -- zoomOutBinding = zoomOutBinding,
newBinding = newBinding -- newBinding = newBinding
} -- }
loadKeyConfig :: IO KeyConfigSDL loadKeyConfig :: IO KeyConfigSDL
loadKeyConfig = do loadKeyConfig = return defaultKeyConfigSDL
fExists <- doesFileExist "keys.json"
if fExists
then do
mayConfig <- decodeFileStrict "keys.json"
print mayConfig
case mayConfig of
Just config ->
return
KeyConfigSDL
{ moveUpKey = getSdlScancode $ moveUpBinding config,
moveDownKey = getSdlScancode $ moveDownBinding config,
moveLeftKey = getSdlScancode $ moveLeftBinding config,
moveRightKey = getSdlScancode $ moveRightBinding config,
pauseKey = getSdlScancode $ pauseBinding config,
escapeKey = getSdlScancode $ escapeBinding config,
dropItemKey = getSdlScancode $ dropItemBinding config,
toggleMapKey = getSdlScancode $ toggleMapBinding config,
reloadKey = getSdlScancode $ reloadBinding config,
testEventKey = getSdlScancode $ testEventBinding config,
spaceActionKey = getSdlScancode $ spaceActionBinding config,
rotateCameraPlusKey = getSdlScancode $ rotateCameraPlusBinding config,
rotateCameraMinusKey = getSdlScancode $ rotateCameraMinusBinding config,
zoomInKey = getSdlScancode $ zoomInBinding config,
zoomOutKey = getSdlScancode $ zoomOutBinding config,
newKey = getSdlScancode $ newBinding config
}
Nothing -> do
putStrLn "invalid keys.json, loading default config"
-- This is duplicated but not sure how to reduce
return defaultKeyConfigSDL
else do
putStrLn "No keys.json found, loading default config"
return defaultKeyConfigSDL
getSdlScancode :: Int -> SDL.Scancode --loadKeyConfig' :: IO KeyConfigSDL
getSdlScancode x = SDL.Internal.Numbered.fromNumber (fromIntegral x) :: SDL.Scancode --loadKeyConfig' = do
-- fExists <- doesFileExist "keys.json"
-- if fExists
-- then do
-- mayConfig <- decodeFileStrict "keys.json"
-- print mayConfig
-- case mayConfig of
-- Just config ->
-- return
-- KeyConfigSDL
-- { moveUpKey = getSdlScancode $ moveUpBinding config,
-- moveDownKey = getSdlScancode $ moveDownBinding config,
-- moveLeftKey = getSdlScancode $ moveLeftBinding config,
-- moveRightKey = getSdlScancode $ moveRightBinding config,
-- pauseKey = getSdlScancode $ pauseBinding config,
-- escapeKey = getSdlScancode $ escapeBinding config,
-- dropItemKey = getSdlScancode $ dropItemBinding config,
-- toggleMapKey = getSdlScancode $ toggleMapBinding config,
-- reloadKey = getSdlScancode $ reloadBinding config,
-- testEventKey = getSdlScancode $ testEventBinding config,
-- spaceActionKey = getSdlScancode $ spaceActionBinding config,
-- rotateCameraPlusKey = getSdlScancode $ rotateCameraPlusBinding config,
-- rotateCameraMinusKey = getSdlScancode $ rotateCameraMinusBinding config,
-- zoomInKey = getSdlScancode $ zoomInBinding config,
-- zoomOutKey = getSdlScancode $ zoomOutBinding config,
-- newKey = getSdlScancode $ newBinding config
-- }
-- Nothing -> do
-- putStrLn "invalid keys.json, loading default config"
-- -- This is duplicated but not sure how to reduce
-- return defaultKeyConfigSDL
-- else do
-- putStrLn "No keys.json found, loading default config"
-- return defaultKeyConfigSDL
--
--getSdlScancode :: Int -> SDL.Scancode
--getSdlScancode x = SDL.Internal.Numbered.fromNumber (fromIntegral x) :: SDL.Scancode
+1 -2
View File
@@ -10,8 +10,7 @@ import Preload.Data
import Preload.Update import Preload.Update
import Data.Aeson (encodeFile) import Data.Aeson (encodeFile)
import Control.Monad (when) --import Control.Monad (when)
{- | {- |
Write the current world configuration to disk as a json file. Write the current world configuration to disk as a json file.
-} -}
+21 -49
View File
@@ -5,9 +5,10 @@ module Dodge.Creature
, pistolCrit , pistolCrit
, ltAutoCrit , ltAutoCrit
, spreadGunCrit , spreadGunCrit
, autoCrit
) )
where where
import Dodge.Creature.Stance.Data --import Dodge.Creature.Stance.Data
import Dodge.Creature.State.Data import Dodge.Creature.State.Data
import Dodge.Creature.ImpulseRat import Dodge.Creature.ImpulseRat
import Dodge.Creature.ActionRat import Dodge.Creature.ActionRat
@@ -18,10 +19,12 @@ import Dodge.Creature.LauncherCrit
import Dodge.Creature.PistolCrit import Dodge.Creature.PistolCrit
import Dodge.Creature.LtAutoCrit import Dodge.Creature.LtAutoCrit
import Dodge.Creature.SpreadGunCrit import Dodge.Creature.SpreadGunCrit
import Dodge.Creature.AutoCrit
import Dodge.Data import Dodge.Data
import Dodge.Default import Dodge.Default
import Dodge.Base import Dodge.Base
import Dodge.Item.Weapon import Dodge.Item.Weapon
import Dodge.Item.Equipment
import Dodge.Item.Consumable import Dodge.Item.Consumable
import Dodge.WorldEvent.Cloud import Dodge.WorldEvent.Cloud
import Dodge.Creature.YourControl import Dodge.Creature.YourControl
@@ -30,29 +33,21 @@ import Dodge.Creature.State
import Dodge.Creature.Picture import Dodge.Creature.Picture
import Dodge.Creature.Rationality import Dodge.Creature.Rationality
import Dodge.Creature.ChooseTarget import Dodge.Creature.ChooseTarget
import Dodge.Item --import Dodge.Item
import Dodge.Picture.Layer import Dodge.Picture.Layer
import Picture import Picture
import Geometry --import Geometry
import Data.List --import Data.List
import Data.Char --import Data.Char
import Data.Maybe --import Data.Maybe
import Data.Function --import Data.Function
import Data.Graph.Inductive.Graph
import Data.Graph.Inductive.PatriciaTree
import Codec.BMP
import qualified Data.ByteString as B
import Control.Lens import Control.Lens
import Control.Applicative
import Control.Monad.State import Control.Monad.State
import Control.Monad --import System.Random
import System.Random --import qualified Data.Set as S
import qualified Data.Set as S
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import qualified Data.Map as M --import qualified Data.Map as M
import Foreign.ForeignPtr
import Control.Concurrent
spawnerCrit :: Creature spawnerCrit :: Creature
spawnerCrit = defaultCreature spawnerCrit = defaultCreature
@@ -74,9 +69,12 @@ smallChaseCrit = defaultCreature
chaseCrit :: Creature chaseCrit :: Creature
chaseCrit = defaultCreature chaseCrit = defaultCreature
{ _crUpdate = stateUpdate $ impulsiveAIR $ { _crUpdate = stateUpdate $ impulsiveAIR $
chaseTargetR targetYouLOS <=< doStrategyActionsR >=>
overrideMeleeCloseTargetR <=< performActionsR >=>
basicPerceptionUpdateR [0] <=< overrideMeleeCloseTargetR >=>
chaseTargetR targetYouLOS >=>
basicPerceptionUpdateR [0] >=>
targetYouWhenCognizantR >=>
return . (crMeleeCooldown . _Just %~ (max 0 . subtract 1)) return . (crMeleeCooldown . _Just %~ (max 0 . subtract 1))
, _crHP = 300 , _crHP = 300
, _crPict = basicCrPict green , _crPict = basicCrPict green
@@ -165,33 +163,6 @@ multGunCrit = defaultCreature
, _crGoal = [] , _crGoal = []
} }
} }
autoCrit :: Creature
autoCrit = defaultCreature
{ _crPict = basicCrPict red
, _crUpdate = stateUpdate $ impulsiveAI $ composeInternalAIs
[ performActions
, watchUpdateStrat
[ (crHasTargetLOS, shootAdvanceStrat 0)
, (crAwayFromPost, goToPostStrat)
]
, basicPerceptionUpdate [0]
, doStrategyActions
, reloadOverride
, targetYouWhenCognizant
, overrideInternal (onBoth (&&) crHasTarget (crStratConMatches (GetTo (0,0))))
$ \ _ -> crActionPlan . crStrategy .~ WatchAndWait
]
, _crActionPlan = ActionPlan
{ _crImpulse = []
, _crAction = []
, _crStrategy = StrategyActions WatchAndWait [StartSentinelPost]
, _crGoal = []
}
, _crInv = IM.fromList [(0,autoGun),(1,medkit 100)]
, _crInvSel = 0
, _crRad = 10
, _crHP = 300
}
addArmour :: Creature -> Creature addArmour :: Creature -> Creature
addArmour = over crInv insarmour addArmour = over crInv insarmour
where where
@@ -215,6 +186,7 @@ startCr = defaultCreature
, _crFaction = PlayerFaction , _crFaction = PlayerFaction
} }
{- | Items you start with. -} {- | Items you start with. -}
startInventory :: IM.IntMap Item
startInventory = IM.fromList (zip [0..20] startInventory = IM.fromList (zip [0..20]
( (
[bezierGun [bezierGun
@@ -241,6 +213,6 @@ startInventory = IM.fromList (zip [0..20]
] ]
++ ++
repeat NoItem)) repeat NoItem))
smokeGenGun :: Item
smokeGenGun = effectGun "smoke" $ const spawnSmokeAtCursor smokeGenGun = effectGun "smoke" $ const spawnSmokeAtCursor
+12 -12
View File
@@ -9,25 +9,25 @@ module Dodge.Creature.Action
import Dodge.Creature.Action.UseItem import Dodge.Creature.Action.UseItem
import Dodge.Creature.Action.Movement import Dodge.Creature.Action.Movement
import Dodge.Creature.Stance.Data import Dodge.Creature.Stance.Data
import Dodge.Creature.State.Data --import Dodge.Creature.State.Data
import Dodge.WorldEvent.Shockwave import Dodge.WorldEvent.Shockwave
import Dodge.Data hiding (carriage) import Dodge.Data
import Dodge.Base import Dodge.Base
import Dodge.SoundLogic import Dodge.SoundLogic
import Dodge.WorldEvent --import Dodge.WorldEvent
import Dodge.Inventory import Dodge.Inventory
import Dodge.LightSources --import Dodge.LightSources
import Geometry import Geometry
import Picture import Picture
import Control.Lens import Control.Lens
import Control.Monad --import Control.Monad
import Control.Applicative --import Control.Applicative
import Data.Maybe import Data.Maybe
import Data.List --import Data.List
import System.Random import System.Random
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import qualified Data.Map as M --import qualified Data.Map as M
crStrafeLeft crStrafeLeft
:: Float -- ^ Speed :: Float -- ^ Speed
@@ -271,7 +271,7 @@ turnBy a n = over (creatures . ix n . crDir) (+ a)
youDropItem :: World -> World youDropItem :: World -> World
youDropItem w = case yourItem w of youDropItem w = case yourItem w of
NoItem -> w NoItem -> w
it -> rmSelectedInvItem (_yourID w) _ -> rmSelectedInvItem (_yourID w)
. copyItemToFloor (you w) (_crInvSel $ you w) . copyItemToFloor (you w) (_crInvSel $ you w)
$ soundOnce putDownSound $ soundOnce putDownSound
w w
@@ -287,9 +287,9 @@ copyItemToFloor cr i w = case _crInv cr IM.! i of
where where
(rot, g) = randomR (-pi,pi) $ _randGen w (rot, g) = randomR (-pi,pi) $ _randGen w
offset = (_crRad cr + 2) *.* unitVectorAtAngle rot offset = (_crRad cr + 2) *.* unitVectorAtAngle rot
updateLocation w = case it ^? itID of updateLocation w' = case it ^? itID of
Just (Just i) -> w & itemPositions . ix i .~ OnFloor flid Just (Just i') -> w' & itemPositions . ix i' .~ OnFloor flid
_ -> w _ -> w'
flid = newKey $ _floorItems w flid = newKey $ _floorItems w
theflit = FlIt theflit = FlIt
{_flIt = it {_flIt = it
+1 -1
View File
@@ -8,7 +8,7 @@ import Data.Maybe
retreatPointForFrom retreatPointForFrom
:: Float -> World -> Creature -> Point2 -> Maybe Point2 :: Float -> World -> Creature -> Point2 -> Maybe Point2
retreatPointForFrom d w cr p retreatPointForFrom d _ cr p
= listToMaybe = listToMaybe
. sortOn (dist cpos) . sortOn (dist cpos)
$ divideCircle 10 p d $ divideCircle 10 p d
+57 -29
View File
@@ -6,27 +6,32 @@ module Dodge.Creature.ActionRat
, shootAdvance , shootAdvance
, shootFirstMiss , shootFirstMiss
, doStrategyActions , doStrategyActions
, doStrategyActionsR
, reloadOverride , reloadOverride
, reloadOverrideR
, reloadOverrideNoHolster , reloadOverrideNoHolster
, shootAdvanceStrat , shootAdvanceStrat
, shootMoveStrat , shootMoveStrat
, watchUpdateStrat , watchUpdateStrat
, watchUpdateStratR
, goToPostStrat , goToPostStrat
, overrideInternal , overrideInternal
, overrideInternalR
, fleeTime , fleeTime
) )
where where
import Dodge.Data import Dodge.Data
import Dodge.Base import Dodge.Base
import Dodge.Base.Collide --import Dodge.Base.Collide
import Dodge.Creature.ChooseTarget --import Dodge.Creature.ChooseTarget
import Dodge.Creature.Stance.Data import Dodge.Creature.Stance.Data
import Dodge.Creature.Test import Dodge.Creature.Test
import Geometry --import Geometry
import Data.List import Data.List
import qualified Data.IntMap.Strict as IM --import qualified Data.IntMap.Strict as IM
import Control.Lens import Control.Lens
import Control.Monad.Reader
shootTargetWithStrat shootTargetWithStrat
:: (Creature -> World -> Maybe Creature) -- ^ Function for determining target :: (Creature -> World -> Maybe Creature) -- ^ Function for determining target
@@ -65,8 +70,9 @@ suppress w cr tcr as
] ]
| otherwise = as | otherwise = as
-- This should be decomposed properly
shootFirstMiss :: Int -> World -> Creature -> Strategy shootFirstMiss :: Int -> World -> Creature -> Strategy
shootFirstMiss tcid w cr = StrategyActions (ShootAt tcid) acs shootFirstMiss tcid _ _ = StrategyActions (ShootAt tcid) acs
where where
acs = acs =
[ DoActionIfElse NoAction crIsAiming (DoActionThen DrawWeapon (WaitThen 50 NoAction)) [ DoActionIfElse NoAction crIsAiming (DoActionThen DrawWeapon (WaitThen 50 NoAction))
@@ -88,7 +94,7 @@ shootFirstMiss tcid w cr = StrategyActions (ShootAt tcid) acs
advanceShoot = ImpulsesList [[UseItem, MoveForward 3]] advanceShoot = ImpulsesList [[UseItem, MoveForward 3]]
fleeTime :: Int -> World -> Creature -> Strategy fleeTime :: Int -> World -> Creature -> Strategy
fleeTime t w cr = StrategyActions Flee fleeTime t _ _ = StrategyActions Flee
[ t `DoReplicate` [ t `DoReplicate`
UseTargetCID FleeFrom UseTargetCID FleeFrom
`DoActionThen` `DoActionThen`
@@ -110,9 +116,6 @@ aimThenShootStrat tcid _ _ = StrategyActions (ShootAt tcid)
, _slowAimAngle = pi/8 , _slowAimAngle = pi/8
} }
] ]
where
lostest (w,cr') = canSee (_crID cr') tcid w
advanceShoot = ImpulsesList [[UseItem, MoveForward 3]]
shootMoveStrat :: Point2 -> Int -> World -> Creature -> Strategy shootMoveStrat :: Point2 -> Int -> World -> Creature -> Strategy
shootMoveStrat moveV tcid _ _ = StrategyActions (ShootAt tcid) shootMoveStrat moveV tcid _ _ = StrategyActions (ShootAt tcid)
@@ -165,7 +168,7 @@ goToPostStrat w cr = case find sentinelGoal $ _crGoal $ _crActionPlan cr of
] ]
_ -> WatchAndWait _ -> WatchAndWait
where where
sentinelGoal (SentinelAt p dir) = True sentinelGoal (SentinelAt _ _) = True
sentinelGoal _ = False sentinelGoal _ = False
holsterIfAiming holsterIfAiming
| crIsAiming (w,cr) = HolsterWeapon | crIsAiming (w,cr) = HolsterWeapon
@@ -181,6 +184,16 @@ overrideInternal test update w cr
| test (w,cr) = update w cr | test (w,cr) = update w cr
| otherwise = cr | otherwise = cr
overrideInternalR
:: ((World , Creature) -> Bool)
-> (World -> Creature -> Creature)
-> Creature
-> Reader World Creature
overrideInternalR test update cr = reader $ \w ->
if test (w,cr)
then update w cr
else cr
shootAdvance :: World -> Creature -> Creature -> [Action] -> [Action] shootAdvance :: World -> Creature -> Creature -> [Action] -> [Action]
shootAdvance w cr tcr as shootAdvance w cr tcr as
| lostest (w,cr) && cr ^. crStance . posture /= Aiming | lostest (w,cr) && cr ^. crStance . posture /= Aiming
@@ -205,33 +218,25 @@ shootAdvance w cr tcr as
= [ HolsterWeapon ] = [ HolsterWeapon ]
| otherwise = as | otherwise = as
where where
lostest (w,cr') = canSee (_crID cr) (_crID tcr) w lostest (w',cr') = canSee (_crID cr') (_crID tcr) w'
advanceShoot = ImpulsesList [[UseItem, MoveForward 3]] advanceShoot = ImpulsesList [[UseItem, MoveForward 3]]
applyNewStrategies
:: World
-> Creature
-> Creature
applyNewStrategies w cr = case cr ^? crActionPlan . crStrategy of
Just (StrategyActions strat acs) -> cr & crActionPlan . crAction .~ acs
& crActionPlan . crStrategy .~ strat
_ -> cr
doStrategyActions doStrategyActions
:: World :: World
-> Creature -> Creature
-> Creature -> Creature
doStrategyActions w cr = case cr ^? crActionPlan . crStrategy of doStrategyActions _ cr = case cr ^? crActionPlan . crStrategy of
Just (StrategyActions strat acs) -> cr & crActionPlan . crAction .~ acs Just (StrategyActions strat acs) -> cr & crActionPlan . crAction .~ acs
& crActionPlan . crStrategy .~ strat & crActionPlan . crStrategy .~ strat
_ -> cr _ -> cr
updateShoot doStrategyActionsR
:: World :: Creature
-> Creature -> Reader World Creature
-> Creature doStrategyActionsR cr = return $ case cr ^? crActionPlan . crStrategy of
updateShoot w cr = case _crStrategy $ _crActionPlan cr of Just (StrategyActions strat acs) -> cr & crActionPlan . crAction .~ acs
WatchAndWait -> undefined & crActionPlan . crStrategy .~ strat
_ -> cr
reloadOverride reloadOverride
:: World :: World
@@ -245,7 +250,21 @@ reloadOverride _ cr
where where
reloadActions = reloadActions =
[ HolsterWeapon [ HolsterWeapon
, WaitThen 1 $ DoActionWhileThen NoAction crIsReloading (DoImpulses [ChangeStrategy WatchAndWait]) , WaitThen 1 $ DoActionWhileInterrupt NoAction crIsReloading (DoImpulses [ChangeStrategy WatchAndWait])
]
reloadOverrideR
:: Creature
-> Reader World Creature
reloadOverrideR cr
| cr ^? crInv . ix (_crInvSel cr) . wpLoadedAmmo == Just 0
&& cr ^. crStance . posture == Aiming
= return $ cr & crActionPlan . crStrategy .~ StrategyActions Reload reloadActions
| otherwise = return $ cr
where
reloadActions =
[ HolsterWeapon
, WaitThen 1 $ DoActionWhileInterrupt NoAction crIsReloading (DoImpulses [ChangeStrategy WatchAndWait])
] ]
reloadOverrideNoHolster reloadOverrideNoHolster
@@ -259,7 +278,7 @@ reloadOverrideNoHolster _ cr
| otherwise = cr | otherwise = cr
where where
reloadActions = reloadActions =
[ DoActionWhileThen NoAction crIsReloading (DoImpulses [ChangeStrategy WatchAndWait]) [ DoActionWhileInterrupt NoAction crIsReloading (DoImpulses [ChangeStrategy WatchAndWait])
] ]
watchUpdateStrat watchUpdateStrat
@@ -272,6 +291,15 @@ watchUpdateStrat fs w cr = case cr ^? crActionPlan . crStrategy of
& crActionPlan . crStrategy .~ listGuard (fs, \_ _ -> WatchAndWait) (w, cr) w cr & crActionPlan . crStrategy .~ listGuard (fs, \_ _ -> WatchAndWait) (w, cr) w cr
_ -> cr _ -> cr
watchUpdateStratR
:: [ ((World, Creature) -> Bool, World -> Creature -> Strategy) ]
-> Creature
-> Reader World Creature
watchUpdateStratR fs cr = reader $ \w -> case cr ^? crActionPlan . crStrategy of
Just WatchAndWait -> cr
& crActionPlan . crStrategy .~ listGuard (fs, \_ _ -> WatchAndWait) (w, cr) w cr
_ -> cr
listGuard :: ([(a -> Bool, b)] , b) -> a -> b listGuard :: ([(a -> Bool, b)] , b) -> a -> b
listGuard ( (test,y):ps, z ) x listGuard ( (test,y):ps, z ) x
| test x = y | test x = y
+52
View File
@@ -0,0 +1,52 @@
module Dodge.Creature.AutoCrit
( autoCrit
) where
import Dodge.Data
import Dodge.Default
import Dodge.Creature.Picture
import Dodge.Creature.Test
import Dodge.Creature.ActionRat
--import Dodge.Creature.ChooseTarget
import Dodge.Creature.SetTarget
import Dodge.Creature.Rationality
import Dodge.Creature.AlertLevel
import Dodge.Creature.State
--import Dodge.Creature.State.Data
import Dodge.Item.Weapon
import Dodge.Item.Consumable
--import Geometry
import Picture
--import Dodge.RandomHelp
--import Data.Maybe
import qualified Data.IntMap.Strict as IM
import Control.Lens
import Control.Monad
--import System.Random
autoCrit :: Creature
autoCrit = defaultCreature
{ _crPict = basicCrPict red
, _crUpdate = stateUpdate $ impulsiveAIR $
performActionsR
>=> watchUpdateStratR
[ (crHasTargetLOS, shootAdvanceStrat 0)
, (crAwayFromPost, goToPostStrat)
]
>=> basicPerceptionUpdateR [0]
>=> doStrategyActionsR
>=> reloadOverrideR
>=> targetYouWhenCognizantR
>=> (overrideInternalR (onBoth (&&) crHasTarget (crStratConMatches (GetTo (0,0))))
$ \ _ -> crActionPlan . crStrategy .~ WatchAndWait)
, _crActionPlan = ActionPlan
{ _crImpulse = []
, _crAction = []
, _crStrategy = StrategyActions WatchAndWait [StartSentinelPost]
, _crGoal = []
}
, _crInv = IM.fromList [(0,autoGun),(1,medkit 100)]
, _crInvSel = 0
, _crRad = 10
, _crHP = 300
}
+16 -12
View File
@@ -2,7 +2,7 @@ module Dodge.Creature.ImpulseRat
where where
import Dodge.Data import Dodge.Data
import Dodge.Base import Dodge.Base
import Dodge.Creature.ChooseTarget --import Dodge.Creature.ChooseTarget
import Dodge.Creature.State.Data import Dodge.Creature.State.Data
import Geometry import Geometry
@@ -120,15 +120,14 @@ chaseTargetR targFunc cr = reader $ \w -> case targFunc cr w of
Nothing -> cr Nothing -> cr
Just crTarg -> cr & crActionPlan . crImpulse .~ chaseTarg cr crTarg Just crTarg -> cr & crActionPlan . crImpulse .~ chaseTarg cr crTarg
overrideMeleeCloseTarget :: World -> Creature -> Creature overrideMeleeCloseTarget :: World -> Creature -> Creature
overrideMeleeCloseTarget w cr = case _crTarget cr of overrideMeleeCloseTarget _ cr = case _crTarget cr of
Nothing -> cr Nothing -> cr
Just tcr Just tcr
| _crMeleeCooldown cr == Just 0 | _crMeleeCooldown cr == Just 0
&& dist (_crPos tcr) cpos < _crRad cr + _crRad tcr + 5 && dist (_crPos tcr) cpos < _crRad cr + _crRad tcr + 5
&& abs (_crDir cr - argV (_crPos tcr -.- cpos)) < pi/4 && abs (_crDir cr - argV (_crPos tcr -.- cpos)) < pi/4
-> cr & crActionPlan . crStrategy .~ StrategyActions MeleeStrike [DoImpulses [Melee (_crID tcr)]] -> cr & crActionPlan . crAction .~ [DoImpulses [Melee (_crID tcr)]]
| otherwise -> cr | otherwise -> cr
where where
cpos = _crPos cr cpos = _crPos cr
@@ -136,16 +135,21 @@ overrideMeleeCloseTarget w cr = case _crTarget cr of
overrideMeleeCloseTargetR overrideMeleeCloseTargetR
:: Creature :: Creature
-> Reader World Creature -> Reader World Creature
overrideMeleeCloseTargetR cr = reader $ \w -> case _crTarget cr of overrideMeleeCloseTargetR cr = return $ maybe cr (tryMeleeAttack cr) (_crTarget cr)
Nothing -> cr
Just tcr tryMeleeAttack :: Creature -> Creature -> Creature
| _crMeleeCooldown cr == Just 0 tryMeleeAttack cr tcr
&& dist (_crPos tcr) cpos < _crRad cr + _crRad tcr + 5 | _crMeleeCooldown cr == Just 0
&& abs (_crDir cr - argV (_crPos tcr -.- cpos)) < pi/4 && dist (_crPos tcr) cpos < _crRad cr + _crRad tcr + 5
-> cr & crActionPlan . crStrategy .~ StrategyActions MeleeStrike [DoImpulses [Melee (_crID tcr)]] && abs (_crDir cr - argV (_crPos tcr -.- cpos)) < pi/4
| otherwise -> cr = cr & crActionPlan . crStrategy .~ StrategyActions MeleeStrike meleeActions
| otherwise = cr
where where
cpos = _crPos cr cpos = _crPos cr
meleeActions =
[DoImpulses [Melee (_crID tcr)]
`DoActionThen` DoImpulses [ChangeStrategy WatchAndWait]
]
chaseTarg' :: Point2 -> Creature -> Creature -> [Impulse] chaseTarg' :: Point2 -> Creature -> Creature -> [Impulse]
chaseTarg' p cr crT chaseTarg' p cr crT
+2 -1
View File
@@ -4,7 +4,7 @@ Inanimate objects such as lamps, barrels, etc
module Dodge.Creature.Inanimate module Dodge.Creature.Inanimate
where where
import Dodge.Data import Dodge.Data
import Dodge.Creature.Stance.Data --import Dodge.Creature.Stance.Data
import Dodge.Creature.State.Data import Dodge.Creature.State.Data
import Dodge.Base import Dodge.Base
import Dodge.Picture.Layer import Dodge.Picture.Layer
@@ -19,6 +19,7 @@ import Picture
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import Control.Lens import Control.Lens
defaultInanimate :: Creature
defaultInanimate = defaultCreature & crActionPlan .~ Inanimate defaultInanimate = defaultCreature & crActionPlan .~ Inanimate
lamp :: Creature lamp :: Creature
+4 -4
View File
@@ -7,15 +7,15 @@ import Dodge.Default
import Dodge.Creature.Picture import Dodge.Creature.Picture
import Dodge.Creature.Test import Dodge.Creature.Test
import Dodge.Creature.ActionRat import Dodge.Creature.ActionRat
import Dodge.Creature.ChooseTarget --import Dodge.Creature.ChooseTarget
import Dodge.Creature.SetTarget import Dodge.Creature.SetTarget
import Dodge.Creature.Rationality import Dodge.Creature.Rationality
import Dodge.Creature.AlertLevel import Dodge.Creature.AlertLevel
import Dodge.Creature.State import Dodge.Creature.State
import Dodge.Creature.State.Data --import Dodge.Creature.State.Data
import Dodge.Item.Weapon import Dodge.Item.Weapon
import Dodge.Item.Consumable --import Dodge.Item.Consumable
import Geometry --import Geometry
import Picture import Picture
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
+7 -8
View File
@@ -6,24 +6,23 @@ import Dodge.Default
import Dodge.Creature.Picture import Dodge.Creature.Picture
import Dodge.Creature.Test import Dodge.Creature.Test
import Dodge.Creature.ActionRat import Dodge.Creature.ActionRat
import Dodge.Creature.ChooseTarget --import Dodge.Creature.ChooseTarget
import Dodge.Creature.SetTarget import Dodge.Creature.SetTarget
import Dodge.Creature.Rationality import Dodge.Creature.Rationality
import Dodge.Creature.AlertLevel import Dodge.Creature.AlertLevel
import Dodge.Creature.State import Dodge.Creature.State
import Dodge.Creature.State.Data --import Dodge.Creature.State.Data
import Dodge.Item.Weapon import Dodge.Item.Weapon
import Dodge.Item.Consumable import Dodge.Item.Consumable
import Geometry import Geometry
import Picture import Picture
import Dodge.RandomHelp --import Dodge.RandomHelp
import Data.Maybe --import Data.Maybe
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import Control.Lens import Control.Lens
import Control.Monad.State --import Control.Monad.State
import System.Random --import System.Random
ltAutoCrit :: Creature ltAutoCrit :: Creature
ltAutoCrit = defaultCreature ltAutoCrit = defaultCreature
@@ -31,7 +30,7 @@ ltAutoCrit = defaultCreature
, _crUpdate = stateUpdate $ impulsiveAI $ composeInternalAIs , _crUpdate = stateUpdate $ impulsiveAI $ composeInternalAIs
[ performActions [ performActions
, watchUpdateStrat , watchUpdateStrat
[ (crHasTargetLOS, \w cr -> StrategyActions (ShootAt 0) [ (crHasTargetLOS, \_ _ -> StrategyActions (ShootAt 0)
[DoActionIf (not . crIsAiming) DrawWeapon [DoActionIf (not . crIsAiming) DrawWeapon
,DoActionThen ,DoActionThen
(DoActionWhile crHasTargetLOS $ ArbitraryAction chooseMovement) (DoActionWhile crHasTargetLOS $ ArbitraryAction chooseMovement)
+10 -9
View File
@@ -8,7 +8,7 @@ module Dodge.Creature.Picture
import Dodge.Data import Dodge.Data
import Dodge.Creature.Stance.Data import Dodge.Creature.Stance.Data
import Dodge.Creature.State.Data import Dodge.Creature.State.Data
import Dodge.Creature.AlertLevel.Data --import Dodge.Creature.AlertLevel.Data
import Dodge.Picture.Layer import Dodge.Picture.Layer
import Picture import Picture
import Geometry import Geometry
@@ -52,14 +52,14 @@ basicCrPict col cr = pictures
Nothing -> False Nothing -> False
Just x -> x > 5 Just x -> x > 5
drawAwakeLevel --drawAwakeLevel
:: Creature -- :: Creature
-> Picture -- -> Picture
drawAwakeLevel cr = case cr ^? crAttentionDir of --drawAwakeLevel cr = case cr ^? crAttentionDir of
Just (AttentiveTo [0]) -> setPos . color red $ circleSolid 5 -- Just (AttentiveTo [0]) -> setPos . color red $ circleSolid 5
_ -> setPos . color blue $ circleSolid 5 -- _ -> setPos . color blue $ circleSolid 5
where -- where
setPos = translate 0 (_crRad cr) -- setPos = translate 0 (_crRad cr)
drawEquipment drawEquipment
:: Creature :: Creature
@@ -70,4 +70,5 @@ drawEquipment cr = pictures $ map f $ IM.toList (_crInv cr)
Just g | (cr ^? crStance . posture) == Just Aiming -> g cr i Just g | (cr ^? crStance . posture) == Just Aiming -> g cr i
_ -> blank _ -> blank
circLine :: Float -> Picture
circLine x = line [(0,0),(x,0)] circLine x = line [(0,0),(x,0)]
+16 -16
View File
@@ -6,12 +6,12 @@ import Dodge.Default
import Dodge.Creature.Picture import Dodge.Creature.Picture
import Dodge.Creature.Test import Dodge.Creature.Test
import Dodge.Creature.ActionRat import Dodge.Creature.ActionRat
import Dodge.Creature.ChooseTarget --import Dodge.Creature.ChooseTarget
import Dodge.Creature.SetTarget import Dodge.Creature.SetTarget
import Dodge.Creature.Rationality import Dodge.Creature.Rationality
import Dodge.Creature.AlertLevel import Dodge.Creature.AlertLevel
import Dodge.Creature.State import Dodge.Creature.State
import Dodge.Creature.State.Data --import Dodge.Creature.State.Data
import Dodge.Item.Weapon import Dodge.Item.Weapon
import Dodge.Item.Consumable import Dodge.Item.Consumable
import Geometry import Geometry
@@ -22,24 +22,24 @@ import Data.Maybe
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import Control.Lens import Control.Lens
import Control.Monad.State import Control.Monad.State
import System.Random --import System.Random
pistolCrit :: Creature pistolCrit :: Creature
pistolCrit = defaultCreature pistolCrit = defaultCreature
{ _crPict = basicCrPict red { _crPict = basicCrPict red
, _crUpdate = stateUpdate $ impulsiveAI $ composeInternalAIs , _crUpdate = stateUpdate $ impulsiveAIR $
[ performActions performActionsR
, watchUpdateStrat >=> watchUpdateStratR
[ (crHasTargetLOS, \w cr -> StrategyActions (ShootAt 0) [DoActionIf (not . crIsAiming) DrawWeapon,chooseMovement cr w]) [ (crHasTargetLOS, \w cr -> StrategyActions (ShootAt 0)
, (crAwayFromPost, goToPostStrat) [DoActionIf (not . crIsAiming) DrawWeapon,chooseMovement cr w])
] , (crAwayFromPost, goToPostStrat)
, basicPerceptionUpdate [0] ]
, doStrategyActions >=> basicPerceptionUpdateR [0]
, reloadOverride >=> doStrategyActionsR
, targetYouWhenCognizant >=> reloadOverrideR
, overrideInternal (onBoth (&&) crHasTarget (crStratConMatches (GetTo (0,0)))) >=> targetYouWhenCognizantR
$ \ _ -> crActionPlan . crStrategy .~ WatchAndWait >=> overrideInternalR (onBoth (&&) crHasTarget (crStratConMatches (GetTo (0,0))))
] ( \ _ -> crActionPlan . crStrategy .~ WatchAndWait )
, _crActionPlan = ActionPlan , _crActionPlan = ActionPlan
{ _crImpulse = [] { _crImpulse = []
, _crAction = [] , _crAction = []
+23 -32
View File
@@ -3,7 +3,7 @@ module Dodge.Creature.Rationality
import Dodge.Data import Dodge.Data
import Dodge.Base.Collide import Dodge.Base.Collide
import Dodge.Creature.Action import Dodge.Creature.Action
import Dodge.Creature.Action.UseItem --import Dodge.Creature.Action.UseItem
import Dodge.Creature.State.Data import Dodge.Creature.State.Data
import Dodge.Creature.Stance.Data import Dodge.Creature.Stance.Data
import Dodge.SoundLogic import Dodge.SoundLogic
@@ -15,8 +15,6 @@ import System.Random
import Control.Lens import Control.Lens
import Control.Monad.Reader import Control.Monad.Reader
-- Alternatives would probably be a very good fit for actions...
composeInternalAIs composeInternalAIs
:: [World -> Creature -> Creature] :: [World -> Creature -> Creature]
-> World -> World
@@ -40,13 +38,14 @@ impulsiveAI
-> ((World -> World,StdGen), Maybe Creature) -> ((World -> World,StdGen), Maybe Creature)
impulsiveAI impF w (f,g) = followImpulses w (f,g) . impF w impulsiveAI impF w (f,g) = followImpulses w (f,g) . impF w
-- needs cleanup
followImpulses followImpulses
:: World :: World
-> (World -> World,StdGen) -> (World -> World,StdGen)
-> Creature -> Creature
-> ((World -> World,StdGen), Maybe Creature) -> ((World -> World,StdGen), Maybe Creature)
followImpulses w (f,g) cr followImpulses w (f,g) cr
= (\(f''' ,cr) -> ((f''',g'),Just cr)) = (\(f''' ,cr') -> ((f''',g'),Just cr'))
$ foldr $ foldr
(\imp (f' , cr') -> let (f'', cr'') = followImpulse cr' w imp in (f'' . f', cr'')) (\imp (f' , cr') -> let (f'', cr'') = followImpulse cr' w imp in (f'' . f', cr''))
(f, cr) (f, cr)
@@ -68,9 +67,9 @@ followImpulse cr w imp = case imp of
ChangePosture post -> (id, cr & crStance . posture .~ post) ChangePosture post -> (id, cr & crStance . posture .~ post)
UseItem -> (crUseItem cr, cr) UseItem -> (crUseItem cr, cr)
SwitchToItem i -> (id, cr & crInvSel .~ i) SwitchToItem i -> (id, cr & crInvSel .~ i)
Melee crID -> Melee cid ->
(hitCr crID (hitCr cid
, crMvBy (10 *.* normalizeV (posFromID crID -.- cpos)) $ cr & crMeleeCooldown ?~ 20) -- randomise cooldown? , crMvBy (10 *.* normalizeV (posFromID cid -.- cpos)) $ cr & crMeleeCooldown ?~ 20) -- randomise cooldown?
RandomTurn a -> (id, creatureTurn (rr a) cr) RandomTurn a -> (id, creatureTurn (rr a) cr)
MakeSound sid -> ( soundOnceOrigin sid (CrSound (_crID cr)) (_crPos cr) , cr ) MakeSound sid -> ( soundOnceOrigin sid (CrSound (_crID cr)) (_crPos cr) , cr )
DropItem -> undefined DropItem -> undefined
@@ -101,18 +100,6 @@ actionUpdateAI
-> Creature -> Creature
actionUpdateAI actF w c = performActions w $ actF w c actionUpdateAI actF w c = performActions w $ actF w c
performActionR :: Creature -> Reader World Creature
performActionR cr = reader $ \w -> performActions w cr
watchUpdateStratR
:: [ ((World, Creature) -> Bool, World -> Creature -> Strategy) ]
-> Creature
-> Reader World Creature
watchUpdateStratR fs cr = case cr ^? crActionPlan . crStrategy of
Just WatchAndWait -> reader $ \w -> cr
& crActionPlan . crStrategy .~ listGuard (fs, \_ _ -> WatchAndWait) (w, cr) w cr
_ -> reader $ \_ -> cr
listGuard :: ([(a -> Bool, b)] , b) -> a -> b listGuard :: ([(a -> Bool, b)] , b) -> a -> b
listGuard ( (test,y):ps, z ) x listGuard ( (test,y):ps, z ) x
| test x = y | test x = y
@@ -126,6 +113,10 @@ performActions w cr = cr
where where
(iss, mayas) = unzip $ map (performAction cr w) $ cr ^. crActionPlan . crAction (iss, mayas) = unzip $ map (performAction cr w) $ cr ^. crActionPlan . crAction
performActionsR :: Creature -> Reader World Creature
performActionsR cr = reader $ \w -> performActions w cr
{- | Performing an action means that a creature has some impulses for a frame, and {- | Performing an action means that a creature has some impulses for a frame, and
updates or deletes the action itself. -} updates or deletes the action itself. -}
performAction performAction
@@ -154,24 +145,24 @@ performAction cr w ac = case ac of
DoImpulses imps -> (imps, Nothing) DoImpulses imps -> (imps, Nothing)
DrawWeapon -> ([ChangePosture Aiming, MakeSound pickUpSound] , Nothing) DrawWeapon -> ([ChangePosture Aiming, MakeSound pickUpSound] , Nothing)
HolsterWeapon -> ([ChangePosture AtEase, MakeSound putDownSound] , Nothing) HolsterWeapon -> ([ChangePosture AtEase, MakeSound putDownSound] , Nothing)
DoActionThen ac ac' -> case performAction cr w ac of DoActionThen fsta afta -> case performAction cr w fsta of
(imps , Just ac'') -> (imps, Just (DoActionThen ac'' ac')) (imps , Just nxta) -> (imps, Just (DoActionThen nxta afta))
(imps , Nothing ) -> (imps, Just ac') (imps , Nothing ) -> (imps, Just afta)
DoActionWhile f ac -> performAction cr w $ DoActionWhilePartial ac f ac DoActionWhile f repa -> performAction cr w $ DoActionWhilePartial repa f repa
DoActionWhilePartial partAc f resetAc DoActionWhilePartial partAc f resetAc
| f (w,cr) -> case performAction cr w partAc of | f (w,cr) -> case performAction cr w partAc of
(imps, Just ac) -> (imps, Just $ DoActionWhilePartial ac f resetAc) (imps, Just nxta) -> (imps, Just $ DoActionWhilePartial nxta f resetAc)
(imps, _) -> (imps, Just $ DoActionWhilePartial resetAc f resetAc) (imps, _) -> (imps, Just $ DoActionWhilePartial resetAc f resetAc)
| otherwise -> performAction cr w partAc | otherwise -> performAction cr w partAc
DoActionIf f ac DoActionIf f ifa
| f (w,cr) -> performAction cr w ac | f (w,cr) -> performAction cr w ifa
| otherwise -> ([],Nothing) | otherwise -> ([],Nothing)
DoActionIfElse ac f ac' DoActionIfElse ifa f elsea
| f (w,cr) -> performAction cr w ac | f (w,cr) -> performAction cr w ifa
| otherwise -> performAction cr w ac' | otherwise -> performAction cr w elsea
DoActionWhileThen ac f ac' DoActionWhileInterrupt repa f afta
| f (w,cr) -> (fst $ performAction cr w ac, Just $ DoActionWhileThen ac f ac') | f (w,cr) -> (fst $ performAction cr w repa, Just $ DoActionWhileInterrupt repa f afta)
| otherwise -> performAction cr w ac' | otherwise -> performAction cr w afta
DoActions [] -> ([], Nothing) DoActions [] -> ([], Nothing)
DoActions acs -> DoActions acs ->
let (imps, newAcs) = unzip $ map (performAction cr w) acs let (imps, newAcs) = unzip $ map (performAction cr w) acs
+7
View File
@@ -7,6 +7,7 @@ import Dodge.Data
import Dodge.Creature.AlertLevel.Data import Dodge.Creature.AlertLevel.Data
import Control.Lens import Control.Lens
import Control.Monad.Reader
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
{- | Assumes that you are id 0: if creature is cognizant of you, sets you as target -} {- | Assumes that you are id 0: if creature is cognizant of you, sets you as target -}
targetYouWhenCognizant targetYouWhenCognizant
@@ -16,3 +17,9 @@ targetYouWhenCognizant
targetYouWhenCognizant w cr = case cr ^? crAwarenessLevel . ix 0 of targetYouWhenCognizant w cr = case cr ^? crAwarenessLevel . ix 0 of
Just (Cognizant _) -> cr & crTarget ?~ _creatures w IM.! 0 Just (Cognizant _) -> cr & crTarget ?~ _creatures w IM.! 0
_ -> cr & crTarget .~ Nothing _ -> cr & crTarget .~ Nothing
targetYouWhenCognizantR :: Creature -> Reader World Creature
targetYouWhenCognizantR cr = reader $ \w -> case cr ^? crAwarenessLevel . ix 0 of
-- Just (Cognizant _) -> cr & crTarget ?~ _creatures w IM.! 0
Just (Cognizant _) -> cr {_crTarget = Just $! _creatures w IM.! 0}
_ -> cr & crTarget .~ Nothing
+24 -26
View File
@@ -6,47 +6,45 @@ import Dodge.Default
import Dodge.Creature.Picture import Dodge.Creature.Picture
import Dodge.Creature.Test import Dodge.Creature.Test
import Dodge.Creature.ActionRat import Dodge.Creature.ActionRat
import Dodge.Creature.ChooseTarget --import Dodge.Creature.ChooseTarget
import Dodge.Creature.SetTarget import Dodge.Creature.SetTarget
import Dodge.Creature.Rationality import Dodge.Creature.Rationality
import Dodge.Creature.AlertLevel import Dodge.Creature.AlertLevel
import Dodge.Creature.State import Dodge.Creature.State
import Dodge.Creature.State.Data --import Dodge.Creature.State.Data
import Dodge.Item.Weapon import Dodge.Item.Weapon
import Dodge.Item.Consumable import Dodge.Item.Consumable
import Geometry import Geometry
import Picture import Picture
import Dodge.RandomHelp --import Dodge.RandomHelp
import Data.Maybe --import Data.Maybe
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import Control.Lens import Control.Lens
import Control.Monad.State import Control.Monad
import System.Random --import System.Random
spreadGunCrit :: Creature spreadGunCrit :: Creature
spreadGunCrit = defaultCreature spreadGunCrit = defaultCreature
{ _crPict = basicCrPict red { _crPict = basicCrPict red
, _crUpdate = stateUpdate $ impulsiveAI $ composeInternalAIs , _crUpdate = stateUpdate $ impulsiveAIR $
[ performActions performActionsR
, watchUpdateStrat >=> watchUpdateStratR
[ (crHasTargetLOS, \w cr -> StrategyActions (ShootAt 0) [ (crHasTargetLOS, \_ _ -> StrategyActions (ShootAt 0)
[DoActionIf (not . crIsAiming) DrawWeapon [DoActionIf (not . crIsAiming) DrawWeapon
,DoActionThen ,DoActionThen
(DoActionWhile crHasTargetLOS $ ArbitraryAction chooseMovement) (DoActionWhile crHasTargetLOS $ ArbitraryAction chooseMovement)
(DoImpulses [ChangeStrategy WatchAndWait]) (DoImpulses [ChangeStrategy WatchAndWait])
] ]
) )
, (crAwayFromPost, goToPostStrat) , (crAwayFromPost, goToPostStrat)
] ]
, basicPerceptionUpdate [0] >=> basicPerceptionUpdateR [0]
, doStrategyActions >=> doStrategyActionsR
, reloadOverride >=> reloadOverrideR
, targetYouWhenCognizant >=> targetYouWhenCognizantR
, overrideInternal (onBoth (&&) crHasTarget (crStratConMatches (GetTo (0,0)))) >=> (overrideInternalR (onBoth (&&) crHasTarget (crStratConMatches (GetTo (0,0))))
$ \ _ -> crActionPlan . crStrategy .~ WatchAndWait $ \ _ -> crActionPlan . crStrategy .~ WatchAndWait)
]
, _crActionPlan = ActionPlan , _crActionPlan = ActionPlan
{ _crImpulse = [] { _crImpulse = []
, _crAction = [] , _crAction = []
+23 -29
View File
@@ -6,27 +6,25 @@ import Dodge.Base
import Dodge.SoundLogic import Dodge.SoundLogic
import Dodge.RandomHelp import Dodge.RandomHelp
import Dodge.WorldEvent import Dodge.WorldEvent
import Dodge.WallCreatureCollisions --import Dodge.WallCreatureCollisions
import Dodge.Creature.Action import Dodge.Creature.Action
import Geometry import Geometry
import Picture import Picture
import Data.List import Data.List
import Data.Char --import Data.Char
import Data.Maybe --import Data.Maybe
import Data.Function import Data.Function
import Control.Lens import Control.Lens
import Control.Applicative --import Control.Applicative
import Control.Monad.State import Control.Monad.State
import Control.Monad --import Control.Monad
import qualified SDL --import qualified SDL
import qualified SDL.Mixer as Mix --import qualified SDL.Mixer as Mix
import System.Random import System.Random
import qualified Data.Set as S --import qualified Data.Set as S
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import qualified Data.Map as M --import qualified Data.Map as M
import Foreign.ForeignPtr
import Control.Concurrent
type CRUpdate = World -> (World -> World,StdGen) -> Creature -> ((World -> World,StdGen), Maybe Creature) type CRUpdate = World -> (World -> World,StdGen) -> Creature -> ((World -> World,StdGen), Maybe Creature)
@@ -45,15 +43,15 @@ stateUpdate u w (f,g) cr =
, fmap (updateReloadCounter . doDamage . crAutoReload) $ crOrCorpse =<< maybeCr , fmap (updateReloadCounter . doDamage . crAutoReload) $ crOrCorpse =<< maybeCr
) )
where where
crOrCorpse cr crOrCorpse cr'
| cr ^. crHP > 0 = Just cr | cr' ^. crHP > 0 = Just cr'
| otherwise = Nothing | otherwise = Nothing
deathEff deathEff
| cr ^.crHP > 0 = id | cr ^.crHP > 0 = id
| otherwise = stopSoundFrom (CrWeaponSound (_crID cr)) | otherwise = stopSoundFrom (CrWeaponSound (_crID cr))
. over decorations addCorpse . over decorations addCorpse
. dropByState cr . dropByState cr
crBeforeDeath = colCrWall w cr --crBeforeDeath = colCrWall w cr
addCorpse = insertNewKey addCorpse = insertNewKey
$ uncurry translate (_crOldPos cr) $ uncurry translate (_crOldPos cr)
$ rotate (_crDir cr) $ rotate (_crDir cr)
@@ -75,7 +73,7 @@ Given a creature and a velocity, applies friction to that creature and evaluates
velocity to carry across frames. velocity to carry across frames.
-} -}
crFriction :: Creature -> Point2 -> Point2 crFriction :: Creature -> Point2 -> Point2
crFriction cr vel = (0,0) crFriction _ _ = (0,0)
doDamage :: Creature -> Creature doDamage :: Creature -> Creature
doDamage cr = set (crState . crDamage) [] doDamage cr = set (crState . crDamage) []
@@ -84,9 +82,6 @@ doDamage cr = set (crState . crDamage) []
dams = _crDamage $ _crState cr dams = _crDamage $ _crState cr
damagedCr = snd $ _crApplyDamage cr dams cr damagedCr = snd $ _crApplyDamage cr dams cr
sumDamage :: Creature -> DamageType -> Int -> Int
sumDamage cr dm x = x + _dmAmount dm
movementSideEff :: Creature -> World -> World movementSideEff :: Creature -> World -> World
movementSideEff cr w movementSideEff cr w
| hasJetPack | hasJetPack
@@ -178,18 +173,17 @@ updateBarrel
-> (World -> World,StdGen) -> (World -> World,StdGen)
-> Creature -> Creature
-> ((World -> World , StdGen), Maybe Creature) -> ((World -> World , StdGen), Maybe Creature)
updateBarrel w (f,g) cr updateBarrel _ (f,g) cr
| _crHP cr > 0 = ((f, g), newCr) | _crHP cr > 0 = ((f, g), newCr)
| otherwise = ((f, g), Nothing) | otherwise = ((f, g), Nothing)
where where
damages = _crDamage $ _crState cr
newCr = Just $ doDamage cr newCr = Just $ doDamage cr
-- it is easy to leave off the "f" here -- it is easy to leave off the "f" here
-- should find some better way of doing all this that is less prone to error -- should find some better way of doing all this that is less prone to error
updateExpBarrel :: updateExpBarrel ::
World -> (World -> World,StdGen) -> Creature -> ((World -> World , StdGen), Maybe Creature) World -> (World -> World,StdGen) -> Creature -> ((World -> World , StdGen), Maybe Creature)
updateExpBarrel w (f,g) cr updateExpBarrel _ (f,g) cr
| _crHP cr > 0 = ((f . foldr (.) id pierceSparks . hiss, g'), newCr) | _crHP cr > 0 = ((f . foldr (.) id pierceSparks . hiss, g'), newCr)
| otherwise = ((f . makeExplosionAt (_crPos cr) . stopSounds , g'), Nothing) | otherwise = ((f . makeExplosionAt (_crPos cr) . stopSounds , g'), Nothing)
where where
@@ -205,13 +199,13 @@ updateExpBarrel w (f,g) cr
poss = _piercedPoints $ _crSpState $ _crState cr poss = _piercedPoints $ _crSpState $ _crState cr
--newCr = Just $ doDamage $ applyFuseDamage cr -- $ foldr perforate cr damages --newCr = Just $ doDamage $ applyFuseDamage cr -- $ foldr perforate cr damages
newCr = Just $ applyFuseDamage $ set (crState . crDamage) [] $ damToExpBarrel damages cr newCr = Just $ applyFuseDamage $ set (crState . crDamage) [] $ damToExpBarrel damages cr
perforate :: DamageType -> Creature -> Creature --perforate :: DamageType -> Creature -> Creature
perforate (Piercing amount sp int ep) cr = over (crState . crSpState . piercedPoints) --perforate (Piercing amount sp int ep) cr = over (crState . crSpState . piercedPoints)
((:) $ int -.- _crPos cr) cr -- ((:) $ int -.- _crPos cr) cr
perforate _ cr = cr --perforate _ cr = cr
applyFuseDamage cr = over crHP (\hp -> hp - length (_piercedPoints applyFuseDamage cr' = over crHP (subtract $ length (_piercedPoints
$ _crSpState $ _crState cr)) $ _crSpState $ _crState cr'))
cr cr'
hiss | null poss = id hiss | null poss = id
| otherwise = soundMultiFrom [BarrelHiss 0,BarrelHiss 1] 41 50 1 | otherwise = soundMultiFrom [BarrelHiss 0,BarrelHiss 1] 41 50 1
stopSounds = stopSoundFrom (BarrelHiss 0) . stopSoundFrom (BarrelHiss 1) stopSounds = stopSoundFrom (BarrelHiss 0) . stopSoundFrom (BarrelHiss 1)
@@ -224,7 +218,7 @@ damToExpBarrel ds cr = foldr damToExpBarrel' (foldr damToExpBarrel' cr pierceDam
isPierce _ = False isPierce _ = False
damToExpBarrel' :: DamageType -> Creature -> Creature damToExpBarrel' :: DamageType -> Creature -> Creature
damToExpBarrel' (Piercing amount sp int ep) cr damToExpBarrel' (Piercing amount _ int _) cr
= over (crState . crSpState . piercedPoints) ((:) $ int -.- _crPos cr) = over (crState . crSpState . piercedPoints) ((:) $ int -.- _crPos cr)
$ over crHP (\hp -> hp - div amount 200) cr $ over crHP (\hp -> hp - div amount 200) cr
damToExpBarrel' PoisonDam {} cr = cr damToExpBarrel' PoisonDam {} cr = cr
+1 -1
View File
@@ -4,7 +4,7 @@ module Dodge.Creature.State.Data
where where
import Geometry import Geometry
import Dodge.Data.DamageType import Dodge.Data.DamageType
import Dodge.Creature.Stance.Data --import Dodge.Creature.Stance.Data
import Picture.Data import Picture.Data
import Control.Lens import Control.Lens
+9 -11
View File
@@ -5,27 +5,25 @@ module Dodge.Creature.SwarmCrit
import Dodge.Data import Dodge.Data
import Dodge.Default import Dodge.Default
import Dodge.Creature.Picture import Dodge.Creature.Picture
import Dodge.Creature.Test --import Dodge.Creature.Test
import Dodge.Creature.ActionRat --import Dodge.Creature.ActionRat
import Dodge.Creature.ImpulseRat import Dodge.Creature.ImpulseRat
import Dodge.Creature.ChooseTarget import Dodge.Creature.ChooseTarget
import Dodge.Creature.SetTarget --import Dodge.Creature.SetTarget
import Dodge.Creature.Rationality import Dodge.Creature.Rationality
import Dodge.Creature.AlertLevel import Dodge.Creature.AlertLevel
import Dodge.Creature.State import Dodge.Creature.State
import Dodge.Creature.State.Data import Dodge.Creature.State.Data
import Dodge.Item.Weapon
import Dodge.Item.Consumable
import Dodge.Picture.Layer import Dodge.Picture.Layer
import Geometry --import Geometry
import Picture import Picture
import Dodge.RandomHelp --import Dodge.RandomHelp
import Data.Maybe --import Data.Maybe
import qualified Data.IntMap.Strict as IM --import qualified Data.IntMap.Strict as IM
import Control.Lens import Control.Lens
import Control.Monad.State --import Control.Monad.State
import System.Random --import System.Random
swarmCrit :: Creature swarmCrit :: Creature
swarmCrit = defaultCreature swarmCrit = defaultCreature
+1 -1
View File
@@ -12,4 +12,4 @@ unrandUpdate
-> (Creature -> Maybe Creature) -> (Creature -> Maybe Creature)
-> CRUpdate -> CRUpdate
{-# INLINE unrandUpdate #-} {-# INLINE unrandUpdate #-}
unrandUpdate h cF w (f,g) cr = ( ( h cr . f , g) , cF cr ) unrandUpdate h cF _ (f,g) cr = ( ( h cr . f , g) , cF cr )
+7 -7
View File
@@ -1,10 +1,10 @@
module Dodge.Creature.YourControl module Dodge.Creature.YourControl
where where
import Dodge.Data import Dodge.Data
import Dodge.Base --import Dodge.Base
import Dodge.Creature.Action import Dodge.Creature.Action
import Dodge.Creature.State --import Dodge.Creature.State
import Dodge.Creature.State.Data --import Dodge.Creature.State.Data
import Dodge.Creature.Stance.Data import Dodge.Creature.Stance.Data
import Dodge.Update.UsingInput import Dodge.Update.UsingInput
import Dodge.Config.KeyConfig import Dodge.Config.KeyConfig
@@ -43,7 +43,7 @@ wasdWithAiming w speed i cr
mov = rotateV (negate $ _crDir cr - _cameraRot w) mov' mov = rotateV (negate $ _crDir cr - _cameraRot w) mov'
isAiming = _posture (_crStance cr) == Aiming isAiming = _posture (_crStance cr) == Aiming
isMoving = mov' /= (0,0) isMoving = mov' /= (0,0)
mouseDir = case w ^? creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0)) mouseDir = case w ^? creatures . ix i . crInv . ix (_crInvSel (_creatures w IM.! i))
. itAttachment of . itAttachment of
Just (Just ItScope{_scopePos = p}) -> normalizeAngle $ argV Just (Just ItScope{_scopePos = p}) -> normalizeAngle $ argV
$ p +.+ 2 / _cameraZoom w $ p +.+ 2 / _cameraZoom w
@@ -67,9 +67,9 @@ wasdComp ks w = f $ foldr ( (+.+) . wasdM w ) (0,0) ks
{- | Set posture according to mouse presses. -} {- | Set posture according to mouse presses. -}
mouseActionsCr :: S.Set SDL.MouseButton -> Creature -> Creature mouseActionsCr :: S.Set SDL.MouseButton -> Creature -> Creature
mouseActionsCr keys mouseActionsCr pkeys
| rbPressed = crStance . posture .~ Aiming | rbPressed = crStance . posture .~ Aiming
| otherwise = crStance . posture .~ AtEase | otherwise = crStance . posture .~ AtEase
where where
lbPressed = SDL.ButtonLeft `S.member` keys --lbPressed = SDL.ButtonLeft `S.member` pkeys
rbPressed = SDL.ButtonRight `S.member` keys rbPressed = SDL.ButtonRight `S.member` pkeys
+5 -11
View File
@@ -1,4 +1,4 @@
{- {- |
Contains base datatypes that cannot be seperated into Contains base datatypes that cannot be seperated into
different modules because they are interdependent; different modules because they are interdependent;
circular imports are probably not a good idea. circular imports are probably not a good idea.
@@ -11,11 +11,10 @@ module Dodge.Data
( module Dodge.Data ( module Dodge.Data
, module Dodge.Data.DamageType , module Dodge.Data.DamageType
, module Dodge.Data.SoundOrigin , module Dodge.Data.SoundOrigin
, Point2 (..) , Point2
, Sound (..) , Sound (..)
, soundTime , soundTime
) where ) where
import Dodge.Picture.Layer.Data
import Dodge.Creature.State.Data import Dodge.Creature.State.Data
import Dodge.Creature.Stance.Data import Dodge.Creature.Stance.Data
import Dodge.Creature.AlertLevel.Data import Dodge.Creature.AlertLevel.Data
@@ -34,20 +33,14 @@ import qualified DoubleStack as DS
import GHC.Generics import GHC.Generics
import Control.Lens import Control.Lens
import Control.Monad.State
import System.Random import System.Random
import Data.Data
import Data.Graph.Inductive import Data.Graph.Inductive
import Data.Int (Int16) import Data.Int (Int16)
import qualified Data.Set as S import qualified Data.Set as S
import qualified Data.IntSet as IS import qualified Data.IntSet as IS
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import qualified Data.Map as M import qualified Data.Map as M
import qualified Data.DList as DL
import SDL (Scancode, MouseButton) import SDL (Scancode, MouseButton)
import qualified SDL.Mixer as Mix
import Graphics.Rendering.OpenGL (PrimitiveMode (..),GLfloat,Program,VertexArrayObject,BufferObject)
import Codec.Picture (Image,PixelRGBA8)
data World = World data World = World
{ _keys :: !(S.Set Scancode) { _keys :: !(S.Set Scancode)
, _mouseButtons :: !(S.Set MouseButton) , _mouseButtons :: !(S.Set MouseButton)
@@ -562,7 +555,7 @@ data Action
,_doActionIfElseCondition :: (World, Creature) -> Bool ,_doActionIfElseCondition :: (World, Creature) -> Bool
,_doActionIfElseElseAction :: Action ,_doActionIfElseElseAction :: Action
} }
| DoActionWhileThen | DoActionWhileInterrupt
{_doActionWhileThenDo :: Action {_doActionWhileThenDo :: Action
,_doActionWhileThenCondition :: (World, Creature) -> Bool ,_doActionWhileThenCondition :: (World, Creature) -> Bool
,_doActionWhileThenThen :: Action ,_doActionWhileThenThen :: Action
@@ -667,4 +660,5 @@ numColor 8 = (0,0.5,1,1)
numColor 9 = (0,1,0.5,1) numColor 9 = (0,1,0.5,1)
numColor 10 = (0.5,1,0,1) numColor 10 = (0.5,1,0,1)
numColor 11 = (1,0.5,0,1) numColor 11 = (1,0.5,0,1)
numColor 12 = (1,1,1,1) numColor 12 = (1,1,1,1)
numColor _ = (1,1,1,1)
+1 -2
View File
@@ -1,10 +1,9 @@
module Dodge.Debug where module Dodge.Debug where
import Dodge.Data import Dodge.Data
import Dodge.Base import Dodge.Base
import Dodge.Picture import Dodge.Picture
import Dodge.Picture.Layer import Dodge.Picture.Layer
import Geometry.Data --import Geometry.Data
import Picture import Picture
import Control.Lens import Control.Lens
+23 -9
View File
@@ -28,6 +28,7 @@ import qualified Data.Set as S
import Data.Graph.Inductive.Graph hiding ((&)) import Data.Graph.Inductive.Graph hiding ((&))
import Data.List import Data.List
{- Indestructible wall. -} {- Indestructible wall. -}
defaultWall :: Wall
defaultWall = Wall defaultWall = Wall
{ _wlLine = ((0,0),(50,0)) { _wlLine = ((0,0),(50,0))
, _wlID = 0 , _wlID = 0
@@ -36,6 +37,7 @@ defaultWall = Wall
, _wlIsSeeThrough = False , _wlIsSeeThrough = False
} }
{- Indestructible see-through wall. -} {- Indestructible see-through wall. -}
defaultCrystalWall :: Wall
defaultCrystalWall = Wall defaultCrystalWall = Wall
{ _wlLine = ((0,0),(50,0)) { _wlLine = ((0,0),(50,0))
, _wlID = 0 , _wlID = 0
@@ -45,6 +47,7 @@ defaultCrystalWall = Wall
} }
{- Door that opens on approach. {- Door that opens on approach.
Pathable. -} Pathable. -}
defaultAutoDoor :: Wall
defaultAutoDoor = Door defaultAutoDoor = Door
{ _wlLine = ((0,0),(50,0)) { _wlLine = ((0,0),(50,0))
, _wlID = 0 , _wlID = 0
@@ -58,6 +61,7 @@ defaultAutoDoor = Door
{- {-
Non-pathable door. Non-pathable door.
-} -}
defaultDoor :: Wall
defaultDoor = Door defaultDoor = Door
{ _wlLine = ((0,0),(50,0)) { _wlLine = ((0,0),(50,0))
, _wlID = 0 , _wlID = 0
@@ -76,7 +80,7 @@ defaultCreature = Creature
, _crDir = 0 , _crDir = 0
, _crID = 1 , _crID = 1
, _crPict = const $ onLayer CrLayer $ circleSolid 10 , _crPict = const $ onLayer CrLayer $ circleSolid 10
, _crUpdate = \ w f cr -> (f , Just cr) , _crUpdate = \ _ f cr -> (f , Just cr)
, _crRad = 10 , _crRad = 10
, _crMass = 10 , _crMass = 10
, _crHP = 100 , _crHP = 100
@@ -96,19 +100,21 @@ defaultCreature = Creature
, _crTarget = Nothing , _crTarget = Nothing
, _crGroup = LoneWolf , _crGroup = LoneWolf
} }
defaultState :: CreatureState
defaultState = CrSt defaultState = CrSt
{ _crDamage = [] { _crDamage = []
, _crPastDamage = [] , _crPastDamage = []
, _crSpState = GenCr , _crSpState = GenCr
, _crDropsOnDeath = DropAmount 1 , _crDropsOnDeath = DropAmount 1
} }
defaultEquipment :: Item
defaultEquipment = Equipment defaultEquipment = Equipment
{ _itIdentity = Generic { _itIdentity = Generic
, _itName = "genericEquipment" , _itName = "genericEquipment"
, _itMaxStack = 1 , _itMaxStack = 1
, _itAmount = 1 , _itAmount = 1
, _itFloorPict = onLayer FlItLayer $ polygon [(-3,-3),(-3,3),(3,3),(3,-3)] , _itFloorPict = onLayer FlItLayer $ polygon [(-3,-3),(-3,3),(3,3),(3,-3)]
, _itEquipPict = \cr _ -> blank , _itEquipPict = \_ _ -> blank
, _itEffect = NoItEffect , _itEffect = NoItEffect
, _itHammer = HammerUp , _itHammer = HammerUp
, _itID = Nothing , _itID = Nothing
@@ -118,6 +124,7 @@ defaultEquipment = Equipment
, _itInvColor = yellow , _itInvColor = yellow
, _itInvDisplay = _itName , _itInvDisplay = _itName
} }
defaultItZoom :: ItZoom
defaultItZoom = ItZoom 20 0.2 1 20 0.2 1 defaultItZoom = ItZoom 20 0.2 1 20 0.2 1
defaultConsumable :: Item defaultConsumable :: Item
defaultConsumable = Consumable defaultConsumable = Consumable
@@ -144,16 +151,16 @@ defaultApplyDamage ds cr = (id, doPoisonDam $ foldr (\d c -> snd $ applyIndividu
doPoisonDam = over crHP (\hp -> hp - poisonDam) doPoisonDam = over crHP (\hp -> hp - poisonDam)
applyIndividualDamage :: DamageType -> Creature -> (World -> World, Creature) applyIndividualDamage :: DamageType -> Creature -> (World -> World, Creature)
applyIndividualDamage (Concussive amount from push pushexp pushRad) cr applyIndividualDamage (Concussive amount fromDir push pushexp pushRad) cr
= ( id = ( id
, over crHP (\hp -> hp - amount) , over crHP (\hp -> hp - amount)
$ over crPos (+.+ (pushAmount *.* safeNormalizeV (_crPos cr -.- from))) $ over crPos (+.+ (pushAmount *.* safeNormalizeV (_crPos cr -.- fromDir)))
cr cr
) )
where pushAmount | dist (_crPos cr) from == 0 where
= 0 pushAmount
| otherwise = min 5 $ | dist (_crPos cr) fromDir == 0 = 0
(push*5*pushRad / (dist (_crPos cr) from * _crMass cr))**pushexp | otherwise = min 5 $ (push*5*pushRad / (dist (_crPos cr) fromDir * _crMass cr))**pushexp
applyIndividualDamage (TorqueDam amount rot) cr applyIndividualDamage (TorqueDam amount rot) cr
= ( id = ( id
, over crHP (\hp -> hp - amount) $ over crDir (+ rot) cr) , over crHP (\hp -> hp - amount) $ over crDir (+ rot) cr)
@@ -163,7 +170,9 @@ applyIndividualDamage (PushDam amount pback) cr
) )
applyIndividualDamage dt cr applyIndividualDamage dt cr
= ( id , over crHP (\hp -> hp - _dmAmount dt) cr ) = ( id , over crHP (\hp -> hp - _dmAmount dt) cr )
defaultFlIt :: FloorItem
defaultFlIt = FlIt {_flItRot=0,_flIt = defaultIt, _flItPos = (0,0), _flItID = 0} defaultFlIt = FlIt {_flItRot=0,_flIt = defaultIt, _flItPos = (0,0), _flItID = 0}
defaultIt :: Item
defaultIt = Consumable defaultIt = Consumable
{ _itIdentity = Medkit25 { _itIdentity = Medkit25
, _itName = "defaultIt" , _itName = "defaultIt"
@@ -171,13 +180,14 @@ defaultIt = Consumable
, _itAmount = 2 , _itAmount = 2
, _cnEffect = const return , _cnEffect = const return
, _itFloorPict = onLayer FlItLayer $ polygon [(-3,-3),(-3,3),(3,3),(3,-3)] , _itFloorPict = onLayer FlItLayer $ polygon [(-3,-3),(-3,3),(3,3),(3,-3)]
, _itEquipPict = \cr _ -> blank , _itEquipPict = \_ _ -> blank
, _itID = Nothing , _itID = Nothing
, _itInvDisplay = _itName , _itInvDisplay = _itName
, _itInvColor = blue , _itInvColor = blue
, _itEffect = NoItEffect , _itEffect = NoItEffect
, _itHammer = HammerUp , _itHammer = HammerUp
} }
defaultButton :: Button
defaultButton = Button defaultButton = Button
{ _btPict = onLayer WlLayer $ color red $ polygon $ rectNSEW 5 (-5) 10 (-10) { _btPict = onLayer WlLayer $ color red $ polygon $ rectNSEW 5 (-5) 10 (-10)
, _btPos = (0,0) , _btPos = (0,0)
@@ -190,6 +200,7 @@ defaultButton = Button
, _btText = "Button" , _btText = "Button"
, _btState = BtOff , _btState = BtOff
} }
defaultPT :: Projectile
defaultPT = Projectile defaultPT = Projectile
{ _pjPos = (0,0) { _pjPos = (0,0)
, _pjStartPos = (0,0) , _pjStartPos = (0,0)
@@ -198,6 +209,7 @@ defaultPT = Projectile
, _pjID = 0 , _pjID = 0
, _pjUpdate = id , _pjUpdate = id
} }
defaultPP :: PressPlate
defaultPP = PressPlate defaultPP = PressPlate
{ _ppPict = onLayer PressPlateLayer $ color (dim $ dim $ bright blue) $ circleSolid 5 { _ppPict = onLayer PressPlateLayer $ color (dim $ dim $ bright blue) $ circleSolid 5
, _ppPos = (0,0) , _ppPos = (0,0)
@@ -206,6 +218,7 @@ defaultPP = PressPlate
, _ppID = -1 , _ppID = -1
, _ppText = "Pressure plate" , _ppText = "Pressure plate"
} }
defaultWorld :: World
defaultWorld = World defaultWorld = World
{ _keys = S.empty { _keys = S.empty
, _mouseButtons = S.empty , _mouseButtons = S.empty
@@ -266,6 +279,7 @@ defaultWorld = World
, _sideEffects = [] , _sideEffects = []
, _doneSideEffects = [] , _doneSideEffects = []
} }
youLight :: TempLightSource
youLight = youLight =
TLS { _tlsPos = (0,0) TLS { _tlsPos = (0,0)
,_tlsRad = 300 ,_tlsRad = 300
+18 -25
View File
@@ -14,21 +14,21 @@ module Dodge.Event
( handleEvent ( handleEvent
) where ) where
import Dodge.Event.Keyboard import Dodge.Event.Keyboard
import Dodge.Event.Menu --import Dodge.Event.Menu
import Dodge.Data import Dodge.Data
import Dodge.Base import Dodge.Base
import Dodge.Creature.Action --import Dodge.Creature.Action
import Dodge.SoundLogic import Dodge.SoundLogic
import Dodge.Inventory import Dodge.Inventory
import Dodge.Config.Data import Dodge.Config.Data
import Geometry --import Geometry
import Preload.Update import Preload.Update
import Control.Lens import Control.Lens
import Data.Maybe import Data.Maybe
import Data.Char --import Data.Char
import Data.List --import Data.List
import Data.Function (on) --import Data.Function (on)
import qualified Data.Set as S import qualified Data.Set as S
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import SDL import SDL
@@ -61,11 +61,12 @@ handleMouseButtonEvent mbev w = case mouseButtonEventMotion mbev of
handleMouseWheelEvent :: MouseWheelEventData -> World -> Maybe World handleMouseWheelEvent :: MouseWheelEventData -> World -> Maybe World
handleMouseWheelEvent mwev w = case _menuLayers w of handleMouseWheelEvent mwev w = case _menuLayers w of
[] -> case mouseWheelEventPos mwev of [] -> case mouseWheelEventPos mwev of
V2 x y | y > 0 -> Just (wheelUpEvent w) V2 _ y
| y < 0 -> Just (wheelDownEvent w) | y > 0 -> Just (wheelUpEvent w)
| otherwise -> Just w | y < 0 -> Just (wheelDownEvent w)
_ -> Just w | otherwise -> Just w
_ -> Just w
{- | {- |
Resets the world window size, and resizes the fbo that gets the light map drawn into it. Resets the world window size, and resizes the fbo that gets the light map drawn into it.
@@ -123,20 +124,12 @@ wheelDownEvent w = case _carteDisplay w of
numLocs = (fst . IM.findMax $ _seenLocations w) + 1 numLocs = (fst . IM.findMax $ _seenLocations w) + 1
upInvPos :: World -> World upInvPos :: World -> World
upInvPos w = stopSoundFrom (CrReloadSound 0) $ set (creatures . ix (_yourID w) . crInvSel) x w upInvPos w = stopSoundFrom (CrReloadSound 0) $ w
& creatures . ix (_yourID w) . crInvSel %~ (`mod` n) . (subtract 1)
where where
is = IM.keys $ _crInv $ _creatures w IM.! _yourID w n = length $ IM.keys $ _crInv $ _creatures w IM.! _yourID w
isis = is ++ is
x = before (_crInvSel (you w)) isis
downInvPos :: World -> World downInvPos :: World -> World
downInvPos w = stopSoundFrom (CrReloadSound 0) $ set (creatures . ix (_yourID w) . crInvSel) x w downInvPos w = stopSoundFrom (CrReloadSound 0) $ w
& creatures . ix (_yourID w) . crInvSel %~ (`mod` n) . (+ 1)
where where
is = IM.keys $ _crInv $ _creatures w IM.! _yourID w n = length $ IM.keys $ _crInv $ _creatures w IM.! _yourID w
isis = is ++ is
x = after (_crInvSel (you w)) isis
-- these are incomplete: should put in error case here!
before y (x:z:ys) | y == z = x
| otherwise = before y (z:ys)
after y (x:z:ys) | y == x = z
| otherwise = after y (z:ys)
+4 -3
View File
@@ -11,7 +11,7 @@ import Dodge.Picture.Layer
import Dodge.Base import Dodge.Base
import Dodge.Creature.Action import Dodge.Creature.Action
import Dodge.Config.KeyConfig import Dodge.Config.KeyConfig
import Dodge.Room.Placement --import Dodge.Room.Placement
import Dodge.LightSources import Dodge.LightSources
import Dodge.LevelGen import Dodge.LevelGen
import Dodge.Creature.Inanimate import Dodge.Creature.Inanimate
@@ -77,18 +77,19 @@ spaceAction w = if _carteDisplay w
Nothing -> w Nothing -> w
where where
theLoc = fst (_seenLocations w IM.! _selLocation w) w theLoc = fst (_seenLocations w IM.! _selLocation w) w
updateTopCloseObject i w = w & closeActiveObjects %~ ( Right (_buttons w IM.! i) : ) . tail updateTopCloseObject i = closeActiveObjects %~ ( Right (_buttons w IM.! i) : ) . tail
pauseGame :: World -> World pauseGame :: World -> World
pauseGame w = w {_menuLayers = [PauseMenu]} pauseGame w = w {_menuLayers = [PauseMenu]}
toggleMap :: World -> World
toggleMap w = w & carteDisplay %~ not toggleMap w = w & carteDisplay %~ not
escapeMap :: World -> World
escapeMap w = w & carteDisplay .~ False escapeMap w = w & carteDisplay .~ False
dropLight :: World -> World dropLight :: World -> World
dropLight w = placeLS ls dec pos 0 w dropLight w = placeLS ls dec pos 0 w
where --(rot, g) = randomR (-pi,pi) $ _randGen w where --(rot, g) = randomR (-pi,pi) $ _randGen w
i = newCrKey w -- to give different lights different keys
pos = _crPos(you w) pos = _crPos(you w)
ls = lightAt pos 0 ls = lightAt pos 0
dec = onLayer PtLayer $ color white $ circleSolid 8 dec = onLayer PtLayer $ color white $ circleSolid 8
+6 -3
View File
@@ -13,7 +13,7 @@ import Dodge.Layout
import Preload.Update import Preload.Update
import Data.Maybe import Data.Maybe
import qualified Data.Set as S --import qualified Data.Set as S
import Control.Lens import Control.Lens
import SDL import SDL
@@ -62,8 +62,8 @@ handlePressedKeyInMenu mState scode w = case mState of
startLevel = unpause . storeLevel startLevel = unpause . storeLevel
dec x = max 0 (x - 0.1) dec x = max 0 (x - 0.1)
inc x = min 1 (x + 0.1) inc x = min 1 (x + 0.1)
pushMenu ml w = Just $ w & menuLayers %~ (ml :) pushMenu ml w' = Just $ w' & menuLayers %~ (ml :)
popMenu w = Just $ w & menuLayers %~ tail popMenu w' = Just $ w' & menuLayers %~ tail
sw = w & sideEffects %~ (setVol (_config w) : ) sw = w & sideEffects %~ (setVol (_config w) : )
startNewGame = Just $ w startNewGame = Just $ w
& menuLayers .~ [WaitMessage "GENERATING..." 1] & menuLayers .~ [WaitMessage "GENERATING..." 1]
@@ -80,9 +80,12 @@ updateFramebufferSize w = w & sideEffects
(x,y) = (round $ getWindowX w, round $ getWindowY w) (x,y) = (round $ getWindowX w, round $ getWindowY w)
divRes = w ^. config . shadow_resolution divRes = w ^. config . shadow_resolution
cycleResolution :: (Eq a, Num a, Num p) => a -> p
cycleResolution 1 = 2 cycleResolution 1 = 2
cycleResolution 2 = 4 cycleResolution 2 = 4
cycleResolution 4 = 1 cycleResolution 4 = 1
cycleResolution _ = 1
storeLevel :: World -> World storeLevel :: World -> World
storeLevel w = case _storedLevel w of storeLevel w = case _storedLevel w of
+8 -9
View File
@@ -3,15 +3,14 @@ module Dodge.Event.Test
) )
where where
import Dodge.Data import Dodge.Data
import Dodge.Base --import Dodge.Base
import Dodge.Default --import Dodge.Default
--import Picture
import Picture --import Geometry
import Geometry --
--import qualified Data.IntMap as IM
import qualified Data.IntMap as IM --import Control.Lens
import Control.Lens testEvent :: World -> World
testEvent w = w testEvent w = w
--testEvent :: World -> World --testEvent :: World -> World
+22 -22
View File
@@ -3,39 +3,39 @@ The tree of rooms that make up a level. -}
module Dodge.Floor module Dodge.Floor
( levx ( levx
) where ) where
import Geometry --import Geometry
import Picture --import Picture
import Dodge.Data import Dodge.Data
import Dodge.Room --import Dodge.Room
import Dodge.Creature.State.Data import Dodge.Creature.State.Data
import Dodge.Creature.SwarmCrit --import Dodge.Creature.SwarmCrit
import Dodge.Room.Procedural import Dodge.Room.Procedural
import Dodge.Room.RoadBlock import Dodge.Room.RoadBlock
import Dodge.Room.Data import Dodge.Room.Data
import Dodge.Room.Link --import Dodge.Room.Link
import Dodge.Room.Door --import Dodge.Room.Door
import Dodge.Room.Branch import Dodge.Room.Branch
import Dodge.Room.Boss import Dodge.Room.Boss
import Dodge.Room.Airlock --import Dodge.Room.Airlock
import Dodge.Room.LongDoor import Dodge.Room.LongDoor
import Dodge.Room.NoNeedWeapon import Dodge.Room.NoNeedWeapon
import Dodge.Base --import Dodge.Base
import Dodge.Layout --import Dodge.Layout
import Dodge.Layout.Tree.Polymorphic import Dodge.Layout.Tree.Polymorphic
import Dodge.Layout.Tree.Either import Dodge.Layout.Tree.Either
import Dodge.Layout.Tree.GenerateStructure --import Dodge.Layout.Tree.GenerateStructure
import Dodge.Layout.Tree.Annotate import Dodge.Layout.Tree.Annotate
import Dodge.Layout.Tree.Shift import Dodge.Layout.Tree.Shift
import Dodge.Creature import Dodge.Creature
import Dodge.SoundLogic --import Dodge.SoundLogic
import Dodge.RandomHelp --import Dodge.RandomHelp
import Dodge.LightSources --import Dodge.LightSources
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
import Dodge.LevelGen.SwarmPlacement --import Dodge.LevelGen.SwarmPlacement
import Dodge.Item.Weapon import Dodge.Item.Weapon
import Data.Tree --import Data.Tree
import Data.Maybe (fromJust,isNothing) --import Data.Maybe (fromJust,isNothing)
import Control.Lens import Control.Lens
import Control.Monad.State import Control.Monad.State
import Control.Monad.Loops import Control.Monad.Loops
@@ -43,7 +43,7 @@ import System.Random
{- | A test level tree. -} {- | A test level tree. -}
roomTreex :: RandomGen g => State g (Maybe [Room]) roomTreex :: RandomGen g => State g (Maybe [Room])
roomTreex = do roomTreex = do
struct' <- aTreeStrut --struct' <- aTreeStrut
-- let struct = treeFromPost [[SpecificRoom $ fmap (pure . Right) pistolerRoom]] [EndRoom] -- let struct = treeFromPost [[SpecificRoom $ fmap (pure . Right) pistolerRoom]] [EndRoom]
let struct = treeFromPost [[Corridor,SpecificRoom $ fmap (pure . Right) randomFourCornerRoom]] [EndRoom] let struct = treeFromPost [[Corridor,SpecificRoom $ fmap (pure . Right) randomFourCornerRoom]] [EndRoom]
let t' = padCorridors struct let t' = padCorridors struct
@@ -51,12 +51,12 @@ roomTreex = do
[[StartRoom] [[StartRoom]
,[Corridor] ,[Corridor]
,[SpecificRoom . pure . pure . Right $ roomGlassOctogon 400 ,[SpecificRoom . pure . pure . Right $ roomGlassOctogon 400
& rmPS %~ ([sPS (0,50) 0 $ PutCrit chaseCrit ]++) & rmPS %~ ([sPS (0,50) 0 $ PutCrit pistolCrit ]++)
]
,[Corridor]
,[SpecificRoom . pure . pure . Right $ roomGlassOctogon 400
& rmPS %~ ([swarmPS 0 (x,y) 0 swarmCrit | x <- [-20,-19.5.. 20] , y <- [200] ]++)
] ]
-- ,[Corridor]
-- ,[SpecificRoom . pure . pure . Right $ roomGlassOctogon 400
-- & rmPS %~ ([swarmPS 0 (x,y) 0 swarmCrit | x <- [-20,-19.5.. 20] , y <- [200] ]++)
-- ]
,[Corridor] ,[Corridor]
,[Corridor] ,[Corridor]
,[SpecificRoom $ pure . Right <$> twinSlowDoorChasers 30] ,[SpecificRoom $ pure . Right <$> twinSlowDoorChasers 30]
-1
View File
@@ -1,6 +1,5 @@
module Dodge.Graph module Dodge.Graph
where where
import Data.Function (on)
import Data.List.Extra import Data.List.Extra
import Data.Bifunctor (first) import Data.Bifunctor (first)
+1 -6
View File
@@ -1,10 +1,9 @@
module Dodge.Initialisation where module Dodge.Initialisation where
-- imports {{{
import Dodge.Default import Dodge.Default
import Dodge.Data import Dodge.Data
import Dodge.Data.Menu import Dodge.Data.Menu
import Dodge.Creature import Dodge.Creature
import Dodge.Base --import Dodge.Base
import Dodge.Floor import Dodge.Floor
import Dodge.Layout import Dodge.Layout
@@ -13,10 +12,6 @@ import qualified Data.Set as S
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import qualified Data.Map as M import qualified Data.Map as M
import Foreign.ForeignPtr
import Control.Concurrent
import Data.Tree
initializeWorld :: World -> World initializeWorld :: World -> World
initializeWorld w = w initializeWorld w = w
+5 -16
View File
@@ -6,9 +6,8 @@ import Geometry
import Data.Maybe import Data.Maybe
import Data.List import Data.List
import Data.Function (on)
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import System.Random --import System.Random
import Control.Lens import Control.Lens
checkInvSlotsYou' :: Maybe Item -> World -> Maybe Int checkInvSlotsYou' :: Maybe Item -> World -> Maybe Int
@@ -39,7 +38,7 @@ checkInvSlots it its = fmap fst $ find cond $ IM.toList its
addItem :: Item -> Item -> Item addItem :: Item -> Item -> Item
addItem it NoItem = it addItem it NoItem = it
addItem it it' = it' & itAmount +~ 1 addItem _ it' = it' & itAmount +~ 1
numInventorySlots :: Int numInventorySlots :: Int
numInventorySlots = 9 numInventorySlots = 9
@@ -52,19 +51,9 @@ rmInvItem
-> Int -- ^ Inventory position -> Int -- ^ Inventory position
-> World -> World
-> World -> World
rmInvItem n i w = rmInvItem cid itid w = case w ^? creatures . ix cid . crInv . ix itid . itAmount of
let item = _crInv (_creatures w IM.! n) IM.! i Just x | x > 1 -> w & creatures . ix cid . crInv . ix itid . itAmount %~ subtract 1
itRef = creatures . ix n . crInv . ix i _ -> w & creatures . ix cid . crInv . ix itid .~ NoItem
in case item of
Consumable {_itAmount = 1} -> set itRef NoItem w
Craftable {_itAmount = 1} -> set itRef NoItem w
Equipment {_itAmount = 1} -> set itRef NoItem w
Throwable {_itAmount = 1} -> set itRef NoItem w
Consumable {_itAmount = x} -> over (itRef . itAmount) (\y-> y-1) w
Craftable {_itAmount = x} -> over (itRef . itAmount) (\y-> y-1) w
Equipment {_itAmount = x} -> over (itRef . itAmount) (\y-> y-1) w
Throwable {_itAmount = x} -> over (itRef . itAmount) (\y-> y-1) w
_ -> set itRef NoItem w
{- Delete a creature's selected item, the item will no longer exist. -} {- Delete a creature's selected item, the item will no longer exist. -}
rmSelectedInvItem rmSelectedInvItem
:: Int -- ^ Creature id :: Int -- ^ Creature id
+5 -4
View File
@@ -1,8 +1,7 @@
module Dodge.Item module Dodge.Item
where where
import Dodge.Data import Dodge.Data
import Dodge.Base --import Dodge.Base
import Dodge.Default import Dodge.Default
import Dodge.Picture import Dodge.Picture
import Picture import Picture
@@ -14,7 +13,7 @@ keyToken n = defaultEquipment
, _itMaxStack = 5 , _itMaxStack = 5
, _itAmount = 1 , _itAmount = 1
, _itFloorPict = setDepth 0.5 keyPic , _itFloorPict = setDepth 0.5 keyPic
, _itEquipPict = \cr _ -> setDepth 0 $ translate (-5) (-5) $ rotate (pi/2.5) keyPic , _itEquipPict = \_ _ -> setDepth 0 $ translate (-5) (-5) $ rotate (pi/2.5) keyPic
, _itEffect = NoItEffect , _itEffect = NoItEffect
, _itHammer = HammerUp , _itHammer = HammerUp
, _itID = Nothing , _itID = Nothing
@@ -24,6 +23,7 @@ keyToken n = defaultEquipment
, _itInvColor = yellow , _itInvColor = yellow
, _itInvDisplay = _itName , _itInvDisplay = _itName
} }
keyPic :: Picture
keyPic = color green $ keyPic = color green $
pictures [translate (-4) 0 $ thickCircle 4 2 pictures [translate (-4) 0 $ thickCircle 4 2
,lineOfThickness 2 [(0,0),(8,0),(8,-4)] ,lineOfThickness 2 [(0,0),(8,0),(8,-4)]
@@ -37,7 +37,7 @@ latchkey n = defaultEquipment
, _itMaxStack = 1 , _itMaxStack = 1
, _itAmount = 1 , _itAmount = 1
, _itFloorPict = setDepth 0.5 latchkeyPic , _itFloorPict = setDepth 0.5 latchkeyPic
, _itEquipPict = \cr _ -> setDepth 0 $ translate (-5) (-5) $ rotate (pi/2.5) latchkeyPic , _itEquipPict = \_ _ -> setDepth 0 $ translate (-5) (-5) $ rotate (pi/2.5) latchkeyPic
, _itEffect = NoItEffect , _itEffect = NoItEffect
, _itHammer = HammerUp , _itHammer = HammerUp
, _itID = Nothing , _itID = Nothing
@@ -47,6 +47,7 @@ latchkey n = defaultEquipment
, _itInvColor = yellow , _itInvColor = yellow
, _itInvDisplay = _itName , _itInvDisplay = _itName
} }
latchkeyPic :: Picture
latchkeyPic = color yellow $ latchkeyPic = color yellow $
pictures [translate (-4) 0 $ thickCircle 4 2 pictures [translate (-4) 0 $ thickCircle 4 2
,lineOfThickness 2 [(0,0),(8,0),(8,-4)] ,lineOfThickness 2 [(0,0),(8,0),(8,-4)]
+13 -13
View File
@@ -39,19 +39,19 @@ charFiringStrat
charFiringStrat strats cid w = case w ^? creatures . ix cid . crInv charFiringStrat strats cid w = case w ^? creatures . ix cid . crInv
. ix (_crInvSel $ _creatures w IM.! cid) . itAttachment . _Just . itCharMode of . ix (_crInvSel $ _creatures w IM.! cid) . itAttachment . _Just . itCharMode of
Just (c :<| _) -> fromJust (Prelude.lookup c strats) cid w Just (c :<| _) -> fromJust (Prelude.lookup c strats) cid w
Nothing -> w _ -> w
increaseFuse increaseFuse
:: Int -- ^ Old fuse time :: Int -- ^ Old fuse time
-> Int -- ^ Inventory item reference (I believe) -> Int -- ^ Inventory item reference (I believe)
-> World -> World
-> World -> World
increaseFuse fuse itID w = w increaseFuse fuse itid w = w
& creatures . ix 0 . crInv . ix itID . itScrollUp .~ decreaseFuse newTime & creatures . ix 0 . crInv . ix itid %~
& creatures . ix 0 . crInv . ix itID . itScrollDown .~ increaseFuse newTime ( itScrollUp .~ decreaseFuse newTime )
& creatures . ix 0 . crInv . ix itID . itAttachment ?~ ItFuse newTime . (itScrollDown .~ increaseFuse newTime )
& creatures . ix 0 . crInv . ix itID . itZoom . ( itAttachment ?~ ItFuse newTime )
.~ (defaultItZoom {_itAimZoomMax = zm, _itAimZoomMin = zm}) . ( itZoom .~ defaultItZoom{_itAimZoomMax = zm, _itAimZoomMin = zm} )
where where
newTime = min (fuse + 5) 90 newTime = min (fuse + 5) 90
zm = 50 / fromIntegral newTime zm = 50 / fromIntegral newTime
@@ -60,12 +60,12 @@ decreaseFuse
:: Int -- ^ Old fuse time :: Int -- ^ Old fuse time
-> Int -- ^ Inventory item reference (I believe) -> Int -- ^ Inventory item reference (I believe)
-> World -> World -> World -> World
decreaseFuse fuse itID w = w decreaseFuse fuse itid w = w
& creatures . ix 0 . crInv . ix itID . itScrollUp .~ decreaseFuse newTime & creatures . ix 0 . crInv . ix itid %~
& creatures . ix 0 . crInv . ix itID . itScrollDown .~ increaseFuse newTime ( itScrollUp .~ decreaseFuse newTime )
& creatures . ix 0 . crInv . ix itID . itAttachment ?~ ItFuse newTime . ( itScrollDown .~ increaseFuse newTime )
& creatures . ix 0 . crInv . ix itID . itZoom . ( itAttachment ?~ ItFuse newTime )
.~ (defaultItZoom {_itAimZoomMax = zm, _itAimZoomMin = zm}) . ( itZoom .~ defaultItZoom {_itAimZoomMax = zm, _itAimZoomMin = zm} )
where where
newTime = max (fuse - 5) 20 newTime = max (fuse - 5) 20
zm = 50 / fromIntegral newTime zm = 50 / fromIntegral newTime
+60
View File
@@ -0,0 +1,60 @@
module Dodge.Item.Equipment
where
import Dodge.Data
import Dodge.Default
import Dodge.Picture.Layer
import Picture
import Geometry
magShield :: Item
magShield = defaultEquipment
{ _itIdentity = MagShield
, _itName = "MAGSHIELD"
, _itMaxStack = 1
, _itAmount = 1
, _itFloorPict = onLayer FlItLayer $ polygon [(-3,-3),(-3,3),(3,3),(3,-3)]
, _itEquipPict = \_ _ -> blank
, _itID = Nothing
}
flameShield, frontArmour :: Item
flameShield = defaultEquipment
{ _itIdentity = FlameShield
, _itName = "FLAMESHIELD"
, _itMaxStack = 1
, _itAmount = 1
, _itFloorPict = onLayer FlItLayer $ polygon [(-3,-3),(-3,3),(3,3),(3,-3)]
, _itEquipPict = \cr _ -> onLayer CrLayer $ pictures [color cyan $ circle (_crRad cr+2)]
, _itID = Nothing
}
{- |
Slows you down, blocks forward projectiles. -}
frontArmour = defaultEquipment
{ _itIdentity = FrontArmour
, _itName = "FARMOUR"
, _itMaxStack = 1
, _itAmount = 1
, _itFloorPict = onLayer FlItLayer $ translate 0 (-5) $ pictures
[color (greyN 0.1) $ thickArc 0 (pi/2) 10 5
,color (greyN 0.1) $ thickArc (3*pi/2) (2*pi) 10 5
]
, _itEquipPict = \_ _ -> onLayer CrLayer $ pictures
[color (greyN 0.1) $ thickArc 0 (pi/2) 10 5
,color (greyN 0.1) $ thickArc (3*pi/2) (2*pi) 10 5
]
, _itEffect = NoItEffect
, _itID = Nothing
}
{- |
Increases speed, reduces friction, cannot only move forwards. -}
jetPack :: Item
jetPack = defaultEquipment
{ _itIdentity = JetPack
, _itName = "JETPACK"
, _itMaxStack = 1
, _itAmount = 1
, _itFloorPict = onLayer FlItLayer $ color yellow $ polygon [(-3,-3),(-3,3),(3,3),(3,-3)]
, _itEquipPict = \_ _ -> onLayer CrLayer
$ pictures [color yellow $ polygon $ rectNSEW 5 (-5) (-3) (-11) ]
, _itEffect = NoItEffect
, _itID = Nothing
}
+59 -85
View File
@@ -1,8 +1,6 @@
{- | Definitions of weapons. {- | Definitions of weapons.
In progress: move out effects into other modules. -} In progress: move out effects into other modules. -}
module Dodge.Item.Weapon module Dodge.Item.Weapon
( module Dodge.Item.Weapon
)
where where
import Dodge.Data import Dodge.Data
import Dodge.Base import Dodge.Base
@@ -14,7 +12,7 @@ import Dodge.WorldEvent
import Dodge.Default import Dodge.Default
import Dodge.Item.Draw import Dodge.Item.Draw
import Dodge.Item.Weapon.Bullet import Dodge.Item.Weapon.Bullet
import Dodge.Item.Weapon.Decoration --import Dodge.Item.Weapon.Decoration
import Dodge.Item.Weapon.InventoryDisplay import Dodge.Item.Weapon.InventoryDisplay
import Dodge.Item.Weapon.TriggerType import Dodge.Item.Weapon.TriggerType
import Dodge.Item.Weapon.ExtraEffect import Dodge.Item.Weapon.ExtraEffect
@@ -26,27 +24,43 @@ import Dodge.Item.Attachment
import Geometry import Geometry
import Picture import Picture
import Data.List --import Data.List
import Data.Char --import Data.Char
import Data.Maybe import Data.Maybe
import Data.Function import Data.Function
import qualified Data.ByteString as B --import qualified Data.ByteString as B
import qualified Data.Sequence as Seq import qualified Data.Sequence as Seq
import Control.Lens import Control.Lens
import Control.Applicative import Control.Applicative
import Control.Monad.State import Control.Monad.State
import Control.Monad --import Control.Monad
import qualified SDL import qualified SDL
import System.Random import System.Random
import qualified Data.Set as S import qualified Data.Set as S
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import qualified Data.Map as M --import qualified Data.Map as M
import Foreign.ForeignPtr
pistol,lasGun,tractorGun,launcher,autoGun pistol
,lasGun
,tractorGun
,launcher
,autoGun
,ltAutoGun
,hvAutoGun
,miniGun
,teslaGun ,teslaGun
,spreadGun ,spreadGun
,multGun ,multGun
,defaultGun
,defaultAutoGun
,rezGun
,flameLauncher
,poisonLauncher
,teslaLauncher
,remoteLauncher
,bezierGun
,poisonSprayer
,defaultThrowable
-- ,shatterGun -- ,shatterGun
,longGun,flamer,blinkGun,forceFieldGun :: Item ,longGun,flamer,blinkGun,forceFieldGun :: Item
pistol = Weapon pistol = Weapon
@@ -130,6 +144,7 @@ autoGun = defaultGun
, _itScrollDown = decCharMode , _itScrollDown = decCharMode
, _itInvDisplay = basicWeaponDisplay , _itInvDisplay = basicWeaponDisplay
} }
autoFireMode, singleFireMode, autoGunNonTwistEff :: Int -> World -> World
autoFireMode = shootWithSound (fromIntegral autoGunSound) autoFireMode = shootWithSound (fromIntegral autoGunSound)
. torqueBefore 0.05 . torqueBefore 0.05
$ autoGunNonTwistEff $ autoGunNonTwistEff
@@ -714,10 +729,7 @@ moveShell time i cid rot accel w
smokeGen = makeSmokeCloudAt (oldPos +.+ r1 +.+ 30 *.* normalizeV (oldPos -.- newPos)) smokeGen = makeSmokeCloudAt (oldPos +.+ r1 +.+ 30 *.* normalizeV (oldPos -.- newPos))
rot' = rot * 0.995 rot' = rot * 0.995
normalizeAnglePi angle shellPic :: Picture
| normalizeAngle angle > pi = normalizeAngle angle - 2*pi
| otherwise = normalizeAngle angle
shellPic = color black $ polygon [(-6,4),(-6,-4),(6,-4),(8,0),(6,4)] shellPic = color black $ polygon [(-6,4),(-6,-4),(6,-4),(8,0),(6,4)]
remoteShellPic :: Int -> Picture remoteShellPic :: Int -> Picture
remoteShellPic i remoteShellPic i
@@ -730,6 +742,7 @@ remoteShellPic i
col | i > (-99) = green col | i > (-99) = green
| otherwise = red | otherwise = red
shellExplosionAt :: Point2 -> World -> World
shellExplosionAt = makeExplosionAt shellExplosionAt = makeExplosionAt
aGasCloud :: Int -> World -> World aGasCloud :: Int -> World -> World
@@ -739,8 +752,8 @@ aGasCloud cid w = insertCloud $ set randGen g w
cr = _creatures w IM.! cid cr = _creatures w IM.! cid
dir = _crDir cr + a dir = _crDir cr + a
pos = _crPos cr +.+ ((_crRad cr + 2.9) *.* unitVectorAtAngle (_crDir cr)) pos = _crPos cr +.+ ((_crRad cr + 2.9) *.* unitVectorAtAngle (_crDir cr))
pos2 = (0.5 *.* vel) +.+ --pos2 = (0.5 *.* vel) +.+
_crPos cr +.+ ((_crRad cr + 2.9) *.* unitVectorAtAngle (_crDir cr)) -- _crPos cr +.+ ((_crRad cr + 2.9) *.* unitVectorAtAngle (_crDir cr))
vel = (_crPos cr -.- _crOldPos cr) +.+ 10 *.* unitVectorAtAngle dir vel = (_crPos cr -.- _crOldPos cr) +.+ 10 *.* unitVectorAtAngle dir
insertCloud = makeGasCloud pos vel -- . makeFlame pos2 vel (Just cid) insertCloud = makeGasCloud pos vel -- . makeFlame pos2 vel (Just cid)
@@ -761,6 +774,8 @@ reflect :: Float -> Float -> Float
reflect a b = a + 2*(a-b) reflect a b = a + 2*(a-b)
pointToItem :: Applicative f =>
ItemPos -> (Item -> f Item) -> World -> f World
pointToItem (InInv cid invid) = creatures . ix cid . crInv . ix invid pointToItem (InInv cid invid) = creatures . ix cid . crInv . ix invid
pointToItem (OnFloor flid) = floorItems . ix flid . flIt pointToItem (OnFloor flid) = floorItems . ix flid . flIt
@@ -880,8 +895,8 @@ flameGrenade = grenade {
, _twFire = throwGrenade makeFlameExplosionAt , _twFire = throwGrenade makeFlameExplosionAt
} }
where where
fuseTime = 50 fuseTime = 50 :: Int
f x = 50 / fromIntegral x --f x = 50 / fromIntegral x
teslaGrenade :: Item teslaGrenade :: Item
teslaGrenade = grenade { teslaGrenade = grenade {
@@ -889,8 +904,8 @@ teslaGrenade = grenade {
, _twFire = throwGrenade makeTeslaExplosionAt , _twFire = throwGrenade makeTeslaExplosionAt
} }
where where
fuseTime = 50 fuseTime = 50 :: Int
f x = 50 / fromIntegral x --f x = 50 / fromIntegral x
defaultThrowable = grenade defaultThrowable = grenade
remoteBomb = defaultThrowable remoteBomb = defaultThrowable
@@ -941,7 +956,7 @@ fireRemoteLauncher cid w = setLocation
itid = fromMaybe newitid maybeitid itid = fromMaybe newitid maybeitid
moveRemoteShell :: Int -> Int -> Int -> Int -> Float -> World -> World moveRemoteShell :: Int -> Int -> Int -> Int -> Float -> World -> World
moveRemoteShell time i cid itid dir w moveRemoteShell time i cid itid _ w
| time > 40 = if circOnSomeWall oldPos 4 w | time > 40 = if circOnSomeWall oldPos 4 w
then doExplosion w then doExplosion w
else over (projectiles . ix i . pjPos) (+.+ vel) else over (projectiles . ix i . pjPos) (+.+ vel)
@@ -951,7 +966,7 @@ moveRemoteShell time i cid itid dir w
$ setScope $ setScope
w w
| time >= 20 = case thingHit of | time >= 20 = case thingHit of
Just p -> doExplosion w Just _ -> doExplosion w
Nothing -> over (projectiles . ix i . pjPos) (+.+ vel) Nothing -> over (projectiles . ix i . pjPos) (+.+ vel)
$ set (projectiles . ix i . pjPict) pic $ set (projectiles . ix i . pjPict) pic
$ set (projectiles . ix i . pjUpdate) $ set (projectiles . ix i . pjUpdate)
@@ -959,7 +974,7 @@ moveRemoteShell time i cid itid dir w
$ setScope $ setScope
w w
| time > -99 = case thingHit of | time > -99 = case thingHit of
Just p -> doExplosion Just _ -> doExplosion
$ stopSoundFrom (ShellSound i) $ stopSoundFrom (ShellSound i)
w w
Nothing -> over (projectiles . ix i . pjPos) (+.+ vel) Nothing -> over (projectiles . ix i . pjPos) (+.+ vel)
@@ -973,7 +988,7 @@ moveRemoteShell time i cid itid dir w
$ setScope $ setScope
w w
| time > -200 = case thingHit of | time > -200 = case thingHit of
Just p -> doExplosion Just _ -> doExplosion
$ stopSoundFrom (ShellSound i) $ stopSoundFrom (ShellSound i)
w w
Nothing -> over (projectiles . ix i . pjPos) (+.+ vel) Nothing -> over (projectiles . ix i . pjPos) (+.+ vel)
@@ -1011,18 +1026,18 @@ moveRemoteShell time i cid itid dir w
smokeGen = makeSmokeCloudAt $ oldPos +.+ r1 +.+ 30 *.* normalizeV (oldPos -.- newPos) smokeGen = makeSmokeCloudAt $ oldPos +.+ r1 +.+ 30 *.* normalizeV (oldPos -.- newPos)
doExplosion = explodeRemoteRocket itid i cid doExplosion = explodeRemoteRocket itid i cid
setScope w' = case _itemPositions w' IM.! itid of setScope w' = case _itemPositions w' IM.! itid of
InInv cid invid InInv cid' invid
-> w' & creatures . ix cid . crInv . ix invid . itAttachment -> w' & creatures . ix cid' . crInv . ix invid . itAttachment
. _Just . scopePos .~ (newPos -.- _crPos (_creatures w' IM.! cid)) . _Just . scopePos .~ (newPos -.- _crPos (_creatures w' IM.! cid'))
_ -> w' _ -> w'
explodeRemoteRocket explodeRemoteRocket
:: Int -- ^ Item id :: Int -- ^ Item id
-> Int -- ^ Projectile id -> Int -- ^ Projectile id
-> Int -> Int -- ^ (Probably) firing creature id
-> World -> World
-> World -> World
explodeRemoteRocket itid pjid n w explodeRemoteRocket itid pjid _ w
= set (projectiles . ix pjid . pjUpdate) (retireRemoteRocket itid 30 pjid) = set (projectiles . ix pjid . pjUpdate) (retireRemoteRocket itid 30 pjid)
$ set (projectiles . ix pjid . pjPict) blank $ set (projectiles . ix pjid . pjPict) blank
$ set (itPoint . wpFire) (const id) $ set (itPoint . wpFire) (const id)
@@ -1046,7 +1061,7 @@ throwRemoteBomb n w = setLocation $ removePict $ resetFire
} }
i = newProjectileKey w i = newProjectileKey w
-- fireDist = zoom *.* (rotateV (_cameraRot w) (_mousePos w) +.+ _cameraCenter w -.- yourPos) -- fireDist = zoom *.* (rotateV (_cameraRot w) (_mousePos w) +.+ _cameraCenter w -.- yourPos)
d = argV $ _mousePos w --d = argV $ _mousePos w
--(l, _) = randomR (1 - grenadeAccL,1+grenadeAccL) (_randGen w) --(l, _) = randomR (1 - grenadeAccL,1+grenadeAccL) (_randGen w)
--(a, g) = randomR (-grenadeAccA,grenadeAccA) (_randGen w) --(a, g) = randomR (-grenadeAccA,grenadeAccA) (_randGen w)
v' = 0.02 / _cameraZoom w *.* rotateV (_cameraRot w) ( _mousePos w) v' = 0.02 / _cameraZoom w *.* rotateV (_cameraRot w) ( _mousePos w)
@@ -1087,78 +1102,34 @@ explodeRemoteBomb itid pjid n w
(drawWeapon remoteBombUnarmedPic) (drawWeapon remoteBombUnarmedPic)
-- resetScope = creatures . ix n . crInv . ix j . itScope . _Just . scopePos .~ (0,0) -- resetScope = creatures . ix n . crInv . ix j . itScope . _Just . scopePos .~ (0,0)
j = _crInvSel $ _creatures w IM.! n j = _crInvSel $ _creatures w IM.! n
remoteBombPic :: Int -> Picture remoteBombPic
remoteBombPic x = pictures :: Int -- ^ time
-> Picture
remoteBombPic _ = pictures
[ color (dark $ dark orange) $ circleSolid 5 [ color (dark $ dark orange) $ circleSolid 5
] ]
remoteBombUnarmedPic :: Picture remoteBombUnarmedPic :: Picture
remoteBombUnarmedPic = color (dark $ dark orange) $ circleSolid 5 remoteBombUnarmedPic = color (dark $ dark orange) $ circleSolid 5
spreadGunSpread,autogunSpread :: Float spreadGunSpread,autogunSpread :: Float
spreadGunSpread = 0.5 spreadGunSpread = 0.5
autogunSpread = 0.07 autogunSpread = 0.07
pipe :: Item
pipe = Craftable pipe = Craftable
{ _itIdentity = Generic { _itIdentity = Generic
, _itName = "PIPE" , _itName = "PIPE"
, _itMaxStack = 3 , _itMaxStack = 3
, _itAmount = 3 , _itAmount = 3
, _itFloorPict = onLayer FlItLayer $ polygon [(-3,-3),(-3,3),(3,3),(3,-3)] , _itFloorPict = onLayer FlItLayer $ polygon [(-3,-3),(-3,3),(3,3),(3,-3)]
, _itEquipPict = \cr _ -> blank , _itEquipPict = \_ _ -> blank
, _itID = Nothing , _itID = Nothing
, _itInvDisplay = _itName , _itInvDisplay = _itName
, _itInvColor = green , _itInvColor = green
} }
magShield = defaultEquipment
{ _itIdentity = MagShield
, _itName = "MAGSHIELD"
, _itMaxStack = 1
, _itAmount = 1
, _itFloorPict = onLayer FlItLayer $ polygon [(-3,-3),(-3,3),(3,3),(3,-3)]
, _itEquipPict = \cr _ -> blank
, _itID = Nothing
}
flameShield = defaultEquipment
{ _itIdentity = FlameShield
, _itName = "FLAMESHIELD"
, _itMaxStack = 1
, _itAmount = 1
, _itFloorPict = onLayer FlItLayer $ polygon [(-3,-3),(-3,3),(3,3),(3,-3)]
, _itEquipPict = \cr _ -> onLayer CrLayer $ pictures [color cyan $ circle (_crRad cr+2)]
, _itID = Nothing
}
{- |
Slows you down, blocks forward projectiles. -}
frontArmour = defaultEquipment
{ _itIdentity = FrontArmour
, _itName = "FARMOUR"
, _itMaxStack = 1
, _itAmount = 1
, _itFloorPict = onLayer FlItLayer $ translate 0 (-5) $ pictures
[color (greyN 0.1) $ thickArc 0 (pi/2) 10 5
,color (greyN 0.1) $ thickArc (3*pi/2) (2*pi) 10 5
]
, _itEquipPict = \cr _ -> onLayer CrLayer $ pictures
[color (greyN 0.1) $ thickArc 0 (pi/2) 10 5
,color (greyN 0.1) $ thickArc (3*pi/2) (2*pi) 10 5
]
, _itEffect = NoItEffect
, _itID = Nothing
}
{- |
Increases speed, reduces friction, cannot only move forwards. -}
jetPack = defaultEquipment
{ _itIdentity = JetPack
, _itName = "JETPACK"
, _itMaxStack = 1
, _itAmount = 1
, _itFloorPict = onLayer FlItLayer $ color yellow $ polygon [(-3,-3),(-3,3),(3,3),(3,-3)]
, _itEquipPict = \_ _ -> onLayer CrLayer
$ pictures [color yellow $ polygon $ rectNSEW 5 (-5) (-3) (-11) ]
, _itEffect = NoItEffect
, _itID = Nothing
}
{- | {- |
Sends out pulses that display walls. -} Sends out pulses that display walls. -}
radar :: Item
radar = defaultGun radar = defaultGun
{ _itName = "RADAR" { _itName = "RADAR"
, _itIdentity = Generic , _itIdentity = Generic
@@ -1181,6 +1152,7 @@ radar = defaultGun
} }
{- | {- |
Sends out pulses that display creatures. -} Sends out pulses that display creatures. -}
sonar :: Item
sonar = defaultGun sonar = defaultGun
{ _itName = "SONAR" { _itName = "SONAR"
, _itIdentity = Generic , _itIdentity = Generic
@@ -1202,13 +1174,14 @@ sonar = defaultGun
} }
{- | {- |
Automatically sends out pulses that display creatures. -} Automatically sends out pulses that display creatures. -}
autoSonar :: Item
autoSonar = defaultEquipment autoSonar = defaultEquipment
{ _itIdentity = Generic { _itIdentity = Generic
, _itName = "AUTOSONAR" , _itName = "AUTOSONAR"
, _itMaxStack = 1 , _itMaxStack = 1
, _itAmount = 1 , _itAmount = 1
, _itFloorPict = onLayer FlItLayer $ color yellow $ polygon [(-3,-3),(-3,3),(3,3),(3,-3)] , _itFloorPict = onLayer FlItLayer $ color yellow $ polygon [(-3,-3),(-3,3),(3,3),(3,-3)]
, _itEquipPict = \cr _ -> blank , _itEquipPict = \_ _ -> blank
, _itEffect = autoSonarEffect , _itEffect = autoSonarEffect
, _itID = Nothing , _itID = Nothing
, _itAimingSpeed = 1 , _itAimingSpeed = 1
@@ -1217,13 +1190,14 @@ autoSonar = defaultEquipment
} }
{- | {- |
Automatically sends out pulses that display walls. -} Automatically sends out pulses that display walls. -}
autoRadar :: Item
autoRadar = defaultEquipment autoRadar = defaultEquipment
{ _itIdentity = Generic { _itIdentity = Generic
, _itName = "AUTORADAR" , _itName = "AUTORADAR"
, _itMaxStack = 1 , _itMaxStack = 1
, _itAmount = 1 , _itAmount = 1
, _itFloorPict = onLayer FlItLayer $ color yellow $ polygon [(-3,-3),(-3,3),(3,3),(3,-3)] , _itFloorPict = onLayer FlItLayer $ color yellow $ polygon [(-3,-3),(-3,3),(3,3),(3,-3)]
, _itEquipPict = \cr _ -> blank , _itEquipPict = \_ _ -> blank
, _itEffect = autoRadarEffect , _itEffect = autoRadarEffect
, _itID = Nothing , _itID = Nothing
, _itAimingSpeed = 1 , _itAimingSpeed = 1
+22 -46
View File
@@ -4,8 +4,9 @@ Effects of bullets upon impact with walls or creatures, and possibly force field
module Dodge.Item.Weapon.Bullet module Dodge.Item.Weapon.Bullet
where where
import Dodge.Data import Dodge.Data
import Dodge.Base --import Dodge.Base
import Dodge.WorldEvent import Dodge.WorldEvent
import Dodge.WorldEvent.DamageBlock
import Dodge.SoundLogic import Dodge.SoundLogic
import Dodge.RandomHelp import Dodge.RandomHelp
import Dodge.WorldEvent.Shockwave import Dodge.WorldEvent.Shockwave
@@ -17,14 +18,14 @@ import Picture
import System.Random import System.Random
import Control.Lens import Control.Lens
import Control.Monad.State import Control.Monad.State
import qualified Data.IntMap.Strict as IM --import Data.Maybe
--import qualified Data.IntMap.Strict as IM
-- | Basic bullet hit creature effect. -- | Basic bullet hit creature effect.
bulHitCr' :: Particle -> Point2 -> Creature -> World -> World bulHitCr' :: Particle -> Point2 -> Creature -> World -> World
bulHitCr' bt p cr w bulHitCr' bt p cr w
| crIsArmouredFrom p cr | crIsArmouredFrom p cr
= createSpark 8 colID p1 (argV (p1 -.- p) + d1) Nothing . addDamageArmoured $ w = createSpark 8 colID p1 (argV (p1 -.- p) + d1) Nothing . addDamageArmoured $ w
| otherwise | otherwise = addDamage . makeHitSound . flashEff $ w
= addDamage . hitSound . flashEff $ w
where where
sp = head $ _btTrail' bt sp = head $ _btTrail' bt
bulVel = _btVel' bt bulVel = _btVel' bt
@@ -32,19 +33,17 @@ bulHitCr' bt p cr w
mvDams = [ PushDam 1 $ 2 *.* bulVel ] mvDams = [ PushDam 1 $ 2 *.* bulVel ]
addDamage = creatures . ix cid . crState . crDamage %~ ((Piercing 100 sp p ep : mvDams) ++ ) addDamage = creatures . ix cid . crState . crDamage %~ ((Piercing 100 sp p ep : mvDams) ++ )
addDamageArmoured = creatures . ix cid . crState . crDamage %~ (mvDams ++) addDamageArmoured = creatures . ix cid . crState . crDamage %~ (mvDams ++)
hitSound = soundMultiFrom [CrHitSound 0] 15 10 0 makeHitSound = soundMultiFrom [CrHitSound 0] 15 10 0
flashEff = over worldEvents (bloodFlashAt p . ) flashEff = over worldEvents (bloodFlashAt p . )
cid = _crID cr cid = _crID cr
(d1,g) = randomR (-0.7,0.7) $ _randGen w (d1,_) = randomR (-0.7,0.7) $ _randGen w
(colID,_) = randomR (0,11) $ _randGen w (colID,_) = randomR (0,11) $ _randGen w
p1 = p +.+ 2 *.* safeNormalizeV (p -.- _crPos cr) p1 = p +.+ 2 *.* safeNormalizeV (p -.- _crPos cr)
{- | Bounce off armoured creatures, otherwise do damage. -} {- | Bounce off armoured creatures, otherwise do damage. -}
bulBounceArmCr' :: Particle -> Point2 -> Creature -> World -> World bulBounceArmCr' :: Particle -> Point2 -> Creature -> World -> World
bulBounceArmCr' bt p cr w bulBounceArmCr' bt p cr w
| crIsArmouredFrom p cr | crIsArmouredFrom p cr = addBouncer . addDamageArmoured $ w
= addBouncer . addDamageArmoured $ w | otherwise = addDamage . makeHitSound . flashEff $ w
| otherwise
= addDamage . hitSound . flashEff $ w
where where
sp = head $ _btTrail' bt sp = head $ _btTrail' bt
bulVel = _btVel' bt bulVel = _btVel' bt
@@ -52,7 +51,7 @@ bulBounceArmCr' bt p cr w
mvDams = [ PushDam 1 $ 2 *.* bulVel ] mvDams = [ PushDam 1 $ 2 *.* bulVel ]
addDamage = creatures . ix cid . crState . crDamage %~ ((Piercing 100 sp p ep : mvDams) ++ ) addDamage = creatures . ix cid . crState . crDamage %~ ((Piercing 100 sp p ep : mvDams) ++ )
addDamageArmoured = creatures . ix cid . crState . crDamage %~ (mvDams ++) addDamageArmoured = creatures . ix cid . crState . crDamage %~ (mvDams ++)
hitSound = soundMultiFrom [CrHitSound 0] 15 10 0 makeHitSound = soundMultiFrom [CrHitSound 0] 15 10 0
flashEff = over worldEvents ((.) $ bloodFlashAt p) flashEff = over worldEvents ((.) $ bloodFlashAt p)
cid = _crID cr cid = _crID cr
newDir = safeNormalizeV (p -.- _crPos cr) newDir = safeNormalizeV (p -.- _crPos cr)
@@ -77,7 +76,7 @@ bulPenCr' bt p cr w
$ over worldEvents (addPiercer . ) $ over worldEvents (addPiercer . )
w w
where where
(d1,g) = randomR (-0.7,0.7) $ _randGen w (d1,_) = randomR (-0.7,0.7) $ _randGen w
cid = _crID cr cid = _crID cr
sp = head $ _btTrail' bt sp = head $ _btTrail' bt
ep = sp +.+ _btVel' bt ep = sp +.+ _btVel' bt
@@ -100,7 +99,7 @@ hvBulHitCr' bt p cr w
$ soundMultiFrom [CrHitSound 0] 15 10 0 $ soundMultiFrom [CrHitSound 0] 15 10 0
w w
where where
(d1,g) = randomR (-0.7,0.7) $ _randGen w (d1,_) = randomR (-0.7,0.7) $ _randGen w
cid = _crID cr cid = _crID cr
sp = head $ _btTrail' bt sp = head $ _btTrail' bt
ep = sp +.+ _btVel' bt ep = sp +.+ _btVel' bt
@@ -131,32 +130,24 @@ bulConCr' bt p cr w
sp = head $ _btTrail' bt sp = head $ _btTrail' bt
ep = sp +.+ _btVel' bt ep = sp +.+ _btVel' bt
mkwave = over worldEvents $ (.) (makeShockwaveAt [] p 15 4 1 white) mkwave = over worldEvents $ (.) (makeShockwaveAt [] p 15 4 1 white)
{- | Hitting wall effects: create a spark, damage blocks. -} {- | Hitting wall effects: create a spark, damage blocks. -}
bulHitWall' :: Particle -> Point2 -> Wall -> World -> World bulHitWall' :: Particle -> Point2 -> Wall -> World -> World
bulHitWall' bt p x w = damageBlocks x bulHitWall' bt p x w = damageBlocksBy 5 x
$ createSpark 8 colID pOut (reflectDir x) Nothing $ createSpark 8 12 pOut (reflectDir x) Nothing
$ set randGen g $ set randGen g
w w
where where
sp = head $ _btTrail' bt sp = head $ _btTrail' bt
pOut = p +.+ safeNormalizeV (sp -.- p) pOut = p +.+ safeNormalizeV (sp -.- p)
(colID,g) = randomR (0,11) $ _randGen w (a, g) = randomR (-0.2,0.2) $ _randGen w
(a, _) = randomR (-0.1,0.1) $ _randGen w
spid = newKey $ _projectiles w
reflectDir wall = a + argV (reflectIn (uncurry (-.-) (_wlLine wall)) (p -.- sp) ) reflectDir wall = a + argV (reflectIn (uncurry (-.-) (_wlLine wall)) (p -.- sp) )
damageBlocks wall w = case wall ^? blHP of
Just hp -> foldr (\j -> walls . ix j . blHP -~ 5) w (_blIDs wall)
_ -> w
{- | Bounce off walls, do damage to blocks. -} {- | Bounce off walls, do damage to blocks. -}
bulBounceWall' :: Particle -> Point2 -> Wall -> World -> World bulBounceWall' :: Particle -> Point2 -> Wall -> World -> World
bulBounceWall' bt p wl w = damageBlocks wl $ over worldEvents addBouncer w bulBounceWall' bt p wl w = damageBlocksBy 5 wl $ over worldEvents addBouncer w
where where
sp = head $ _btTrail' bt sp = head $ _btTrail' bt
pOut = p +.+ safeNormalizeV (sp -.- p) pOut = p +.+ safeNormalizeV (sp -.- p)
damageBlocks wall w
= case wall ^? blHP of
Just hp -> foldr (\j -> walls . ix j . blHP -~ 5) w (_blIDs wall)
_ -> w
bouncer = (aGenBulAt' Nothing (_btColor' bt) pOut reflectVel bouncer = (aGenBulAt' Nothing (_btColor' bt) pOut reflectVel
(_btHitEffect' bt) (_btWidth' bt) (_btHitEffect' bt) (_btWidth' bt)
) {_btTimer' = _btTimer' bt - 1} ) {_btTimer' = _btTimer' bt - 1}
@@ -174,14 +165,10 @@ bulIncWall'
-> Wall -> Wall
-> World -> World
-> World -> World
bulIncWall' bt p wl w = damageBlocks wl $ incFlamelets w bulIncWall' bt p wl w = damageBlocksBy 5 wl $ incFlamelets w
where where
sp = head $ _btTrail' bt sp = head $ _btTrail' bt
pOut = p +.+ safeNormalizeV (sp -.- p) pOut = p +.+ safeNormalizeV (sp -.- p)
damageBlocks wall w
= case wall ^? blHP of
Just hp -> foldr (\j -> walls . ix j . blHP -~ 5) w (_blIDs wall)
_ -> w
wallV = uncurry (-.-) (_wlLine wl) wallV = uncurry (-.-) (_wlLine wl)
reflectVel = safeNormalizeV $ reflectIn wallV (_btVel' bt) reflectVel = safeNormalizeV $ reflectIn wallV (_btVel' bt)
incFlamelets = over worldEvents $ (.) (makeFlameletTimed pOut reflectVel Nothing 3 20) incFlamelets = over worldEvents $ (.) (makeFlameletTimed pOut reflectVel Nothing 3 20)
@@ -192,15 +179,8 @@ bulConWall'
-> Wall -> Wall
-> World -> World
-> World -> World
bulConWall' bt p wl w = damageBlocks wl $ mkwave w bulConWall' _ p wl = damageBlocksBy 1 wl .
where over worldEvents ( makeShockwaveAt [] p 15 4 1 white . )
sp = head $ _btTrail' bt
pOut = p +.+ safeNormalizeV (sp -.- p)
damageBlocks wall w
= case wall ^? blHP of
Just hp -> foldr (\j -> walls . ix j . blHP -~ 5) w (_blIDs wall)
_ -> w
mkwave = over worldEvents ( makeShockwaveAt [] p 15 4 1 white . )
hvBulHitWall' hvBulHitWall'
:: Particle :: Particle
@@ -208,18 +188,14 @@ hvBulHitWall'
-> Wall -> Wall
-> World -> World
-> World -> World
hvBulHitWall' bt p x w = damageBlocks x $ set randGen g $ foldr ($) w (sparks pOut sv) hvBulHitWall' bt p x w = damageBlocksBy 5 x $ set randGen g $ foldr ($) w (sparks pOut sv)
where where
sp = head $ _btTrail' bt sp = head $ _btTrail' bt
pOut = p +.+ safeNormalizeV (sp -.- p) pOut = p +.+ safeNormalizeV (sp -.- p)
(a, g) = randomR (-0.1,0.1) $ _randGen w (a, g) = randomR (-0.2,0.2) $ _randGen w
spid = newKey $ _projectiles w
reflectDir wall = a + reflectDir wall = a +
argV (reflectIn (uncurry (-.-) (_wlLine wall)) (p -.- sp) ) argV (reflectIn (uncurry (-.-) (_wlLine wall)) (p -.- sp) )
sv = unitVectorAtAngle $ reflectDir x sv = unitVectorAtAngle $ reflectDir x
damageBlocks wall w = case wall ^? blHP of
Just hp -> foldr (\j -> walls . ix j . blHP -~ 20) w (_blIDs wall)
_ -> w
cs = take 10 $ randomRs (0,11) $ _randGen w cs = take 10 $ randomRs (0,11) $ _randGen w
ds = randomRs (-0.7,0.7) $ _randGen w ds = randomRs (-0.7,0.7) $ _randGen w
ts = randomRs (4,8) $ _randGen w ts = randomRs (4,8) $ _randGen w
+1 -1
View File
@@ -6,7 +6,7 @@ module Dodge.Item.Weapon.Decoration
import Dodge.Data import Dodge.Data
import Dodge.Picture.Layer import Dodge.Picture.Layer
import Dodge.Picture import Dodge.Picture
import Geometry.Data --import Geometry.Data
import Picture import Picture
import Control.Lens import Control.Lens
+11 -7
View File
@@ -28,6 +28,7 @@ wpRecock = ItInvEffect
moveHammerUp HammerDown = HammerReleased moveHammerUp HammerDown = HammerReleased
moveHammerUp HammerReleased = HammerUp moveHammerUp HammerReleased = HammerUp
moveHammerUp HammerUp = HammerUp moveHammerUp HammerUp = HammerUp
moveHammerUp NoHammer = NoHammer
fOnIt it = it & itHammer %~ moveHammerUp fOnIt it = it & itHammer %~ moveHammerUp
{- | {- |
Special recock for the bezier gun. Special recock for the bezier gun.
@@ -64,10 +65,10 @@ itemLaserScopeEffect
sp = p +.+ (r + 3) *.* unitVectorAtAngle d sp = p +.+ (r + 3) *.* unitVectorAtAngle d
xp = sp +.+ 3000 *.* unitVectorAtAngle d xp = sp +.+ 3000 *.* unitVectorAtAngle d
ep = case listToMaybe $ thingsHitLongLine sp xp w of ep = case listToMaybe $ thingsHitLongLine sp xp w of
Just (p,_) -> p Just (pos,_) -> pos
Nothing -> xp Nothing -> xp
glowPoint = case listToMaybe $ thingsHitLongLine sp xp w of glowPoint = case listToMaybe $ thingsHitLongLine sp xp w of
Just (p,E3x2 wl) -> p +.+ 2 *.* wallNormal wl Just (pos,E3x2 wl) -> pos +.+ 2 *.* wallNormal wl
_ -> ep -.- 2 *.* unitVectorAtAngle d _ -> ep -.- 2 *.* unitVectorAtAngle d
it = (cr ^. crInv) IM.! invid it = (cr ^. crInv) IM.! invid
reloadFrac reloadFrac
@@ -79,6 +80,7 @@ Automatically send out radar pulses that detect walls. -}
autoRadarEffect :: ItEffect autoRadarEffect :: ItEffect
autoRadarEffect = ItInvEffect {_itInvEffect = f 50 ,_itEffectCounter = 0 } autoRadarEffect = ItInvEffect {_itInvEffect = f 50 ,_itEffectCounter = 0 }
where where
f :: Int -> Creature -> Int -> World -> World
f 0 cr i w = aRadarPulse (_crID cr) w f 0 cr i w = aRadarPulse (_crID cr) w
& creatures . ix (_crID cr) . crInv . ix i & creatures . ix (_crID cr) . crInv . ix i
. itEffect . itInvEffect .~ f 100 . itEffect . itInvEffect .~ f 100
@@ -89,8 +91,10 @@ autoRadarEffect = ItInvEffect {_itInvEffect = f 50 ,_itEffectCounter = 0 }
Automatically send out sonar pulses that detect creatures. -} Automatically send out sonar pulses that detect creatures. -}
autoSonarEffect :: ItEffect autoSonarEffect :: ItEffect
autoSonarEffect = ItInvEffect {_itInvEffect = f 50 ,_itEffectCounter = 0 } autoSonarEffect = ItInvEffect {_itInvEffect = f 50 ,_itEffectCounter = 0 }
where f 0 cr i w = aSonarPulse (_crID cr) where
w & creatures . ix (_crID cr) . crInv . ix i f :: Int -> Creature -> Int -> World -> World
. itEffect . itInvEffect .~ f 140 f 0 cr i w = aSonarPulse (_crID cr)
f t cr i w = w & creatures . ix (_crID cr) . crInv . ix i w & creatures . ix (_crID cr) . crInv . ix i
. itEffect . itInvEffect .~ f (t-1) . itEffect . itInvEffect .~ f 140
f t cr i w = w & creatures . ix (_crID cr) . crInv . ix i
. itEffect . itInvEffect .~ f (t-1)
+7 -7
View File
@@ -6,14 +6,14 @@ import Dodge.Picture.Layer
import Dodge.SoundLogic import Dodge.SoundLogic
import Dodge.Item.Attachment.Data import Dodge.Item.Attachment.Data
import Dodge.Item.Draw import Dodge.Item.Draw
import Dodge.Default --import Dodge.Default
import Picture import Picture
import Geometry import Geometry
import Control.Lens import Control.Lens
import Data.Maybe (fromJust) import Data.Maybe (fromJust)
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import System.Random --import System.Random
moveGrenade moveGrenade
:: Int -- ^ Timer :: Int -- ^ Timer
@@ -21,7 +21,7 @@ moveGrenade
-> Int -- ^ Projectile id -> Int -- ^ Projectile id
-> World -> World
-> World -> World
moveGrenade 0 dir pID w = over projectiles (IM.delete pID) moveGrenade 0 _ pID w = over projectiles (IM.delete pID)
$ explosion (_pjPos (_projectiles w IM.! pID)) $ explosion (_pjPos (_projectiles w IM.! pID))
w w
where where
@@ -60,7 +60,7 @@ throwGrenade
-> Int -- ^ Creature id -> Int -- ^ Creature id
-> World -> World
-> World -> World
throwGrenade explosion n w = setWp $ removePict $ over projectiles addG $ set randGen g w throwGrenade explosion n w = setWp $ removePict $ over projectiles addG $ w
where where
addG = IM.insert i $ Shell addG = IM.insert i $ Shell
{ _pjPos = p { _pjPos = p
@@ -75,8 +75,8 @@ throwGrenade explosion n w = setWp $ removePict $ over projectiles addG $ set ra
j = _crInvSel cr j = _crInvSel cr
removePict = set (creatures . ix n . crInv . ix j . itEquipPict) $ \ _ _ -> blank removePict = set (creatures . ix n . crInv . ix j . itEquipPict) $ \ _ _ -> blank
i = newProjectileKey w i = newProjectileKey w
(a, g) = randomR (-grenadeAccA,grenadeAccA::Float) (_randGen w) --(_, g) = randomR (-grenadeAccA,grenadeAccA::Float) (_randGen w)
(l, _) = randomR (1 - 2*grenadeAccL,1+grenadeAccL::Float) g --(_, _) = randomR (1 - 2*grenadeAccL,1+grenadeAccL::Float) g
v' = 1 / (fromIntegral fuseTime * _cameraZoom w) *.* rotateV (_cameraRot w) ( _mousePos w) v' = 1 / (fromIntegral fuseTime * _cameraZoom w) *.* rotateV (_cameraRot w) ( _mousePos w)
v | magV v' > 6 = 6 *.* normalizeV v' v | magV v' > 6 = 6 *.* normalizeV v'
| otherwise = v' | otherwise = v'
@@ -98,4 +98,4 @@ throwArmReset x = ItInvEffect {_itInvEffect = f ,_itEffectCounter = x }
& itEquipPict .~ drawWeapon (grenadePic 50) & itEquipPict .~ drawWeapon (grenadePic 50)
| otherwise = it & itEffect . itEffectCounter -~ 1 | otherwise = it & itEffect . itEffectCounter -~ 1
(grenadeAccL, grenadeAccA) = (0.1, 0.1) --(grenadeAccL, grenadeAccA) = (0.1, 0.1)
+3 -8
View File
@@ -9,20 +9,15 @@ import Dodge.Item.Attachment.Data
import Data.Sequence import Data.Sequence
import Control.Lens import Control.Lens
import Control.Monad --import Control.Monad
{- | Displays the item name, ammo if loaded, and any selected '_itCharMode'. -}
-- not sure if this is in the right place...
{- |
Displays the item name, ammo if loaded, and any selected '_itCharMode'.
-}
basicWeaponDisplay :: Item -> String basicWeaponDisplay :: Item -> String
basicWeaponDisplay it = case it ^? itAttachment . _Just of basicWeaponDisplay it = case it ^? itAttachment . _Just of
Just ItCharMode {_itCharMode = (c :<| _)} -> midPadL 10 ' ' (_itName it) (' ' : aIfLoaded) ++ [' ',c] Just ItCharMode {_itCharMode = (c :<| _)} -> midPadL 10 ' ' (_itName it) (' ' : aIfLoaded) ++ [' ',c]
Just ItMode {_itMode = i} -> midPadL 10 ' ' (_itName it) (' ' : aIfLoaded) ++ show i Just ItMode {_itMode = i} -> midPadL 10 ' ' (_itName it) (' ' : aIfLoaded) ++ show i
_ -> midPadL 10 ' ' (_itName it) (' ' : aIfLoaded) _ -> midPadL 10 ' ' (_itName it) (' ' : aIfLoaded)
where where
availableAmmo = show $ _wpMaxAmmo it --availableAmmo = show $ _wpMaxAmmo it
aIfLoaded = case it ^? wpReloadState of aIfLoaded = case it ^? wpReloadState of
Just 0 -> show $ _wpLoadedAmmo it Just 0 -> show $ _wpLoadedAmmo it
Just x -> "R" ++ show x Just x -> "R" ++ show x
+9 -8
View File
@@ -5,7 +5,7 @@ import Dodge.Data
import Dodge.Picture import Dodge.Picture
import Dodge.Picture.Layer import Dodge.Picture.Layer
import Dodge.Item.Attachment.Data import Dodge.Item.Attachment.Data
import Dodge.Base --import Dodge.Base
import Dodge.SoundLogic import Dodge.SoundLogic
import Dodge.WorldEvent.SpawnParticle import Dodge.WorldEvent.SpawnParticle
import Dodge.WorldEvent.ThingsHit import Dodge.WorldEvent.ThingsHit
@@ -30,16 +30,17 @@ aLaser cid w = over particles (makeLaserAt phaseV pos dir (Just cid) : )
w w
where where
cr = _creatures w IM.! cid cr = _creatures w IM.! cid
i = newProjectileKey w
pos = _crPos cr +.+ ((_crRad cr +3) *.* unitVectorAtAngle dir) pos = _crPos cr +.+ ((_crRad cr +3) *.* unitVectorAtAngle dir)
dir = _crDir cr dir = _crDir cr
phaseV = charToPhaseV phaseV = charToPhaseV
$ fromMaybe '/' $ Seq.lookup 0 =<< cr ^? crInv . ix j . itAttachment . _Just . itCharMode $ fromMaybe '/' $ Seq.lookup 0 =<< cr ^? crInv . ix j . itAttachment . _Just . itCharMode
j = _crInvSel cr j = _crInvSel cr
charToPhaseV :: Fractional p => Char -> p
charToPhaseV 'V' = 0.2 charToPhaseV 'V' = 0.2
charToPhaseV '/' = 1 charToPhaseV '/' = 1
charToPhaseV 'Z' = 5 charToPhaseV 'Z' = 5
charToPhaseV _ = error "Trying to set an undefined phaseV"
makeLaserAt :: Float -> Point2 -> Float -> Maybe Int -> Particle makeLaserAt :: Float -> Point2 -> Float -> Maybe Int -> Particle
makeLaserAt phaseV pos dir mcid = Particle makeLaserAt phaseV pos dir mcid = Particle
@@ -55,7 +56,7 @@ moveLaser
-> World -> World
-> Particle -> Particle
-> (World, Maybe Particle) -> (World, Maybe Particle)
moveLaser phaseV pos dir mcid w pt moveLaser phaseV pos dir _ w pt
= ( set randGen g $ hitEffect w = ( set randGen g $ hitEffect w
, Just pt {_ptDraw = const $ onLayer PtLayer pic ,_ptUpdate' = ptTimer' 0 } , Just pt {_ptDraw = const $ onLayer PtLayer pic ,_ptUpdate' = ptTimer' 0 }
) )
@@ -83,10 +84,10 @@ moveLaser phaseV pos dir mcid w pt
angleRef angleRef
| reflectExternal = angleInc | reflectExternal = angleInc
| otherwise = asin $ sin angleInc / phaseV | otherwise = asin $ sin angleInc / phaseV
piRange a piRange a'
| a > pi = a - 2 * pi | a' > pi = a' - 2 * pi
| a > negate pi = a | a' > negate pi = a'
| otherwise = a + 2 * pi | otherwise = a' + 2 * pi
isEntering = not $ isLeftOf (x -.- y) (uncurry (-.-) (_wlLine wl)) isEntering = not $ isLeftOf (x -.- y) (uncurry (-.-) (_wlLine wl))
wlNormal' = vNormal $ uncurry (-.-) (_wlLine wl) wlNormal' = vNormal $ uncurry (-.-) (_wlLine wl)
normalDist' = magV (p -.- y) *.* normalizeV wlNormal' normalDist' = magV (p -.- y) *.* normalizeV wlNormal'
@@ -97,7 +98,7 @@ moveLaser phaseV pos dir mcid w pt
reflectInternal = 1 < abs (phaseV * sin angleInc') reflectInternal = 1 < abs (phaseV * sin angleInc')
reflectExternal = 1 < abs (sin angleInc / phaseV) reflectExternal = 1 < abs (sin angleInc / phaseV)
h' ws (_,E3x2 wl) = not $ any (\w -> _wlID w == _wlID wl) ws h' ws (_,E3x2 wl) = not $ any (\w' -> _wlID w' == _wlID wl) ws
h' _ _ = True h' _ _ = True
(thHit, ps) = f [] pos xp (thHit, ps) = f [] pos xp
hitEffect hitEffect
+4 -7
View File
@@ -114,7 +114,6 @@ withWarmUp t f cid w
item = _crInv cr IM.! itRef item = _crInv cr IM.! itRef
pointerToItem = creatures . ix cid . crInv . ix itRef pointerToItem = creatures . ix cid . crInv . ix itRef
fState = _itUseTime item fState = _itUseTime item
fRate = _itUseRate item
reloadCondition = _wpLoadedAmmo item == 0 reloadCondition = _wpLoadedAmmo item == 0
{- | {- |
Adds a sound to a creature based world effect. Adds a sound to a creature based world effect.
@@ -247,7 +246,6 @@ withMuzFlare
withMuzFlare f cid w = tempLightForAt 3 pos . muzzleFlashAt pos2 $ f cid w withMuzFlare f cid w = tempLightForAt 3 pos . muzzleFlashAt pos2 $ f cid w
where where
cr = _creatures w IM.! cid cr = _creatures w IM.! cid
dir = _crDir cr
pos = _crPos cr +.+ _crRad cr *.* unitVectorAtAngle (_crDir cr) pos = _crPos cr +.+ _crRad cr *.* unitVectorAtAngle (_crDir cr)
pos2 = _crPos cr +.+ (2 * _crRad cr) *.* unitVectorAtAngle (_crDir cr) pos2 = _crPos cr +.+ (2 * _crRad cr) *.* unitVectorAtAngle (_crDir cr)
{- | {- |
@@ -282,7 +280,6 @@ withVelWthHiteff vel width hiteff cid w
(colid, g) = randomR (0,11) $ _randGen w (colid, g) = randomR (0,11) $ _randGen w
dir = _crDir cr dir = _crDir cr
pos = _crPos cr +.+ _crRad cr *.* unitVectorAtAngle (_crDir cr) pos = _crPos cr +.+ _crRad cr *.* unitVectorAtAngle (_crDir cr)
pos2 = _crPos cr +.+ (2 * _crRad cr) *.* unitVectorAtAngle (_crDir cr)
{- | {- |
Translate the creature sideways a random amount, apply the effect, translate back. -} Translate the creature sideways a random amount, apply the effect, translate back. -}
withRandomOffset withRandomOffset
@@ -349,7 +346,7 @@ torqueAfter torque feff cid w
| otherwise = set randGen g $ over (creatures . ix cid . crDir) (+rot) $ feff cid w | otherwise = set randGen g $ over (creatures . ix cid . crDir) (+rot) $ feff cid w
where where
(rot, g) = randomR (-torque,torque) $ _randGen w (rot, g) = randomR (-torque,torque) $ _randGen w
rotateScope w = w & creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0)) rotateScope = creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0))
. itAttachment . _Just . scopePos %~ rotateV rot . itAttachment . _Just . scopePos %~ rotateV rot
{- | Create multiple bullets with a given spread, a given amount, given velocity, {- | Create multiple bullets with a given spread, a given amount, given velocity,
given width and given 'HitEffect'. -} given width and given 'HitEffect'. -}
@@ -384,11 +381,11 @@ numVelWthHitEff
-> Int -- ^ Creature id -> Int -- ^ Creature id
-> World -> World
-> World -> World
numVelWthHitEff num vel wth eff cid w = over particles (newbuls ++) w numVelWthHitEff num vel wth eff cid w = over particles (newbuls ++) w
where where
cr = _creatures w IM.! cid cr = _creatures w IM.! cid
newbuls = zipWith newbuls = zipWith
(\pos colid -> aGenBulAt' (Just cid) (numColor colid) pos (rotateV d vel) eff wth) (\p colid -> aGenBulAt' (Just cid) (numColor colid) p (rotateV d vel) eff wth)
poss poss
colids colids
d = _crDir cr d = _crDir cr
@@ -414,6 +411,6 @@ randWalkAngle ma aspeed f cid w = w
& creatures . ix cid . crInv . ix i . wpSpread .~ newa & creatures . ix cid . crInv . ix i . wpSpread .~ newa
where where
a = _wpSpread $ _crInv (_creatures w IM.! cid) IM.! i a = _wpSpread $ _crInv (_creatures w IM.! cid) IM.! i
(walka, g) = randomR (-aspeed,aspeed) (_randGen w) (walka, _) = randomR (-aspeed,aspeed) (_randGen w)
newa = min ma $ max (negate ma) (a + walka) newa = min ma $ max (negate ma) (a + walka)
i = _crInvSel $ _creatures w IM.! cid i = _crInvSel $ _creatures w IM.! cid
+7 -9
View File
@@ -6,10 +6,10 @@ module Dodge.Item.Weapon.UseEffect
import Dodge.Data import Dodge.Data
import Dodge.Base import Dodge.Base
import Dodge.Picture.Layer import Dodge.Picture.Layer
import Dodge.Item.Weapon.Decoration --import Dodge.Item.Weapon.Decoration
import Dodge.Item.Weapon.TriggerType import Dodge.Item.Weapon.TriggerType
import Dodge.WorldEvent.Flash --import Dodge.WorldEvent.Flash
import Dodge.WorldEvent.ThingsHit --import Dodge.WorldEvent.ThingsHit
import Picture import Picture
import Geometry import Geometry
@@ -39,7 +39,7 @@ mvBlip :: Point2 -> Color
-> Int -- ^ Max possible timer value -> Int -- ^ Max possible timer value
-> Int -- ^ Current timer value -> Int -- ^ Current timer value
-> World -> Particle -> (World, Maybe Particle) -> World -> Particle -> (World, Maybe Particle)
mvBlip p col maxt 0 w pt = (w, Nothing) mvBlip _ _ _ 0 w _ = (w, Nothing)
mvBlip p col maxt t w pt mvBlip p col maxt t w pt
= (w, Just $ pt & ptUpdate' .~ mvBlip p col maxt (t-1) = (w, Just $ pt & ptUpdate' .~ mvBlip p col maxt (t-1)
& ptDraw .~ (const . setDepth (-0.5) & ptDraw .~ (const . setDepth (-0.5)
@@ -73,7 +73,7 @@ mvSonar x p w pt = (w, Just $ pt {_ptDraw = const pic
where crad = _crRad cr where crad = _crRad cr
cpos = _crPos cr cpos = _crPos cr
r = fromIntegral (500 - x*5) r = fromIntegral (500 - x*5)
sweepPics = [colHelper 0.05 $ uncurry translate p $ thickCircle r 5 ] --sweepPics = [colHelper 0.05 $ uncurry translate p $ thickCircle r 5 ]
globalAlpha | x > 10 = 1 globalAlpha | x > 10 = 1
| otherwise = fromIntegral x / 10 | otherwise = fromIntegral x / 10
colHelper y = color (withAlpha (y * globalAlpha) green) colHelper y = color (withAlpha (y * globalAlpha) green)
@@ -97,7 +97,7 @@ mvRadar x p w pt =
where where
pic = onLayerL [levLayer ShadowLayer, 1] $ pictures sweepPics pic = onLayerL [levLayer ShadowLayer, 1] $ pictures sweepPics
putBlips = over worldEvents ( over particles (blips ++) . ) putBlips = over worldEvents ( over particles (blips ++) . )
blips = map (\p -> blipAt p (withAlpha (0.5*globalAlpha) red) 50) circPoints blips = map (\bp -> blipAt bp (withAlpha (0.5*globalAlpha) red) 50) circPoints
circPoints = mapMaybe (\wl -> uncurry collidePointCircCorrect (_wlLine wl) r p) circPoints = mapMaybe (\wl -> uncurry collidePointCircCorrect (_wlLine wl) r p)
$ map (over wlLine swp) (IM.elems $ wallsAlongCirc p r w) $ map (over wlLine swp) (IM.elems $ wallsAlongCirc p r w)
++ IM.elems (wallsAlongCirc p r w) ++ IM.elems (wallsAlongCirc p r w)
@@ -109,7 +109,7 @@ mvRadar x p w pt =
] ]
globalAlpha | x > 10 = 1 globalAlpha | x > 10 = 1
| otherwise = fromIntegral x / 10 | otherwise = fromIntegral x / 10
colHelper y = color (withAlpha (y * globalAlpha) red) --colHelper y = color (withAlpha (y * globalAlpha) red)
aTractorBeam aTractorBeam
:: Int -- ^ Color id :: Int -- ^ Color id
@@ -186,9 +186,7 @@ updateTractor colID time i w
| x > -1 = x | x > -1 = x
| x > -5 = -1 | x > -5 = -1
| otherwise = (x - 10) / 5 | otherwise = (x - 10) / 5
d = errorNormalizeV 13 $ p' -.- p1
f x = g x / 50 f x = g x / 50
cID = fromIntegral colID / 10
col = mixColors 0.5 0.5 white blue col = mixColors 0.5 0.5 white blue
px z = (fromIntegral time + 5) *.* z px z = (fromIntegral time + 5) *.* z
pz z = fromIntegral time * 10 *.* z pz z = fromIntegral time * 10 *.* z
+5 -15
View File
@@ -1,16 +1,12 @@
module Dodge.Layout module Dodge.Layout
( module Dodge.Layout
, module Dodge.Layout.Tree
)
where where
import Dodge.Data import Dodge.Data
import Dodge.LevelGen import Dodge.LevelGen
import Dodge.LevelGen.StaticWalls import Dodge.LevelGen.StaticWalls
import Dodge.LevelGen.Data --import Dodge.LevelGen.Data
import Dodge.Base import Dodge.Base
import Dodge.RandomHelp --import Dodge.RandomHelp
import Dodge.Graph import Dodge.Graph
import Dodge.Layout.Tree
import Dodge.Layout.Tree.Polymorphic (applyToRoot) import Dodge.Layout.Tree.Polymorphic (applyToRoot)
import Dodge.Room.Data import Dodge.Room.Data
import Dodge.Default import Dodge.Default
@@ -20,15 +16,10 @@ import Dodge.Room.Link
import Control.Monad.State import Control.Monad.State
import Control.Lens import Control.Lens
import System.Random import System.Random
import Data.List --import Data.List
import Data.Maybe --import Data.Maybe
import Data.Tree import Data.Tree
import Data.Either import Data.Graph.Inductive.Graph (labNodes)
import Data.Function
import Data.Graph.Inductive.Graph hiding ((&))
import Data.Graph.Inductive.Basic
import Data.Graph.Inductive.PatriciaTree
import Data.Graph.Inductive.NodeMap
import qualified Data.Map as M import qualified Data.Map as M
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
@@ -86,7 +77,6 @@ wallsFromTree t =
where where
assignKeys = IM.fromList . zip [0..] . zipWith f [0..] assignKeys = IM.fromList . zip [0..] . zipWith f [0..]
f i (x,y) = defaultWall {_wlLine = (x,y) , _wlID = i} f i (x,y) = defaultWall {_wlLine = (x,y) , _wlID = i}
g (x,y) = (x-3855,y - 2613)
wallsFromRooms :: [Room] -> IM.IntMap Wall wallsFromRooms :: [Room] -> IM.IntMap Wall
wallsFromRooms = wallsFromRooms =
+3 -3
View File
@@ -5,7 +5,7 @@ module Dodge.Layout.Generate
where where
import Data.Tree import Data.Tree
import Control.Monad.State import Control.Monad.State
import System.Random --import System.Random
generateLayout :: State g (Tree RoomProperties) generateLayout :: State g (Tree RoomProperties)
generateLayout = undefined generateLayout = undefined
@@ -16,10 +16,10 @@ data RoomProperties = RProps
} }
randomTreeStructure :: Int -> State g (Tree ()) randomTreeStructure :: Int -> State g (Tree ())
randomTreeStructure i = undefined randomTreeStructure = undefined
treeMaxDepthFromTrunk :: Int -> Int -> State g (Tree ()) treeMaxDepthFromTrunk :: Int -> Int -> State g (Tree ())
treeMaxDepthFromTrunk nNodes maxDepth = do treeMaxDepthFromTrunk = do
undefined undefined
+3 -3
View File
@@ -3,7 +3,7 @@ Combining and composing trees.
-} -}
module Dodge.Layout.Tree module Dodge.Layout.Tree
where where
import Data.Tree --import Data.Tree
import Control.Monad.State --import Control.Monad.State
import System.Random --import System.Random
+2 -1
View File
@@ -30,8 +30,9 @@ appendEitherTree
-> [Tree (Either a a)] -- ^ The forest to append -> [Tree (Either a a)] -- ^ The forest to append
-> Tree (Either a a) -> Tree (Either a a)
appendEitherTree (Node (Left x) ts) ts' = Node (Left x) $ map (`appendEitherTree` ts') ts appendEitherTree (Node (Left x) ts) ts' = Node (Left x) $ map (`appendEitherTree` ts') ts
appendEitherTree (Node (Right x) ts) ts' = Node (Left x) ts' appendEitherTree (Node (Right x) _) ts' = Node (Left x) ts'
removeEither :: Either p p -> p
removeEither (Left y) = y removeEither (Left y) = y
removeEither (Right y) = y removeEither (Right y) = y
+2 -2
View File
@@ -26,11 +26,11 @@ shiftRoomTreeSearch
shiftRoomTreeSearch _ Empty = Just [] shiftRoomTreeSearch _ Empty = Just []
shiftRoomTreeSearch bs (Node r ts :<| ts') shiftRoomTreeSearch bs (Node r ts :<| ts')
| roomIsClipping = Nothing | roomIsClipping = Nothing
| otherwise = fmap (r :) . shiftRoomTreeSearch newBounds $ ts' >< children | otherwise = fmap (r :) . shiftRoomTreeSearch newBounds $ ts' >< chldren
where where
roomIsClipping = or (polysIntersect <$> _rmBound r <*> bs) roomIsClipping = or (polysIntersect <$> _rmBound r <*> bs)
newBounds = _rmBound r ++ bs newBounds = _rmBound r ++ bs
children = fromList $ zipWith (applyToRoot . shiftRoomToLink) (_rmLinks r) ts chldren = fromList $ zipWith (applyToRoot . shiftRoomToLink) (_rmLinks r) ts
{- | {- |
All: Depth first search of trees of rooms, produces a list of lists of rooms that are not clipping. All: Depth first search of trees of rooms, produces a list of lists of rooms that are not clipping.
-} -}
+25 -12
View File
@@ -10,7 +10,7 @@ module Dodge.LevelGen
) where ) where
import Dodge.Data import Dodge.Data
import Dodge.Base import Dodge.Base
import Dodge.Room.Data --import Dodge.Room.Data
import Dodge.LevelGen.Block import Dodge.LevelGen.Block
import Dodge.LevelGen.LineBlock import Dodge.LevelGen.LineBlock
import Dodge.LevelGen.Pathing import Dodge.LevelGen.Pathing
@@ -22,16 +22,16 @@ import Dodge.LevelGen.Data
import Geometry import Geometry
import Picture import Picture
import System.Random --import System.Random
import Control.Monad.State import Control.Monad.State
import Control.Applicative --import Control.Applicative
import Control.Lens import Control.Lens
import Data.List.Extra import Data.List.Extra
import Data.Function --import Data.Function
import Data.Maybe --import Data.Maybe
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import qualified Data.Set as S --import qualified Data.Set as S
import qualified Data.Map as M --import qualified Data.Map as M
placeSpots :: [Placement] -> World -> World placeSpots :: [Placement] -> World -> World
placeSpots pss w = foldr (placeSpot . _placementSpot) w' singlePlacements placeSpots pss w = foldr (placeSpot . _placementSpot) w' singlePlacements
@@ -43,7 +43,7 @@ placeSpots pss w = foldr (placeSpot . _placementSpot) w' singlePlacements
gplmnts = groupOn _groupPlacementID $ sortOn _groupPlacementID groupedPlacements gplmnts = groupOn _groupPlacementID $ sortOn _groupPlacementID groupedPlacements
w' = foldr putGroup w gplmnts w' = foldr putGroup w gplmnts
putGroup :: [Placement] -> World -> World putGroup :: [Placement] -> World -> World
putGroup gps w = (_groupUpdate $ head gps) w gps putGroup gps w'' = (_groupUpdate $ head gps) w'' gps
{- | OK, this is perhaps slightly impenetrable. {- | OK, this is perhaps slightly impenetrable.
- The idea is that for a list of collected group placements, we first update - The idea is that for a list of collected group placements, we first update
@@ -81,17 +81,17 @@ placeSpot ps w = case _psType ps of
mapBoth fn (x,y) = (fn x, fn y) mapBoth fn (x,y) = (fn x, fn y)
PutDoubleDoor col f a b -> putDoubleDoor col f (shiftPointBy (p,rot) a) (shiftPointBy (p,rot) b) w PutDoubleDoor col f a b -> putDoubleDoor col f (shiftPointBy (p,rot) a) (shiftPointBy (p,rot) b) w
PutAutoDoor a b -> addAutoDoor (shiftPointBy (p,rot) a) (shiftPointBy (p,rot) b) w PutAutoDoor a b -> addAutoDoor (shiftPointBy (p,rot) a) (shiftPointBy (p,rot) b) w
PutBlock (hp:hps) col ps -> putBlock (map (shiftPointBy (p,rot)) ps) hp col False hps w PutBlock (hp:hps) col ps' -> putBlock (map (shiftPointBy (p,rot)) ps') hp col False hps w
PutBtDoor c bp f a b -> addButtonDoor c (shiftPointBy (p,rot) bp) (f + rot) PutBtDoor c bp f a b -> addButtonDoor c (shiftPointBy (p,rot) bp) (f + rot)
(shiftPointBy (p,rot) a) (shiftPointBy (p,rot) b) w (shiftPointBy (p,rot) a) (shiftPointBy (p,rot) b) w
PutSwitchDoor c bp f a b -> addSwitchDoor c (shiftPointBy (p,rot) bp) (f + rot) PutSwitchDoor c bp f a b -> addSwitchDoor c (shiftPointBy (p,rot) bp) (f + rot)
(shiftPointBy (p,rot) a) (shiftPointBy (p,rot) b) w (shiftPointBy (p,rot) a) (shiftPointBy (p,rot) b) w
PutLineBlock wl width depth a b PutLineBlock wl width depth a b
-> putLineBlock wl width depth (shiftPointBy (p,rot) a) (shiftPointBy (p,rot) b) w -> putLineBlock wl width depth (shiftPointBy (p,rot) a) (shiftPointBy (p,rot) b) w
PutWall { _pwPoly = ps, _pwWall = wl } -> rmCrossPaths $ over walls (addWalls (q:qs) wl) w PutWall { _pwPoly = ps', _pwWall = wl } -> rmCrossPaths $ over walls (addWalls (q:qs) wl) w
where where
(q:qs) = map (shiftPointBy (p,rot)) ps (q:qs) = map (shiftPointBy (p,rot)) ps'
rmCrossPaths w = foldr (uncurry removePathsCrossing) w $ zip (q:qs) (qs++[q]) rmCrossPaths w' = foldr (uncurry removePathsCrossing) w' $ zip (q:qs) (qs++[q])
_ -> w _ -> w
where where
p = _psPos ps p = _psPos ps
@@ -118,6 +118,7 @@ instance Shiftable PlacementSpot where
translateS p' (PS p r x) = PS (p +.+ p') r x translateS p' (PS p r x) = PS (p +.+ p') r x
rotateS r' (PS p r x) = PS (rotateV r' p) (r + r') x rotateS r' (PS p r x) = PS (rotateV r' p) (r + r') x
shiftPointBy :: (Point2,Float) -> Point2 -> Point2
shiftPointBy (pos,rot) p = pos +.+ rotateV rot p shiftPointBy (pos,rot) p = pos +.+ rotateV rot p
addWalls :: [Point2] -> Wall -> IM.IntMap Wall -> IM.IntMap Wall addWalls :: [Point2] -> Wall -> IM.IntMap Wall -> IM.IntMap Wall
@@ -133,6 +134,12 @@ addPane wl (p0,p1) wls = IM.insert (newKey wls) (wl
}) })
wls wls
placeBt
:: Button
-> Point2
-> Float -- ^ Rotation
-> World
-> World
placeBt bt p rot = over buttons addBT placeBt bt p rot = over buttons addBT
where where
addBT bts = IM.insert (newKey bts) (bt {_btPos = p, _btRot = rot, _btID = newKey bts}) bts addBT bts = IM.insert (newKey bts) (bt {_btPos = p, _btRot = rot, _btID = newKey bts}) bts
@@ -154,6 +161,12 @@ placeFlIt itm p rot = floorItems %~
} }
) fis ) fis
placePressPlate
:: PressPlate
-> Point2
-> Float -- ^ Rotation
-> World
-> World
placePressPlate pp p rot = over pressPlates addPP placePressPlate pp p rot = over pressPlates addPP
where where
addPP pps = IM.insert (newKey pps) (pp {_ppPos = p,_ppRot = rot}) pps addPP pps = IM.insert (newKey pps) (pp {_ppPos = p,_ppRot = rot}) pps
+11 -9
View File
@@ -5,7 +5,7 @@ Creation of doors that open when creatures approach them.
module Dodge.LevelGen.AutoDoor module Dodge.LevelGen.AutoDoor
where where
import Dodge.Data import Dodge.Data
import Dodge.Creature.State.Data --import Dodge.Creature.State.Data
import Dodge.Base import Dodge.Base
import Dodge.SoundLogic import Dodge.SoundLogic
import Dodge.Creature.Property import Dodge.Creature.Property
@@ -13,11 +13,11 @@ import Geometry
import Picture import Picture
import qualified DoubleStack as DS import qualified DoubleStack as DS
import Data.List --import Data.List
import Data.Maybe --import Data.Maybe
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import Control.Lens import Control.Lens
import Control.DeepSeq (deepseq) --import Control.DeepSeq (deepseq)
addAutoDoor addAutoDoor
:: Point2 -- ^ Left point :: Point2 -- ^ Left point
@@ -41,10 +41,11 @@ mkAutoDoor
-> Point2 -- ^ Right point (though the two points should be symmetric) -> Point2 -- ^ Right point (though the two points should be symmetric)
-> [Int] -- ^ Wall ids -> [Int] -- ^ Wall ids
-> [Wall] -> [Wall]
mkAutoDoor pl pr xs = addSound $ zipWith3 (autoDoorPane (pl,pr)) mkAutoDoor pl pr xs = addSound
xs $ zipWith3 (autoDoorPane (pl,pr))
(lDoorClosed ++ rDoorClosed) xs
(map shiftL lDoorClosed ++ map shiftR rDoorClosed) (lDoorClosed ++ rDoorClosed)
(map shiftL lDoorClosed ++ map shiftR rDoorClosed)
where where
lDoorClosed = [ (pld,hwd) lDoorClosed = [ (pld,hwd)
, (hwd,hwu) , (hwd,hwu)
@@ -67,7 +68,8 @@ mkAutoDoor pl pr xs = addSound $ zipWith3 (autoDoorPane (pl,pr))
shiftR = h $ (-.- parallel) . (+.+ normalizeV parallel) shiftR = h $ (-.- parallel) . (+.+ normalizeV parallel)
h func (x,y) = (func x,func y) h func (x,y) = (func x,func y)
addSound (x:xs) = f x : xs addSound (x:ys) = f x : ys
addSound _ = error "Trying to add a sound to malformed auto door"
f wl = over doorMech g wl f wl = over doorMech g wl
g dm w g dm w
| dist wp pld > 2 && dist wp hwd > 2 | dist wp pld > 2 && dist wp hwd > 2
+19 -15
View File
@@ -1,6 +1,4 @@
{- | {- | Creation, update and destruction of destructible walls. -}
Creation, update and destruction of destructible walls.
-}
module Dodge.LevelGen.Block where module Dodge.LevelGen.Block where
import Dodge.Data import Dodge.Data
import Dodge.Base import Dodge.Base
@@ -13,6 +11,7 @@ import Picture.Data
import Control.Lens import Control.Lens
import Control.Monad.State import Control.Monad.State
import Data.List import Data.List
import Data.Maybe
import Data.Function import Data.Function
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import System.Random import System.Random
@@ -37,19 +36,21 @@ Plays destruction sound and sets to be displayed other walls that were shadowed
killBlock :: Wall -> World -> World killBlock :: Wall -> World -> World
killBlock bl w = f bl . flip (foldr unshadow) (_blShadows bl) $ w killBlock bl w = f bl . flip (foldr unshadow) (_blShadows bl) $ w
where where
f bl@Block{_blDegrades = (x:xs)} = degradeBlock bl . hitSound bl f :: Wall -> World -> World
f bl = hitSound' bl f bl'
| isJust (bl ^? blDegrades . ix 0) = degradeBlock bl' . breakHitSound bl
| otherwise = hitSound' bl'
pos = fst $ _wlLine bl pos = fst $ _wlLine bl
hitSound bl breakHitSound bl'
| _wlIsSeeThrough bl = mkSoundBreakGlass pos | _wlIsSeeThrough bl' = mkSoundBreakGlass pos
| otherwise = soundMultiFrom sos soundid 25 0 | otherwise = soundMultiFrom sos soundid 25 0
hitSound' bl hitSound' bl'
| _wlIsSeeThrough bl = mkSoundSplinterGlass pos | _wlIsSeeThrough bl' = mkSoundSplinterGlass pos
| otherwise = soundMultiFrom sos soundid 25 0 | otherwise = soundMultiFrom sos soundid 25 0
sos = [BlockDegradeSound 0,BlockDegradeSound 1] sos = [BlockDegradeSound 0,BlockDegradeSound 1]
(soundid,_) = randomR (29,32) $ _randGen w (soundid,_) = randomR (29,32) $ _randGen w
unshadow :: Int -> World -> World unshadow :: Int -> World -> World
unshadow bid w = case w ^? walls . ix bid of unshadow bid w' = case w' ^? walls . ix bid of
Just b -> Just b ->
let (x,y) = zoneOfPoint $ uncurry pHalf (_wlLine b) let (x,y) = zoneOfPoint $ uncurry pHalf (_wlLine b)
in w & wallsZone . ix x . ix y . ix bid . blVisible %~ const True in w & wallsZone . ix x . ix y . ix bid . blVisible %~ const True
@@ -101,9 +102,9 @@ addBlock (p:ps) hp col isSeeThrough degradability w
& wallsZone %~ flip (IM.foldr wallInZone) panes & wallsZone %~ flip (IM.foldr wallInZone) panes
& walls %~ IM.union panes & walls %~ IM.union panes
where where
lines = zip (p:ps) (ps ++ [p]) lns = zip (p:ps) (ps ++ [p])
i = newKey $ _walls w i = newKey $ _walls w
is = [i.. i + length lines-1] is = [i.. i + length lns-1]
panes = IM.fromList $ zip is $ zipWith panes = IM.fromList $ zip is $ zipWith
(\j (a,b) -> Block (\j (a,b) -> Block
{ _wlLine = (a,b) { _wlLine = (a,b)
@@ -117,7 +118,7 @@ addBlock (p:ps) hp col isSeeThrough degradability w
, _blShadows = [] , _blShadows = []
, _blDegrades = degradability , _blDegrades = degradability
} }
) is lines ) is lns
wallInZone wl wallInZone wl
| uncurry dist (_wlLine wl) <= 2*zoneSize | uncurry dist (_wlLine wl) <= 2*zoneSize
= insertIMInZone x y wlid wl = insertIMInZone x y wlid wl
@@ -126,9 +127,12 @@ addBlock (p:ps) hp col isSeeThrough degradability w
(x,y) = zoneOfPoint $ uncurry pHalf (_wlLine wl) (x,y) = zoneOfPoint $ uncurry pHalf (_wlLine wl)
wlid = _wlID wl wlid = _wlID wl
ips = map zoneOfPoint $ uncurry (divideLine (2*zoneSize)) (_wlLine wl) ips = map zoneOfPoint $ uncurry (divideLine (2*zoneSize)) (_wlLine wl)
addBlock _ _ _ _ _ _ = error "Trying to add a block with incomplete polygon"
putBlock :: [Point2] -> Int -> Color -> Bool -> [Int] -> World -> World putBlock :: [Point2] -> Int -> Color -> Bool -> [Int] -> World -> World
putBlock (p:ps) i c b is w = foldr (uncurry removePathsCrossing) wWithBlock pairs putBlock (p:ps) i c b is w = foldr (uncurry removePathsCrossing) wWithBlock pairs
where pairs = zip (p:ps) (ps ++ [p]) where
wWithBlock = addBlock (p:ps) i c b is w pairs = zip (p:ps) (ps ++ [p])
wWithBlock = addBlock (p:ps) i c b is w
putBlock _ _ _ _ _ _ = error "Trying to put a block with incomplete polygon"
+5 -7
View File
@@ -1,13 +1,11 @@
module Dodge.LevelGen.InnerWalls module Dodge.LevelGen.InnerWalls
where where
import Dodge.Data --import Dodge.Data
import Dodge.Base --import Dodge.Base
--import Geometry
import Geometry
import Control.Lens
import qualified Data.IntMap as IM
--import Control.Lens
--import qualified Data.IntMap as IM
------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------
-- idea: create inner walls to draw and to cast shadows -- idea: create inner walls to draw and to cast shadows
--createInnerWalls :: IM.IntMap Wall -> IM.IntMap Wall --createInnerWalls :: IM.IntMap Wall -> IM.IntMap Wall
+9 -12
View File
@@ -6,14 +6,11 @@ module Dodge.LevelGen.LineBlock
import Dodge.Data import Dodge.Data
import Dodge.Base import Dodge.Base
import Dodge.LevelGen.Pathing import Dodge.LevelGen.Pathing
import Picture --import Picture
import Geometry import Geometry
import Control.Lens import Control.Lens
import qualified Data.IntMap as IM import qualified Data.IntMap as IM
-- | Taken from online, splits a list into its even and odd elements
evenOddSplit = foldr f ([],[])
where f a (ls,rs) = (rs, a : ls)
putLineBlock putLineBlock
:: Wall -- ^ Base pane :: Wall -- ^ Base pane
@@ -39,7 +36,7 @@ putLineBlock basePane blockWidth depth a b w = removePathsCrossing a b $ foldr i
,( halfBlockWidth,-depth) ,( halfBlockWidth,-depth)
] ]
cornersAt p = fmap ( (p +.+) . rotateV rot) cornerPoints cornersAt p = fmap ( (p +.+) . rotateV rot) cornerPoints
linesAt p = map (\(a,b) -> (a,b)) $ makeLoopPairs $ cornersAt p linesAt p = makeLoopPairs $ cornersAt p
k = newKey $ _walls w k = newKey $ _walls w
ksAtI i = map ( + (k + i*4) ) [0,1,2,3] ksAtI i = map ( + (k + i*4) ) [0,1,2,3]
visibilityAt i visibilityAt i
@@ -52,13 +49,13 @@ putLineBlock basePane blockWidth depth a b w = removePathsCrossing a b $ foldr i
| otherwise = ksAtI (i-1) ++ ksAtI (i+1) | otherwise = ksAtI (i-1) ++ ksAtI (i+1)
makeBlockAt :: Point2 -> Int -> [Wall] makeBlockAt :: Point2 -> Int -> [Wall]
makeBlockAt p i = zipWith3 (makePane i) (visibilityAt i) (ksAtI i) (linesAt p) makeBlockAt p i = zipWith3 (makePane i) (visibilityAt i) (ksAtI i) (linesAt p)
makePane i visStatus k' ps makePane i visStatus k' ps = basePane
= basePane {_wlID = k' {_wlID = k'
,_wlLine = ps ,_wlLine = ps
,_blIDs = ksAtI i ,_blIDs = ksAtI i
,_blShadows = shadowsAt i ,_blShadows = shadowsAt i
,_blVisible = visStatus ,_blVisible = visStatus
} }
listBlocks = concat $ zipWith makeBlockAt blockCenPs is listBlocks = concat $ zipWith makeBlockAt blockCenPs is
insertBlock :: Wall -> World -> World insertBlock :: Wall -> World -> World
insertBlock wl = over walls $ IM.insert (_wlID wl) wl insertBlock wl = over walls $ IM.insert (_wlID wl) wl
+9 -11
View File
@@ -1,28 +1,26 @@
module Dodge.LevelGen.Pathing module Dodge.LevelGen.Pathing
where where
import Dodge.Data
import Dodge.Base
import Geometry import Geometry
import Control.Lens import Control.Lens
import Dodge.Data
import Dodge.Base
import Data.Maybe import Data.Maybe
import Data.List import Data.List
import qualified Data.IntMap as IM import qualified Data.IntMap as IM
import Data.Graph.Inductive hiding ((&)) import Data.Graph.Inductive hiding ((&))
import Data.Graph.Inductive.NodeMap --import Data.Graph.Inductive.NodeMap
pairsToGraph :: (Ord a, Eq a, Eq b) => (a -> a -> b) -> [(a,a)] -> Gr a b pairsToGraph :: (Ord a, Eq a, Eq b) => (a -> a -> b) -> [(a,a)] -> Gr a b
pairsToGraph f pairs = let nodes = nub (map fst pairs ++ map snd pairs) pairsToGraph f pairs =
pairs' = map (\(x,y)->(x,y,f x y)) pairs let nodes' = nub (map fst pairs ++ map snd pairs)
in undir $ run_ Data.Graph.Inductive.empty $ insMapNodesM nodes >> insMapEdgesM pairs' pairs' = map (\(x,y)->(x,y,f x y)) pairs
in undir $ run_ Data.Graph.Inductive.empty $ insMapNodesM nodes' >> insMapEdgesM pairs'
removePathsCrossing :: Point2 -> Point2 -> World -> World removePathsCrossing :: Point2 -> Point2 -> World -> World
removePathsCrossing a b w = set pathGraph newGraph $ set pathGraph' pg' removePathsCrossing a b w = set pathGraph newGraph $ set pathGraph' pg'
$ set pathPoints (foldr insertPoint IM.empty (labNodes newGraph)) $ set pathPoints (foldr insertPoint IM.empty (labNodes newGraph))
w w
where where
pg' = filter (isNothing . uncurry (intersectSegSeg' a b)) $ _pathGraph' w pg' = filter (isNothing . uncurry (intersectSegSeg' a b)) $ _pathGraph' w
insertPoint pp@(_,(x,y)) = insertInZoneWith (floorHun x) (floorHun y) (++) [pp] insertPoint pp@(_,(x,y)) = insertInZoneWith (floorHun x) (floorHun y) (++) [pp]
+24 -23
View File
@@ -5,17 +5,16 @@ Description : Concerns carving out of static walls to create the general room pl
module Dodge.LevelGen.StaticWalls module Dodge.LevelGen.StaticWalls
where where
import Dodge.Data import Dodge.Data
import Dodge.Base --import Dodge.Base
import Dodge.Default --import Dodge.Default
import Geometry import Geometry
import Control.Lens --import Control.Lens
import Data.Function (on) import Data.Function (on)
import Data.Graph
import Data.List import Data.List
import Data.Maybe import Data.Maybe
import qualified Data.IntMap as IM --import qualified Data.IntMap as IM
import qualified Data.Set as S --import qualified Data.Set as S
-- | Describe a wall as two points. -- | Describe a wall as two points.
-- Order is important: the wall face is to the left as you move from 'fst' -- Order is important: the wall face is to the left as you move from 'fst'
-- to 'snd'. -- to 'snd'.
@@ -48,7 +47,6 @@ cutWalls ps wls = case mapMaybe (`checkWallRight` newWalls) newWalls of
_ -> cutWalls (map (rotateV 0.001) $ expandPolyBy 0.01 ps) wls _ -> cutWalls (map (rotateV 0.001) $ expandPolyBy 0.01 ps) wls
where where
newWalls = cutWalls' ps wls newWalls = cutWalls' ps wls
errsL = mapMaybe (`checkWallLeft` newWalls) newWalls
-- | As 'cutWalls', but rotate in the other direction. -- | As 'cutWalls', but rotate in the other direction.
cutWallsL :: [Point2] -> [WallP] -> [WallP] cutWallsL :: [Point2] -> [WallP] -> [WallP]
cutWallsL ps wls = case mapMaybe (`checkWallRight` newWalls) newWalls of cutWallsL ps wls = case mapMaybe (`checkWallRight` newWalls) newWalls of
@@ -58,7 +56,6 @@ cutWallsL ps wls = case mapMaybe (`checkWallRight` newWalls) newWalls of
_ -> cutWalls (map (rotateV (-0.001)) $ expandPolyBy 0.01 ps) wls _ -> cutWalls (map (rotateV (-0.001)) $ expandPolyBy 0.01 ps) wls
where where
newWalls = cutWalls' ps wls newWalls = cutWalls' ps wls
errsL = mapMaybe (`checkWallLeft` newWalls) newWalls
-- | Cut out a polygon from a set of walls, and check for errors in the -- | Cut out a polygon from a set of walls, and check for errors in the
-- created walls. -- created walls.
-- Give error if created walls are not consistent. -- Give error if created walls are not consistent.
@@ -87,8 +84,8 @@ checkWallRight (x,y) wls
| length ins == length outs = Nothing | length ins == length outs = Nothing
| otherwise = Just ((x,y), outs) | otherwise = Just ((x,y), outs)
where where
ins = filter (\(a,b) -> b == y) wls ins = filter (\(_,b) -> b == y) wls
outs = filter (\(a,b) -> a == y) wls outs = filter (\(a,_) -> a == y) wls
-- | Given a specific wall and list of walls, checks that the number of walls leaving the -- | Given a specific wall and list of walls, checks that the number of walls leaving the
-- first point is the same as the number of walls entering the first point of -- first point is the same as the number of walls entering the first point of
-- the specific wall. -- the specific wall.
@@ -99,8 +96,8 @@ checkWallLeft (x,y) wls
| length ins == length outs = Nothing | length ins == length outs = Nothing
| otherwise = Just ((x,y), outs) | otherwise = Just ((x,y), outs)
where where
ins = filter (\(a,b) -> a == x) wls ins = filter (\(a,_) -> a == x) wls
outs = filter (\(a,b) -> b == x) wls outs = filter (\(_,b) -> b == x) wls
-- | Given a polygon of points and collection of walls, cuts out the polygon. -- | Given a polygon of points and collection of walls, cuts out the polygon.
-- Ie returns a new set of walls with a hole determined by anticlockwise ordering of the points. -- Ie returns a new set of walls with a hole determined by anticlockwise ordering of the points.
-- The overall procedure is: -- The overall procedure is:
@@ -113,7 +110,7 @@ checkWallLeft (x,y) wls
-- 6. remove any duplicate walls -- 6. remove any duplicate walls
-- Unclear behaviour if a line in the polygon is colinear with a wall. -- Unclear behaviour if a line in the polygon is colinear with a wall.
cutWalls' :: [Point2] -> [WallP] -> [WallP] cutWalls' :: [Point2] -> [WallP] -> [WallP]
cutWalls' qs walls = cutWalls' qs wls =
nub nub
. filter (not.wallIsZeroLength) . filter (not.wallIsZeroLength)
. fuseWallsWith zs . fuseWallsWith zs
@@ -124,7 +121,7 @@ cutWalls' qs walls =
$ removeWallsInPolygon ps $ removeWallsInPolygon ps
cwals cwals
where where
(zs,cwals) = cutWallsWithPoints ps walls (zs,cwals) = cutWallsWithPoints ps wls
ps = orderPolygon qs ps = orderPolygon qs
rs = orderPolygon $ nub $ zs ++ qs rs = orderPolygon $ nub $ zs ++ qs
-- | Given a value and a poly, pushes the poly points out from the center by the -- | Given a value and a poly, pushes the poly points out from the center by the
@@ -145,6 +142,7 @@ cutWallsWithPoints (p:ps) ws = foldr f ([],ws) (zip (p:ps) (ps++[p]))
( nub $ as ++ cutWallsPoints p1 p2 ws' ( nub $ as ++ cutWallsPoints p1 p2 ws'
, concatMap (cutWall p1 p2) ws' , concatMap (cutWall p1 p2) ws'
) )
cutWallsWithPoints _ _ = error "Trying to cut empty polygon"
-- | List the points of intersection between a segment and collection of walls. -- | List the points of intersection between a segment and collection of walls.
cutWallsPoints :: Point2 -> Point2 -> [WallP] -> [Point2] cutWallsPoints :: Point2 -> Point2 -> [WallP] -> [Point2]
--cutWallsPoints p1 p2 ws = mapMaybe (\(x:y:_) -> intersectExtendedSegSeg p1 p2 x y) --cutWallsPoints p1 p2 ws = mapMaybe (\(x:y:_) -> intersectExtendedSegSeg p1 p2 x y)
@@ -154,11 +152,13 @@ cutWall :: Point2 -> Point2 -> WallP -> [WallP]
cutWall p1 p2 (x,y) = case myIntersectSegSeg p1 p2 x y of cutWall p1 p2 (x,y) = case myIntersectSegSeg p1 p2 x y of
Nothing -> [(x,y)] Nothing -> [(x,y)]
Just cp -> [(x,cp),(cp,y)] Just cp -> [(x,cp),(cp,y)]
-- | Add poly walls?
addPolyWalls addPolyWalls
:: [Point2] -- ^ Multiple walls described as a polygon. :: [Point2] -- ^ Multiple walls described as a polygon.
-> [WallP] -> [WallP]
-> [WallP] -> [WallP]
addPolyWalls (q:qs) walls = foldr addPolyWall walls (zip (q:qs) (qs++[q])) addPolyWalls (q:qs) wls = foldr addPolyWall wls (zip (q:qs) (qs++[q]))
addPolyWalls _ _ = error "Trying to add empty poly walls"
-- | Add a new wall to a list of walls only if either -- | Add a new wall to a list of walls only if either
-- 1. no wall already exists on the normal line from the new wall -- 1. no wall already exists on the normal line from the new wall
-- 2. any of the first existing walls hit on the normal line from the new wall -- 2. any of the first existing walls hit on the normal line from the new wall
@@ -166,12 +166,12 @@ addPolyWalls (q:qs) walls = foldr addPolyWall walls (zip (q:qs) (qs++[q]))
-- The normal line is the line from the center point of the new wall outwards -- The normal line is the line from the center point of the new wall outwards
-- along the clockwise normal of the new wall (currently 10000 units along) -- along the clockwise normal of the new wall (currently 10000 units along)
addPolyWall :: WallP -> [WallP] -> [WallP] addPolyWall :: WallP -> [WallP] -> [WallP]
addPolyWall (p1,p2) walls = addPolyWall (p1,p2) wls =
case maybeWs of case maybeWs of
Just ws -> if all (\(x,y) -> isLHS x y p3) ws Just ws -> if all (\(x,y) -> isLHS x y p3) ws
then walls then wls
else (p1,p2) : walls else (p1,p2) : wls
Nothing -> (p1,p2) : walls Nothing -> (p1,p2) : wls
where where
p3 = 0.5 *.* (p1 +.+ p2) p3 = 0.5 *.* (p1 +.+ p2)
p4 = p3 +.+ 10000 *.* vNormal (p2 -.- p1) p4 = p3 +.+ 10000 *.* vNormal (p2 -.- p1)
@@ -182,10 +182,10 @@ addPolyWall (p1,p2) walls =
wlsP :: [(WallP, Point2)] wlsP :: [(WallP, Point2)]
wlsP = sortBy (compare `on` (dist p3 . snd)) wlsP = sortBy (compare `on` (dist p3 . snd))
. catMaybes . catMaybes
$ zipWith f walls maybes $ zipWith f wls maybes
f a (Just b) = Just (a,b) f a (Just b) = Just (a,b)
f _ Nothing = Nothing f _ Nothing = Nothing
maybes = map (uncurry $ myIntersectSegSeg p3 p4) walls maybes = map (uncurry $ myIntersectSegSeg p3 p4) wls
-- | Given a list of points and a point, returns a point in the list if any is close -- | Given a list of points and a point, returns a point in the list if any is close
-- to the point. -- to the point.
findClosePoint :: [Point2] -> Point2 -> Maybe Point2 findClosePoint :: [Point2] -> Point2 -> Maybe Point2
@@ -212,10 +212,11 @@ fuseWall (ps, (x,y)) = ( nub (x':y':ps) , (x',y') )
fuseWallsWith :: [Point2] -> [WallP] -> [WallP] fuseWallsWith :: [Point2] -> [WallP] -> [WallP]
fuseWallsWith zs ws = snd $ foldr fuseWalls' (zs, []) ws fuseWallsWith zs ws = snd $ foldr fuseWalls' (zs, []) ws
where where
fuseWalls' w (ps, ws) = fuseWalls' w (ps, ws') =
let (qs, w') = fuseWall (ps, w) let (qs, w') = fuseWall (ps, w)
in (qs, w' : ws) in (qs, w' : ws')
-- | Test if fst p == snd p. -- | Test if fst p == snd p.
wallIsZeroLength :: Eq a => (a,a) -> Bool
wallIsZeroLength (x,y) = x == y wallIsZeroLength (x,y) = x == y
-- | Given a polygon and list of walls, removes walls inside the polygon. -- | Given a polygon and list of walls, removes walls inside the polygon.
removeWallsInPolygon :: [Point2] -> [WallP] -> [WallP] removeWallsInPolygon :: [Point2] -> [WallP] -> [WallP]
+2
View File
@@ -50,6 +50,7 @@ makeSwitch c effOn effOff = Button
switchEffect b = case _btState b of switchEffect b = case _btState b of
BtOff -> effOn . over buttons (IM.adjust turnOn (_btID b)) BtOff -> effOn . over buttons (IM.adjust turnOn (_btID b))
BtOn -> effOff . over buttons (IM.adjust turnOff (_btID b)) BtOn -> effOff . over buttons (IM.adjust turnOff (_btID b))
_ -> error "Trying to switch a button with no label"
offPict = onLayer WlLayer $ color c $ pictures [--translate (-8) 4 $ circleSolid 5 offPict = onLayer WlLayer $ color c $ pictures [--translate (-8) 4 $ circleSolid 5
polygon $ rectNSEW (-2) (-5) (-10) 10 polygon $ rectNSEW (-2) (-5) (-10) 10
,polygon [(-2,-5),(-10,4),(-6,4),(2,-5)] ,polygon [(-2,-5),(-10,4),(-6,4),(2,-5)]
@@ -70,3 +71,4 @@ makeSwitch c effOn effOff = Button
, _btPict = offPict , _btPict = offPict
, _btText = "SWITCH/" , _btText = "SWITCH/"
} }
+4 -5
View File
@@ -14,9 +14,7 @@ import Data.List
import Data.Maybe import Data.Maybe
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import Control.Lens import Control.Lens
import Control.DeepSeq (deepseq)
import Data.Graph.Inductive hiding ((&)) import Data.Graph.Inductive hiding ((&))
import Data.Graph.Inductive.NodeMap
-- probably don't have to rebuild the entire graph, oh well -- probably don't have to rebuild the entire graph, oh well
addButtonDoor :: Color -> Point2 -> Float -> Point2 -> Point2 -> World -> World addButtonDoor :: Color -> Point2 -> Float -> Point2 -> Point2 -> World -> World
@@ -27,7 +25,7 @@ addButtonDoor c btp btr a b w = over buttons (IM.insert bid bt)
$ putDoubleDoor c cond a b w $ putDoubleDoor c cond a b w
where where
bid = newKey $ _buttons w bid = newKey $ _buttons w
cond w = BtNoLabel == _btState (_buttons w IM.! bid) cond w' = BtNoLabel == _btState (_buttons w' IM.! bid)
bt = (makeButton c eff) {_btPos = btp, _btRot = btr, _btID = bid} bt = (makeButton c eff) {_btPos = btp, _btRot = btr, _btID = bid}
(newGraphPairs,removedPairs) = partition (isNothing . uncurry (intersectSegSeg' a b)) (newGraphPairs,removedPairs) = partition (isNothing . uncurry (intersectSegSeg' a b))
$ _pathGraph' w $ _pathGraph' w
@@ -45,7 +43,7 @@ addSwitchDoor c btp btr a b w = over buttons (IM.insert bid bt)
$ putDoubleDoor c cond a b w $ putDoubleDoor c cond a b w
where where
bid = newKey $ _buttons w bid = newKey $ _buttons w
cond w = BtOn == _btState (_buttons w IM.! bid) cond w' = BtOn == _btState (_buttons w' IM.! bid)
bt = (makeSwitch c openDoor closeDoor) {_btPos = btp, _btRot = btr, _btID = bid} bt = (makeSwitch c openDoor closeDoor) {_btPos = btp, _btRot = btr, _btID = bid}
(newGraphPairs,removedPairs) = partition (isNothing . uncurry (intersectSegSeg' a b)) (newGraphPairs,removedPairs) = partition (isNothing . uncurry (intersectSegSeg' a b))
$ _pathGraph' w $ _pathGraph' w
@@ -127,7 +125,8 @@ mkTriggerDoubleDoor c cond pl pr xs = addSound $ zipWith3 (triggerDoorPaneLinear
prd = pr -.- norm prd = pr -.- norm
hwu = hw +.+ norm hwu = hw +.+ norm
hwd = hw -.- norm hwd = hw -.- norm
addSound (x:xs) = f x : xs addSound (x:ys) = f x : ys
addSound _ = error "When creating a trigger door, added a sound to nothing"
f wl = over doorMech g wl f wl = over doorMech g wl
g dm w g dm w
| dist wp pld > 2 && dist wp hwd > 2 | dist wp pld > 2 && dist wp hwd > 2
+13 -7
View File
@@ -1,13 +1,14 @@
module Dodge.LightSources where module Dodge.LightSources where
import Dodge.Data import Dodge.Data
import Dodge.Base --import Dodge.Base
import Dodge.Picture.Layer import Dodge.Picture.Layer
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
import Geometry --import Geometry
import Picture import Picture
import qualified Data.IntMap.Strict as IM --import qualified Data.IntMap.Strict as IM
lightAt :: Point2 -> Int -> LightSource
lightAt p i = lightAt p i =
LS {_lsID = i LS {_lsID = i
,_lsPos = p ,_lsPos = p
@@ -15,13 +16,12 @@ lightAt p i =
,_lsRad = 600 ,_lsRad = 600
,_lsIntensity = 0.75 ,_lsIntensity = 0.75
} }
basicLS :: PSType
basicLS = PutLS ls dec basicLS = PutLS ls dec
where where
ls = lightAt (0,0) 0 ls = lightAt (0,0) 0
dec = onLayer PtLayer $ color white $ circleSolid 8 dec = onLayer PtLayer $ color white $ circleSolid 8
tLightFade :: Int -> Float -> (Int -> Float) -> Point2 -> TempLightSource tLightFade :: Int -> Float -> (Int -> Float) -> Point2 -> TempLightSource
tLightFade 0 rmax intensityF p = TLS tLightFade 0 rmax intensityF p = TLS
{ _tlsPos = p { _tlsPos = p
@@ -36,8 +36,13 @@ tLightFade i rmax intensityF p = TLS
, _tlsUpdate = \w _ -> (w, Just $ tLightFade (i-1) rmax intensityF p) , _tlsUpdate = \w _ -> (w, Just $ tLightFade (i-1) rmax intensityF p)
} }
tLightRad :: Int -> Float -> Float -> Point2 -> TempLightSource tLightRad
tLightRad 0 rmax rmin p = TLS :: Int
-> Float -- ^ maximal radius
-> Float -- ^ minimal radius (unused)
-> Point2
-> TempLightSource
tLightRad 0 rmax _ p = TLS
{ _tlsPos = p { _tlsPos = p
, _tlsRad = rmax , _tlsRad = rmax
, _tlsIntensity = 0.5 , _tlsIntensity = 0.5
@@ -50,4 +55,5 @@ tLightRad i rmax rmin p = TLS
, _tlsUpdate = \w _ -> (w, Just $ tLightRad (i-1) rmax rmin p) , _tlsUpdate = \w _ -> (w, Just $ tLightRad (i-1) rmax rmin p)
} }
tLightAt :: Int -> Point2 -> TempLightSource
tLightAt i = tLightRad i 100 0 tLightAt i = tLightRad i 100 0
-6
View File
@@ -1,11 +1,5 @@
module Dodge.LoadSound where module Dodge.LoadSound where
import Dodge.Data
import Data.Maybe
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import qualified Data.Map as M
import Control.Monad
import Control.Lens
import qualified SDL.Mixer as Mix import qualified SDL.Mixer as Mix
loadSounds :: IO (IM.IntMap Mix.Chunk) loadSounds :: IO (IM.IntMap Mix.Chunk)
+36 -31
View File
@@ -31,7 +31,7 @@ divideLineFixed x a b = fmap
( \i -> a +.+ i * x *.* normalizeV (b -.- a) ) ( \i -> a +.+ i * x *.* normalizeV (b -.- a) )
ns ns
where where
numPoints = floor $ dist a b / x numPoints = floor $ dist a b / x :: Int
ns = map fromIntegral [1 .. numPoints] ns = map fromIntegral [1 .. numPoints]
-- ok, astar or something like it -- ok, astar or something like it
@@ -40,25 +40,27 @@ type SearchedNodes = (HP.MinHeap (Float,(Float,[Point2])), [Point2])
stripRight :: Either a b -> b stripRight :: Either a b -> b
stripRight (Right x) = x stripRight (Right x) = x
stripRight _ = error "Trying to strip Right where there is a Left"
stepPath :: (Point2 -> [Point2]) -> Point2 -> SearchedNodes -> Either [Point2] SearchedNodes stepPath :: (Point2 -> [Point2]) -> Point2 -> SearchedNodes -> Either [Point2] SearchedNodes
stepPath f p (nextNodes, seenNodes) = case HP.view nextNodes of stepPath h p (nextNodes, seenNodes) = case HP.view nextNodes of
Nothing -> Left [] Nothing -> Left []
Just ((_,(cost,q:qs)), nextNodes') Just ((_,(cost,q:qs)), nextNodes')
| q == p -> Left (q:qs) | q == p -> Left (q:qs)
| otherwise -> | otherwise ->
let rs' = f q let rs' = h q
rs = rs' \\ seenNodes rs = rs' \\ seenNodes
newNodes = map (\r -> (cost + dist q r + dist r p , (cost + dist q r , r:q:qs))) rs newNodes' = map (\r -> (cost + dist q r + dist r p , (cost + dist q r , r:q:qs))) rs
in Right (foldr HP.insert nextNodes' newNodes , rs ++ seenNodes) in Right (foldr HP.insert nextNodes' newNodes' , rs ++ seenNodes)
Just _ -> error "In step path"
stepPath' :: (Point2 -> [Point2]) -> Point2 -> SearchedNodes -> [Point2] stepPath' :: (Point2 -> [Point2]) -> Point2 -> SearchedNodes -> [Point2]
stepPath' f p s = case stepPath f p s of stepPath' h p s = case stepPath h p s of
Left ps -> ps Left ps -> ps
Right s' -> stepPath' f p s' Right s' -> stepPath' h p s'
makePath' :: (Point2 -> [Point2]) -> Point2 -> Point2 -> [Point2] makePath' :: (Point2 -> [Point2]) -> Point2 -> Point2 -> [Point2]
makePath' f s e = stepPath' f e (HP.singleton (0,(0,[s])) , []) makePath' h s e = stepPath' h e (HP.singleton (0,(0,[s])) , [])
makeNode :: Point2 -> SearchedNodes makeNode :: Point2 -> SearchedNodes
makeNode e = (HP.singleton (0,(0,[e])) , []) makeNode e = (HP.singleton (0,(0,[e])) , [])
@@ -69,18 +71,20 @@ tp1 = (0,1)
tp2 = (0,20) tp2 = (0,20)
tp3 = (30,40) tp3 = (30,40)
f :: Point2 -> [Point2]
f = incidenceToFunction $ pairsToIncidence f = incidenceToFunction $ pairsToIncidence
[(tp1,tp2) [(tp1,tp2)
,(tp2,tp3) ,(tp2,tp3)
,(tp2,tp1) ,(tp2,tp1)
,(tp1,tp3) ,(tp1,tp3)
] ]
g = pairsToIncidence --g :: [(Point2,[Point2])]
[(tp1,tp2) --g = pairsToIncidence
,(tp2,tp3) -- [(tp1,tp2)
,(tp2,tp1) -- ,(tp2,tp3)
,(tp1,tp3) -- ,(tp2,tp1)
] -- ,(tp1,tp3)
-- ]
pathBetween :: Point2 -> Point2 -> World -> Maybe [Point2] pathBetween :: Point2 -> Point2 -> World -> Maybe [Point2]
pathBetween a b w = (makePath' $ \p -> _pathInc w M.! p) <$> a' <*> b' pathBetween a b w = (makePath' $ \p -> _pathInc w M.! p) <$> a' <*> b'
@@ -92,46 +96,46 @@ pathBetween a b w = (makePath' $ \p -> _pathInc w M.! p) <$> a' <*> b'
b' = find (flip (isWalkable b) w) nsb b' = find (flip (isWalkable b) w) nsb
makePathBetween :: Point2 -> Point2 -> World -> Maybe [Int] makePathBetween :: Point2 -> Point2 -> World -> Maybe [Int]
makePathBetween a b w = join $ sp <$> fmap fst a' <*> fmap fst b' <*> return g makePathBetween a b w = join $ sp <$> fmap fst a' <*> fmap fst b' <*> return g'
where where
g = _pathGraph w g' = _pathGraph w
nsa = concat $ lookLookups (zoneAroundPoint a) (_pathPoints w) nsa = concat $ lookLookups (zoneAroundPoint a) (_pathPoints w)
nsb = concat $ lookLookups (zoneAroundPoint b) (_pathPoints w) nsb = concat $ lookLookups (zoneAroundPoint b) (_pathPoints w)
a' = find (flip (isWalkable a) w . snd) nsa a' = find (flip (isWalkable a) w . snd) nsa
b' = find (flip (isWalkable b) w . snd) nsb b' = find (flip (isWalkable b) w . snd) nsb
ezipWith :: Monoid a => (b -> c -> d) -> Either a b -> Either a c -> Either a d ezipWith :: Monoid a => (b -> c -> d) -> Either a b -> Either a c -> Either a d
ezipWith f (Right x) (Right y) = Right (f x y) ezipWith f' (Right x) (Right y) = Right (f' x y)
ezipWith f (Left x) (Right _) = Left x ezipWith _ (Left x) (Right _) = Left x
ezipWith f (Right _) (Left y) = Left y ezipWith _ (Right _) (Left y) = Left y
ezipWith f (Left x) (Left y) = Left (mappend x y) ezipWith _ (Left x) (Left y) = Left (mappend x y)
makePathBetween' :: Point2 -> Point2 -> World -> Either String [Int] makePathBetween' :: Point2 -> Point2 -> World -> Either String [Int]
makePathBetween' a b w = makePathBetween' a b w =
let g = _pathGraph w let g' = _pathGraph w
ns = labNodes g ns = labNodes g'
nsa = _pathPoints w `ixNZ` a --nsa = _pathPoints w `ixNZ` a
nsb = _pathPoints w `ixNZ` b --nsb = _pathPoints w `ixNZ` b
a' = case listToMaybe $ sortBy (compare `on` dist a . snd) $ filter (flip (isWalkable a) w . snd) ns of a' = case listToMaybe $ sortBy (compare `on` dist a . snd) $ filter (flip (isWalkable a) w . snd) ns of
Just p -> Right $ fst p Just p -> Right $ fst p
_ -> Left "FIRST POINT UNSEEN" _ -> Left "FIRST POINT UNSEEN"
b' = case listToMaybe $ sortBy (compare `on` dist b . snd) $ filter (flip (isWalkable b) w . snd) ns of b' = case listToMaybe $ sortBy (compare `on` dist b . snd) $ filter (flip (isWalkable b) w . snd) ns of
Just p -> Right $ fst p Just p -> Right $ fst p
_ -> Left $ "SECOND POINT UNSEEN" ++ show b _ -> Left $ "SECOND POINT UNSEEN" ++ show b
in case ezipWith (\x y -> sp x y g) a' b' of in case ezipWith (\x y -> sp x y g') a' b' of
Right (Just xs) -> Right xs Right (Just xs) -> Right xs
Right Nothing -> Left $ "NO PATH" ++ show a ++ show b ++ show a' ++ show b' Right Nothing -> Left $ "NO PATH" ++ show a ++ show b ++ show a' ++ show b'
Left m -> Left m Left m -> Left m
makePathBetweenPs :: Point2 -> Point2 -> World -> Maybe [Point2] makePathBetweenPs :: Point2 -> Point2 -> World -> Maybe [Point2]
makePathBetweenPs a b w = mapMaybe (lab g) <$> makePathBetween b a w makePathBetweenPs a b w = mapMaybe (lab g') <$> makePathBetween b a w
where where
g = _pathGraph w g' = _pathGraph w
makePathBetweenPs' :: Point2 -> Point2 -> World -> Either String [Point2] makePathBetweenPs' :: Point2 -> Point2 -> World -> Either String [Point2]
makePathBetweenPs' a b w = mapMaybe (lab g) <$> makePathBetween' a b w makePathBetweenPs' a b w = mapMaybe (lab g') <$> makePathBetween' a b w
where where
g = _pathGraph w g' = _pathGraph w
pointTowardsImpulse :: Point2 -> Point2 -> World -> Maybe Point2 pointTowardsImpulse :: Point2 -> Point2 -> World -> Maybe Point2
pointTowardsImpulse a b w = find (flip (isWalkable a) w) =<< makePathBetweenPs a b w pointTowardsImpulse a b w = find (flip (isWalkable a) w) =<< makePathBetweenPs a b w
@@ -161,10 +165,11 @@ randomGraphStepRestricted n notns g = do
---- supposes that the list is non-empty ---- supposes that the list is non-empty
randomGraphWalk :: RandomGen g => [Int] -> Gr a b -> State g [Int] randomGraphWalk :: RandomGen g => [Int] -> Gr a b -> State g [Int]
randomGraphWalk (n:ns) g = do randomGraphWalk (n:ns) g = do
next <- randomGraphStepRestricted n ns g next' <- randomGraphStepRestricted n ns g
case next of case next' of
Nothing -> return (n:ns) Nothing -> return (n:ns)
Just n' -> randomGraphWalk (n':n:ns) g Just n' -> randomGraphWalk (n':n:ns) g
randomGraphWalk _ _ = error "Trying to walk in an empty list"
randomPointXStepsFrom :: Int -> Point2 -> World -> Point2 randomPointXStepsFrom :: Int -> Point2 -> World -> Point2
randomPointXStepsFrom i p w = randomPointXStepsFrom i p w =
+22 -22
View File
@@ -8,29 +8,29 @@ module Dodge.Render
import Dodge.Data import Dodge.Data
import Dodge.Config.Data import Dodge.Config.Data
import Dodge.Base import Dodge.Base
import Dodge.Render.HUD --import Dodge.Render.HUD
import Dodge.Render.MenuScreen --import Dodge.Render.MenuScreen
import Dodge.Render.Picture import Dodge.Render.Picture
import Dodge.Render.PerspectiveMatrix import Dodge.Render.PerspectiveMatrix
import Geometry import Geometry
import Picture --import Picture
import Picture.Render import Picture.Render
import Picture.Preload import Picture.Preload
import Shader import Shader
import Foreign (Word32) import Foreign (Word32)
import Control.Applicative --import Control.Applicative
import Control.Monad.State --import Control.Monad.State
import Control.Lens import Control.Lens
import qualified Control.Foldl as F import qualified Control.Foldl as F
import Data.Tuple.Extra import Data.Tuple.Extra
import Data.Maybe import Data.Maybe
import Data.List --import Data.List
import Data.Bifunctor --import Data.Bifunctor
import Data.Function --import Data.Function
import qualified Data.IntMap.Strict as IM --import qualified Data.IntMap.Strict as IM
import qualified Data.Map as M --import qualified Data.Map as M
import qualified Data.Set as S --import qualified Data.Set as S
import Graphics.Rendering.OpenGL hiding (color,scale,translate,rotate) import Graphics.Rendering.OpenGL hiding (color,scale,translate,rotate)
import qualified SDL import qualified SDL
@@ -43,9 +43,9 @@ doDrawing pdata w = do
sTicks <- SDL.ticks sTicks <- SDL.ticks
clear [ColorBuffer,DepthBuffer] clear [ColorBuffer,DepthBuffer]
let rot = _cameraRot w let rot = _cameraRot w
zoom = _cameraZoom w camzoom = _cameraZoom w
trans@(tranx,trany) = _cameraCenter w trans = _cameraCenter w
wins@(winx,winy) = (getWindowX w,getWindowY w) wins = (getWindowX w,getWindowY w)
wallPointsCol = wallsPointsAndCols w wallPointsCol = wallsPointsAndCols w
windowPoints = wallsWindows w windowPoints = wallsWindows w
lightPoints = lightsForGloom' w lightPoints = lightsForGloom' w
@@ -53,16 +53,16 @@ doDrawing pdata w = do
pic = worldPictures w pic = worldPictures w
wallPoints = map fst wallPointsCol wallPoints = map fst wallPointsCol
-- set the coordinate uniforms ready for drawing elements with using world coordinates -- set the coordinate uniforms ready for drawing elements with using world coordinates
setCommonUniforms pdata rot zoom trans wins setCommonUniforms pdata rot camzoom trans wins
depthFunc $= Just Less depthFunc $= Just Less
pmat <- (newMatrix RowMajor $ perspectiveMatrix rot zoom trans wins viewFroms) pmat <- (newMatrix RowMajor $ perspectiveMatrix rot camzoom trans wins viewFroms)
:: IO (GLmatrix GLfloat) :: IO (GLmatrix GLfloat)
-- draw the lightmap. Probably changes the bound framebufferObject -- draw the lightmap. Probably changes the bound framebufferObject
createLightMap pdata (w ^. config . shadow_resolution) wallPoints lightPoints viewFroms pmat createLightMap pdata (w ^. config . shadow_resolution) wallPoints lightPoints viewFroms pmat
-- draw the background. Assumes that depth testing is not enabled or that -- draw the background. Assumes that depth testing is not enabled or that
-- the depth buffer is ready to be drawn on -- the depth buffer is ready to be drawn on
blendFuncSeparate $= ((SrcAlphaSaturate, OneMinusSrcAlpha), (Zero,One)) blendFuncSeparate $= ((SrcAlphaSaturate, OneMinusSrcAlpha), (Zero,One))
renderBackground pdata rot zoom trans wins renderBackground pdata rot camzoom trans wins
-- draw the walls -- draw the walls
depthFunc $= Just Less depthFunc $= Just Less
if w ^. config . wall_textured if w ^. config . wall_textured
@@ -70,20 +70,20 @@ doDrawing pdata w = do
else renderBlankWalls pdata wallPointsCol pmat else renderBlankWalls pdata wallPointsCol pmat
-- I believe a more apt name would be setCeilingDepth: stops drawing of objects -- I believe a more apt name would be setCeilingDepth: stops drawing of objects
-- at points that are behind the extension of walls to the screen edge -- at points that are behind the extension of walls to the screen edge
setWallDepth pdata wallPoints (viewFromx,viewFromy) pmat _ <- setWallDepth pdata wallPoints (viewFromx,viewFromy) pmat
-- draw the first layer of pictures -- draw the first layer of pictures
-- these will probably all be opaque -- these will probably all be opaque
renderFoldable pdata $ picToLTree (Just 0) pic _ <- renderFoldable pdata $ picToLTree (Just 0) pic
-- reset blend so that light map doesn't apply -- reset blend so that light map doesn't apply
-- useful for drawing vivid projectiles -- useful for drawing vivid projectiles
blendFuncSeparate $= ((SrcAlpha,OneMinusSrcAlpha) , (Zero,One)) blendFuncSeparate $= ((SrcAlpha,OneMinusSrcAlpha) , (Zero,One))
depthFunc $= Just Lequal depthFunc $= Just Lequal
renderFoldable pdata $ picToLTree (Just 1) pic _ <- renderFoldable pdata $ picToLTree (Just 1) pic
-- reset blend so that light map applies again -- reset blend so that light map applies again
-- allows us to be certain these elements are drawn on top of those before, -- allows us to be certain these elements are drawn on top of those before,
-- in case we want transparency effects -- in case we want transparency effects
blendFuncSeparate $= ((SrcAlphaSaturate, OneMinusSrcAlpha), (Zero,One)) blendFuncSeparate $= ((SrcAlphaSaturate, OneMinusSrcAlpha), (Zero,One))
renderFoldable pdata $ picToLTree (Just 2) pic _ <- renderFoldable pdata $ picToLTree (Just 2) pic
depthMask $= Disabled depthMask $= Disabled
-- render transparent walls -- render transparent walls
-- the ordering between these and transparent clouds perhaps presents a challenge -- the ordering between these and transparent clouds perhaps presents a challenge
@@ -111,7 +111,7 @@ doDrawing pdata w = do
-- coordinates -- coordinates
resetShaderUniforms (map extractProgAndUnis $ _pictureShaders pdata) resetShaderUniforms (map extractProgAndUnis $ _pictureShaders pdata)
blendFunc $= (SrcAlpha,OneMinusSrcAlpha) blendFunc $= (SrcAlpha,OneMinusSrcAlpha)
renderFoldable pdata (picToLTree Nothing $ fixedCoordPictures w) _ <- renderFoldable pdata (picToLTree Nothing $ fixedCoordPictures w)
eTicks <- SDL.ticks eTicks <- SDL.ticks
return (eTicks - sTicks) return (eTicks - sTicks)
+12 -14
View File
@@ -1,16 +1,13 @@
module Dodge.Render.HUD module Dodge.Render.HUD
where where
import Dodge.Data import Dodge.Data
import Dodge.Base import Dodge.Base
import Dodge.Inventory import Dodge.Inventory
import Picture import Picture
import Geometry import Geometry
import Data.Maybe import Data.Maybe
import qualified Data.IntMap as IM import qualified Data.IntMap as IM
import Control.Lens import Control.Lens
hudDrawings :: World -> Picture hudDrawings :: World -> Picture
@@ -40,7 +37,7 @@ displayListTopLeft :: [(String,Color)] -> World -> [Picture]
displayListTopLeft scols w = displayListTopLeft scols w =
map scaler $ zipWith map scaler $ zipWith
(translate (15-halfWidth w)) (translate (15-halfWidth w))
( map (\x -> halfHeight w - (20 * (fromIntegral x+1))) [0..] ) ( map (\x -> halfHeight w - (20 * (fromIntegral x+1))) ([0..]::[Int]) )
( map (\(s,col) -> scale 0.1 0.1 . dShadCol col $ text s) scols ) ( map (\(s,col) -> scale 0.1 0.1 . dShadCol col $ text s) scols )
where where
scaler = scale (2 / getWindowX w) (2 / getWindowY w) scaler = scale (2 / getWindowX w) (2 / getWindowY w)
@@ -55,15 +52,15 @@ itemStringCol NoItem = ("----", greyN 0.5)
itemStringCol itm = (_itInvDisplay itm itm, _itInvColor itm) itemStringCol itm = (_itInvDisplay itm itm, _itInvColor itm)
drawLocations :: World -> [Picture] drawLocations :: World -> [Picture]
drawLocations w = displayListTopLeft locs w drawLocations wrld = displayListTopLeft locs wrld
++ zipWith bFunc (displayListEndCoords w locTexts) locPoss ++ zipWith bFunc (displayListEndCoords wrld locTexts) locPoss
++ mapOverlay w ++ mapOverlay wrld
++ [drawListCursor white iPos w] ++ [drawListCursor white iPos wrld]
where where
iPos = _selLocation w iPos = _selLocation wrld
locs = map (\(_,s) -> (s,white)) . IM.elems . _seenLocations $ w locs = map (\(_,s) -> (s,white)) . IM.elems . _seenLocations $ wrld
locPoss = map (cartePosToScreen w . ($ w) . fst) . IM.elems . _seenLocations $ w locPoss = map (cartePosToScreen wrld . ($ wrld) . fst) . IM.elems . _seenLocations $ wrld
zoom = _carteZoom w --cZoom = _carteZoom w
locTexts = map fst locs locTexts = map fst locs
bFunc (x,y) (z,w) = pictures bFunc (x,y) (z,w) = pictures
[ bezierQuad (withAlpha 0.0 white) (withAlpha 0.2 white) 0.050 0.010 (x,y) (0,y) (z,w) [ bezierQuad (withAlpha 0.0 white) (withAlpha 0.2 white) 0.050 0.010 (x,y) (0,y) (z,w)
@@ -72,7 +69,7 @@ drawLocations w = displayListTopLeft locs w
] --cheapo antialiasing ] --cheapo antialiasing
displayListCoords :: World -> [Point2] displayListCoords :: World -> [Point2]
displayListCoords w = map (g . f) [1..] displayListCoords w = map (g . f) [(1::Int)..]
where where
f i = ( 15 - halfWidth w , halfHeight w - (20 * fromIntegral i) ) f i = ( 15 - halfWidth w , halfHeight w - (20 * fromIntegral i) )
g (x,y) = (2*x / getWindowX w, 2*y / getWindowY w) g (x,y) = (2*x / getWindowX w, 2*y / getWindowY w)
@@ -106,7 +103,7 @@ mapWall w wl =
{- | Pictures of popup text for items close to your position.-} {- | Pictures of popup text for items close to your position.-}
closeObjectTexts :: World -> Picture closeObjectTexts :: World -> Picture
closeObjectTexts w = pictures $ zipWith renderList [0..] (map colAndText $ _closeActiveObjects w) closeObjectTexts w = pictures $ zipWith renderList [(0::Int)..] (map colAndText $ _closeActiveObjects w)
++ maybeToList maybeLine ++ maybeToList maybeLine
where where
colAndText (Left x) = (_itInvColor $ _flIt x, _itName $ _flIt x) colAndText (Left x) = (_itInvColor $ _flIt x, _itName $ _flIt x)
@@ -126,6 +123,7 @@ closeObjectTexts w = pictures $ zipWith renderList [0..] (map colAndText $ _clos
maybeLeft (Left x) = Just x maybeLeft (Left x) = Just x
maybeLeft _ = Nothing maybeLeft _ = Nothing
pushout = 140 pushout = 140
xtran :: Int -> Float
xtran 0 = case mayIt of Nothing -> 25 xtran 0 = case mayIt of Nothing -> 25
_ -> -25 _ -> -25
xtran _ = 0 xtran _ = 0
+4 -4
View File
@@ -6,9 +6,9 @@ module Dodge.Render.MenuScreen
) )
where where
import Dodge.Data.Menu import Dodge.Data.Menu
import Dodge.Config.Update --import Dodge.Config.Update
import Dodge.Config.Data import Dodge.Config.Data
import Dodge.Base (halfWidth,halfHeight) --import Dodge.Base (halfWidth,halfHeight)
import Picture import Picture
menuScreen menuScreen
@@ -18,7 +18,6 @@ menuScreen
-> [MenuLayer] -> [MenuLayer]
-> Picture -> Picture
menuScreen cfig hw hh mLays = case mLays of menuScreen cfig hw hh mLays = case mLays of
[] -> blank
(LevelMenu x:_) -> optionsList hw hh ("LEVEL"++show x) [] (LevelMenu x:_) -> optionsList hw hh ("LEVEL"++show x) []
(PauseMenu:_) -> optionsList hw hh "PAUSED" (PauseMenu:_) -> optionsList hw hh "PAUSED"
["N - NEW LEVEL" ["N - NEW LEVEL"
@@ -57,7 +56,7 @@ menuScreen cfig hw hh mLays = case mLays of
mavol = f $ _volume_master cfig mavol = f $ _volume_master cfig
snvol = f $ _volume_sound cfig snvol = f $ _volume_sound cfig
muvol = f $ _volume_music cfig muvol = f $ _volume_music cfig
f x = show $ round $ 10 * x f x = show $ (round $ 10 * x :: Int)
showShadRes i = "1/"++ show i showShadRes i = "1/"++ show i
optionsList optionsList
@@ -74,6 +73,7 @@ optionsList hw hh tit ops = pictures $
where where
placeString x y sc t = translate x y $ scale sc sc $ color white $ text t placeString x y sc t = translate x y $ scale sc sc $ color white $ text t
controlsList :: Picture
controlsList = pictures $ concat $ zipWith butAndEff controlsList = pictures $ concat $ zipWith butAndEff
[("wasd", "movement") [("wasd", "movement")
,("[rmb]", "aim") ,("[rmb]", "aim")
+13 -13
View File
@@ -64,7 +64,7 @@ clDraw c = uncurry translate (_clPos c) (_clPict c c)
wallFloorsToDraw :: World -> [Wall] wallFloorsToDraw :: World -> [Wall]
wallFloorsToDraw w = filter isVisible $ IM.elems $ wallsOnScreen w wallFloorsToDraw w = filter isVisible $ IM.elems $ wallsOnScreen w
where where
onScreen wall = lineOnScreen w ((\(a,b) -> [a,b]) $ _wlLine wall) onScreen wall = uncurry (lineOnScreen w) $ _wlLine wall
isVisible wl isVisible wl
| wl ^? blVisible == Just False = False | wl ^? blVisible == Just False = False
| otherwise = onScreen wl | otherwise = onScreen wl
@@ -98,12 +98,12 @@ outsideScreenPolygon w = [tr,tl,bl,br]
where where
scRot = rotateV (_cameraRot w) scRot = rotateV (_cameraRot w)
scZoom p | _cameraZoom w /= 0 = (1/_cameraZoom w) *.* p scZoom p | _cameraZoom w /= 0 = (1/_cameraZoom w) *.* p
| otherwise = error "Trying to set screen zoom to zero"
scTran p = p +.+ _cameraCenter w scTran p = p +.+ _cameraCenter w
tr = scTran $ scRot $ scZoom ( 3*halfWidth w , 3* halfHeight w) tr = scTran $ scRot $ scZoom ( 3*halfWidth w , 3* halfHeight w)
tl = scTran $ scRot $ scZoom (- (3*halfWidth w), 3* halfHeight w) tl = scTran $ scRot $ scZoom (- (3*halfWidth w), 3* halfHeight w)
br = scTran $ scRot $ scZoom ( 3*halfWidth w ,- (3* halfHeight w)) br = scTran $ scRot $ scZoom ( 3*halfWidth w ,- (3* halfHeight w))
bl = scTran $ scRot $ scZoom (- (3*halfWidth w),- (3* halfHeight w)) bl = scTran $ scRot $ scZoom (- (3*halfWidth w),- (3* halfHeight w))
x = halfWidth w + halfHeight w
wallShadowsToDraw :: World -> [Wall] wallShadowsToDraw :: World -> [Wall]
wallShadowsToDraw w = filter (fromMaybe True . (^? blVisible)) wallShadowsToDraw w = filter (fromMaybe True . (^? blVisible))
@@ -112,8 +112,8 @@ wallShadowsToDraw w = filter (fromMaybe True . (^? blVisible))
-- cannot only test if walls are on screen, but also if they are on the cone -- cannot only test if walls are on screen, but also if they are on the cone
-- towards the center of sight -- towards the center of sight
lineOnScreenCone :: World -> [Point2] -> Bool lineOnScreenCone :: World -> Point2 -> Point2 -> Bool
lineOnScreenCone w (p1:p2:_) = errorPointInPolygon 8 p1 sp || errorPointInPolygon 9 p2 sp lineOnScreenCone w p1 p2 = errorPointInPolygon 8 p1 sp || errorPointInPolygon 9 p2 sp
|| any (isJust . uncurry (intersectSegSeg' p1 p2)) sps || any (isJust . uncurry (intersectSegSeg' p1 p2)) sps
where where
sp' = screenPolygon w sp' = screenPolygon w
@@ -123,8 +123,8 @@ lineOnScreenCone w (p1:p2:_) = errorPointInPolygon 8 p1 sp || errorPointInPolygo
sps = zip sp (tail sp ++ [head sp]) sps = zip sp (tail sp ++ [head sp])
lineOnScreen :: World -> [Point2] -> Bool lineOnScreen :: World -> Point2 -> Point2 -> Bool
lineOnScreen w (p1:p2:_) = errorPointInPolygon 8 p1 sp || errorPointInPolygon 9 p2 sp lineOnScreen w p1 p2 = errorPointInPolygon 8 p1 sp || errorPointInPolygon 9 p2 sp
|| any (isJust . uncurry (intersectSegSeg' p1 p2)) sps || any (isJust . uncurry (intersectSegSeg' p1 p2)) sps
where where
sp = screenPolygon w sp = screenPolygon w
@@ -156,17 +156,19 @@ extendConeToScreenEdge w c (x,y) = orderPolygon $ wallScreenIntersect ++ [x,y] +
wallScreenIntersect = mapMaybe (uncurry $ intersectSegSeg' y ((2*.*y) -.- x)) wallScreenIntersect = mapMaybe (uncurry $ intersectSegSeg' y ((2*.*y) -.- x))
. makeLoopPairs $ screenPolygon w . makeLoopPairs $ screenPolygon w
rectangleSolid :: Float -> Float -> Picture
rectangleSolid x y = polygon [(x,y),(x,-y),(-x,-y),(-x,y)] rectangleSolid x y = polygon [(x,y),(x,-y),(-x,-y),(-x,y)]
drawItem :: FloorItem -> Picture drawItem :: FloorItem -> Picture
drawItem flIt = uncurry translate (_flItPos flIt) drawItem flit = uncurry translate (_flItPos flit)
$ rotate (_flItRot flIt) (_itFloorPict (_flIt flIt)) $ rotate (_flItRot flit) (_itFloorPict (_flIt flit))
ffToDraw :: World -> [ForceField] ffToDraw :: World -> [ForceField]
ffToDraw w = filter (lineOnScreen w . _ffLine) $ ffToDraw _ = []
IM.elems $ over ffLine (map ( -.- _cameraCenter w)) <$> -- filter (lineOnScreen w . _ffLine) $
_forceFields w -- IM.elems $ over ffLine (map ( -.- _cameraCenter w)) <$>
-- _forceFields w
drawFF :: ForceField -> Picture drawFF :: ForceField -> Picture
drawFF FF{_ffLine = l, _ffColor = col} = pictures drawFF FF{_ffLine = l, _ffColor = col} = pictures
@@ -179,14 +181,12 @@ drawFFShadow w ff
| youOnFF = [] | youOnFF = []
| otherwise = map (rotate ( _cameraRot w) . pane) [0,0.05..0.25] | otherwise = map (rotate ( _cameraRot w) . pane) [0,0.05..0.25]
where where
p = rotateV (-_cameraRot w) ypShift
x = rotateV (-_cameraRot w) x' x = rotateV (-_cameraRot w) x'
y = rotateV (-_cameraRot w) y' y = rotateV (-_cameraRot w) y'
yp = _crPos $ you w yp = _crPos $ you w
(x1:y1:_) = _ffLine ff (x1:y1:_) = _ffLine ff
(x':y':_) | isRHS x1 y1 yp = [y1,x1] (x':y':_) | isRHS x1 y1 yp = [y1,x1]
| otherwise = [x1,y1] | otherwise = [x1,y1]
fCol = color (_ffColor ff)
col = _ffColor ff col = _ffColor ff
ypShift = yp -.- _cameraCenter w ypShift = yp -.- _cameraCenter w
youOnFF = circOnSeg x' y' ypShift (_crRad $ you w) youOnFF = circOnSeg x' y' ypShift (_crRad $ you w)
+22 -33
View File
@@ -8,47 +8,37 @@ module Dodge.Room
import Dodge.Data import Dodge.Data
import Dodge.Item.Weapon import Dodge.Item.Weapon
import Dodge.Creature import Dodge.Creature
import Dodge.Creature.Inanimate --import Dodge.Creature.Inanimate
import Dodge.LevelGen --import Dodge.LevelGen
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
import Dodge.Base --import Dodge.Base
import Dodge.RandomHelp import Dodge.RandomHelp
import Dodge.Default import Dodge.Default
import Dodge.Path --import Dodge.Path
import Dodge.Layout --import Dodge.Layout
import Dodge.Layout.Tree.Polymorphic import Dodge.Layout.Tree.Polymorphic
import Dodge.Layout.Tree.Either import Dodge.Layout.Tree.Either
import Dodge.LightSources --import Dodge.LightSources
import Dodge.SoundLogic --import Dodge.SoundLogic
import Dodge.Room.Data import Dodge.Room.Data
import Dodge.Room.Placement import Dodge.Room.Placement
import Dodge.Room.Procedural import Dodge.Room.Procedural
import Dodge.Room.Corridor import Dodge.Room.Corridor
import Dodge.Room.Link import Dodge.Room.Link
import Dodge.Room.Branch --import Dodge.Room.Branch
import Dodge.Room.Door import Dodge.Room.Door
import Dodge.Room.Airlock import Dodge.Room.Airlock
import Dodge.Room.LongDoor import Dodge.Room.LongDoor
import Geometry import Geometry
import Picture import Picture
import qualified SDL.Mixer as Mix
import Control.Lens import Control.Lens
import Control.Monad.State import Control.Monad.State
import Control.Monad.Loops import Control.Monad.Loops
import System.Random import System.Random
import Data.List
import Data.Maybe
import Data.Tree import Data.Tree
import Data.Either --import qualified Data.Map as M
import Data.Function --import qualified Data.IntMap.Strict as IM
import Data.Graph.Inductive.Graph hiding ((&))
import Data.Graph.Inductive.Basic
import Data.Graph.Inductive.PatriciaTree
import Data.Graph.Inductive.NodeMap
import qualified Data.Map as M
import qualified Data.IntMap.Strict as IM
roomC :: Float -> Float -> Room roomC :: Float -> Float -> Room
roomC x y = Room roomC x y = Room
@@ -144,7 +134,7 @@ miniRoom1 = do
,windowLine (wth-60, 40+3*hf) (wllen,40+3*hf) ,windowLine (wth-60, 40+3*hf) (wllen,40+3*hf)
,windowLine (wth-wllen,40+4*hf) (60,40+4*hf) ,windowLine (wth-wllen,40+4*hf) (60,40+4*hf)
,sPS (crx,cry) 0 $ PutCrit miniGunCrit ,sPS (crx,cry) 0 $ PutCrit miniGunCrit
,sPS (wth-20,hgt/2+40) 0 randC ,sPS (wth-20,hgt/2+40) 0 randC1
,sPS (wth/2,hgt/2) 0 putLamp ,sPS (wth/2,hgt/2) 0 putLamp
,blockLine ( 0, 40+1*hf) (wllen,40+1*hf) ,blockLine ( 0, 40+1*hf) (wllen,40+1*hf)
,blockLine (wth-wllen, 40+2*hf) ( wth,40+2*hf) ,blockLine (wth-wllen, 40+2*hf) ( wth,40+2*hf)
@@ -258,7 +248,6 @@ randFirstWeapon = do
++ replicate 2 autoGun ++ replicate 2 autoGun
++ [launcher] ++ [launcher]
randC = randC1
weaponEmptyRoom :: RandomGen g => State g (Tree (Either Room Room)) weaponEmptyRoom :: RandomGen g => State g (Tree (Either Room Room))
weaponEmptyRoom = do weaponEmptyRoom = do
@@ -285,21 +274,21 @@ weaponUnderCrits = do
(connectRoom (set rmPS plmnts corridorN)) (connectRoom (set rmPS plmnts corridorN))
rcp' <- roomCenterPillar rcp' <- roomCenterPillar
let rcp = over rmPS ( sPS (120,80) 0 putLamp : ) rcp' let rcp = over rmPS ( sPS (120,80) 0 putLamp : ) rcp'
deadEndRoom <- takeOne [roomPillars,rcp] deadEndRoom' <- takeOne [roomPillars,rcp]
junctionRoom <- takeOne [Left tEast,Left tWest] junctionRoom <- takeOne [Left tEast,Left tWest]
return $ treeFromTrunk [Left corridorN,Left corridorN] return $ treeFromTrunk [Left corridorN,Left corridorN]
$ Node junctionRoom $ Node junctionRoom
[continuationRoom [continuationRoom
,deadRoom deadEndRoom ,deadRoom deadEndRoom'
] ]
weaponBehindPillar :: RandomGen g => State g (Tree (Either Room Room)) weaponBehindPillar :: RandomGen g => State g (Tree (Either Room Room))
weaponBehindPillar = do weaponBehindPillar = do
crPos <- takeOne $ [(x,y) | x <- [20,220], y <- [20,220]] ++ [(120,160),(120,200)] cpos <- takeOne $ [(x,y) | x <- [20,220], y <- [20,220]] ++ [(120,160),(120,200)]
let d p = argV $ (120,80) -.- p let d p = argV $ (120,80) -.- p
let plmnts1 = let plmnts1 =
[sPS (120,160) 0 $ RandPS randFirstWeapon [sPS (120,160) 0 $ RandPS randFirstWeapon
,sPS crPos (d crPos) randC1 ,sPS cpos (d cpos) randC1
] ]
rcp <- roomCenterPillar rcp <- roomCenterPillar
return $ treeFromTrunk return $ treeFromTrunk
@@ -337,11 +326,11 @@ weaponLongCorridor = do
let branch2 = treeFromTrunk (replicate i2 $ Left corridorN) (deadRoom $ putWp corridor) let branch2 = treeFromTrunk (replicate i2 $ Left corridorN) (deadRoom $ putWp corridor)
return $ Node (Left root) [branch1,branch2] return $ Node (Left root) [branch1,branch2]
where where
putCrs = over rmPS (++ [sPS (10,40) (-pi/2) randC ,sPS (-10,40) (-pi/2) randC ]) putCrs = over rmPS (++ [sPS (10,40) (-pi/2) randC1 ,sPS (-10,40) (-pi/2) randC1 ])
putWp = set rmPS [sPS (20,40) 0 $ RandPS randFirstWeapon ,sPS (20,60) 0 putLamp ] putWp = set rmPS [sPS (20,40) 0 $ RandPS randFirstWeapon ,sPS (20,60) 0 putLamp ]
critInDeadEnd :: Room critInDeadEnd :: Room
critInDeadEnd = set rmPS [sPS (0,0) 0 randC] deadEndRoom critInDeadEnd = set rmPS [sPS (0,0) 0 randC1] deadEndRoom
deadEndRoom :: Room deadEndRoom :: Room
deadEndRoom = Room deadEndRoom = Room
@@ -367,7 +356,7 @@ weaponRoom = join $ takeOne
roomCCrits :: RandomGen g => State g (Tree (Either Room Room)) roomCCrits :: RandomGen g => State g (Tree (Either Room Room))
roomCCrits = do roomCCrits = do
ps <- replicateM 20 $ randInCirc 9 ps <- replicateM 20 $ randInCirc 9
let plmnts = map (\p -> sPS p 0 randC) let plmnts = map (\p -> sPS p 0 randC1)
$ zipWith (+.+) [(x,y) | x<-[110,130,150,170,190], y<- [70,90,110,130,150]] ps $ zipWith (+.+) [(x,y) | x<-[110,130,150,170,190], y<- [70,90,110,130,150]] ps
lamps = [sPS (50,100) 0 putLamp , sPS (175,100) 0 putLamp] lamps = [sPS (50,100) 0 putLamp , sPS (175,100) 0 putLamp]
return $ connectRoom $ over rmPS ((lamps ++) . (plmnts ++)) $ roomC 200 200 return $ connectRoom $ over rmPS ((lamps ++) . (plmnts ++)) $ roomC 200 200
@@ -457,10 +446,10 @@ shootersRoom = do
pistolerRoom :: RandomGen g => State g Room pistolerRoom :: RandomGen g => State g Room
pistolerRoom = do pistolerRoom = do
let f2 x y = singleBlock (x,y) let f2 x y = singleBlock (x,y)
f3 x y = [blockLine (x-20,y) (x+20,y) --f3 x y = [blockLine (x-20,y) (x+20,y)
,blockLine (x,y-20) (x,y+20) ] -- ,blockLine (x,y-20) (x,y+20) ]
f4 x y = [blockLine (x-20,y-20) (x+20,y+20) --f4 x y = [blockLine (x-20,y-20) (x+20,y+20)
,blockLine (x+20,y-20) (x-20,y+20) ] -- ,blockLine (x+20,y-20) (x-20,y+20) ]
f <- takeOne [f2] f <- takeOne [f2]
h <- state $ randomR (400,800) h <- state $ randomR (400,800)
let w = h let w = h
+1 -1
View File
@@ -154,4 +154,4 @@ airlockCrystal n = Room
col = dim $ dim $ bright red col = dim $ dim $ bright red
pss :: [(Point2,Point2)] pss :: [(Point2,Point2)]
pss = reverse $ fmap ( (\x -> ((50,x),(50,x+50)) ) . fromIntegral) pss = reverse $ fmap ( (\x -> ((50,x),(50,x+50)) ) . fromIntegral)
[20,22..70] [20::Int,22..70]
+2 -2
View File
@@ -3,12 +3,12 @@ Collections of rooms that branch into multiple paths.
-} -}
module Dodge.Room.Branch module Dodge.Room.Branch
where where
import Geometry --import Geometry
import Dodge.Room.Data import Dodge.Room.Data
import Dodge.Room.Door import Dodge.Room.Door
import Dodge.Room.Link import Dodge.Room.Link
import Dodge.Room.Procedural import Dodge.Room.Procedural
import Dodge.LevelGen.Data --import Dodge.LevelGen.Data
import Dodge.Layout.Tree.Polymorphic import Dodge.Layout.Tree.Polymorphic
import Control.Monad.State import Control.Monad.State
+14 -6
View File
@@ -64,7 +64,7 @@ shiftRoomToLink l r
(p,a) = last $ _rmLinks r (p,a) = last $ _rmLinks r
shiftRoomBy :: (Point2,Float) -> Room -> Room shiftRoomBy :: (Point2,Float) -> Room -> Room
shiftRoomBy shift@(pos,rot) r = shiftRoomBy shift r =
over rmPolys (fmap (map (shiftPointBy shift))) over rmPolys (fmap (map (shiftPointBy shift)))
$ over rmLinks (fmap (shiftLinkBy shift)) $ over rmLinks (fmap (shiftLinkBy shift))
$ over rmPath (map (shiftPathPointBy shift)) $ over rmPath (map (shiftPathPointBy shift))
@@ -72,14 +72,22 @@ shiftRoomBy shift@(pos,rot) r =
$ over rmBound (fmap (map (shiftPointBy shift))) $ over rmBound (fmap (map (shiftPointBy shift)))
r r
shiftLinkBy
:: (Point2,Float)
-> (Point2,Float)
-> (Point2,Float)
shiftLinkBy (pos,rot) (p,r) = (shiftPointBy (pos,rot) p, r + rot) shiftLinkBy (pos,rot) (p,r) = (shiftPointBy (pos,rot) p, r + rot)
shiftPSBy
:: (Point2,Float)
-> Placement
-> Placement
shiftPSBy (pos,rot) ps = ps shiftPSBy (pos,rot) ps = ps
& placementSpot . psPos %~ shiftPointBy (pos,rot) & placementSpot . psPos %~ shiftPointBy (pos,rot)
& placementSpot . psRot %~ (+ rot) & placementSpot . psRot %~ (+ rot)
--shiftPSBy (pos,rot) ps = case ps of shiftPathPointBy
-- PS {} -> over psPos (shiftPointBy (pos,rot)) :: (Point2,Float)
-- $ over psRot (+rot) -> (Point2,Point2)
-- ps -> (Point2,Point2)
shiftPathPointBy s (p1,p2) = (shiftPointBy s p1, shiftPointBy s p2) shiftPathPointBy s (p1,p2) = (shiftPointBy s p1, shiftPointBy s p2)
+6 -5
View File
@@ -57,8 +57,8 @@ twinSlowDoorRoom drID w h x = Room
[0..nDrp] [0..nDrp]
drR = fmap ((\h' -> ((-x,-h'),(-x,h-h'))) . (* h) . (/ fromIntegral nDrp) . fromIntegral) drR = fmap ((\h' -> ((-x,-h'),(-x,h-h'))) . (* h) . (/ fromIntegral nDrp) . fromIntegral)
[0..nDrp] [0..nDrp]
nDrp = ceiling h nDrp = ceiling h :: Int
cond w = or $ M.lookup (DoorNumOpen drID) (_worldState w) cond w' = or $ M.lookup (DoorNumOpen drID) (_worldState w')
col = dim $ dim $ bright red col = dim $ dim $ bright red
twinSlowDoorChasers twinSlowDoorChasers
@@ -90,7 +90,7 @@ slowDoorRoom = do
ys' <- replicateM 5 $ state $ randomR (h+20,y) ys' <- replicateM 5 $ state $ randomR (h+20,y)
let crits = zipWith (\p r -> sPS p r randC1) ps rs let crits = zipWith (\p r -> sPS p r randC1) ps rs
lsources = [sPS (x/2,30) 0 putLamp, sPS (x/2,y-30) 0 putLamp] lsources = [sPS (x/2,30) 0 putLamp, sPS (x/2,y-30) 0 putLamp]
barrels = zipWith (\x y -> sPS (x,y) 0 $ PutCrit explosiveBarrel) xs' ys' barrels = zipWith (\x' y' -> sPS (x',y') 0 $ PutCrit explosiveBarrel) xs' ys'
pillarsa = [] pillarsa = []
pillarsb = putBlockRect (x/5-20) (x/5+20) (h/2-20) (h/2+20) pillarsb = putBlockRect (x/5-20) (x/5+20) (h/2-20) (h/2+20)
++ putBlockRect (2*x/5-20) (2*x/5+20) (h/2-20) (h/2+20) ++ putBlockRect (2*x/5-20) (2*x/5+20) (h/2-20) (h/2+20)
@@ -99,8 +99,8 @@ slowDoorRoom = do
pillarsc = putBlockRect (x/3-20) (x/3+20) (h/2-20) (h/2+20) pillarsc = putBlockRect (x/3-20) (x/3+20) (h/2-20) (h/2+20)
++ putBlockRect (2*x/3-20) (2*x/3+20) (h/2-20) (h/2+20) ++ putBlockRect (2*x/3-20) (2*x/3+20) (h/2-20) (h/2+20)
pillars <- takeOne [pillarsa, pillarsb, pillarsc] pillars <- takeOne [pillarsa, pillarsb, pillarsc]
let cond x = (snd . fst) x > h + 40 let cond x' = (snd . fst) x' > h + 40
cond2 x = (snd . fst) x < h - 40 cond2 x' = (snd . fst) x' < h - 40
but <- takeOne [PutBtDoor (dim $ light red) butPos butRot (0,h) (x,h) but <- takeOne [PutBtDoor (dim $ light red) butPos butRot (0,h) (x,h)
-- ,PutSwitchDoor (dim $ light red) butPos butRot (0,h) (x,h) -- ,PutSwitchDoor (dim $ light red) butPos butRot (0,h) (x,h)
] ]
@@ -112,4 +112,5 @@ slowDoorRoom = do
) )
) )
randC1 :: PSType
randC1 = RandPS $ takeOne $ map PutCrit $ armourChaseCrit : replicate 50 chaseCrit randC1 = RandPS $ takeOne $ map PutCrit $ armourChaseCrit : replicate 50 chaseCrit
+2 -2
View File
@@ -5,7 +5,7 @@ module Dodge.Room.NoNeedWeapon
import Dodge.Data import Dodge.Data
import Dodge.Creature import Dodge.Creature
import Dodge.Creature.State.Data import Dodge.Creature.State.Data
import Dodge.Creature.Inanimate --import Dodge.Creature.Inanimate
import Dodge.Room.Data import Dodge.Room.Data
import Dodge.Room.Procedural import Dodge.Room.Procedural
import Dodge.Room.Link import Dodge.Room.Link
@@ -13,7 +13,7 @@ import Dodge.RandomHelp
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
import Control.Lens import Control.Lens
import Control.Monad --import Control.Monad
import Control.Monad.State import Control.Monad.State
import System.Random import System.Random
{- | {- |
+32 -3
View File
@@ -12,12 +12,16 @@ import Geometry
import Data.List import Data.List
import Control.Lens import Control.Lens
putLamp :: PSType
putLamp = PutCrit lamp putLamp = PutCrit lamp
singleBlock :: Point2 -> [Placement] singleBlock :: Point2 -> [Placement]
singleBlock a = [sPS a 0 $ PutBlock [5,20,20] (greyN 0.5) singleBlock a =
$ reverse $ rectNSWE 10 (-10) (-10) 10] [sPS a 0
$ PutBlock [5,20,20] (greyN 0.5)
$ reverse
$ rectNSWE 10 (-10) (-10) 10
]
{- {-
Places a line of blocks between two points. Places a line of blocks between two points.
Width 9, also extends out from each point by 9. Width 9, also extends out from each point by 9.
@@ -128,20 +132,45 @@ subZipWith f g xs ys =
let (zs,ws) = partition f xs let (zs,ws) = partition f xs
in zipWith g zs ys ++ ws in zipWith g zs ys ++ ws
isPutID :: Int -> Placement -> Bool
isPutID i ps = Just i == ps ^? placementSpot . psType . putID isPutID i ps = Just i == ps ^? placementSpot . psType . putID
putBlockRect
:: Float
-> Float
-> Float
-> Float
-> [Placement]
putBlockRect a x b y = [ blockLine (a,b) (a,y) putBlockRect a x b y = [ blockLine (a,b) (a,y)
, blockLine (a,y) (x,y) , blockLine (a,y) (x,y)
, blockLine (x,y) (x,b) , blockLine (x,y) (x,b)
, blockLine (x,b) (a,b) , blockLine (x,b) (a,b)
] ]
putBlockV
:: Float
-> Float
-> Float
-> Float
-> [Placement]
putBlockV a x b y = [ blockLine (a,b) (a,y) putBlockV a x b y = [ blockLine (a,b) (a,y)
, blockLine (x,b) (a,b) , blockLine (x,b) (a,b)
] ]
putBlockC
:: Float
-> Float
-> Float
-> Float
-> [Placement]
putBlockC a x b y = [ blockLine (a,b) (a,y) putBlockC a x b y = [ blockLine (a,b) (a,y)
, blockLine (x,b) (a,b) , blockLine (x,b) (a,b)
, blockLine (a,y) (x,y) , blockLine (a,y) (x,y)
] ]
putBlockN
:: Float
-> Float
-> Float
-> Float
-> [Placement]
putBlockN a x b y = [ blockLine (a,b) (a,y) putBlockN a x b y = [ blockLine (a,b) (a,y)
, blockLine (x,b) (a,b) , blockLine (x,b) (a,b)
, blockLine (x,y) (x,b) , blockLine (x,y) (x,b)
+28 -28
View File
@@ -12,16 +12,17 @@ import Dodge.Room.Data
import Dodge.Room.Placement import Dodge.Room.Placement
import Dodge.Room.Link import Dodge.Room.Link
import Dodge.Item.Consumable import Dodge.Item.Consumable
import Dodge.Item.Equipment
import Dodge.Item.Weapon import Dodge.Item.Weapon
import Dodge.RandomHelp import Dodge.RandomHelp
import Dodge.LevelGen import Dodge.LevelGen
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
import Dodge.Creature import Dodge.Creature
import Dodge.Default --import Dodge.Default
import Geometry import Geometry
import Picture import Picture
import Data.List (nub,nubBy,sortBy,minimumBy) import Data.List
import Data.Function (on) import Data.Function (on)
import qualified Data.Tuple.Extra as Tup import qualified Data.Tuple.Extra as Tup
import qualified Data.Map as M import qualified Data.Map as M
@@ -94,19 +95,19 @@ combineRooms r r' = Room
, _rmPS = _rmPS r ++ _rmPS r' , _rmPS = _rmPS r ++ _rmPS r'
, _rmBound = _rmBound r ++ _rmBound r' , _rmBound = _rmBound r ++ _rmBound r'
} }
{- The top fourth of a room of a given height. -} --{- The top fourth of a room of a given height. -}
fourth --fourth
:: Float -- ^ Distance from center of room to top edge -- :: Float -- ^ Distance from center of room to top edge
-> Room -- -> Room
fourth w = Room --fourth w = Room
{ _rmPolys = [ [(0,0),(w,w),(-w,w)] ] -- { _rmPolys = [ [(0,0),(w,w),(-w,w)] ]
, _rmLinks = [((0,w), 0)] -- , _rmLinks = [((0,w), 0)]
, _rmPath = [((0,w),(0,0)),((0,0),(0,w))] -- , _rmPath = [((0,w),(0,0)),((0,0),(0,w))]
, _rmPS = -- , _rmPS =
[sPS (0,w/2) 0 putLamp -- [sPS (0,w/2) 0 putLamp
] -- ]
, _rmBound = [[(0,0),(w,w),(-w,w)]] -- , _rmBound = [[(0,0),(w,w),(-w,w)]]
} -- }
{- Randomly generate a top fourth of a room possibly with a wall. {- Randomly generate a top fourth of a room possibly with a wall.
Add a light and a 'PutNothing' placement. -} Add a light and a 'PutNothing' placement. -}
fourthWall :: RandomGen g => Float -> State g Room fourthWall :: RandomGen g => Float -> State g Room
@@ -136,18 +137,17 @@ fourthWall w = do
, _rmPS = b , _rmPS = b
, _rmBound = [[(0,0),(w,w),(-w,w)]] , _rmBound = [[(0,0),(w,w),(-w,w)]]
} }
--fourthCorner :: Float -> Room
fourthCorner :: Float -> Room --fourthCorner w = Room
fourthCorner w = Room -- { _rmPolys = [ [(0,0),(w,w),(0,2*w),(-w,w)] ]
{ _rmPolys = [ [(0,0),(w,w),(0,2*w),(-w,w)] ] -- , _rmLinks =
, _rmLinks = -- [((w/2,3*w/2), negate $ pi/4)
[((w/2,3*w/2), negate $ pi/4) -- ,((negate $ w/2,3*w/2), pi/4)
,((negate $ w/2,3*w/2), pi/4) -- ]
] -- , _rmPath = [((0,w),(0,0)),((0,0),(0,w))]
, _rmPath = [((0,w),(0,0)),((0,0),(0,w))] -- , _rmPS = [sPS (0,w) 0 putLamp]
, _rmPS = [sPS (0,w) 0 putLamp] -- , _rmBound = [[(w,w),(0,2*w),(-w,w)]]
, _rmBound = [[(w,w),(0,2*w),(-w,w)]] -- }
}
fourthCornerWall :: RandomGen g => Float -> State g Room fourthCornerWall :: RandomGen g => Float -> State g Room
fourthCornerWall w = do fourthCornerWall w = do
@@ -261,5 +261,5 @@ centerVaultRoom n w h d = do
(over worldState (M.insert (DoorNumOpen i) True)) (over worldState (M.insert (DoorNumOpen i) True))
(over worldState (M.insert (DoorNumOpen i) False)) (over worldState (M.insert (DoorNumOpen i) False))
] ]
cond i w = or $ M.lookup (DoorNumOpen i) (_worldState w) cond i w' = or $ M.lookup (DoorNumOpen i) (_worldState w')
+1 -1
View File
@@ -9,7 +9,7 @@ import Dodge.Room.Link
import Dodge.Room.Placement import Dodge.Room.Placement
import Dodge.Room.Corridor import Dodge.Room.Corridor
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
import Dodge.RandomHelp --import Dodge.RandomHelp
import Dodge.Creature import Dodge.Creature
import Dodge.Layout.Tree.Polymorphic import Dodge.Layout.Tree.Polymorphic
+1 -2
View File
@@ -9,7 +9,7 @@ import Dodge.Base
import Dodge.Room.Data import Dodge.Room.Data
import Dodge.Room.Procedural import Dodge.Room.Procedural
import Dodge.Room.Placement import Dodge.Room.Placement
import Dodge.Layout --import Dodge.Layout
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
import Geometry import Geometry
import Picture import Picture
@@ -44,5 +44,4 @@ telRoomLev i = do
levelReset pp w levelReset pp w
| dist (_crPos $ you w) (_ppPos pp) < 20 = makeExplosionAt (_ppPos pp) $ startNewGame w | dist (_crPos $ you w) (_ppPos pp) < 20 = makeExplosionAt (_ppPos pp) $ startNewGame w
| otherwise = w | otherwise = w
ppPoly pp = map (+.+ _ppPos pp) ppFootprint
startNewGame w = w & worldTriggers %~ S.insert (ResetLevel i) startNewGame w = w & worldTriggers %~ S.insert (ResetLevel i)
+2 -2
View File
@@ -10,9 +10,9 @@ import Dodge.Room.Data
import Dodge.Room.Placement import Dodge.Room.Placement
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
import Data.List --import Data.List
import Control.Monad.State import Control.Monad.State
import Control.Lens --import Control.Lens
import System.Random import System.Random
{- | A triangular room with loot at the top (with 'PutID' 2), {- | A triangular room with loot at the top (with 'PutID' 2),
creatures in the bottom two corners (with 'PutID' 0), creatures in the bottom two corners (with 'PutID' 0),
-22
View File
@@ -20,28 +20,6 @@ module Dodge.SoundLogic (
, pauseSound , pauseSound
-- * Synonyms for sound identifiers -- * Synonyms for sound identifiers
, clickSound
, reloadSound
, pickUpSound
, putDownSound
, fireSound
, grenadeBang
, tapQuiet
, twoStepSound
, healSound
, doorSound
, twoStepSlowSound
, knifeSound
, buzzSound
, hitSound
, autoGunSound
, shotgunSound
, teleSound
, longGunSound
, launcherSound
, smokeTrailSound
, foot1Sound
, foot2Sound
, module Dodge.SoundLogic.Synonyms , module Dodge.SoundLogic.Synonyms
) where ) where
import Dodge.Data import Dodge.Data
+2 -1
View File
@@ -1,7 +1,7 @@
module Dodge.SoundLogic.Synonyms module Dodge.SoundLogic.Synonyms
where where
reloadSound,putDownSound,pickUpSound,fireSound,grenadeBang,healSound,teleSound,twoStepSlowSound :: Int clickSound , reloadSound , pickUpSound , putDownSound , fireSound , grenadeBang , tapQuiet , twoStepSound , healSound , doorSound , twoStepSlowSound , knifeSound , buzzSound , hitSound , autoGunSound , shotgunSound , teleSound , longGunSound , launcherSound , smokeTrailSound , foot1Sound , foot2Sound , drawWeaponSound , holsterWeaponSound :: Int
clickSound = 1 clickSound = 1
reloadSound = 2 reloadSound = 2
pickUpSound = 4 pickUpSound = 4
@@ -27,3 +27,4 @@ foot2Sound = 23
drawWeaponSound = 4 drawWeaponSound = 4
holsterWeaponSound = 5 holsterWeaponSound = 5
+14 -17
View File
@@ -8,12 +8,12 @@ module Dodge.Update
import Dodge.Data import Dodge.Data
import Dodge.Data.Menu import Dodge.Data.Menu
import Dodge.World.Trigger.Data import Dodge.World.Trigger.Data
import Dodge.Config.Data --import Dodge.Config.Data
import Dodge.Base import Dodge.Base
import Dodge.WallCreatureCollisions import Dodge.WallCreatureCollisions
import Dodge.LevelGen.Block import Dodge.LevelGen.Block
import Dodge.Update.Camera import Dodge.Update.Camera
import Dodge.Update.UsingInput --import Dodge.Update.UsingInput
import Dodge.SoundLogic import Dodge.SoundLogic
import Dodge.Inventory import Dodge.Inventory
import Dodge.Initialisation import Dodge.Initialisation
@@ -29,6 +29,7 @@ import qualified Data.IntMap.Strict as IM
import qualified Data.Map as M import qualified Data.Map as M
import Control.Lens import Control.Lens
update :: World -> World
update = update' . pushSideEffects update = update' . pushSideEffects
pushSideEffects :: World -> World pushSideEffects :: World -> World
@@ -40,7 +41,7 @@ pushSideEffects w = w
For most menus the only way to change the world is using event handling. -} For most menus the only way to change the world is using event handling. -}
update' :: World -> World update' :: World -> World
update' w = case _menuLayers w of update' w = case _menuLayers w of
(WaitMessage s i: ls) (WaitMessage s i: _)
| i < 1 -> w & doubleArgumentFor _worldEvents | i < 1 -> w & doubleArgumentFor _worldEvents
| otherwise -> w & menuLayers %~ ( (WaitMessage s (i-1) :) . tail ) | otherwise -> w & menuLayers %~ ( (WaitMessage s (i-1) :) . tail )
(GameOverMenu : _) -> updateParticles (GameOverMenu : _) -> updateParticles
@@ -99,6 +100,7 @@ updateTriggers w
where where
cr = _creatures w IM.! 0 & crPos .~ (0,0) cr = _creatures w IM.! 0 & crPos .~ (0,0)
updateSoundQueue :: World -> World
updateSoundQueue = set soundQueue [] . set sounds M.empty updateSoundQueue = set soundQueue [] . set sounds M.empty
updateLightSources :: World -> World updateLightSources :: World -> World
@@ -106,6 +108,7 @@ updateLightSources w = set tempLightSources (catMaybes tlss) w'
where where
(w',tlss) = mapAccumR (\a b -> _tlsUpdate b a b) w $ _tempLightSources w (w',tlss) = mapAccumR (\a b -> _tlsUpdate b a b) w $ _tempLightSources w
updateProjectiles :: World -> World
updateProjectiles w = IM.foldr' _pjUpdate w $ _projectiles w updateProjectiles w = IM.foldr' _pjUpdate w $ _projectiles w
{- {-
Apply internal particle updates, delete 'Nothing's. -} Apply internal particle updates, delete 'Nothing's. -}
@@ -126,7 +129,7 @@ updateWalls :: World -> World
updateWalls w = IM.foldr (fromMaybe id . (^? doorMech)) w (_walls w) updateWalls w = IM.foldr (fromMaybe id . (^? doorMech)) w (_walls w)
ppEvents :: World -> World ppEvents :: World -> World
ppEvents w = IM.foldr (\pp w -> _ppEvent pp pp w) w $ _pressPlates w ppEvents w = IM.foldr (\pp w' -> _ppEvent pp pp w') w $ _pressPlates w
updateSeenWalls :: World -> World updateSeenWalls :: World -> World
updateSeenWalls w = foldr markSeen w wallsToUpdate updateSeenWalls w = foldr markSeen w wallsToUpdate
@@ -136,10 +139,10 @@ updateSeenWalls w = foldr markSeen w wallsToUpdate
$ nRays 20 $ nRays 20
markSeen i = set (walls . ix i . wlSeen) True markSeen i = set (walls . ix i . wlSeen) True
setTestStringIO :: IO World -> IO World --setTestStringIO :: IO World -> IO World
setTestStringIO = fmap (\ w -> set testString (show $ s w) w) --setTestStringIO = fmap (\ w -> set testString (show $ s w) w)
where -- where
s w = (-.-) <$> (w ^? creatures . ix 0 . crPos) <*> (w ^? creatures . ix 0 . crOldPos) -- s w = (-.-) <$> (w ^? creatures . ix 0 . crPos) <*> (w ^? creatures . ix 0 . crOldPos)
checkEndGame :: World -> World checkEndGame :: World -> World
checkEndGame w checkEndGame w
@@ -158,7 +161,7 @@ moveCloud :: Cloud -> World -> World
moveCloud c w = _clEffect c c . theUpdate $ w moveCloud c w = _clEffect c c . theUpdate $ w
where where
newVel = 0.95 *.* springVels newVel = 0.95 *.* springVels
springVels = IM.foldr' (clClSpringVel c w) (_clVel c) (cloudsNearPoint oldPos w) springVels = IM.foldr' (clClSpringVel c) (_clVel c) (cloudsNearPoint oldPos w)
oldPos = _clPos c oldPos = _clPos c
newPos = oldPos +.+ newVel newPos = oldPos +.+ newVel
hitWl = collideCircWalls' oldPos newPos 5 $ wallsNearPoint newPos w hitWl = collideCircWalls' oldPos newPos 5 $ wallsNearPoint newPos w
@@ -169,8 +172,8 @@ moveCloud c w = _clEffect c c . theUpdate $ w
& clouds . ix (_clID c) . clVel .~ finalVel & clouds . ix (_clID c) . clVel .~ finalVel
& clouds . ix (_clID c) . clPos .~ finalPos & clouds . ix (_clID c) . clPos .~ finalPos
clClSpringVel :: Cloud -> World -> Cloud -> Point2 -> Point2 clClSpringVel :: Cloud -> Cloud -> Point2 -> Point2
clClSpringVel a w b v clClSpringVel a b v
| ida == idb = v | ida == idb = v
| dist pa pb < radDist = v +.+ 0.1 *.* safeNormalizeV (pa -.- pb) | dist pa pb < radDist = v +.+ 0.1 *.* safeNormalizeV (pa -.- pb)
| otherwise = v | otherwise = v
@@ -218,10 +221,4 @@ visibleWalls p1 p2 ws
$ IM.toList ws $ IM.toList ws
where where
f (i,wl) = (uncurry intersectSegSeg' (_wlLine wl) p1 p2, (i,wl)) f (i,wl) = (uncurry intersectSegSeg' (_wlLine wl) p1 p2, (i,wl))
takeUntil h xs =
let (ys,zs) = span h xs
in ys ++ tf zs
where
tf (x:_) = [x]
tf _ = []
+24 -26
View File
@@ -13,40 +13,38 @@ import Dodge.Item.Attachment.Data
import Geometry import Geometry
import Control.Lens import Control.Lens
import Control.Monad
import Data.Maybe import Data.Maybe
import qualified Data.Set as S import qualified Data.Set as S
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import qualified SDL import qualified SDL
{- Update the screen camera rotation and position, including any in rold scope/remote camera modifiers;
{- update where your avatar's view is from. -}
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 :: World -> World
updateCamera = rotCam . moveCamera . updateScopeZoom updateCamera = rotCam . moveCamera . updateScopeZoom
{- Updte the center of the screen camera center and where your avatar's view is from in world. -} {- Updte the center of the screen camera center and where your avatar's view is from in world. -}
moveCamera :: World -> World moveCamera :: World -> World
moveCamera w = w & cameraCenter .~ idealPos moveCamera w = w & cameraCenter .~ idealPos
& cameraViewFrom .~ sightFrom & cameraViewFrom .~ sightFrom
where where
aimRangeFactor | _cameraZoom w == 0 = 0 aimRangeFactor
| otherwise = fromMaybe 0 (yourItem w ^? itAimingRange) / _cameraZoom w | _cameraZoom w == 0 = 0
aimingMult | SDL.ButtonRight `S.member` _mouseButtons w = 1 | otherwise = fromMaybe 0 (yourItem w ^? itAimingRange) / _cameraZoom w
| otherwise = 0 aimingMult
| SDL.ButtonRight `S.member` _mouseButtons w = 1
| otherwise = 0
ypos = _crPos $ you w ypos = _crPos $ you w
idealOffset = rotateV (_cameraRot w) (aimRangeFactor * aimingMult *.* _mousePos w) --idealOffset = rotateV (_cameraRot w) (aimRangeFactor * aimingMult *.* _mousePos w)
currentOffset = currentPos -.- camCenter --currentOffset = currentPos -.- camCenter
idealPos = camCenter +.+ rotateV (_cameraRot w) idealPos = camCenter +.+ rotateV (_cameraRot w)
(aimRangeFactor * aimingMult *.* _mousePos w) (aimRangeFactor * aimingMult *.* _mousePos w)
currentPos = _cameraCenter w --currentPos = _cameraCenter w
camCenter = ypos +.+ scope camCenter = ypos +.+ scope
isCam :: Bool isCam :: Bool
isCam = fromMaybe False $ yourItem w ^? itAttachment . _Just . scopeIsCamera isCam = fromMaybe False $ yourItem w ^? itAttachment . _Just . scopeIsCamera
scope = fromMaybe (0,0) $ yourItem w ^? itAttachment . _Just . scopePos scope = fromMaybe (0,0) $ yourItem w ^? itAttachment . _Just . scopePos
sightFrom | isCam = camCenter sightFrom
| otherwise = ypos | isCam = camCenter
| otherwise = ypos
updateScopeZoom :: World -> World updateScopeZoom :: World -> World
updateScopeZoom w updateScopeZoom w
@@ -73,6 +71,7 @@ updateScopeZoom w
updateScope (ItScope _ _ _ bl) = ItScope (0,0) 0 1 bl updateScope (ItScope _ _ _ bl) = ItScope (0,0) 0 1 bl
updateScope otherAtt = otherAtt updateScope otherAtt = otherAtt
zoomSpeed :: Float
zoomSpeed = 39/40 zoomSpeed = 39/40
zoomInLongGun :: World -> World zoomInLongGun :: World -> World
@@ -96,16 +95,18 @@ zoomOutLongGun w
wpPointer = creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0)) wpPointer = creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0))
wp = _crInv (_creatures w IM.! 0) IM.! _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 . _Just . scopeZoom
currentCursorDisplacement = fromJust $ _itAttachment wp --currentCursorDisplacement = fromJust $ _itAttachment wp
rotCam :: World -> World
rotCam = rotateCameraL . rotateCameraR . zoomCamIn . zoomCamOut . autoZoomCam rotCam = rotateCameraL . rotateCameraR . zoomCamIn . zoomCamOut . autoZoomCam
rotateCameraL :: World -> World rotateCameraL :: World -> World
rotateCameraL w | rotateCameraPlusKey (_keyConfig w) `S.member` _keys w rotateCameraL w
= w & cameraRot +~ 0.015 | rotateCameraPlusKey (_keyConfig w) `S.member` _keys w
& creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0)) = w & cameraRot +~ 0.015
& creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0))
. itAttachment . _Just . scopePos %~ rotateV 0.015 . itAttachment . _Just . scopePos %~ rotateV 0.015
| otherwise = w | otherwise = w
rotateCameraR :: World -> World rotateCameraR :: World -> World
rotateCameraR w | rotateCameraMinusKey (_keyConfig w) `S.member` _keys w rotateCameraR w | rotateCameraMinusKey (_keyConfig w) `S.member` _keys w
= w & cameraRot -~ 0.015 = w & cameraRot -~ 0.015
@@ -127,9 +128,7 @@ Automatically sets the zoom of the camera according to the surrounding walls.
autoZoomCam :: World -> World autoZoomCam :: World -> World
autoZoomCam w = over cameraZoom changeZoom w autoZoomCam w = over cameraZoom changeZoom w
where where
maxViewDistance = 800
camPos = _cameraViewFrom w camPos = _cameraViewFrom w
camRot = _cameraRot w
wallZoom = farWallDist camPos w wallZoom = farWallDist camPos w
idealZoom | SDL.ButtonRight `S.member` _mouseButtons w idealZoom | SDL.ButtonRight `S.member` _mouseButtons w
= scZoom * = scZoom *
@@ -168,6 +167,5 @@ farWallDist cpos w = min (halfWidth w / (horizontalMax+50) ) (halfHeight w / (ve
zs = takeWhile (< maxViewDistance) [-maxViewDistance,negate $ 0.75*maxViewDistance..] zs = takeWhile (< maxViewDistance) [-maxViewDistance,negate $ 0.75*maxViewDistance..]
maxViewDistance = 800 maxViewDistance = 800
--dirRays :: Float -> [Point2]
dirRays :: Float -> [Point2] --dirRays dir = take 11 $ iterate (rotateV (0.5 * pi / 10)) $ rotateV (dir-pi*0.25) (600,0)
dirRays dir = take 11 $ iterate (rotateV (0.5 * pi / 10)) $ rotateV (dir-pi*0.25) (600,0)
+18 -21
View File
@@ -20,9 +20,9 @@ colCrWall :: World -> Creature -> Creature
colCrWall w c colCrWall w c
| p1 == p2 = pushOrCrush ls c | p1 == p2 = pushOrCrush ls c
| otherwise = c & crPos %~ | otherwise = c & crPos %~
collideCorners rad p1 wallPoints collideCorners rad wallPoints
. collideWalls rad p1 ls . collideWalls rad p1 ls
. checkPushThroughs rad p1 ls . checkPushThroughs p1 ls
where where
rad = _crRad c + wallBuffer rad = _crRad c + wallBuffer
p1 = _crOldPos c p1 = _crOldPos c
@@ -39,27 +39,28 @@ colCrWall w c
-- -- probably best to push check pushing through walls before creature springs -- -- probably best to push check pushing through walls before creature springs
-- the amount to push creatures out from walls, extra to their radius -- the amount to push creatures out from walls, extra to their radius
wallBuffer :: Float
wallBuffer = 0 wallBuffer = 0
-- the following tests whether or not a point is on a wall, and if so pushes it -- the following tests whether or not a point is on a wall, and if so pushes it
-- out from the wall -- out from the wall
-- this is then repeated if the point ends up on a new wall -- this is then repeated if the point ends up on a new wall
collideWalls :: Float -> Point2 -> [(Point2,Point2)] -> Point2 -> Point2 collideWalls :: Float -> Point2 -> [(Point2,Point2)] -> Point2 -> Point2
collideWalls rad cp1 walls cp2 = case (listToMaybe.mapMaybe (pushOutFromWall rad cp2)) walls of collideWalls rad cp1 wls cp2 = case (listToMaybe.mapMaybe (pushOutFromWall rad cp2)) wls of
Nothing -> cp2 Nothing -> cp2
Just cp3 -> case (listToMaybe.reverse.mapMaybe (pushOutFromWall rad cp3)) walls of Just cp3 -> case (listToMaybe.reverse.mapMaybe (pushOutFromWall rad cp3)) wls of
Nothing -> cp3 Nothing -> cp3
Just cp4 -> 0.5 *.* (cp4 +.+ cp1) Just cp4 -> 0.5 *.* (cp4 +.+ cp1)
-- pushes a point out from a list of walls -- pushes a point out from a list of walls
-- if multiple new points occur, chooses the one closest to the orignal point -- if multiple new points occur, chooses the one closest to the orignal point
pushOutFromWalls :: Float -> [(Point2,Point2)] -> Point2 -> Point2 pushOutFromWalls :: Float -> [(Point2,Point2)] -> Point2 -> Point2
pushOutFromWalls rad walls p = pushOutFromWalls rad wls p =
fromMaybe p fromMaybe p
. listToMaybe . listToMaybe
. sortBy (compare `on` dist p) . sortBy (compare `on` dist p)
$ mapMaybe (pushOutFromWall rad p) $ mapMaybe (pushOutFromWall rad p)
walls wls
pushOrCrush :: [(Point2,Point2)] -> Creature -> Creature pushOrCrush :: [(Point2,Point2)] -> Creature -> Creature
pushOrCrush wls cr = case mapMaybe (pushOutFromWall (_crRad cr) cpos) wls of pushOrCrush wls cr = case mapMaybe (pushOutFromWall (_crRad cr) cpos) wls of
@@ -81,8 +82,6 @@ pushOutFromWall rad cp2 (wp1,wp2)
wp2' = (rad *.* norm) +.+ wp2 wp2' = (rad *.* norm) +.+ wp2
newP = errorClosestPointOnLine 5 wp1' wp2' cp2 newP = errorClosestPointOnLine 5 wp1' wp2' cp2
isOnWall = circOnSegNoEndpoints wp1 wp2 cp2 rad isOnWall = circOnSegNoEndpoints wp1 wp2 cp2 rad
isJust Nothing = False
isJust _ = True
pushOutFromCorners :: World -> Creature -> Creature pushOutFromCorners :: World -> Creature -> Creature
pushOutFromCorners w cr = cr & crPos .~ newPos pushOutFromCorners w cr = cr & crPos .~ newPos
@@ -90,8 +89,8 @@ pushOutFromCorners w cr = cr & crPos .~ newPos
newPos = foldr (intersectCirclePoint (_crRad cr)) (_crPos cr) ls newPos = foldr (intersectCirclePoint (_crRad cr)) (_crPos cr) ls
ls = nub . concatMap (\(x,y) -> [x,y]) . IM.elems $ _wlLine <$> wallsNearPoint (_crPos cr) w ls = nub . concatMap (\(x,y) -> [x,y]) . IM.elems $ _wlLine <$> wallsNearPoint (_crPos cr) w
collideCorners :: Float -> Point2 -> [Point2] -> Point2 -> Point2 collideCorners :: Float -> [Point2] -> Point2 -> Point2
collideCorners rad p1 ps p2 = foldr (intersectCirclePoint rad) p2 ps collideCorners rad ps p2 = foldr (intersectCirclePoint rad) p2 ps
-- collide circles with points (outer corners) -- collide circles with points (outer corners)
intersectCirclePoint :: Float -> Point2 -> Point2 -> Point2 intersectCirclePoint :: Float -> Point2 -> Point2 -> Point2
@@ -99,19 +98,17 @@ intersectCirclePoint rad p cCen
| dist cCen p > rad = cCen | dist cCen p > rad = cCen
| otherwise = p +.+ (rad *.* errorNormalizeV 65 (cCen -.- p)) | otherwise = p +.+ (rad *.* errorNormalizeV 65 (cCen -.- p))
checkPushThroughs :: Float -> Point2 -> [(Point2,Point2)] -> Point2 -> Point2 checkPushThroughs :: Point2 -> [(Point2,Point2)] -> Point2 -> Point2
checkPushThroughs rad cp1 walls cp2 checkPushThroughs cp1 wls cp2
= fromMaybe cp2 $ (listToMaybe.mapMaybe (checkPushThrough rad cp1 cp2)) walls = fromMaybe cp2 $ (listToMaybe.mapMaybe (checkPushThrough cp1 cp2)) wls
checkPushThrough :: Float -> Point2 -> Point2 -> (Point2,Point2) -> Maybe Point2 checkPushThrough :: Point2 -> Point2 -> (Point2,Point2) -> Maybe Point2
checkPushThrough rad cp1 cp2 (wp1,wp2) checkPushThrough cp1 cp2 (wp1,wp2)
| isPushedThrough = intersectSegSeg' cp1 cp2 wp1 wp2 | isPushedThrough = intersectSegSeg' cp1 cp2 wp1 wp2
| otherwise = Nothing | otherwise = Nothing
where where
norm = errorNormalizeV 61 $ vNormal (wp1 -.- wp2) --norm = errorNormalizeV 61 $ vNormal (wp1 -.- wp2)
wp1' = (rad *.* norm) +.+ wp1 --wp1' = (rad *.* norm) +.+ wp1
wp2' = (rad *.* norm) +.+ wp2 --wp2' = (rad *.* norm) +.+ wp2
newP = errorClosestPointOnLine 5 wp1' wp2' cp2 --newP = errorClosestPointOnLine 5 wp1' wp2' cp2
isPushedThrough = isRHS wp1 wp2 cp2 && isJust (intersectSegSeg' cp1 cp2 wp1 wp2) isPushedThrough = isRHS wp1 wp2 cp2 && isJust (intersectSegSeg' cp1 cp2 wp1 wp2)
isJust Nothing = False
isJust _ = True
+4 -14
View File
@@ -3,40 +3,30 @@ module Dodge.WorldEvent
, module Dodge.WorldEvent.Bullet , module Dodge.WorldEvent.Bullet
, module Dodge.WorldEvent.Flash , module Dodge.WorldEvent.Flash
, module Dodge.WorldEvent.ThingsHit , module Dodge.WorldEvent.ThingsHit
, module Dodge.WorldEvent.HelperParticle
, module Dodge.WorldEvent.Cloud , module Dodge.WorldEvent.Cloud
, module Dodge.WorldEvent.HitEffect , module Dodge.WorldEvent.HitEffect
, module Dodge.WorldEvent.Explosion , module Dodge.WorldEvent.Explosion
, module Dodge.WorldEvent.SpawnParticle , module Dodge.WorldEvent.SpawnParticle
) )
where where
import Dodge.WorldEvent.Bullet import Dodge.WorldEvent.Bullet
import Dodge.WorldEvent.Flash import Dodge.WorldEvent.Flash
import Dodge.WorldEvent.ThingsHit import Dodge.WorldEvent.ThingsHit
import Dodge.WorldEvent.HelperParticle --import Dodge.WorldEvent.HelperParticle
import Dodge.WorldEvent.Cloud import Dodge.WorldEvent.Cloud
import Dodge.WorldEvent.HitEffect import Dodge.WorldEvent.HitEffect
import Dodge.WorldEvent.Explosion import Dodge.WorldEvent.Explosion
import Dodge.WorldEvent.SpawnParticle import Dodge.WorldEvent.SpawnParticle
import Dodge.WorldEvent.Shockwave --import Dodge.WorldEvent.Shockwave
import Dodge.LightSources import Dodge.LightSources
import Dodge.Creature.State.Data import Dodge.Creature.State.Data
import Dodge.Data import Dodge.Data
import Dodge.Base --import Dodge.Base
import Dodge.SoundLogic
import Dodge.RandomHelp
import Geometry import Geometry
import Picture --import Picture
import Control.Lens import Control.Lens
import Control.Monad.State
import System.Random import System.Random
import Data.Maybe
import Data.Function
import Data.List
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
createBarrelSpark :: Point2 -> Float -> Maybe Int -> Int -> Int -> World -> World createBarrelSpark :: Point2 -> Float -> Maybe Int -> Int -> Int -> World -> World
+6 -12
View File
@@ -4,20 +4,16 @@ Bullet update.
module Dodge.WorldEvent.Bullet module Dodge.WorldEvent.Bullet
where where
import Dodge.Data import Dodge.Data
import Dodge.Base --import Dodge.Base
import Dodge.WorldEvent.ThingsHit import Dodge.WorldEvent.ThingsHit
--import Picture
import Picture
import Geometry import Geometry
import Control.Lens import Control.Lens
--import Data.Maybe
import Data.Maybe --import Data.List
import Data.List --import Data.Bifunctor
import Data.Function (on) --import qualified Data.IntMap.Strict as IM
import Data.Bifunctor
import qualified Data.IntMap.Strict as IM
{- {-
Update for a generic bullet. Update for a generic bullet.
@@ -32,9 +28,7 @@ mvGenBullet' w bt
| otherwise = hiteff bt (thingsHitExceptCr mcr p (p +.+ vel) w) w | otherwise = hiteff bt (thingsHitExceptCr mcr p (p +.+ vel) w) w
where where
mcr = _btPassThrough' bt mcr = _btPassThrough' bt
col = _btColor' bt
(p:ps) = _btTrail' bt (p:ps) = _btTrail' bt
vel = _btVel' bt vel = _btVel' bt
hiteff = _btHitEffect' bt hiteff = _btHitEffect' bt
wth = _btWidth' bt
t = _btTimer' bt t = _btTimer' bt
+1 -3
View File
@@ -3,9 +3,7 @@ module Dodge.WorldEvent.Cloud
import Dodge.Data import Dodge.Data
import Dodge.Base import Dodge.Base
--import Geometry
import Geometry
import Picture import Picture
import Control.Lens import Control.Lens
+16
View File
@@ -0,0 +1,16 @@
module Dodge.WorldEvent.DamageBlock
( damageBlocksBy
)
where
import Dodge.Data
import Data.Maybe
import Control.Lens
{- | Given a wall, if it is a damageable block
- then damage it and connecting walls by a certain amount. -}
damageBlocksBy :: Int -> Wall -> World -> World
{-# INLINE damageBlocksBy #-}
damageBlocksBy x wall w
| isJust (wall ^? blHP) = foldr (\j -> walls . ix j . blHP -~ x) w (_blIDs wall)
| otherwise = w
+2 -3
View File
@@ -3,7 +3,6 @@ Explosions: creation of shockwave and particles at a given point.
-} -}
module Dodge.WorldEvent.Explosion module Dodge.WorldEvent.Explosion
where where
import Dodge.Data import Dodge.Data
import Dodge.Base import Dodge.Base
import Dodge.WorldEvent.SpawnParticle import Dodge.WorldEvent.SpawnParticle
@@ -16,7 +15,7 @@ import Picture
import Control.Monad.State import Control.Monad.State
import Data.List import Data.List
import Data.Maybe --import Data.Maybe
import System.Random import System.Random
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import Control.Lens import Control.Lens
@@ -78,6 +77,6 @@ makeExplosionAt p w
times = randomRs (20,25) $ _randGen w times = randomRs (20,25) $ _randGen w
mF q v size time = makeFlameletTimed q v Nothing size time mF q v size time = makeFlameletTimed q v Nothing size time
newFs = zipWith4 mF fPs (fmap (3 *.*) fVs') sizes times newFs = zipWith4 mF fPs (fmap (3 *.*) fVs') sizes times
addFlames w = foldr ($) w newFs addFlames w' = foldr ($) w' newFs
pushAgainstWalls q = maybe q (uncurry (+.+)) $ reflectPointWalls p q $ wallsNearPoint q w pushAgainstWalls q = maybe q (uncurry (+.+)) $ reflectPointWalls p q $ wallsNearPoint q w
+6 -7
View File
@@ -11,18 +11,15 @@ flicker : potentially long, moving, abrupt changes in alpha
module Dodge.WorldEvent.Flash module Dodge.WorldEvent.Flash
where where
import Dodge.Data import Dodge.Data
import Dodge.Base --import Dodge.Base
import Dodge.Picture import Dodge.Picture
import Dodge.LightSources import Dodge.LightSources
import Dodge.WorldEvent.ThingsHit import Dodge.WorldEvent.ThingsHit
import Dodge.WorldEvent.HelperParticle import Dodge.WorldEvent.HelperParticle
import Picture import Picture
import Geometry import Geometry
import Data.Maybe (maybeToList) import Data.Maybe (maybeToList)
import Control.Lens import Control.Lens
glareAt :: Int -> Float -> Float -> Color -> Int -> Float -> Point2 -> World -> World glareAt :: Int -> Float -> Float -> Color -> Int -> Float -> Point2 -> World -> World
@@ -70,12 +67,13 @@ lowLightPic :: Float -> Float -> Color -> (Point2, Point2) -> World -> Picture
lowLightPic len wdth col (a,b) w = case thingsHit a b w of lowLightPic len wdth col (a,b) w = case thingsHit a b w of
((p, E3x2 wall):_) ((p, E3x2 wall):_)
-> setCol . lineOfThickness wdth $ [alongSegBy len p wa, alongSegBy len p wb] -> setCol . lineOfThickness wdth $ [alongSegBy len p wa, alongSegBy len p wb]
where x = len *.* normalizeV (wa -.- wb) where
(wa,wb) = _wlLine wall (wa,wb) = _wlLine wall
((p, E3x1 cr):_) ((p, E3x1 cr):_)
-> setCol . uncurry translate cp . rotate (-0.25 * pi + argV (p -.- cp)) -> setCol . uncurry translate cp . rotate (-0.25 * pi + argV (p -.- cp))
$ thickArc 0 (pi/2) (_crRad cr) wdth $ thickArc 0 (pi/2) (_crRad cr) wdth
where cp = _crPos cr where
cp = _crPos cr
_ -> blank _ -> blank
where setCol = color col . setDepth (-0.5) . setLayer 2 where setCol = color col . setDepth (-0.5) . setLayer 2
@@ -93,6 +91,7 @@ explosionFlashAt p = over tempLightSources ((:) $ tLightFade 20 150 intensityFu
| x < 10 = 1 / (10 - fromIntegral x) | x < 10 = 1 / (10 - fromIntegral x)
| otherwise = 1 | otherwise = 1
flameGlareAt :: Point2 -> World -> World
flameGlareAt = glareAt 1 10 5 (withAlpha 0.05 orange) 8 40 flameGlareAt = glareAt 1 10 5 (withAlpha 0.05 orange) 8 40
lowLightDirected :: Color -> Point2 -> Point2 -> [Float] -> World -> World lowLightDirected :: Color -> Point2 -> Point2 -> [Float] -> World -> World
+3 -8
View File
@@ -1,14 +1,9 @@
{- {- Helper functions for particles. -}
Helper functions for particles.
-}
module Dodge.WorldEvent.HelperParticle module Dodge.WorldEvent.HelperParticle
where where
import Dodge.Data import Dodge.Data
{- {- A simple timer update for particles. -}
A simple timer update for particles.
-}
ptTimer' :: Int -> World -> Particle -> (World, Maybe Particle) ptTimer' :: Int -> World -> Particle -> (World, Maybe Particle)
ptTimer' 0 w pt = (w, Nothing) ptTimer' 0 w _ = (w, Nothing)
ptTimer' n w pt = (w, Just $ pt {_ptUpdate' = ptTimer' (n-1)}) ptTimer' n w pt = (w, Just $ pt {_ptUpdate' = ptTimer' (n-1)})
+50 -28
View File
@@ -2,21 +2,25 @@ module Dodge.WorldEvent.HitEffect
where where
import Dodge.Data import Dodge.Data
import Dodge.Creature.State.Data import Dodge.Creature.State.Data
import Geometry import Geometry
import Data.Bifunctor import Data.Bifunctor
import Data.Maybe import Data.Maybe
import Control.Lens import Control.Lens
type HitCreatureEffect = Particle -> Point2 -> Creature -> World -> World type HitCreatureEffect = Particle -> Point2 -> Creature -> World -> World
type HitWallEffect = Particle -> Point2 -> Wall -> World -> World type HitWallEffect = Particle -> Point2 -> Wall -> World -> World
type HitForceFieldEffect = Particle -> Point2 -> ForceField -> World -> World type HitForceFieldEffect = Particle -> Point2 -> ForceField -> World -> World
passThroughAll :: HitCreatureEffect -> HitWallEffect -> HitForceFieldEffect -> passThroughAll
Particle -> [(Point2, Either3 Creature Wall ForceField)] -> World -> (World, Maybe Particle) :: HitCreatureEffect
passThroughAll crEff wlEff ffEff pt hitThings w = (w, mvPt) -> HitWallEffect
-> HitForceFieldEffect
-> Particle
-> [(Point2, Either3 Creature Wall ForceField)] -- ^ hit things
-> World
-> (World, Maybe Particle)
passThroughAll _ _ _ pt _ w = (w, mvPt)
where where
mvPt = Just $ pt & btTrail' .~ (newP : trl) mvPt = Just $ pt & btTrail' .~ (newP : trl)
& btTimer' %~ (\t -> t - 1) & btTimer' %~ (\t -> t - 1)
@@ -24,24 +28,38 @@ passThroughAll crEff wlEff ffEff pt hitThings w = (w, mvPt)
trl = _btTrail' pt trl = _btTrail' pt
newP = head trl +.+ _btVel' pt newP = head trl +.+ _btVel' pt
destroyOnImpact :: HitCreatureEffect -> HitWallEffect -> HitForceFieldEffect -> destroyOnImpact
Particle -> [(Point2, Either3 Creature Wall ForceField)] -> World -> (World, Maybe Particle) :: HitCreatureEffect
-> HitWallEffect
-> HitForceFieldEffect
-> Particle
-> [(Point2, Either3 Creature Wall ForceField)]
-> World
-> (World, Maybe Particle)
destroyOnImpact crEff wlEff ffEff pt hitThings w = case hitThings of destroyOnImpact crEff wlEff ffEff pt hitThings w = case hitThings of
[] -> ( w, mvPt) [] -> ( w, mvPt)
((p,E3x1 cr):_) -> (crEff pt p cr w, destroyAt p) ((p,E3x1 cr):_) -> (crEff pt p cr w, destroyAt p)
((p,E3x2 wl):_) -> (wlEff pt p wl w, destroyAt p) ((p,E3x2 wl):_) -> (wlEff pt p wl w, destroyAt p)
((p,E3x3 ff):_) -> (ffEff pt p ff w, destroyAt p) ((p,E3x3 ff):_) -> (ffEff pt p ff w, destroyAt p)
where destroyAt hitp = Just $ pt & btTrail' .~ (hitp : trl) where
& btTimer' .~ 3 destroyAt hitp = Just $ pt
mvPt = Just $ pt & btTrail' .~ (newP : trl) & btTrail' .~ (hitp : trl)
& btTimer' %~ (\t -> t - 1) & btTimer' .~ 3
& btPassThrough' .~ Nothing mvPt = Just $ pt
trl = _btTrail' pt & btTrail' .~ (newP : trl)
wth = _btWidth' pt & btTimer' %~ (\t -> t - 1)
newP = head trl +.+ _btVel' pt & btPassThrough' .~ Nothing
trl = _btTrail' pt
newP = head trl +.+ _btVel' pt
penWalls :: HitCreatureEffect -> HitWallEffect -> HitForceFieldEffect -> penWalls
Particle -> [(Point2, Either3 Creature Wall ForceField)] -> World -> (World, Maybe Particle) :: HitCreatureEffect
-> HitWallEffect
-> HitForceFieldEffect
-> Particle
-> [(Point2, Either3 Creature Wall ForceField)]
-> World
-> (World, Maybe Particle)
penWalls crEff wlEff ffEff pt hitThings w = case hitThings of penWalls crEff wlEff ffEff pt hitThings w = case hitThings of
[] -> ( w, mvPt) [] -> ( w, mvPt)
((p,E3x1 cr):_) -> (crEff pt p cr w, destroyAt p) ((p,E3x1 cr):_) -> (crEff pt p cr w, destroyAt p)
@@ -49,19 +67,23 @@ penWalls crEff wlEff ffEff pt hitThings w = case hitThings of
((p,E3x2 wl):hs) | isJust (wl ^? blHP) ((p,E3x2 wl):hs) | isJust (wl ^? blHP)
-> first (wlEff pt p wl) $ penWalls crEff wlEff ffEff pt hs w -> first (wlEff pt p wl) $ penWalls crEff wlEff ffEff pt hs w
((p,E3x2 wl):_) | otherwise -> (wlEff pt p wl w, destroyAt p) ((p,E3x2 wl):_) | otherwise -> (wlEff pt p wl w, destroyAt p)
where destroyAt hitp = Just $ pt & btTrail' .~ (hitp : trl) where
& btTimer' .~ 3 destroyAt hitp = Just $ pt
mvPt = Just $ pt & btTrail' .~ (newP : trl) & btTrail' .~ (hitp : trl)
& btTimer' %~ (\t -> t - 1) & btTimer' .~ 3
& btPassThrough' .~ Nothing mvPt = Just $ pt
trl = _btTrail' pt & btTrail' .~ (newP : trl)
wth = _btWidth' pt & btTimer' %~ (\t -> t - 1)
newP = head trl +.+ _btVel' pt & btPassThrough' .~ Nothing
trl = _btTrail' pt
newP = head trl +.+ _btVel' pt
doFlameDam :: Int -> Particle -> Point2 -> Creature -> World -> World doFlameDam :: Int -> Particle -> Point2 -> Creature -> World -> World
doFlameDam amount pt p cr = over (creatures . ix (_crID cr) . crState . crDamage) doFlameDam amount pt p cr = over (creatures . ix (_crID cr) . crState . crDamage)
((:) $ Flaming amount sp p ep) ((:) $ Flaming amount sp p ep)
where sp = _btPos' pt where
ep = sp +.+ _btVel' pt sp = _btPos' pt
ep = sp +.+ _btVel' pt
noEff :: a -> b -> c -> d -> d
noEff _ _ _ = id noEff _ _ _ = id
+4 -15
View File
@@ -4,6 +4,7 @@ module Dodge.WorldEvent.Shockwave
) )
where where
import Dodge.Data import Dodge.Data
import Dodge.WorldEvent.DamageBlock
import Dodge.Creature.State.Data import Dodge.Creature.State.Data
import Dodge.Base import Dodge.Base
import Dodge.Picture.Layer import Dodge.Picture.Layer
@@ -72,14 +73,8 @@ mvShockwave is w pt
t = _btTimer' pt t = _btTimer' pt
tFraction = fromIntegral t / fromIntegral (_btMaxTime' pt) tFraction = fromIntegral t / fromIntegral (_btMaxTime' pt)
rad = r - (3/4) * r * tFraction rad = r - (3/4) * r * tFraction
dams = over creatures (IM.map damCr) . flip (IM.foldr damageBlocks) hitBlocks dams = over creatures (IM.map damCr) . flip (IM.foldr (damageBlocksBy 1)) hitBlocks
hitBlocks = wallsOnCirc p rad $ wallsNearPoint p w hitBlocks = wallsOnCirc p rad $ wallsNearPoint p w
damageBlocks wall w
= case wall ^? blHP of
Just hp -> foldr (\j -> over (walls . ix j . blHP) (\y -> y - 1))
w
(_blIDs wall)
_ -> w
damCr cr | _crID cr `elem` is = cr damCr cr | _crID cr `elem` is = cr
| dist (_crPos cr) p < rad + _crRad cr | dist (_crPos cr) p < rad + _crRad cr
= over (crState . crDamage) = over (crState . crDamage)
@@ -100,7 +95,7 @@ inverseShockwaveAt
-> Float -- Push amount parameter -> Float -- Push amount parameter
-> World -> World
-> World -> World
inverseShockwaveAt p rad dam push pushexp = over particles (theShockwave :) inverseShockwaveAt p rad _ push pushexp = over particles (theShockwave :)
where where
theShockwave = Particle theShockwave = Particle
{ _ptDraw = const blank { _ptDraw = const blank
@@ -124,14 +119,8 @@ moveInverseShockWave t p r push pushexp w pt
$ color cyan $ thickCircle rad thickness) $ color cyan $ thickCircle rad thickness)
rad = r - (4/40) * r * fromIntegral (10 - t) rad = r - (4/40) * r * fromIntegral (10 - t)
thickness = fromIntegral (10 - t) **2 * rad / 40 thickness = fromIntegral (10 - t) **2 * rad / 40
dams = over creatures (IM.map damCr) . flip (foldr damageBlocks) hitBlocks dams = over creatures (IM.map damCr) . flip (foldr (damageBlocksBy 1)) hitBlocks
hitBlocks = wallsOnCirc p rad $ wallsNearPoint p w hitBlocks = wallsOnCirc p rad $ wallsNearPoint p w
damageBlocks wall w
= case wall ^? blHP of
Just hp -> foldr (\j -> over (walls . ix j . blHP) (\y -> y - 1))
w
(_blIDs wall)
_ -> w
damCr cr | dist (_crPos cr) p < rad + _crRad cr damCr cr | dist (_crPos cr) p < rad + _crRad cr
= over (crState . crDamage) = over (crState . crDamage)
((:) $ PushDam 1 (25 *.* safeNormalizeV (p -.- _crPos cr))) ((:) $ PushDam 1 (25 *.* safeNormalizeV (p -.- _crPos cr)))
-2
View File
@@ -1,8 +1,6 @@
module Dodge.WorldEvent.Sound module Dodge.WorldEvent.Sound
where where
import Dodge.Data import Dodge.Data
import Geometry.Data (Point2)
import Dodge.SoundLogic import Dodge.SoundLogic
import System.Random import System.Random
+11 -17
View File
@@ -12,7 +12,6 @@ import Dodge.WorldEvent.HitEffect
import Dodge.WorldEvent.ThingsHit import Dodge.WorldEvent.ThingsHit
import Dodge.WorldEvent.Cloud import Dodge.WorldEvent.Cloud
import Dodge.WorldEvent.Flash import Dodge.WorldEvent.Flash
import Dodge.WorldEvent.HelperParticle
import Dodge.WorldEvent.Bullet import Dodge.WorldEvent.Bullet
import Dodge.SoundLogic import Dodge.SoundLogic
import Dodge.RandomHelp import Dodge.RandomHelp
@@ -98,7 +97,7 @@ moveFlame
moveFlame rotd w pt moveFlame rotd w pt
| time <= 0 = (smokeGen w, Nothing) | time <= 0 = (smokeGen w, Nothing)
| otherwise = case thingsHitExceptCr (_btPassThrough' pt) sp ep w of | otherwise = case thingsHitExceptCr (_btPassThrough' pt) sp ep w of
((p,E3x1 cr):_) -> (soundAndGlare damcrs , mvPt') ((_,E3x1 _):_) -> (soundAndGlare damcrs , mvPt')
(thing@(p,E3x2 wl):_) -> (fst $ hiteff [thing] damcrs , rfl wl p) (thing@(p,E3x2 wl):_) -> (fst $ hiteff [thing] damcrs , rfl wl p)
_ -> (soundAndGlare damcrs , mvPt) _ -> (soundAndGlare damcrs , mvPt)
where where
@@ -198,12 +197,8 @@ drawFlamelet rot pt = setLayer 1 $ pictures [pic , piu , pi2 , glow]
sc = (*) 2 $ log $ 1 + fromIntegral time / 20 sc = (*) 2 $ log $ 1 + fromIntegral time / 20
s1 = (*) 2 $ log $ 2 + fromIntegral time / 40 s1 = (*) 2 $ log $ 2 + fromIntegral time / 40
s2 = 0.5 * (sc + s1) s2 = 0.5 * (sc + s1)
thepicture = pictures [pic , piu , pi2 , glow] {- Update of a flamelet.
Applies movement and attaches damage to nearby creatures. -}
{-
Update of a flamelet.
Applies movement and attaches damage to nearby creatures.
-}
moveFlamelet :: World -> Particle -> (World, Maybe Particle) moveFlamelet :: World -> Particle -> (World, Maybe Particle)
moveFlamelet w pt moveFlamelet w pt
| _btTimer' pt <= 0 = ( w, Nothing) | _btTimer' pt <= 0 = ( w, Nothing)
@@ -297,11 +292,10 @@ moveTeslaArc p d i w =
f1 (E3x1 cr) = Just $ _crID cr f1 (E3x1 cr) = Just $ _crID cr
f1 _ = Nothing f1 _ = Nothing
hitCrs = mapMaybe f1 $ take 14 $ crsLightChain p d 0 w hitCrs = mapMaybe f1 $ take 14 $ crsLightChain p d 0 w
damCrs i = over (creatures . ix i . crHP) (\hp -> hp - 5) damCrs cid = over (creatures . ix cid . crHP) (\hp -> hp - 5)
f2 0 = cyan f2 0 = cyan
f2 1 = azure f2 1 = azure
f2 _ = white f2 _ = white
sID = newProjectileKey w
q1 = last $ init ps' q1 = last $ init ps'
q2 = last ps' q2 = last ps'
hitWall = reflectPointWalls q1 ((2 *.* q2) -.- q1) $ wallsNearPoint q1 w hitWall = reflectPointWalls q1 ((2 *.* q2) -.- q1) $ wallsNearPoint q1 w
@@ -372,13 +366,11 @@ crOrWallSensitive p dir wlAttract w =
g (E3x2 p1) = 100 + dist p p1 -- tweak makes it more likely to hit crs first g (E3x2 p1) = 100 + dist p p1 -- tweak makes it more likely to hit crs first
--g (E3x2 p1) = dist p p1 - 100 -- tweak makes it more likely to hit walls first --g (E3x2 p1) = dist p p1 - 100 -- tweak makes it more likely to hit walls first
g (E3x1 cr1) = dist p $ _crPos cr1 g (E3x1 cr1) = dist p $ _crPos cr1
g _ = 0
(arcLen,_) = randomR (25,50) $ _randGen w (arcLen,_) = randomR (25,50) $ _randGen w
-- BUG: can hit crs through walls -- BUG: can hit crs through walls
{- Finds whether a creature or wall is in front of a given point and direction.
{- Evaluates to a creature as an 'E3x1' or a wall as an 'E3x2'. -}
Finds whether a creature or wall is in front of a given point and direction.
Evaluates to a creature as an 'E3x1' or a wall as an 'E3x2'.
-}
crOrWall :: Point2 -> Float -> World -> Either3 Creature Point2 Point2 crOrWall :: Point2 -> Float -> World -> Either3 Creature Point2 Point2
crOrWall p dir w = fromMaybe (E3x3 $ p +.+ rotateV dir (arcLen,0)) crOrWall p dir w = fromMaybe (E3x3 $ p +.+ rotateV dir (arcLen,0))
$ listToMaybe $ sortBy (compare `on` g) $ listToMaybe $ sortBy (compare `on` g)
@@ -400,8 +392,8 @@ crOrWall p dir w = fromMaybe (E3x3 $ p +.+ rotateV dir (arcLen,0))
g (E3x2 p1) = 100 + dist p p1 -- tweak makes it more likely to hit crs first g (E3x2 p1) = 100 + dist p p1 -- tweak makes it more likely to hit crs first
--g (E3x2 p1) = dist p p1 - 100 -- tweak makes it more likely to hit walls first --g (E3x2 p1) = dist p p1 - 100 -- tweak makes it more likely to hit walls first
g (E3x1 cr1) = dist p $ _crPos cr1 g (E3x1 cr1) = dist p $ _crPos cr1
g _ = 0
(arcLen,_) = randomR (25,50) $ _randGen w (arcLen,_) = randomR (25,50) $ _randGen w
-- | Create a spark. -- | Create a spark.
-- If the spark is created by another Particle, it cannot be directly added to -- If the spark is created by another Particle, it cannot be directly added to
-- the list, hence the redirect through worldEvents. -- the list, hence the redirect through worldEvents.
@@ -428,4 +420,6 @@ createSpark time colid pos dir maycid w
ep = sp +.+ _btVel' bt ep = sp +.+ _btVel' bt
drawBul :: Particle -> Picture drawBul :: Particle -> Picture
drawBul pt = setLayer 1 . color white $ thickLine (take 2 $ _btTrail' pt) (_btWidth' pt) drawBul pt = setLayer 1 . color thecolor $ thickLine (take 2 $ _btTrail' pt) (_btWidth' pt)
where
thecolor = _btColor' pt
+5 -6
View File
@@ -10,7 +10,6 @@ import Geometry
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import Data.List import Data.List
import Data.Maybe import Data.Maybe
import Data.Function (on)
{- List those objects that appear on a line. -} {- List those objects that appear on a line. -}
thingsHit thingsHit
:: Point2 -- ^ Line start point :: Point2 -- ^ Line start point
@@ -19,7 +18,7 @@ thingsHit
-> [(Point2, Either3 Creature Wall ForceField)] -> [(Point2, Either3 Creature Wall ForceField)]
thingsHit sp ep w thingsHit sp ep w
| sp == ep = [] | sp == ep = []
| otherwise = sortBy (compare `on` dist sp . fst) (crs ++ walls ++ ffs) | otherwise = sortOn (dist sp . fst) (crs ++ wls ++ ffs)
where where
hitCrs = IM.elems hitCrs = IM.elems
$ IM.filter (\cr -> circOnSeg sp ep (_crPos cr) (_crRad cr)) $ IM.filter (\cr -> circOnSeg sp ep (_crPos cr) (_crRad cr))
@@ -33,8 +32,8 @@ thingsHit sp ep w
f i m = case IM.lookup i m of f i m = case IM.lookup i m of
Just val -> val Just val -> val
_ -> IM.empty _ -> IM.empty
walls = zip (map (fromJust . hitPoint) hitWls) (map E3x2 hitWls) wls = zip (map (fromJust . hitPoint) hitWls) (map E3x2 hitWls)
hitPoint w = uncurry (intersectSegSeg' sp ep) (_wlLine w) hitPoint w' = uncurry (intersectSegSeg' sp ep) (_wlLine w')
hitFFs = mapMaybe (collidePointFF sp ep (_randGen w)) (IM.elems $ _forceFields w) hitFFs = mapMaybe (collidePointFF sp ep (_randGen w)) (IM.elems $ _forceFields w)
ffs = map (\(p,(_,i)) -> (p, E3x3 $ _forceFields w IM.! i)) hitFFs ffs = map (\(p,(_,i)) -> (p, E3x3 $ _forceFields w IM.! i)) hitFFs
{- List objects that appear on a line. {- List objects that appear on a line.
@@ -66,7 +65,7 @@ thingsHitExceptCrLongLine (Just cid) sp ep = filter crNotCid . thingsHitLongLine
thingsHitLongLine :: Point2 -> Point2 -> World -> [(Point2, Either3 Creature Wall ForceField)] thingsHitLongLine :: Point2 -> Point2 -> World -> [(Point2, Either3 Creature Wall ForceField)]
thingsHitLongLine sp ep w thingsHitLongLine sp ep w
| sp == ep = [] | sp == ep = []
| otherwise = sortOn (dist sp . fst) (crs ++ walls ++ ffs) | otherwise = sortOn (dist sp . fst) (crs ++ wls ++ ffs)
where where
crs = zip crPs (map E3x1 hitCrs) crs = zip crPs (map E3x1 hitCrs)
hitCrs = IM.elems hitCrs = IM.elems
@@ -74,7 +73,7 @@ thingsHitLongLine sp ep w
$ _creatures w $ _creatures w
-- $ creaturesAlongLine sp ep w -- $ creaturesAlongLine sp ep w
crPs = map (\cr -> ssaTriPoint ep (_crPos cr) sp (_crRad cr)) hitCrs crPs = map (\cr -> ssaTriPoint ep (_crPos cr) sp (_crRad cr)) hitCrs
walls = zip (map (fromJust . hitPoint) hitWls) (map E3x2 hitWls) wls = zip (map (fromJust . hitPoint) hitWls) (map E3x2 hitWls)
hitWls = wallsOnLine sp ep $ wallsAlongLine sp ep w hitWls = wallsOnLine sp ep $ wallsAlongLine sp ep w
hitPoint wl = uncurry (intersectSegSeg' sp ep) (_wlLine wl) hitPoint wl = uncurry (intersectSegSeg' sp ep) (_wlLine wl)
hitFFs = mapMaybe (collidePointFF sp ep (_randGen w)) (IM.elems $ _forceFields w) hitFFs = mapMaybe (collidePointFF sp ep (_randGen w)) (IM.elems $ _forceFields w)
+3
View File
@@ -8,11 +8,14 @@ newtype DS a = DS (a,[a],[a])
Unsafe. -} Unsafe. -}
fromListL :: [a] -> DS a fromListL :: [a] -> DS a
fromListL (x:xs) = DS (x,xs,[]) fromListL (x:xs) = DS (x,xs,[])
fromListL _ = undefined
singleton :: a -> DS a singleton :: a -> DS a
singleton x = DS (x,[],[]) singleton x = DS (x,[],[])
head :: DS a -> a
head (DS (x,_,_)) = x head (DS (x,_,_)) = x
left, right :: DS a -> [a]
left (DS (_,l,_)) = l left (DS (_,l,_)) = l
right (DS (_,_,r)) = r right (DS (_,_,r)) = r
+3 -3
View File
@@ -1,7 +1,7 @@
module Geometry.Data module Geometry.Data
( Point2 (..) ( Point2
, Point3 (..) , Point3
, Point4 (..) , Point4
) )
where where
type Point2 = (Float,Float) type Point2 = (Float,Float)
+5 -8
View File
@@ -1,20 +1,18 @@
{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -Wno-unused-top-binds #-}
module Picture.Preload module Picture.Preload
( RenderData (..) ( RenderData (..)
, preloadRender , preloadRender
, cleanUpRenderPreload , cleanUpRenderPreload
) )
where where
import Picture.Data import Picture.Data
import Shader import Shader
import Geometry (Point2,Point3,Point4) import Geometry.Data
import Graphics.Rendering.OpenGL hiding (Point (..),translate,scale,imageHeight,imageWidth)
import Graphics.Rendering.OpenGL hiding (Point,translate,scale,imageHeight)
import Control.Lens import Control.Lens
import Foreign import Foreign
import qualified Control.Foldl as F import qualified Control.Foldl as F
data RenderData = RenderData data RenderData = RenderData
@@ -34,7 +32,6 @@ data RenderData = RenderData
, _fbo2 :: (FramebufferObject, TextureObject, RenderbufferObject) , _fbo2 :: (FramebufferObject, TextureObject, RenderbufferObject)
, _fbo3 :: (FramebufferObject, TextureObject, RenderbufferObject) , _fbo3 :: (FramebufferObject, TextureObject, RenderbufferObject)
} }
makeLenses ''RenderData makeLenses ''RenderData
preloadRender :: IO RenderData preloadRender :: IO RenderData
@@ -187,7 +184,7 @@ pokeBezQStrat (RenderBezQ vs) = fmap (\((x,y,z),(r,g,b,a),(s,t,u,v)) -> [[x,y,z]
pokeBezQStrat _ = [] pokeBezQStrat _ = []
{-# INLINE pokeTriStrat #-} {-# INLINE pokeTriStrat #-}
pokeTriStrat :: RenderType -> [[[Float]]] pokeTriStrat,pokeCharStrat,pokeArcStrat,pokeLineStrat,pokeEllStrat :: RenderType -> [[[Float]]]
pokeTriStrat (RenderPoly vs) = fmap (\((x,y,z),(r,g,b,a)) -> [[x,y,z],[r,g,b,a]]) vs pokeTriStrat (RenderPoly vs) = fmap (\((x,y,z),(r,g,b,a)) -> [[x,y,z],[r,g,b,a]]) vs
pokeTriStrat _ = [] pokeTriStrat _ = []
@@ -203,6 +200,7 @@ pokeLineStrat _ = []
pokeEllStrat (RenderEllipse vs) = fmap (\((x,y,z),(r,g,b,a)) -> [[x,y,z],[r,g,b,a]]) vs pokeEllStrat (RenderEllipse vs) = fmap (\((x,y,z),(r,g,b,a)) -> [[x,y,z],[r,g,b,a]]) vs
pokeEllStrat _ = [] pokeEllStrat _ = []
vert, geom, frag :: ShaderType
vert = VertexShader vert = VertexShader
geom = GeometryShader geom = GeometryShader
frag = FragmentShader frag = FragmentShader
@@ -215,4 +213,3 @@ pokeWPColStrat (((x,y),(z,w)),(r,g,b,a)) = [[[x,y,z,w],[r,g,b,a]]]
pokeBGStrat :: a -> [[[Float]]] pokeBGStrat :: a -> [[[Float]]]
pokeBGStrat = const [] pokeBGStrat = const []

Some files were not shown because too many files have changed in this diff Show More