module Game.Antisplice.Paths where
import Data.Monoid
import Game.Antisplice.Action
import Game.Antisplice.Monad.Dungeon
import Game.Antisplice.Rooms
import Game.Antisplice.Utils.Graph
import Game.Antisplice.Utils.None
unipath :: MonadDungeon m => NodeId -> NodeId -> Direction -> m ()
unipath f t d = establishWay f t d none
bipath :: MonadDungeon m => NodeId -> NodeId -> Direction -> m ()
bipath f t d = unipath f t d >> unipath t f (opp d)
where opp North = South
opp NorthEast = SouthWest
opp East = West
opp SouthEast = NorthWest
opp South = North
opp SouthWest = NorthEast
opp West = East
opp NorthWest = SouthEast
opp Up = Down
opp Down = Up
guardedPath :: MonadDungeon m => NodeId -> NodeId -> Direction -> Prerequisite -> m ()
guardedPath f t d p = establishWay f t d $ PathState p noneM noneM
newtype Gate = Gate { runGate :: PathState }
instance None Gate where
none = Gate $ PathState (return True) noneM noneM
instance Monoid Gate where
mempty = none
mappend g h = Gate $ PathState
(runPrerequisite $ Prerequisite (pathPrerequisiteOf $ runGate g) <> Prerequisite (pathPrerequisiteOf $ runGate h))
(pathTriggerBeforeWalkOf (runGate g) >> pathTriggerBeforeWalkOf (runGate h))
(pathTriggerAfterWalkOf (runGate g) >> pathTriggerAfterWalkOf (runGate h))
instance IsAction Gate where
g #&& h = Gate $ PathState
(runPrerequisite $ Prerequisite (pathPrerequisiteOf $ runGate g) #&& Prerequisite (pathPrerequisiteOf $ runGate h))
(pathTriggerBeforeWalkOf (runGate g) >> pathTriggerBeforeWalkOf (runGate h))
(pathTriggerAfterWalkOf (runGate g) >> pathTriggerAfterWalkOf (runGate h))
g #|| h = Gate $ PathState
(runPrerequisite $ Prerequisite (pathPrerequisiteOf $ runGate g) #|| Prerequisite (pathPrerequisiteOf $ runGate h))
(pathPrerequisiteOf (runGate g) >>= \b -> if b then pathTriggerBeforeWalkOf (runGate g) else pathTriggerBeforeWalkOf (runGate h))
(pathPrerequisiteOf (runGate g) >>= \b -> if b then pathTriggerAfterWalkOf (runGate g) else pathTriggerAfterWalkOf (runGate h))
g !&& h = Gate $ PathState
(runPrerequisite $ Prerequisite (pathPrerequisiteOf $ runGate g) !&& Prerequisite (pathPrerequisiteOf $ runGate h))
(pathTriggerBeforeWalkOf (runGate g) >> pathTriggerBeforeWalkOf (runGate h))
(pathTriggerAfterWalkOf (runGate g) >> pathTriggerAfterWalkOf (runGate h))
g !|| h = Gate $ PathState
(runPrerequisite $ Prerequisite (pathPrerequisiteOf $ runGate g) !|| Prerequisite (pathPrerequisiteOf $ runGate h))
(pathPrerequisiteOf (runGate g) >>= \b -> pathPrerequisiteOf (runGate h) >> if b then pathTriggerBeforeWalkOf (runGate g) else pathTriggerBeforeWalkOf (runGate h))
(pathPrerequisiteOf (runGate g) >>= \b -> pathPrerequisiteOf (runGate h) >> if b then pathTriggerAfterWalkOf (runGate g) else pathTriggerAfterWalkOf (runGate h))
class Gatifiable g where
toGate :: g -> Gate
instance Gatifiable Gate where
toGate = id
instance Gatifiable PrerequisiteBox where
toGate g = Gate $ PathState (runPrerequisite g) noneM noneM
instance Gatifiable PathState where
toGate g = Gate g
instance Gatifiable ActionBefore where
toGate (ActionBefore g) = Gate $ PathState (askAction g) (runAction g) noneM
instance Gatifiable ActionAfter where
toGate (ActionAfter g) = Gate $ PathState (askAction g) noneM (runAction g)
gatedPath :: (Gatifiable g,MonadDungeon m) => NodeId -> NodeId -> Direction -> g -> m ()
gatedPath f t d g = establishWay f t d (runGate $ toGate g)