    {-# LANGUAGE DeriveGeneric, GeneralizedNewtypeDeriving #-}
    -- | Abstract identifiers for the main types in the engine. This is imported
    -- by modules that don't need to know the internal structure
    -- of the types. As a side effect, this prevents mutual dependencies
    -- among modules.
    module Game.LambdaHack.Common.Types
      ( ItemId, FactionId, LevelId, ActorId
      , Container(..)
      ) where

    import Prelude ()

    import Game.LambdaHack.Core.Prelude

    import Data.Binary
    import Data.Hashable
    import GHC.Generics (Generic)

    import Game.LambdaHack.Common.Point
    import Game.LambdaHack.Definition.Defs

    -- | A unique identifier of an item in the dungeon.
    newtype ItemId = ItemId Int
      deriving (Int -> ItemId -> ShowS
    [ItemId] -> ShowS
    ItemId -> String
    (Int -> ItemId -> ShowS)
    -> (ItemId -> String) -> ([ItemId] -> ShowS) -> Show ItemId
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ItemId -> ShowS
    showsPrec :: Int -> ItemId -> ShowS
    $cshow :: ItemId -> String
    show :: ItemId -> String
    $cshowList :: [ItemId] -> ShowS
    showList :: [ItemId] -> ShowS
    Show, ItemId -> ItemId -> Bool
    (ItemId -> ItemId -> Bool)
    -> (ItemId -> ItemId -> Bool) -> Eq ItemId
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ItemId -> ItemId -> Bool
    == :: ItemId -> ItemId -> Bool
    $c/= :: ItemId -> ItemId -> Bool
    /= :: ItemId -> ItemId -> Bool
    Eq, Eq ItemId
    Eq ItemId =>
    (ItemId -> ItemId -> Ordering)
    -> (ItemId -> ItemId -> Bool)
    -> (ItemId -> ItemId -> Bool)
    -> (ItemId -> ItemId -> Bool)
    -> (ItemId -> ItemId -> Bool)
    -> (ItemId -> ItemId -> ItemId)
    -> (ItemId -> ItemId -> ItemId)
    -> Ord ItemId
    ItemId -> ItemId -> Bool
    ItemId -> ItemId -> Ordering
    ItemId -> ItemId -> ItemId
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: ItemId -> ItemId -> Ordering
    compare :: ItemId -> ItemId -> Ordering
    $c< :: ItemId -> ItemId -> Bool
    < :: ItemId -> ItemId -> Bool
    $c<= :: ItemId -> ItemId -> Bool
    <= :: ItemId -> ItemId -> Bool
    $c> :: ItemId -> ItemId -> Bool
    > :: ItemId -> ItemId -> Bool
    $c>= :: ItemId -> ItemId -> Bool
    >= :: ItemId -> ItemId -> Bool
    $cmax :: ItemId -> ItemId -> ItemId
    max :: ItemId -> ItemId -> ItemId
    $cmin :: ItemId -> ItemId -> ItemId
    min :: ItemId -> ItemId -> ItemId
    Ord, Int -> ItemId
    ItemId -> Int
    ItemId -> [ItemId]
    ItemId -> ItemId
    ItemId -> ItemId -> [ItemId]
    ItemId -> ItemId -> ItemId -> [ItemId]
    (ItemId -> ItemId)
    -> (ItemId -> ItemId)
    -> (Int -> ItemId)
    -> (ItemId -> Int)
    -> (ItemId -> [ItemId])
    -> (ItemId -> ItemId -> [ItemId])
    -> (ItemId -> ItemId -> [ItemId])
    -> (ItemId -> ItemId -> ItemId -> [ItemId])
    -> Enum ItemId
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: ItemId -> ItemId
    succ :: ItemId -> ItemId
    $cpred :: ItemId -> ItemId
    pred :: ItemId -> ItemId
    $ctoEnum :: Int -> ItemId
    toEnum :: Int -> ItemId
    $cfromEnum :: ItemId -> Int
    fromEnum :: ItemId -> Int
    $cenumFrom :: ItemId -> [ItemId]
    enumFrom :: ItemId -> [ItemId]
    $cenumFromThen :: ItemId -> ItemId -> [ItemId]
    enumFromThen :: ItemId -> ItemId -> [ItemId]
    $cenumFromTo :: ItemId -> ItemId -> [ItemId]
    enumFromTo :: ItemId -> ItemId -> [ItemId]
    $cenumFromThenTo :: ItemId -> ItemId -> ItemId -> [ItemId]
    enumFromThenTo :: ItemId -> ItemId -> ItemId -> [ItemId]
    Enum, Get ItemId
    [ItemId] -> Put
    ItemId -> Put
    (ItemId -> Put) -> Get ItemId -> ([ItemId] -> Put) -> Binary ItemId
    forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
    $cput :: ItemId -> Put
    put :: ItemId -> Put
    $cget :: Get ItemId
    get :: Get ItemId
    $cputList :: [ItemId] -> Put
    putList :: [ItemId] -> Put
    Binary)

    -- | A unique identifier of a faction in a game. It's assigned in the order
    -- from game mode roster, starting from one. We keep the @FactionId@
    -- and @TeamContinuity@ types separate mostly to let @FactionId@ reflect
    -- the order, which influences starting faction positions, etc.
    -- We use @TeamContinuity@ for dictionaries containing teams that may
    -- or may not be active factions in the current game, while @FactionId@ are
    -- used only for factions in the game (in particular, because they vary
    -- depending on order in game mode roster, while @TeamContinuity@ are stable).
    newtype FactionId = FactionId Int
      deriving (Int -> FactionId -> ShowS
    [FactionId] -> ShowS
    FactionId -> String
    (Int -> FactionId -> ShowS)
    -> (FactionId -> String)
    -> ([FactionId] -> ShowS)
    -> Show FactionId
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> FactionId -> ShowS
    showsPrec :: Int -> FactionId -> ShowS
    $cshow :: FactionId -> String
    show :: FactionId -> String
    $cshowList :: [FactionId] -> ShowS
    showList :: [FactionId] -> ShowS
    Show, FactionId -> FactionId -> Bool
    (FactionId -> FactionId -> Bool)
    -> (FactionId -> FactionId -> Bool) -> Eq FactionId
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: FactionId -> FactionId -> Bool
    == :: FactionId -> FactionId -> Bool
    $c/= :: FactionId -> FactionId -> Bool
    /= :: FactionId -> FactionId -> Bool
    Eq, Eq FactionId
    Eq FactionId =>
    (FactionId -> FactionId -> Ordering)
    -> (FactionId -> FactionId -> Bool)
    -> (FactionId -> FactionId -> Bool)
    -> (FactionId -> FactionId -> Bool)
    -> (FactionId -> FactionId -> Bool)
    -> (FactionId -> FactionId -> FactionId)
    -> (FactionId -> FactionId -> FactionId)
    -> Ord FactionId
    FactionId -> FactionId -> Bool
    FactionId -> FactionId -> Ordering
    FactionId -> FactionId -> FactionId
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: FactionId -> FactionId -> Ordering
    compare :: FactionId -> FactionId -> Ordering
    $c< :: FactionId -> FactionId -> Bool
    < :: FactionId -> FactionId -> Bool
    $c<= :: FactionId -> FactionId -> Bool
    <= :: FactionId -> FactionId -> Bool
    $c> :: FactionId -> FactionId -> Bool
    > :: FactionId -> FactionId -> Bool
    $c>= :: FactionId -> FactionId -> Bool
    >= :: FactionId -> FactionId -> Bool
    $cmax :: FactionId -> FactionId -> FactionId
    max :: FactionId -> FactionId -> FactionId
    $cmin :: FactionId -> FactionId -> FactionId
    min :: FactionId -> FactionId -> FactionId
    Ord, Int -> FactionId
    FactionId -> Int
    FactionId -> [FactionId]
    FactionId -> FactionId
    FactionId -> FactionId -> [FactionId]
    FactionId -> FactionId -> FactionId -> [FactionId]
    (FactionId -> FactionId)
    -> (FactionId -> FactionId)
    -> (Int -> FactionId)
    -> (FactionId -> Int)
    -> (FactionId -> [FactionId])
    -> (FactionId -> FactionId -> [FactionId])
    -> (FactionId -> FactionId -> [FactionId])
    -> (FactionId -> FactionId -> FactionId -> [FactionId])
    -> Enum FactionId
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: FactionId -> FactionId
    succ :: FactionId -> FactionId
    $cpred :: FactionId -> FactionId
    pred :: FactionId -> FactionId
    $ctoEnum :: Int -> FactionId
    toEnum :: Int -> FactionId
    $cfromEnum :: FactionId -> Int
    fromEnum :: FactionId -> Int
    $cenumFrom :: FactionId -> [FactionId]
    enumFrom :: FactionId -> [FactionId]
    $cenumFromThen :: FactionId -> FactionId -> [FactionId]
    enumFromThen :: FactionId -> FactionId -> [FactionId]
    $cenumFromTo :: FactionId -> FactionId -> [FactionId]
    enumFromTo :: FactionId -> FactionId -> [FactionId]
    $cenumFromThenTo :: FactionId -> FactionId -> FactionId -> [FactionId]
    enumFromThenTo :: FactionId -> FactionId -> FactionId -> [FactionId]
    Enum, Eq FactionId
    Eq FactionId =>
    (Int -> FactionId -> Int)
    -> (FactionId -> Int) -> Hashable FactionId
    Int -> FactionId -> Int
    FactionId -> Int
    forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
    $chashWithSalt :: Int -> FactionId -> Int
    hashWithSalt :: Int -> FactionId -> Int
    $chash :: FactionId -> Int
    hash :: FactionId -> Int
    Hashable, Get FactionId
    [FactionId] -> Put
    FactionId -> Put
    (FactionId -> Put)
    -> Get FactionId -> ([FactionId] -> Put) -> Binary FactionId
    forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
    $cput :: FactionId -> Put
    put :: FactionId -> Put
    $cget :: Get FactionId
    get :: Get FactionId
    $cputList :: [FactionId] -> Put
    putList :: [FactionId] -> Put
    Binary)

    -- | Abstract level identifiers.
    newtype LevelId = LevelId Int
      deriving (Int -> LevelId -> ShowS
    [LevelId] -> ShowS
    LevelId -> String
    (Int -> LevelId -> ShowS)
    -> (LevelId -> String) -> ([LevelId] -> ShowS) -> Show LevelId
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> LevelId -> ShowS
    showsPrec :: Int -> LevelId -> ShowS
    $cshow :: LevelId -> String
    show :: LevelId -> String
    $cshowList :: [LevelId] -> ShowS
    showList :: [LevelId] -> ShowS
    Show, LevelId -> LevelId -> Bool
    (LevelId -> LevelId -> Bool)
    -> (LevelId -> LevelId -> Bool) -> Eq LevelId
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: LevelId -> LevelId -> Bool
    == :: LevelId -> LevelId -> Bool
    $c/= :: LevelId -> LevelId -> Bool
    /= :: LevelId -> LevelId -> Bool
    Eq, Eq LevelId
    Eq LevelId =>
    (LevelId -> LevelId -> Ordering)
    -> (LevelId -> LevelId -> Bool)
    -> (LevelId -> LevelId -> Bool)
    -> (LevelId -> LevelId -> Bool)
    -> (LevelId -> LevelId -> Bool)
    -> (LevelId -> LevelId -> LevelId)
    -> (LevelId -> LevelId -> LevelId)
    -> Ord LevelId
    LevelId -> LevelId -> Bool
    LevelId -> LevelId -> Ordering
    LevelId -> LevelId -> LevelId
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: LevelId -> LevelId -> Ordering
    compare :: LevelId -> LevelId -> Ordering
    $c< :: LevelId -> LevelId -> Bool
    < :: LevelId -> LevelId -> Bool
    $c<= :: LevelId -> LevelId -> Bool
    <= :: LevelId -> LevelId -> Bool
    $c> :: LevelId -> LevelId -> Bool
    > :: LevelId -> LevelId -> Bool
    $c>= :: LevelId -> LevelId -> Bool
    >= :: LevelId -> LevelId -> Bool
    $cmax :: LevelId -> LevelId -> LevelId
    max :: LevelId -> LevelId -> LevelId
    $cmin :: LevelId -> LevelId -> LevelId
    min :: LevelId -> LevelId -> LevelId
    Ord, Eq LevelId
    Eq LevelId =>
    (Int -> LevelId -> Int) -> (LevelId -> Int) -> Hashable LevelId
    Int -> LevelId -> Int
    LevelId -> Int
    forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
    $chashWithSalt :: Int -> LevelId -> Int
    hashWithSalt :: Int -> LevelId -> Int
    $chash :: LevelId -> Int
    hash :: LevelId -> Int
    Hashable, Get LevelId
    [LevelId] -> Put
    LevelId -> Put
    (LevelId -> Put)
    -> Get LevelId -> ([LevelId] -> Put) -> Binary LevelId
    forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
    $cput :: LevelId -> Put
    put :: LevelId -> Put
    $cget :: Get LevelId
    get :: Get LevelId
    $cputList :: [LevelId] -> Put
    putList :: [LevelId] -> Put
    Binary)

    instance Enum LevelId where
      fromEnum :: LevelId -> Int
    fromEnum (LevelId Int
    n) = Int
    n
      toEnum :: Int -> LevelId
    toEnum = Int -> LevelId
    LevelId  -- picks the main branch of the dungeon

    -- | A unique identifier of an actor in the dungeon.
    newtype ActorId = ActorId Int
      deriving (Int -> ActorId -> ShowS
    [ActorId] -> ShowS
    ActorId -> String
    (Int -> ActorId -> ShowS)
    -> (ActorId -> String) -> ([ActorId] -> ShowS) -> Show ActorId
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ActorId -> ShowS
    showsPrec :: Int -> ActorId -> ShowS
    $cshow :: ActorId -> String
    show :: ActorId -> String
    $cshowList :: [ActorId] -> ShowS
    showList :: [ActorId] -> ShowS
    Show, ActorId -> ActorId -> Bool
    (ActorId -> ActorId -> Bool)
    -> (ActorId -> ActorId -> Bool) -> Eq ActorId
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ActorId -> ActorId -> Bool
    == :: ActorId -> ActorId -> Bool
    $c/= :: ActorId -> ActorId -> Bool
    /= :: ActorId -> ActorId -> Bool
    Eq, Eq ActorId
    Eq ActorId =>
    (ActorId -> ActorId -> Ordering)
    -> (ActorId -> ActorId -> Bool)
    -> (ActorId -> ActorId -> Bool)
    -> (ActorId -> ActorId -> Bool)
    -> (ActorId -> ActorId -> Bool)
    -> (ActorId -> ActorId -> ActorId)
    -> (ActorId -> ActorId -> ActorId)
    -> Ord ActorId
    ActorId -> ActorId -> Bool
    ActorId -> ActorId -> Ordering
    ActorId -> ActorId -> ActorId
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: ActorId -> ActorId -> Ordering
    compare :: ActorId -> ActorId -> Ordering
    $c< :: ActorId -> ActorId -> Bool
    < :: ActorId -> ActorId -> Bool
    $c<= :: ActorId -> ActorId -> Bool
    <= :: ActorId -> ActorId -> Bool
    $c> :: ActorId -> ActorId -> Bool
    > :: ActorId -> ActorId -> Bool
    $c>= :: ActorId -> ActorId -> Bool
    >= :: ActorId -> ActorId -> Bool
    $cmax :: ActorId -> ActorId -> ActorId
    max :: ActorId -> ActorId -> ActorId
    $cmin :: ActorId -> ActorId -> ActorId
    min :: ActorId -> ActorId -> ActorId
    Ord, Int -> ActorId
    ActorId -> Int
    ActorId -> [ActorId]
    ActorId -> ActorId
    ActorId -> ActorId -> [ActorId]
    ActorId -> ActorId -> ActorId -> [ActorId]
    (ActorId -> ActorId)
    -> (ActorId -> ActorId)
    -> (Int -> ActorId)
    -> (ActorId -> Int)
    -> (ActorId -> [ActorId])
    -> (ActorId -> ActorId -> [ActorId])
    -> (ActorId -> ActorId -> [ActorId])
    -> (ActorId -> ActorId -> ActorId -> [ActorId])
    -> Enum ActorId
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: ActorId -> ActorId
    succ :: ActorId -> ActorId
    $cpred :: ActorId -> ActorId
    pred :: ActorId -> ActorId
    $ctoEnum :: Int -> ActorId
    toEnum :: Int -> ActorId
    $cfromEnum :: ActorId -> Int
    fromEnum :: ActorId -> Int
    $cenumFrom :: ActorId -> [ActorId]
    enumFrom :: ActorId -> [ActorId]
    $cenumFromThen :: ActorId -> ActorId -> [ActorId]
    enumFromThen :: ActorId -> ActorId -> [ActorId]
    $cenumFromTo :: ActorId -> ActorId -> [ActorId]
    enumFromTo :: ActorId -> ActorId -> [ActorId]
    $cenumFromThenTo :: ActorId -> ActorId -> ActorId -> [ActorId]
    enumFromThenTo :: ActorId -> ActorId -> ActorId -> [ActorId]
    Enum, Get ActorId
    [ActorId] -> Put
    ActorId -> Put
    (ActorId -> Put)
    -> Get ActorId -> ([ActorId] -> Put) -> Binary ActorId
    forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
    $cput :: ActorId -> Put
    put :: ActorId -> Put
    $cget :: Get ActorId
    get :: Get ActorId
    $cputList :: [ActorId] -> Put
    putList :: [ActorId] -> Put
    Binary)

    -- | Item container type.
    data Container =
        CFloor LevelId Point
      | CEmbed LevelId Point
      | CActor ActorId CStore
      | CTrunk FactionId LevelId Point   -- ^ for bootstrapping actor bodies
      deriving (Int -> Container -> ShowS
    [Container] -> ShowS
    Container -> String
    (Int -> Container -> ShowS)
    -> (Container -> String)
    -> ([Container] -> ShowS)
    -> Show Container
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Container -> ShowS
    showsPrec :: Int -> Container -> ShowS
    $cshow :: Container -> String
    show :: Container -> String
    $cshowList :: [Container] -> ShowS
    showList :: [Container] -> ShowS
    Show, Container -> Container -> Bool
    (Container -> Container -> Bool)
    -> (Container -> Container -> Bool) -> Eq Container
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Container -> Container -> Bool
    == :: Container -> Container -> Bool
    $c/= :: Container -> Container -> Bool
    /= :: Container -> Container -> Bool
    Eq, Eq Container
    Eq Container =>
    (Container -> Container -> Ordering)
    -> (Container -> Container -> Bool)
    -> (Container -> Container -> Bool)
    -> (Container -> Container -> Bool)
    -> (Container -> Container -> Bool)
    -> (Container -> Container -> Container)
    -> (Container -> Container -> Container)
    -> Ord Container
    Container -> Container -> Bool
    Container -> Container -> Ordering
    Container -> Container -> Container
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: Container -> Container -> Ordering
    compare :: Container -> Container -> Ordering
    $c< :: Container -> Container -> Bool
    < :: Container -> Container -> Bool
    $c<= :: Container -> Container -> Bool
    <= :: Container -> Container -> Bool
    $c> :: Container -> Container -> Bool
    > :: Container -> Container -> Bool
    $c>= :: Container -> Container -> Bool
    >= :: Container -> Container -> Bool
    $cmax :: Container -> Container -> Container
    max :: Container -> Container -> Container
    $cmin :: Container -> Container -> Container
    min :: Container -> Container -> Container
    Ord, (forall x. Container -> Rep Container x)
    -> (forall x. Rep Container x -> Container) -> Generic Container
    forall x. Rep Container x -> Container
    forall x. Container -> Rep Container x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. Container -> Rep Container x
    from :: forall x. Container -> Rep Container x
    $cto :: forall x. Rep Container x -> Container
    to :: forall x. Rep Container x -> Container
    Generic)

    instance Binary Container