module Dodge.Creature.YourControl where import Dodge.Data import Dodge.Base import Dodge.Creature.Action import Dodge.Creature.State import Dodge.Creature.State.Data import Dodge.Creature.Stance.Data import Dodge.Update.UsingInput import Dodge.Config.KeyConfig import Dodge.Item.Attachment.Data import Geometry import Control.Lens import qualified SDL import Data.Maybe import qualified Data.Set as S import qualified Data.IntMap.Strict as IM import System.Random {- | The AI equivalent for your control. -} yourControl :: World -> (World -> World,StdGen) -> Creature -> ((World -> World,StdGen), Maybe Creature) yourControl w (f,g) cr = ( (updateUsingInput . f, g) , Just . mouseActionsCr (_mouseButtons w) $ wasdWithAiming w speed 0 cr ) where speed = _varMovementSpeedModifier w * equipFactor equipFactor = product $ map equipSpeed $ IM.elems $ _crInv $ _creatures w IM.! 0 {- | Turn key presses into creature movement. -} wasdWithAiming :: World -> Float -- ^ Base speed -> Int -- ^ Creature id -> Creature -> Creature wasdWithAiming w speed i cr | isAiming = set crDir mouseDir $ crMvBy (speed *.* mov) cr | isMoving = crMvForward speed $ over crDir (`fromMaybe` dir) cr | otherwise = cr where (mov',dir') = wasdComp (view keys w) w dir = fmap (_cameraRot w +) dir' mov = rotateV (negate $ _crDir cr) mov' isAiming = _posture (_crStance cr) == Aiming isMoving = mov' /= (0,0) mouseDir = case w ^? creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0)) . itAttachment of Just (Just ItScope{_scopePos = p}) -> normalizeAngle $ argV $ p +.+ 2 / _cameraZoom w *.* rotateV (_cameraRot w) (_mousePos w) _ -> normalizeAngle $ argV (_mousePos w) + _cameraRot w wasdM :: World -> SDL.Scancode -> Point2 wasdM w scancode | scancode == moveUpKey (_keyConfig w) = ( 0, 1) | scancode == moveDownKey (_keyConfig w) = ( 0,-1) | scancode == moveRightKey (_keyConfig w) = ( 1, 0) | scancode == moveLeftKey (_keyConfig w) = (-1, 0) wasdM _ _ = (0,0) wasdComp :: S.Set SDL.Scancode -> World -> (Point2,Maybe Float) wasdComp ks w = f $ foldr ( (+.+) . wasdM w ) (0,0) ks where f (0,0) = ((0,0), Nothing) f p = (errorNormalizeV 46 p, Just $ argV p) {- | Set posture according to mouse presses. -} mouseActionsCr :: S.Set SDL.MouseButton -> Creature -> Creature mouseActionsCr keys | rbPressed = crStance . posture .~ Aiming | otherwise = crStance . posture .~ AtEase where lbPressed = SDL.ButtonLeft `S.member` keys rbPressed = SDL.ButtonRight `S.member` keys