{- | Actions performed by creatures within the world -} module Dodge.Creature.Action ( module Dodge.Creature.Action , module Dodge.Creature.Action.UseItem , module Dodge.Creature.Action.Movement ) where import Dodge.Creature.Action.UseItem import Dodge.Creature.Action.Movement import Dodge.Creature.Stance.Data --import Dodge.Creature.State.Data import Dodge.WorldEvent.Shockwave import Dodge.Data import Dodge.Base import Dodge.SoundLogic --import Dodge.WorldEvent import Dodge.Inventory --import Dodge.LightSources import Geometry import Picture import qualified IntMapHelp as IM import Control.Lens --import Control.Monad --import Control.Applicative import Data.Maybe --import Data.List import System.Random --import qualified Data.Map as M startReloadingWeapon :: Creature -> World -> Maybe World startReloadingWeapon cr w = let cid = _crID cr it = _crInv cr IM.! _crInvSel cr itRef = creatures . ix cid . crInv . ix (_crInvSel cr) in case it of Weapon {_wpMaxAmmo=maxA,_wpLoadedAmmo=lA,_wpReloadState=rS,_wpReloadTime=rT} | lA < maxA && rS == 0 -> Just $ set ( itRef . wpLoadedAmmo) maxA $ set ( itRef . wpReloadState) rT w _ -> Nothing {- | Start reloading if clip is empty. -} crAutoReload :: Creature -> Creature crAutoReload cr = case cr ^? crInv . ix (_crInvSel cr) . wpLoadedAmmo of Just 0 | _posture (_crStance cr) /= Aiming -> cr & crInv . ix (_crInvSel cr) . wpReloadState %~ (`fromMaybe` reloadT) & crInv . ix (_crInvSel cr) . wpLoadedAmmo %~ (`fromMaybe` maxA) _ -> cr where reloadT = cr ^? crInv . ix (_crInvSel cr) . wpReloadTime maxA = cr ^? crInv . ix (_crInvSel cr) . wpMaxAmmo {- | Teleport a creature to the mouse position -} blinkAction :: Creature -> World -> World blinkAction cr w = soundOnce teleSound . set (creatures . ix cid . crPos) p3 . blinkShockwave cid p3 $ inverseShockwaveAt cpos 40 2 2 2 w where cid = _crID cr p1 = mouseWorldPos w cpos = _crPos cr p2 = reflectPointWalls cpos p1 $ wallsAlongLine cpos p1 w r = 1.5 * _crRad cr p3 = maybe p1 (mvPointTowardAtSpeed r cpos . fst) p2 blinkShockwave :: Int -- ^ Blinking creature ID. -> Point2 -> World -> World blinkShockwave i p = makeShockwaveAt [i] p 60 1 2 cyan {- | Get your creature to drop the item under the cursor. -} youDropItem :: World -> World youDropItem w = case yourItem w of NoItem -> w _ -> rmSelectedInvItem (_yourID w) . copyItemToFloor (you w) (_crInvSel $ you w) $ soundOnce putDownSound w {- | Copy an inventory item to the floor. -} copyItemToFloor :: Creature -> Int -- ^ Inventory position -> World -> World copyItemToFloor cr i w = case _crInv cr IM.! i of NoItem -> w it -> over floorItems (IM.insert flid theflit) . updateLocation $ set randGen g w where (rot, g) = randomR (-pi,pi) $ _randGen w offset = (_crRad cr + 2) *.* unitVectorAtAngle rot updateLocation w' = case it ^? itID of Just (Just i') -> w' & itemPositions . ix i' .~ OnFloor flid _ -> w' flid = IM.newKey $ _floorItems w theflit = FlIt {_flIt = it ,_flItPos = offset +.+ _crPos cr ,_flItRot = rot ,_flItID = flid } {- | Pick up a specific item. -} pickUpItem :: Int -- ^ Creature id -> FloorItem -> World -> World pickUpItem cid flit w = case maybeInvSlot of Nothing -> w Just i -> w & soundOnce pickUpSound & updateItLocation i & floorItems %~ IM.delete (_flItID flit) & creatures . ix cid . crInv . ix i %~ addItem it where it = _flIt flit maybeInvSlot = checkInvSlotsYou it w updateItLocation invid w' = case _itID it of Nothing -> w' Just j -> w' & itemPositions . ix j .~ InInv 0 invid