81 lines
2.8 KiB
Haskell
81 lines
2.8 KiB
Haskell
module Dodge.Creature.YourControl
|
|
( yourControl
|
|
) where
|
|
import Dodge.Data
|
|
import Dodge.Base.Coordinate
|
|
import Dodge.Creature.Impulse.Movement
|
|
import Dodge.Update.UsingInput
|
|
import Dodge.InputFocus
|
|
--import Dodge.Config.KeyConfig
|
|
import Geometry
|
|
|
|
import Control.Lens
|
|
import qualified SDL
|
|
import qualified Data.Set as S
|
|
--import qualified Data.IntMap.Strict as IM
|
|
import Data.Maybe
|
|
{- | The AI equivalent for your control. -}
|
|
yourControl :: Creature -> World -> World
|
|
yourControl cr w
|
|
| inTermFocus w = w
|
|
| otherwise = w
|
|
& creatures . ix (_crID cr) %~
|
|
(wasdWithAiming w (_mvSpeed $ _crMvType cr) . mouseActionsCr (_mouseButtons w))
|
|
& updateUsingInput
|
|
|
|
-- note the order of operation, setting the posture first--this prevents the twist fire bug
|
|
|
|
{- | Turn key presses into creature movement. -}
|
|
wasdWithAiming
|
|
:: World
|
|
-> Float -- ^ Base speed
|
|
-> Creature
|
|
-> Creature
|
|
wasdWithAiming w speed cr
|
|
| isAiming = addAnyTwist $ set crDir mouseDir $ theMovement cr
|
|
| isReloading && SDL.ButtonRight `S.member` _mouseButtons w
|
|
= addAnyTwist $ set crDir (mouseDir + anytwist) $ theMovement cr
|
|
| otherwise = theMovement $ theTurn $ removeTwist cr
|
|
where
|
|
twistamount = 1.6
|
|
removeTwist cr' = cr'
|
|
& crDir +~ _crTwist cr'
|
|
& crTwist .~ 0
|
|
anytwist = case cr ^? crInv . ix (_crInvSel cr) . itUse . useAim . aimStance of
|
|
Just TwoHandTwist -> twistamount * pi
|
|
_ -> 0
|
|
addAnyTwist = crTwist .~ anytwist
|
|
theMovement
|
|
| movDir == V2 0 0 = id
|
|
| otherwise = crMvAbsolute (speed *.* movAbs) . set crMvDir dir
|
|
theTurn cr' = creatureTurnTowardDir (_crMvDir cr') 0.2 cr'
|
|
movDir = wasdDir w
|
|
dir = _cameraRot w + argV movDir
|
|
movAbs = rotateV (_cameraRot w) $ normalizeV movDir
|
|
isAiming = _posture (_crStance cr) == Aiming
|
|
isReloading = _posture (_crStance cr) == Reloading
|
|
mouseDir = case cr ^? crInv . ix (_crInvSel cr) . itScope . scopePos of
|
|
Just _ -> argV $ mouseWorldPos w -.- _crPos cr
|
|
_ -> argV (_mousePos w) + _cameraRot w
|
|
|
|
wasdM :: SDL.Scancode -> Point2
|
|
wasdM scancode = case scancode of
|
|
SDL.ScancodeW -> V2 0 1
|
|
SDL.ScancodeS -> V2 0 (-1)
|
|
SDL.ScancodeD -> V2 1 0
|
|
SDL.ScancodeA -> V2 (-1) 0
|
|
_ -> V2 0 0
|
|
|
|
wasdDir :: World -> Point2
|
|
wasdDir = foldr ((+.+) . wasdM) (V2 0 0) . _keys
|
|
|
|
{- | Set posture according to mouse presses. -}
|
|
mouseActionsCr :: S.Set SDL.MouseButton -> Creature -> Creature
|
|
mouseActionsCr pkeys cr
|
|
| reloading = cr & crStance . posture .~ Reloading
|
|
| rbPressed = cr & crStance . posture .~ Aiming
|
|
| otherwise = cr & crStance . posture .~ AtEase
|
|
where
|
|
reloading = isJust $ cr ^? crInv . ix (_crInvSel cr) . itConsumption . laReloadState . _Just'
|
|
rbPressed = SDL.ButtonRight `S.member` pkeys
|