module Dodge.Creature.YourControl (-- yourControl yourControl' ) where import Dodge.Data import Dodge.Creature.Impulse.Movement import Dodge.Update.UsingInput --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 -> World, Creature) yourControl cr w = ( updateUsingInput , mouseActionsCr (_mouseButtons w) $ wasdWithAiming w speed 0 cr ) where speed = _mvSpeed $ _crMvType cr yourControl' :: Creature -> World -> World yourControl' cr w = w & updateUsingInput & creatures . ix (_crID cr) %~ (mouseActionsCr (_mouseButtons w) . wasdWithAiming w speed 0) where speed = _mvSpeed $ _crMvType cr {- | Turn key presses into creature movement. -} wasdWithAiming :: World -> Float -- ^ Base speed -> Int -- ^ Creature id -> Creature -> Creature wasdWithAiming w speed i 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' = case _crTwist cr' of t -> cr' & crDir +~ t & crTwist .~ 0 anytwist = case cr ^? crInv . ix (_crInvSel (_creatures w IM.! i)) . itUse . useAim . aimStance of Just TwoHandTwist -> twistamount * pi _ -> 0 addAnyTwist cr' = case cr' ^? crInv . ix (_crInvSel (_creatures w IM.! i)) . itUse . useAim . aimStance of Just TwoHandTwist -> cr' & crTwist .~ twistamount * pi _ -> cr' 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 w ^? creatures . ix i . crInv . ix (_crInvSel (_creatures w IM.! i)) . itScope . scopePos of Just p -> normalizeAngle $ argV $ p +.+ 2 / _cameraZoom w *.* rotateV (_cameraRot w) (_mousePos w) _ -> normalizeAngle $ 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 w = foldr ((+.+) . wasdM) (V2 0 0) $ _keys w {- | 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 . reloadState . _Just' rbPressed = SDL.ButtonRight `S.member` pkeys