{-# LANGUAGE DeriveGeneric #-}
module Game.LambdaHack.Common.ReqFailure
( ReqFailure(..)
, impossibleReqFailure, showReqFailure
, permittedPrecious, permittedProject, permittedProjectAI, permittedApply
#ifdef EXPOSE_INTERNAL
#endif
) where
import Prelude ()
import Game.LambdaHack.Core.Prelude
import Data.Binary
import GHC.Generics (Generic)
import Game.LambdaHack.Common.Item
import qualified Game.LambdaHack.Common.ItemAspect as IA
import Game.LambdaHack.Common.Time
import qualified Game.LambdaHack.Content.ItemKind as IK
import qualified Game.LambdaHack.Definition.Ability as Ability
data ReqFailure =
MoveUnskilled
| MoveNothing
| MeleeUnskilled
| MeleeSelf
| MeleeDistant
| DisplaceUnskilled
| DisplaceDistant
| DisplaceAccess
| DisplaceMultiple
| DisplaceDying
| DisplaceBraced
| DisplaceImmobile
| DisplaceSupported
| AlterUnskilled
| AlterUnwalked
| AlterDistant
| AlterBlockActor
| AlterBlockItem
| AlterNothing
| WaitUnskilled
| YellUnskilled
| MoveItemUnskilled
| EqpOverfull
| EqpStackFull
| ApplyUnskilled
| ApplyFood
| ApplyRead
| ApplyPeriodic
| ApplyOutOfReach
| ApplyCharging
| ApplyNoEffects
| ItemNothing
| ItemNotCalm
| NotCalmPrecious
| ProjectUnskilled
| ProjectAimOnself
| ProjectBlockTerrain
| ProjectBlockActor
| ProjectLobable
| ProjectOutOfReach
| TriggerNothing
| NoChangeDunLeader
deriving (Int -> ReqFailure -> ShowS
[ReqFailure] -> ShowS
ReqFailure -> String
(Int -> ReqFailure -> ShowS)
-> (ReqFailure -> String)
-> ([ReqFailure] -> ShowS)
-> Show ReqFailure
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ReqFailure] -> ShowS
$cshowList :: [ReqFailure] -> ShowS
show :: ReqFailure -> String
$cshow :: ReqFailure -> String
showsPrec :: Int -> ReqFailure -> ShowS
$cshowsPrec :: Int -> ReqFailure -> ShowS
Show, ReqFailure -> ReqFailure -> Bool
(ReqFailure -> ReqFailure -> Bool)
-> (ReqFailure -> ReqFailure -> Bool) -> Eq ReqFailure
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ReqFailure -> ReqFailure -> Bool
$c/= :: ReqFailure -> ReqFailure -> Bool
== :: ReqFailure -> ReqFailure -> Bool
$c== :: ReqFailure -> ReqFailure -> Bool
Eq, (forall x. ReqFailure -> Rep ReqFailure x)
-> (forall x. Rep ReqFailure x -> ReqFailure) -> Generic ReqFailure
forall x. Rep ReqFailure x -> ReqFailure
forall x. ReqFailure -> Rep ReqFailure x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ReqFailure x -> ReqFailure
$cfrom :: forall x. ReqFailure -> Rep ReqFailure x
Generic)
instance Binary ReqFailure
impossibleReqFailure :: ReqFailure -> Bool
impossibleReqFailure :: ReqFailure -> Bool
impossibleReqFailure reqFailure :: ReqFailure
reqFailure = case ReqFailure
reqFailure of
MoveUnskilled -> Bool
False
MoveNothing -> Bool
True
MeleeUnskilled -> Bool
False
MeleeSelf -> Bool
True
MeleeDistant -> Bool
True
DisplaceUnskilled -> Bool
False
DisplaceDistant -> Bool
True
DisplaceAccess -> Bool
True
DisplaceMultiple -> Bool
True
DisplaceDying -> Bool
True
DisplaceBraced -> Bool
True
DisplaceImmobile -> Bool
False
DisplaceSupported -> Bool
False
AlterUnskilled -> Bool
False
AlterUnwalked -> Bool
False
AlterDistant -> Bool
True
AlterBlockActor -> Bool
True
AlterBlockItem -> Bool
True
AlterNothing -> Bool
True
WaitUnskilled -> Bool
False
YellUnskilled -> Bool
False
MoveItemUnskilled -> Bool
False
EqpOverfull -> Bool
True
EqpStackFull -> Bool
True
ApplyUnskilled -> Bool
False
ApplyFood -> Bool
False
ApplyRead -> Bool
False
ApplyPeriodic -> Bool
False
ApplyOutOfReach -> Bool
True
ApplyCharging -> Bool
False
ApplyNoEffects -> Bool
False
ItemNothing -> Bool
True
ItemNotCalm -> Bool
False
NotCalmPrecious -> Bool
False
ProjectUnskilled -> Bool
False
ProjectAimOnself -> Bool
True
ProjectBlockTerrain -> Bool
True
ProjectBlockActor -> Bool
True
ProjectLobable -> Bool
False
ProjectOutOfReach -> Bool
True
TriggerNothing -> Bool
True
NoChangeDunLeader -> Bool
True
showReqFailure :: ReqFailure -> Text
showReqFailure :: ReqFailure -> Text
showReqFailure reqFailure :: ReqFailure
reqFailure = case ReqFailure
reqFailure of
MoveUnskilled -> "too low movement stat"
MoveNothing -> "wasting time on moving into obstacle"
MeleeUnskilled -> "too low melee combat stat"
MeleeSelf -> "trying to melee oneself"
MeleeDistant -> "trying to melee a distant foe"
DisplaceUnskilled -> "too low actor displacing stat"
DisplaceDistant -> "trying to displace a distant actor"
DisplaceAccess -> "trying to switch places without access"
DisplaceMultiple -> "trying to displace multiple actors"
DisplaceDying -> "trying to displace a dying foe"
DisplaceBraced -> "trying to displace a braced foe"
DisplaceImmobile -> "trying to displace an immobile foe"
DisplaceSupported -> "trying to displace a foe supported by teammates"
AlterUnskilled -> "alter stat is needed to search or exploit terrain"
AlterUnwalked -> "too low altering stat to enter or exploit terrain"
AlterDistant -> "trying to alter distant terrain"
AlterBlockActor -> "blocked by an actor"
AlterBlockItem -> "jammed by an item"
AlterNothing -> "wasting time on altering nothing"
WaitUnskilled -> "too low wait stat"
YellUnskilled -> "actors unskilled in waiting cannot yell/yawn"
MoveItemUnskilled -> "too low item moving stat"
EqpOverfull -> "cannot equip any more items"
EqpStackFull -> "cannot equip the whole item stack"
ApplyUnskilled -> "too low item applying stat"
ApplyFood -> "eating food requires apply stat 2"
ApplyRead -> "activating cultural artifacts requires apply stat 3"
ApplyPeriodic -> "manually activating periodic items requires apply stat 4"
ApplyOutOfReach -> "cannot apply an item out of reach"
ApplyCharging -> "cannot apply an item that is still charging"
ApplyNoEffects -> "cannot apply an item that produces no effect"
ItemNothing -> "wasting time on void item manipulation"
ItemNotCalm -> "you are too alarmed to use the shared stash"
NotCalmPrecious -> "you are too alarmed to handle such an exquisite item"
ProjectUnskilled -> "too low item flinging stat"
ProjectAimOnself -> "cannot aim at oneself"
ProjectBlockTerrain -> "aiming obstructed by terrain"
ProjectBlockActor -> "aiming blocked by an actor"
ProjectLobable -> "flinging a lobable item that stops at target position requires fling stat 3"
ProjectOutOfReach -> "cannot aim an item out of reach"
TriggerNothing -> "wasting time on triggering nothing"
NoChangeDunLeader -> "no manual level change for your team"
permittedPrecious :: Bool -> Bool -> ItemFull -> Either ReqFailure Bool
permittedPrecious :: Bool -> Bool -> ItemFull -> Either ReqFailure Bool
permittedPrecious forced :: Bool
forced calmE :: Bool
calmE itemFull :: ItemFull
itemFull@ItemFull{ItemDisco
itemDisco :: ItemFull -> ItemDisco
itemDisco :: ItemDisco
itemDisco} =
let arItem :: AspectRecord
arItem = ItemFull -> AspectRecord
aspectRecordFull ItemFull
itemFull
isPrecious :: Bool
isPrecious = Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Precious AspectRecord
arItem
in if Bool -> Bool
not Bool
forced Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
calmE Bool -> Bool -> Bool
&& Bool
isPrecious
then ReqFailure -> Either ReqFailure Bool
forall a b. a -> Either a b
Left ReqFailure
NotCalmPrecious
else Bool -> Either ReqFailure Bool
forall a b. b -> Either a b
Right (Bool -> Either ReqFailure Bool) -> Bool -> Either ReqFailure Bool
forall a b. (a -> b) -> a -> b
$ Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Durable AspectRecord
arItem
Bool -> Bool -> Bool
|| case ItemDisco
itemDisco of
ItemDiscoFull{} -> Bool
True
_ -> Bool -> Bool
not Bool
isPrecious
permittedPreciousAI :: Bool -> ItemFull -> Bool
permittedPreciousAI :: Bool -> ItemFull -> Bool
permittedPreciousAI calmE :: Bool
calmE itemFull :: ItemFull
itemFull@ItemFull{ItemDisco
itemDisco :: ItemDisco
itemDisco :: ItemFull -> ItemDisco
itemDisco} =
let arItem :: AspectRecord
arItem = ItemFull -> AspectRecord
aspectRecordFull ItemFull
itemFull
isPrecious :: Bool
isPrecious = Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Precious AspectRecord
arItem
in (Bool
calmE Bool -> Bool -> Bool
|| Bool -> Bool
not Bool
isPrecious)
Bool -> Bool -> Bool
&& Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Durable AspectRecord
arItem
Bool -> Bool -> Bool
|| case ItemDisco
itemDisco of
ItemDiscoFull{} -> Bool
True
_ -> Bool -> Bool
not Bool
isPrecious
permittedProject :: Bool -> Int -> Bool -> ItemFull -> Either ReqFailure Bool
permittedProject :: Bool -> Int -> Bool -> ItemFull -> Either ReqFailure Bool
permittedProject forced :: Bool
forced skill :: Int
skill calmE :: Bool
calmE itemFull :: ItemFull
itemFull =
let arItem :: AspectRecord
arItem = ItemFull -> AspectRecord
aspectRecordFull ItemFull
itemFull
in if | Bool -> Bool
not Bool
forced Bool -> Bool -> Bool
&& Int
skill Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 1 -> ReqFailure -> Either ReqFailure Bool
forall a b. a -> Either a b
Left ReqFailure
ProjectUnskilled
| Bool -> Bool
not Bool
forced
Bool -> Bool -> Bool
&& Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Lobable AspectRecord
arItem
Bool -> Bool -> Bool
&& Int
skill Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 3 -> ReqFailure -> Either ReqFailure Bool
forall a b. a -> Either a b
Left ReqFailure
ProjectLobable
| Bool
otherwise -> case Bool -> Bool -> ItemFull -> Either ReqFailure Bool
permittedPrecious Bool
forced Bool
calmE ItemFull
itemFull of
Left failure :: ReqFailure
failure -> ReqFailure -> Either ReqFailure Bool
forall a b. a -> Either a b
Left ReqFailure
failure
Right False -> Bool -> Either ReqFailure Bool
forall a b. b -> Either a b
Right Bool
False
Right True -> Bool -> Either ReqFailure Bool
forall a b. b -> Either a b
Right (Bool -> Either ReqFailure Bool) -> Bool -> Either ReqFailure Bool
forall a b. (a -> b) -> a -> b
$
let badSlot :: Bool
badSlot = case AspectRecord -> Maybe EqpSlot
IA.aEqpSlot AspectRecord
arItem of
Just Ability.EqpSlotShine -> Bool
False
Just _ -> Bool
True
Nothing -> AspectRecord -> Bool
IA.goesIntoEqp AspectRecord
arItem
in Bool -> Bool
not Bool
badSlot
permittedProjectAI :: Int -> Bool -> ItemFull -> Bool
permittedProjectAI :: Int -> Bool -> ItemFull -> Bool
permittedProjectAI skill :: Int
skill calmE :: Bool
calmE itemFull :: ItemFull
itemFull =
let arItem :: AspectRecord
arItem = ItemFull -> AspectRecord
aspectRecordFull ItemFull
itemFull
in if | Int
skill Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 1 -> Bool
False
| Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Lobable AspectRecord
arItem
Bool -> Bool -> Bool
&& Int
skill Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 3 -> Bool
False
| Bool
otherwise -> Bool -> ItemFull -> Bool
permittedPreciousAI Bool
calmE ItemFull
itemFull
permittedApply :: Time -> Int -> Bool-> ItemFull -> ItemQuant
-> Either ReqFailure Bool
permittedApply :: Time
-> Int -> Bool -> ItemFull -> ItemQuant -> Either ReqFailure Bool
permittedApply localTime :: Time
localTime skill :: Int
skill calmE :: Bool
calmE
itemFull :: ItemFull
itemFull@ItemFull{ItemKind
itemKind :: ItemFull -> ItemKind
itemKind :: ItemKind
itemKind, Bool
itemSuspect :: ItemFull -> Bool
itemSuspect :: Bool
itemSuspect} kit :: ItemQuant
kit =
if | Int
skill Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 1 -> ReqFailure -> Either ReqFailure Bool
forall a b. a -> Either a b
Left ReqFailure
ApplyUnskilled
| Int
skill Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 2 Bool -> Bool -> Bool
&& ItemKind -> Char
IK.isymbol ItemKind
itemKind Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [',', '"'] -> ReqFailure -> Either ReqFailure Bool
forall a b. a -> Either a b
Left ReqFailure
ApplyFood
| Int
skill Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 3 Bool -> Bool -> Bool
&& ItemKind -> Char
IK.isymbol ItemKind
itemKind Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '?' -> ReqFailure -> Either ReqFailure Bool
forall a b. a -> Either a b
Left ReqFailure
ApplyRead
| Int
skill Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 4
Bool -> Bool -> Bool
&& let arItem :: AspectRecord
arItem = ItemFull -> AspectRecord
aspectRecordFull ItemFull
itemFull
in Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Periodic AspectRecord
arItem -> ReqFailure -> Either ReqFailure Bool
forall a b. a -> Either a b
Left ReqFailure
ApplyPeriodic
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Time -> ItemFull -> ItemQuant -> Bool
hasCharge Time
localTime ItemFull
itemFull ItemQuant
kit -> ReqFailure -> Either ReqFailure Bool
forall a b. a -> Either a b
Left ReqFailure
ApplyCharging
| Bool
otherwise ->
if [Effect] -> Bool
forall a. [a] -> Bool
null (ItemKind -> [Effect]
IK.ieffects ItemKind
itemKind) Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
itemSuspect
then ReqFailure -> Either ReqFailure Bool
forall a b. a -> Either a b
Left ReqFailure
ApplyNoEffects
else Bool -> Bool -> ItemFull -> Either ReqFailure Bool
permittedPrecious Bool
False Bool
calmE ItemFull
itemFull