module Behavior
(Behavior(..),
dbBehave)
where
import DB
import DBData
import Facing
import Data.Ratio
import Tool
import Control.Monad.Error
import Combat
import Travel
import Creature
import Plane
import PlaneVisibility
import Data.List
import Control.Monad.Maybe
--
-- Every possible behavior that a creature might take, AI or Human.
--
data Behavior =
Step Facing
| TurnInPlace Facing
| Pickup ToolRef
| Wield ToolRef
| Unwield
| Drop ToolRef
| Fire Facing
| Attack Facing
| Wait
| Vanish
dbBehave :: Behavior -> CreatureRef -> DB ()
dbBehave (Step face) creature_ref =
do dbMove (stepCreature face) creature_ref
dbAdvanceTime (1%20) creature_ref
dbBehave (TurnInPlace face) creature_ref =
do dbMove (turnCreature face) creature_ref
dbAdvanceTime (1%40) creature_ref
dbBehave (Pickup tool_ref) creature_ref =
do dbMove (dbPickupTool creature_ref) tool_ref
dbAdvanceTime (1%20) creature_ref
dbBehave (Wield tool_ref) creature_ref =
do tool_parent <- liftM extractLocation $ dbWhere tool_ref
when (tool_parent /= Just creature_ref) $ throwError $ DBErrorFlag "not-in-inventory"
dbMove dbWieldTool tool_ref
dbAdvanceTime (1%10) creature_ref
dbBehave (Unwield) creature_ref =
do dbUnwieldCreature creature_ref
dbAdvanceTime (1%40) creature_ref
dbBehave (Drop tool_ref) creature_ref =
do tool_parent <- liftM extractLocation $ dbWhere tool_ref
when (tool_parent /= Just creature_ref) $ throwError $ DBErrorFlag "not-in-inventory"
dbMove dbDropTool tool_ref
return ()
dbBehave (Fire face) creature_ref =
do dbMove (turnCreature face) creature_ref
atomic $ liftM dbExecuteRangedAttack $ dbResolveRangedAttack creature_ref face
dbAdvanceTime (1%20) creature_ref
return ()
dbBehave (Attack face) creature_ref =
do dbMove (turnCreature face) creature_ref
atomic $ liftM dbExecuteMeleeAttack $ dbResolveMeleeAttack creature_ref face
dbAdvanceTime (1%20) creature_ref
return ()
dbBehave Wait creature_ref =
do dbAdvanceTime (1%40) creature_ref
dbBehave Vanish creature_ref =
do runMaybeT $
do plane_ref <- MaybeT $ liftM (fmap $ fst . location) $ getPlanarLocation creature_ref
lift $
do faction <- getCreatureFaction creature_ref
is_visible_to_anyone_else <- liftM (any (creature_ref `elem`)) $
mapM (flip dbGetVisibleObjectsForFaction plane_ref) (delete faction [minBound..maxBound])
when (not is_visible_to_anyone_else) $ deleteCreature creature_ref
dbAdvanceTime (1%100) creature_ref