module Dodge.Creature.YourControl ( yourControl ) where import Dodge.Data import Dodge.LightSource import Dodge.Base.Coordinate import Dodge.Creature.Impulse.Movement import Dodge.Creature.Test import Dodge.Update.UsingInput import Dodge.InputFocus import Geometry import LensHelp import qualified SDL import qualified Data.Map.Strict as M {- | The AI equivalent for your control. -} yourControl :: Creature -> World -> World yourControl cr w | inTermFocus w = dimCreatureLight cr w & updateUsingInput | otherwise = dimCreatureLight cr w & creatures . ix (_crID cr) %~ (wasdWithAiming w (_mvSpeed $ _crMvType cr) . mouseActionsCr (_mouseButtons w)) & updateUsingInput dimCreatureLight :: Creature -> World -> World dimCreatureLight cr = tempLightSources .:~ tlsTimeRadColPos 1 300 0.1 (addZ 100 $ _crPos cr) -- 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 | crIsReloading cr && SDL.ButtonRight `M.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 (crSel 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 mouseDir = case cr ^? crInv . ix (crSel 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 :: M.Map SDL.MouseButton Bool -> Creature -> Creature mouseActionsCr pkeys cr | rbPressed && cr ^?! crInvSel . iselAction == NoInvSelAction = cr & crStance . posture .~ Aiming | otherwise = cr & crStance . posture .~ AtEase where rbPressed = SDL.ButtonRight `M.member` pkeys