Files
loop/src/Dodge/Creature/Action.hs
T
2021-05-24 13:59:51 +02:00

129 lines
4.0 KiB
Haskell

{- | 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