{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleContexts #-} module Object.Computer where import Affection as A import Control.Monad (when) import Control.Monad.IO.Class (MonadIO(..)) import Data.Ecstasy import Data.Maybe import Data.String import Linear -- internal imports import Types import Object.ActionTime computerObjectAction :: (Monad m, MonadIO m) => Double -> ObjType -> ObjState -> Ent -> SystemT Entity m () computerObjectAction dt t@ObjComputer s@"on" ent = do pent <- efor (anEnt ent) $ do with objUsedBy query objUsedBy vls <- efor (anEnt $ head pent) $ do with player with vel query vel emap (anEnt ent) $ do mtime <- queryMaybe objStateTime case mtime of Nothing -> do liftIO $ logIO Verbose ("Computer " <> fromString (show ent) <> ": on!") let dur = actionTime t s return unchanged { objStateTime = Set dur } Just ttl -> return unchanged { objStateTime = Set (ttl - dt) } trans <- efor (anEnt ent) $ do mttl <- queryMaybe objStateTime case mttl of Nothing -> return Nothing Just ttl -> do pa <- query objPlayerActivated if ttl < 0 then return (Just pa) else if not (null vls) && head vls `dot` head vls > 0 then return (Just pa) else return Nothing maybe (return ()) (\tpa -> setEntity ent =<< computerObjectTransition t s tpa ent Nothing) (head trans) computerObjectAction dt t@ObjComputer s@"hack" ent = do aent <- efor (anEnt ent) $ do with objUsedBy query objUsedBy vls <- efor (anEnt $ head aent) $ do with player with vel query vel emap (anEnt ent) $ do mtime <- queryMaybe objStateTime case mtime of Nothing -> do liftIO $ logIO Verbose ("Computer " <> fromString (show ent) <> ": hacking!") return unchanged { objStateTime = Set (actionTime t s) } Just ttl -> return unchanged { objStateTime = Set (ttl - dt) } trans <- efor (anEnt ent) $ do mttl <- queryMaybe objStateTime case mttl of Nothing -> return Nothing Just ttl -> do if (ttl < 0) || (not (null vls) && head vls `dot` head vls > 0) then do tpa <- query objPlayerActivated return (Just tpa) else return Nothing maybe (return ()) (\tpa -> setEntity ent =<< computerObjectTransition t s tpa ent Nothing) (head trans) computerObjectAction _ _ _ _ = return () computerObjectTransition :: (Monad m, MonadIO m) => ObjType -> ObjState -> Bool -> Ent -> Maybe Ent -> SystemT Entity m (Entity 'SetterOf) computerObjectTransition ObjComputer "off" pa ent (Just aent) = do ldir <- efor (anEnt aent) (query rot) let dir = head ldir e <- efor (anEnt ent) $ do solved <- queryMaybe objSolved if pa then if not (fromMaybe False solved) then do let nstat = AnimState (AnimId AnimComputer "hack" dir) 0 0 return unchanged { anim = Set nstat , objState = Set "hack" , objPlayerActivated = Set True , objUsedBy = Set aent } else do let nstat = AnimState (AnimId AnimComputer "on" dir) 0 0 return unchanged { anim = Set nstat , objState = Set "on" , objPlayerActivated = Set True , objUsedBy = Set aent } else do let nstat = AnimState (AnimId AnimComputer "on" dir) 0 0 return unchanged { anim = Set nstat , objState = Set "on" , objPlayerActivated = Set False , objUsedBy = Set aent } return (head e) computerObjectTransition ObjComputer "on" _ ent _ = do e <- efor (anEnt ent) $ do dir <- query rot let nstat = AnimState (AnimId AnimComputer "off" dir) 0 0 return unchanged { anim = Set nstat , objState = Set "off" , objPlayerActivated = Unset , objStateTime = Unset , objUsedBy = Unset } return (head e) computerObjectTransition ObjComputer "hack" pa ent _ = if pa then do e <- efor (anEnt ent) $ do dir <- query rot let nstat = AnimState (AnimId AnimComputer "off" dir) 0 0 ost <- query objStateTime return unchanged { anim = Set nstat , objState = Set "off" , objPlayerActivated = Unset , objStateTime = Unset , objUsedBy = Unset , objSolved = if pa then Set (ost < 0) else Keep } return (head e) else return unchanged computerObjectTransition _ _ _ _ _ = return unchanged