module Game.LambdaHack.Client.UI.ItemDescription
( partItem, partItemShort, partItemShortest, partItemHigh
, partItemWsDetail, partItemWs, partItemWsShortest, partItemWsShort
, partItemWsLong, partItemWsRanged
, partItemShortAW, partItemMediumAW, partItemShortWownW
, viewItem, viewItemBenefitColored, itemDesc
#ifdef EXPOSE_INTERNAL
, partItemN, textAllPowers
#endif
) where
import Prelude ()
import Game.LambdaHack.Core.Prelude
import Data.Char (isAlpha, isAlphaNum)
import qualified Data.EnumMap.Strict as EM
import Data.Int (Int64)
import qualified Data.Text as T
import qualified NLP.Miniutter.English as MU
import Game.LambdaHack.Client.UI.EffectDescription
import Game.LambdaHack.Client.UI.Overlay
import Game.LambdaHack.Common.Faction
import Game.LambdaHack.Common.Item
import qualified Game.LambdaHack.Common.ItemAspect as IA
import Game.LambdaHack.Common.Misc
import Game.LambdaHack.Common.Time
import Game.LambdaHack.Common.Types
import qualified Game.LambdaHack.Content.ItemKind as IK
import qualified Game.LambdaHack.Core.Dice as Dice
import qualified Game.LambdaHack.Definition.Ability as Ability
import qualified Game.LambdaHack.Definition.Color as Color
import Game.LambdaHack.Definition.Defs
import Game.LambdaHack.Definition.Flavour
partItemN :: Int -> FactionId -> FactionDict -> Bool -> DetailLevel -> Int
-> Time -> ItemFull -> ItemQuant
-> (MU.Part, MU.Part)
partItemN :: Int
-> FactionId
-> FactionDict
-> Bool
-> DetailLevel
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> (Part, Part)
partItemN Int
width FactionId
side FactionDict
factionD Bool
ranged DetailLevel
detailLevel Int
maxWordsToShow Time
localTime
ItemFull
itemFull ItemQuant
kit =
let ([Text]
_, Part
r2, Part
r3) =
Int
-> FactionId
-> FactionDict
-> Bool
-> DetailLevel
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> ([Text], Part, Part)
partItemN3 Int
width FactionId
side FactionDict
factionD Bool
ranged DetailLevel
detailLevel Int
maxWordsToShow
Time
localTime ItemFull
itemFull ItemQuant
kit
in (Part
r2, Part
r3)
partItemN3 :: Int -> FactionId -> FactionDict -> Bool -> DetailLevel -> Int
-> Time -> ItemFull -> ItemQuant
-> ([Text], MU.Part, MU.Part)
partItemN3 :: Int
-> FactionId
-> FactionDict
-> Bool
-> DetailLevel
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> ([Text], Part, Part)
partItemN3 Int
width FactionId
side FactionDict
factionD Bool
ranged DetailLevel
detailLevel Int
maxWordsToShow Time
localTime
itemFull :: ItemFull
itemFull@ItemFull{Item
itemBase :: ItemFull -> Item
itemBase :: Item
itemBase, ItemKind
itemKind :: ItemFull -> ItemKind
itemKind :: ItemKind
itemKind, Bool
itemSuspect :: ItemFull -> Bool
itemSuspect :: Bool
itemSuspect}
(Int
itemK, ItemTimers
itemTimers) =
let flav :: Text
flav = Flavour -> Text
flavourToName (Flavour -> Text) -> Flavour -> Text
forall a b. (a -> b) -> a -> b
$ Item -> Flavour
jflavour Item
itemBase
arItem :: AspectRecord
arItem = ItemFull -> AspectRecord
aspectRecordFull ItemFull
itemFull
timeout :: Int
timeout = AspectRecord -> Int
IA.aTimeout AspectRecord
arItem
temporary :: Bool
temporary = Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Fragile AspectRecord
arItem
Bool -> Bool -> Bool
&& Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Periodic AspectRecord
arItem
ncha :: Int
ncha = Time -> ItemQuant -> Int
ncharges Time
localTime (Int
itemK, ItemTimers
itemTimers)
charges :: Text
charges | Bool
temporary = case ItemTimers
itemTimers of
[] -> if Int
itemK Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ncha
then Text
""
else [Char] -> Text
forall a. HasCallStack => [Char] -> a
error ([Char] -> Text) -> [Char] -> Text
forall a b. (a -> b) -> a -> b
$ [Char]
"partItemN3: charges with null timer"
[Char] -> (FactionId, ItemFull, Int, ItemTimers) -> [Char]
forall v. Show v => [Char] -> v -> [Char]
`showFailure`
(FactionId
side, ItemFull
itemFull, Int
itemK, ItemTimers
itemTimers)
ItemTimer
t : ItemTimers
_ -> if Int
itemK Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ncha
then Text
"(ready to expire)"
else let total :: Delta Time
total = Time -> ItemTimer -> Delta Time
deltaOfItemTimer Time
localTime ItemTimer
t
in Text
"for" Text -> Text -> Text
<+> Delta Time -> Text
timeDeltaInSecondsText Delta Time
total
| Int
itemK Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ncha = Text
""
| Int
itemK Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 Bool -> Bool -> Bool
&& Int
ncha Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Text
"(charging)"
| Int
ncha Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Text
"(all charging)"
| Bool
otherwise = Text
"(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
tshow (Int
itemK Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
ncha) Text -> Text -> Text
<+> Text
"charging)"
skipRecharging :: Bool
skipRecharging = DetailLevel
detailLevel DetailLevel -> DetailLevel -> Bool
forall a. Ord a => a -> a -> Bool
<= DetailLevel
DetailLow Bool -> Bool -> Bool
&& Int
ncha Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
([Text]
orTs, [Text]
powerTs, [Text]
rangedDamage) =
Int -> DetailLevel -> Bool -> ItemFull -> ([Text], [Text], [Text])
textAllPowers Int
width DetailLevel
detailLevel Bool
skipRecharging ItemFull
itemFull
lsource :: [Text]
lsource = case Item -> Maybe FactionId
jfid Item
itemBase of
Just FactionId
fid | ItemKind -> Text
IK.iname ItemKind
itemKind Text -> [Text] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"impressed"] ->
[Text
"by" Text -> Text -> Text
<+> if FactionId
fid FactionId -> FactionId -> Bool
forall a. Eq a => a -> a -> Bool
== FactionId
side
then Text
"us"
else Faction -> Text
gname (FactionDict
factionD FactionDict -> FactionId -> Faction
forall k a. Enum k => EnumMap k a -> k -> a
EM.! FactionId
fid)]
Maybe FactionId
_ -> []
powerTsBeginsWithAlphaOrNum :: Bool
powerTsBeginsWithAlphaOrNum = case (Text -> [Char]) -> [Text] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map Text -> [Char]
T.unpack [Text]
powerTs of
(Char
c : [Char]
_) : [[Char]]
_ -> Char -> Bool
isAlpha Char
c Bool -> Bool -> Bool
|| Char -> Bool
isAlphaNum Char
c
[[Char]]
_ -> Bool
False
displayPowers :: Bool
displayPowers = Int
maxWordsToShow Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1
Bool -> Bool -> Bool
|| Bool
powerTsBeginsWithAlphaOrNum Bool -> Bool -> Bool
&& [Text] -> Int
forall a. [a] -> Int
length [Text]
powerTs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1
ts :: [Text]
ts = [Text]
lsource
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ (if Bool
displayPowers
then Int -> [Text] -> [Text]
forall a. Int -> [a] -> [a]
take Int
maxWordsToShow [Text]
powerTs
else [])
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [Text
"(...)" | Bool
displayPowers Bool -> Bool -> Bool
&& [Text] -> Int
forall a. [a] -> Int
length [Text]
powerTs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
maxWordsToShow]
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ (if Bool
displayPowers Bool -> Bool -> Bool
&& Bool
ranged then [Text]
rangedDamage else [])
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [Text
charges | Int
maxWordsToShow Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1]
name :: Text
name | Bool
temporary =
let adj :: Text
adj = if Int
timeout Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Text
"temporarily" else Text
"impermanent"
in Text
adj Text -> Text -> Text
<+> ItemKind -> Text
IK.iname ItemKind
itemKind
| Bool
itemSuspect = Text
flav Text -> Text -> Text
<+> ItemKind -> Text
IK.iname ItemKind
itemKind
| Bool
otherwise = ItemKind -> Text
IK.iname ItemKind
itemKind
in ([Text]
orTs, Text -> Part
MU.Text Text
name, if Bool
displayPowers
then [Part] -> Part
MU.Phrase ([Part] -> Part) -> [Part] -> Part
forall a b. (a -> b) -> a -> b
$ (Text -> Part) -> [Text] -> [Part]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Part
MU.Text [Text]
ts
else Text -> Part
MU.Text (Text -> Part) -> Text -> Part
forall a b. (a -> b) -> a -> b
$ AspectRecord -> Text
IA.aELabel AspectRecord
arItem)
textAllPowers :: Int -> DetailLevel -> Bool -> ItemFull
-> ([Text], [Text], [Text])
textAllPowers :: Int -> DetailLevel -> Bool -> ItemFull -> ([Text], [Text], [Text])
textAllPowers Int
width DetailLevel
detailLevel Bool
skipRecharging
itemFull :: ItemFull
itemFull@ItemFull{ItemKind
itemKind :: ItemKind
itemKind :: ItemFull -> ItemKind
itemKind, ItemDisco
itemDisco :: ItemFull -> ItemDisco
itemDisco :: ItemDisco
itemDisco} =
let arItem :: AspectRecord
arItem = ItemFull -> AspectRecord
aspectRecordFull ItemFull
itemFull
aspectsFull :: [Aspect]
aspectsFull = case ItemDisco
itemDisco of
ItemDiscoMean IA.KindMean{Bool
AspectRecord
kmMean :: KindMean -> AspectRecord
kmConst :: KindMean -> Bool
kmMean :: AspectRecord
kmConst :: Bool
..} | Bool
kmConst ->
AspectRecord -> [Aspect]
IA.aspectRecordToList AspectRecord
kmMean
ItemDiscoMean{} -> ItemKind -> [Aspect]
IK.iaspects ItemKind
itemKind
ItemDiscoFull AspectRecord
iAspect -> AspectRecord -> [Aspect]
IA.aspectRecordToList AspectRecord
iAspect
mtimeout :: Maybe Aspect
mtimeout = (Aspect -> Bool) -> [Aspect] -> Maybe Aspect
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find Aspect -> Bool
IK.timeoutAspect [Aspect]
aspectsFull
elab :: Text
elab = AspectRecord -> Text
IA.aELabel AspectRecord
arItem
periodic :: Bool
periodic = Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Periodic AspectRecord
arItem
hurtMeleeAspect :: IK.Aspect -> Bool
hurtMeleeAspect :: Aspect -> Bool
hurtMeleeAspect (IK.AddSkill Skill
Ability.SkHurtMelee Dice
_) = Bool
True
hurtMeleeAspect Aspect
_ = Bool
False
active :: Bool
active = AspectRecord -> Bool
IA.goesIntoEqp AspectRecord
arItem
splitA :: DetailLevel -> [IK.Aspect] -> ([Text], [Text])
splitA :: DetailLevel -> [Aspect] -> ([Text], [Text])
splitA DetailLevel
detLev [Aspect]
aspects =
let ppA :: Aspect -> Text
ppA = Aspect -> Text
kindAspectToSuffix
ppE :: Effect -> Text
ppE = DetailLevel -> Effect -> Text
effectToSuffix DetailLevel
detLev
reduce_a :: Dice -> Text
reduce_a = Text -> (Int -> Text) -> Maybe Int -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"?" Int -> Text
forall a. Show a => a -> Text
tshow (Maybe Int -> Text) -> (Dice -> Maybe Int) -> Dice -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dice -> Maybe Int
Dice.reduceDice
restEs :: [Effect]
restEs | DetailLevel
detLev DetailLevel -> DetailLevel -> Bool
forall a. Ord a => a -> a -> Bool
>= DetailLevel
DetailHigh
Bool -> Bool -> Bool
|| Bool -> Bool
not (Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.MinorEffects AspectRecord
arItem) =
ItemKind -> [Effect]
IK.ieffects ItemKind
itemKind
| Bool
otherwise = []
([Effect]
smashEffs, [Effect]
noSmashEffs) = (Effect -> Bool) -> [Effect] -> ([Effect], [Effect])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition Effect -> Bool
IK.onSmashEffect [Effect]
restEs
unSmash :: Effect -> Effect
unSmash (IK.OnSmash Effect
eff) = Effect
eff
unSmash Effect
eff = Effect
eff
onSmashTs :: Text
onSmashTs = Text -> [Text] -> Text
T.intercalate Text
" " ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ (Text -> Bool) -> [Text] -> [Text]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Text -> Bool) -> Text -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Bool
T.null)
([Text] -> [Text]) -> [Text] -> [Text]
forall a b. (a -> b) -> a -> b
$ (Effect -> Text) -> [Effect] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (Effect -> Text
ppE (Effect -> Text) -> (Effect -> Effect) -> Effect -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Effect -> Effect
unSmash) [Effect]
smashEffs
unCombine :: Effect -> Effect
unCombine (IK.OnCombine Effect
eff) = Effect
eff
unCombine Effect
eff = Effect
eff
([Effect]
combineEffsRaw, [Effect]
noSmashCombineEffsRaw) =
(Effect -> Bool) -> [Effect] -> ([Effect], [Effect])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition Effect -> Bool
IK.onCombineEffect [Effect]
noSmashEffs
onCombineRawTs :: Text
onCombineRawTs = Text -> [Text] -> Text
T.intercalate Text
" " ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ (Text -> Bool) -> [Text] -> [Text]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Text -> Bool) -> Text -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Bool
T.null)
([Text] -> [Text]) -> [Text] -> [Text]
forall a b. (a -> b) -> a -> b
$ (Effect -> Text) -> [Effect] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (Effect -> Text
ppE (Effect -> Text) -> (Effect -> Effect) -> Effect -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Effect -> Effect
unCombine) [Effect]
combineEffsRaw
onCombineRawTsTooLarge :: Bool
onCombineRawTsTooLarge =
DetailLevel
detailLevel DetailLevel -> DetailLevel -> Bool
forall a. Ord a => a -> a -> Bool
>= DetailLevel
DetailAll Bool -> Bool -> Bool
&& Text -> Int
T.length Text
onCombineRawTs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
120
([Effect]
combineEffs, [Effect]
noSmashCombineEffs) =
if Bool
onCombineRawTsTooLarge
then ([Effect]
combineEffsRaw, [Effect]
noSmashCombineEffsRaw)
else ([], [Effect]
noSmashEffs)
unOr :: Effect -> [Effect]
unOr (IK.OrEffect Effect
eff1 Effect
eff2) = Effect -> [Effect]
unOr Effect
eff1 [Effect] -> [Effect] -> [Effect]
forall a. [a] -> [a] -> [a]
++ Effect -> [Effect]
unOr Effect
eff2
unOr Effect
eff = [Effect
eff]
ppAnd :: Effect -> Text
ppAnd (IK.AndEffect (IK.ConsumeItems [(Int, GroupName ItemKind)]
tools [(Int, GroupName ItemKind)]
raw) Effect
eff) =
let (Text
tcraft, Text
traw, Text
ttools) = [(Int, GroupName ItemKind)]
-> [(Int, GroupName ItemKind)] -> Effect -> (Text, Text, Text)
describeCrafting [(Int, GroupName ItemKind)]
tools [(Int, GroupName ItemKind)]
raw Effect
eff
in if Text -> Int
T.length Text
tcraft Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Text -> Int
T.length Text
traw Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Text -> Int
T.length Text
ttools
Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
width Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
4
then Text
tcraft Text -> Text -> Text
<+> Text
traw Text -> Text -> Text
<+> Text
ttools
else Text
tcraft Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\n---" Text -> Text -> Text
<+> Text
traw Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\n---" Text -> Text -> Text
<+> Text
ttools
ppAnd Effect
eff = Effect -> Text
ppE Effect
eff
ppOr :: Effect -> Text
ppOr Effect
eff = Text
"*" Text -> Text -> Text
<+> Text -> [Text] -> Text
T.intercalate Text
"\n* "
([Text] -> [Text]
forall a. Eq a => [a] -> [a]
nub ([Text] -> [Text]) -> [Text] -> [Text]
forall a b. (a -> b) -> a -> b
$ (Text -> Bool) -> [Text] -> [Text]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Text -> Bool) -> Text -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Bool
T.null)
([Text] -> [Text]) -> [Text] -> [Text]
forall a b. (a -> b) -> a -> b
$ (Effect -> Text) -> [Effect] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Effect -> Text
ppAnd ([Effect] -> [Text]) -> [Effect] -> [Text]
forall a b. (a -> b) -> a -> b
$ Effect -> [Effect]
unOr Effect
eff)
onCombineTs :: [Text]
onCombineTs =
(Text -> Bool) -> [Text] -> [Text]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Text -> Bool) -> Text -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Bool
T.null) ([Text] -> [Text]) -> [Text] -> [Text]
forall a b. (a -> b) -> a -> b
$ (Effect -> Text) -> [Effect] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Effect -> Text
ppOr ([Effect] -> [Text]) -> [Effect] -> [Text]
forall a b. (a -> b) -> a -> b
$ (Effect -> Effect) -> [Effect] -> [Effect]
forall a b. (a -> b) -> [a] -> [b]
map Effect -> Effect
unCombine [Effect]
combineEffs
rechargingTs :: Text
rechargingTs = Text -> [Text] -> Text
T.intercalate Text
" "
([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ [Text
damageText | ItemKind -> Dice
IK.idamage ItemKind
itemKind Dice -> Dice -> Bool
forall a. Eq a => a -> a -> Bool
/= Dice
0]
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ (Text -> Bool) -> [Text] -> [Text]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Text -> Bool) -> Text -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Bool
T.null)
((Effect -> Text) -> [Effect] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Effect -> Text
ppE [Effect]
noSmashCombineEffs)
fragile :: Bool
fragile = Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Fragile AspectRecord
arItem
periodicText :: Text
periodicText =
if Bool
periodic Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
skipRecharging Bool -> Bool -> Bool
&& Bool -> Bool
not (Text -> Bool
T.null Text
rechargingTs)
then case (Maybe Aspect
mtimeout, Bool
fragile) of
(Maybe Aspect
Nothing, Bool
True) ->
Text
"(each turn until gone:" Text -> Text -> Text
<+> Text
rechargingTs Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
(Maybe Aspect
Nothing, Bool
False) ->
Text
"(each turn:" Text -> Text -> Text
<+> Text
rechargingTs Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
(Just (IK.Timeout Dice
t), Bool
True) ->
Text
"(every" Text -> Text -> Text
<+> Dice -> Text
reduce_a Dice
t Text -> Text -> Text
<+> Text
"until gone:"
Text -> Text -> Text
<+> Text
rechargingTs Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
(Just (IK.Timeout Dice
t), Bool
False) ->
Text
"(every" Text -> Text -> Text
<+> Dice -> Text
reduce_a Dice
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
":" Text -> Text -> Text
<+> Text
rechargingTs Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
(Maybe Aspect, Bool)
_ -> [Char] -> Text
forall a. HasCallStack => [Char] -> a
error ([Char] -> Text) -> [Char] -> Text
forall a b. (a -> b) -> a -> b
$ [Char]
"" [Char] -> Maybe Aspect -> [Char]
forall v. Show v => [Char] -> v -> [Char]
`showFailure` Maybe Aspect
mtimeout
else Text
""
ppERestEs :: [Text]
ppERestEs = if Bool
periodic
then [Text
periodicText]
else (Effect -> Text) -> [Effect] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Effect -> Text
ppE [Effect]
noSmashCombineEffs
aes :: [Text]
aes = if Bool
active
then (Aspect -> Text) -> [Aspect] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Aspect -> Text
ppA [Aspect]
aspects [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [Text]
ppERestEs
else [Text]
ppERestEs [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ (Aspect -> Text) -> [Aspect] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Aspect -> Text
ppA [Aspect]
aspects
onSmash :: Text
onSmash = if Text -> Bool
T.null Text
onSmashTs then Text
""
else Text
"(on smash:" Text -> Text -> Text
<+> Text
onSmashTs Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
onCombine :: Text
onCombine = if [Effect] -> Bool
forall a. [a] -> Bool
null [Effect]
combineEffs Bool -> Bool -> Bool
&& Bool -> Bool
not (Text -> Bool
T.null Text
onCombineRawTs)
then Text
"(on combine:" Text -> Text -> Text
<+> Text
onCombineRawTs Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
else Text
""
damageText :: Text
damageText = case (Aspect -> Bool) -> [Aspect] -> Maybe Aspect
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find Aspect -> Bool
hurtMeleeAspect [Aspect]
aspects of
Just (IK.AddSkill Skill
Ability.SkHurtMelee Dice
hurtMelee) ->
(if ItemKind -> Dice
IK.idamage ItemKind
itemKind Dice -> Dice -> Bool
forall a. Eq a => a -> a -> Bool
== Dice
0
then Text
"0d0"
else Dice -> Text
forall a. Show a => a -> Text
tshow (ItemKind -> Dice
IK.idamage ItemKind
itemKind))
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Dice -> Text
affixDice Dice
hurtMelee Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"%"
Maybe Aspect
_ -> if ItemKind -> Dice
IK.idamage ItemKind
itemKind Dice -> Dice -> Bool
forall a. Eq a => a -> a -> Bool
== Dice
0
then Text
""
else Dice -> Text
forall a. Show a => a -> Text
tshow (ItemKind -> Dice
IK.idamage ItemKind
itemKind)
timeoutText :: Text
timeoutText = case Maybe Aspect
mtimeout of
Maybe Aspect
Nothing -> Text
""
Just (IK.Timeout Dice
t) -> Text
"(cooldown" Text -> Text -> Text
<+> Dice -> Text
reduce_a Dice
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
Maybe Aspect
_ -> [Char] -> Text
forall a. HasCallStack => [Char] -> a
error ([Char] -> Text) -> [Char] -> Text
forall a b. (a -> b) -> a -> b
$ [Char]
"" [Char] -> Maybe Aspect -> [Char]
forall v. Show v => [Char] -> v -> [Char]
`showFailure` Maybe Aspect
mtimeout
in ( [Text]
onCombineTs
, [Text
damageText]
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [Text
timeoutText | DetailLevel
detLev DetailLevel -> DetailLevel -> Bool
forall a. Ord a => a -> a -> Bool
> DetailLevel
DetailLow Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
periodic]
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [Text]
aes
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ if DetailLevel
detLev DetailLevel -> DetailLevel -> Bool
forall a. Ord a => a -> a -> Bool
>= DetailLevel
DetailAll
then [Text
onCombine, Text
onSmash]
else [Text
onCombineRawTs] )
hurtMult :: Int
hurtMult = Bool -> Skills -> Skills -> Int
armorHurtCalculation Bool
True (AspectRecord -> Skills
IA.aSkills AspectRecord
arItem)
Skills
Ability.zeroSkills
dmg :: Double
dmg = Dice -> Double
Dice.meanDice (Dice -> Double) -> Dice -> Double
forall a b. (a -> b) -> a -> b
$ ItemKind -> Dice
IK.idamage ItemKind
itemKind
rawDeltaHP :: Int64
rawDeltaHP = Double -> Int64
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Double -> Int64) -> Double -> Int64
forall a b. (a -> b) -> a -> b
$ Int -> Double
intToDouble Int
hurtMult Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
xD Double
dmg Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
100
IK.ThrowMod{Int
throwVelocity :: ThrowMod -> Int
throwVelocity :: Int
IK.throwVelocity} = AspectRecord -> ThrowMod
IA.aToThrow AspectRecord
arItem
speed :: Speed
speed = Int -> Int -> Speed
speedFromWeight (ItemKind -> Int
IK.iweight ItemKind
itemKind) Int
throwVelocity
pdeltaHP :: Int64
pdeltaHP = Int64 -> Speed -> Int64
modifyDamageBySpeed Int64
rawDeltaHP Speed
speed
rangedDamageDesc :: [Text]
rangedDamageDesc = [ Text
"{avg" Text -> Text -> Text
<+> Int64 -> Text
show64With2 Int64
pdeltaHP Text -> Text -> Text
<+> Text
"ranged}"
| Int64
pdeltaHP Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
> Int64
0 ]
splitTry :: [Aspect] -> ([Text], [Text])
splitTry [Aspect]
ass =
let splits :: [([Text], [Text])]
splits = (DetailLevel -> ([Text], [Text]))
-> [DetailLevel] -> [([Text], [Text])]
forall a b. (a -> b) -> [a] -> [b]
map (DetailLevel -> [Aspect] -> ([Text], [Text])
`splitA` [Aspect]
ass) [DetailLevel
forall a. Bounded a => a
minBound..DetailLevel
forall a. Bounded a => a
maxBound]
splitsToTry :: [([Text], [Text])]
splitsToTry = Int -> [([Text], [Text])] -> [([Text], [Text])]
forall a. Int -> [a] -> [a]
drop (DetailLevel -> Int
forall a. Enum a => a -> Int
fromEnum DetailLevel
detailLevel) [([Text], [Text])]
splits
splitsValid :: [([Text], [Text])]
splitsValid | Text -> Bool
T.null Text
elab = (([Text], [Text]) -> Bool)
-> [([Text], [Text])] -> [([Text], [Text])]
forall a. (a -> Bool) -> [a] -> [a]
filter (([Text], [Text]) -> ([Text], [Text]) -> Bool
forall a. Eq a => a -> a -> Bool
/= ([], [])) [([Text], [Text])]
splitsToTry
| Bool
otherwise = [([Text], [Text])]
splitsToTry
in case [([Text], [Text])]
splitsValid of
([Text]
onCombineTsSplit, [Text]
tsSplit) : [([Text], [Text])]
_ -> ([Text]
onCombineTsSplit, [Text]
tsSplit)
[] -> ([], [])
([Text]
onCombineTsAss, [Text]
aspectDescs) =
let aMain :: Aspect -> Bool
aMain IK.AddSkill{} = Bool
True
aMain Aspect
_ = Bool
False
([Aspect]
aspectsMain, [Aspect]
aspectsAux) = (Aspect -> Bool) -> [Aspect] -> ([Aspect], [Aspect])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition Aspect -> Bool
aMain [Aspect]
aspectsFull
([Text]
onCombineTsSplit, [Text]
tsSplit) = [Aspect] -> ([Text], [Text])
splitTry [Aspect]
aspectsMain
in ( [Text]
onCombineTsSplit
, (Text -> Bool) -> [Text] -> [Text]
forall a. (a -> Bool) -> [a] -> [a]
filter (Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Text
"")
([Text] -> [Text]) -> [Text] -> [Text]
forall a b. (a -> b) -> a -> b
$ Text
elab
Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: [Text]
tsSplit
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ if DetailLevel
detailLevel DetailLevel -> DetailLevel -> Bool
forall a. Ord a => a -> a -> Bool
>= DetailLevel
DetailAll
then (Aspect -> Text) -> [Aspect] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Aspect -> Text
kindAspectToSuffix [Aspect]
aspectsAux
else [] )
in ([Text]
onCombineTsAss, [Text]
aspectDescs, [Text]
rangedDamageDesc)
partItem :: Int -> FactionId -> FactionDict -> Time -> ItemFull -> ItemQuant
-> (MU.Part, MU.Part)
partItem :: Int
-> FactionId
-> FactionDict
-> Time
-> ItemFull
-> ItemQuant
-> (Part, Part)
partItem Int
width FactionId
side FactionDict
factionD =
Int
-> FactionId
-> FactionDict
-> Bool
-> DetailLevel
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> (Part, Part)
partItemN Int
width FactionId
side FactionDict
factionD Bool
False DetailLevel
DetailMedium Int
4
partItemShort :: Int -> FactionId -> FactionDict -> Time -> ItemFull
-> ItemQuant
-> (MU.Part, MU.Part)
partItemShort :: Int
-> FactionId
-> FactionDict
-> Time
-> ItemFull
-> ItemQuant
-> (Part, Part)
partItemShort Int
width FactionId
side FactionDict
factionD =
Int
-> FactionId
-> FactionDict
-> Bool
-> DetailLevel
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> (Part, Part)
partItemN Int
width FactionId
side FactionDict
factionD Bool
False DetailLevel
DetailLow Int
4
partItemShortest :: Int -> FactionId -> FactionDict -> Time -> ItemFull
-> ItemQuant
-> (MU.Part, MU.Part)
partItemShortest :: Int
-> FactionId
-> FactionDict
-> Time
-> ItemFull
-> ItemQuant
-> (Part, Part)
partItemShortest Int
width FactionId
side FactionDict
factionD =
Int
-> FactionId
-> FactionDict
-> Bool
-> DetailLevel
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> (Part, Part)
partItemN Int
width FactionId
side FactionDict
factionD Bool
False DetailLevel
DetailLow Int
1
partItemHigh :: Int -> FactionId -> FactionDict -> Time -> ItemFull -> ItemQuant
-> ([Text], MU.Part, MU.Part)
partItemHigh :: Int
-> FactionId
-> FactionDict
-> Time
-> ItemFull
-> ItemQuant
-> ([Text], Part, Part)
partItemHigh Int
width FactionId
side FactionDict
factionD =
Int
-> FactionId
-> FactionDict
-> Bool
-> DetailLevel
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> ([Text], Part, Part)
partItemN3 Int
width FactionId
side FactionDict
factionD Bool
False DetailLevel
DetailAll Int
100
partItemWsRanged :: Int -> FactionId -> FactionDict -> Bool -> DetailLevel
-> Int -> Int -> Time -> ItemFull -> ItemQuant
-> MU.Part
partItemWsRanged :: Int
-> FactionId
-> FactionDict
-> Bool
-> DetailLevel
-> Int
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> Part
partItemWsRanged Int
width FactionId
side FactionDict
factionD Bool
ranged DetailLevel
detail
Int
maxWordsToShow Int
count Time
localTime ItemFull
itemFull ItemQuant
kit =
let (Part
name, Part
powers) = Int
-> FactionId
-> FactionDict
-> Bool
-> DetailLevel
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> (Part, Part)
partItemN Int
width FactionId
side FactionDict
factionD Bool
ranged DetailLevel
detail
Int
maxWordsToShow Time
localTime ItemFull
itemFull ItemQuant
kit
arItem :: AspectRecord
arItem = ItemFull -> AspectRecord
aspectRecordFull ItemFull
itemFull
periodic :: Bool
periodic = Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Periodic AspectRecord
arItem
condition :: Bool
condition = Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Condition AspectRecord
arItem
maxCount :: Int
maxCount = Dice -> Int
Dice.supDice (Dice -> Int) -> Dice -> Int
forall a b. (a -> b) -> a -> b
$ ItemKind -> Dice
IK.icount (ItemKind -> Dice) -> ItemKind -> Dice
forall a b. (a -> b) -> a -> b
$ ItemFull -> ItemKind
itemKind ItemFull
itemFull
in if | Bool
condition Bool -> Bool -> Bool
&& Int
count Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 -> [Part] -> Part
MU.Phrase [Part
name, Part
powers]
| Bool
condition Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
periodic Bool -> Bool -> Bool
&& Int
maxCount Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1 ->
let percent :: Int
percent = Int
100 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
count Int -> Int -> Int
forall a. Integral a => a -> a -> a
`divUp` Int
maxCount
amount :: Text
amount = Int -> Text
forall a. Show a => a -> Text
tshow Int
count Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"-strong"
Text -> Text -> Text
<+> Text
"(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
tshow Int
percent Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"%)"
in [Part] -> Part
MU.Phrase [Text -> Part
MU.Text Text
amount, Part
name, Part
powers]
| Bool
condition ->
[Part] -> Part
MU.Phrase [Text -> Part
MU.Text (Text -> Part) -> Text -> Part
forall a b. (a -> b) -> a -> b
$ Int -> Text
forall a. Show a => a -> Text
tshow Int
count Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"-fold", Part
name, Part
powers]
| Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Unique AspectRecord
arItem -> case Int
count of
Int
0 -> [Part] -> Part
MU.Phrase [Part
"none of", Part
name, Part
powers]
Int
1 -> [Part] -> Part
MU.Phrase [Part
name, Part
powers]
Int
_ -> [Part] -> Part
MU.Phrase [Int -> Part
MU.Car Int
count, Part
"of", Part -> Part
MU.Ws Part
name, Part
powers]
| Bool
otherwise -> [Part] -> Part
MU.Phrase [Int -> Part -> Part
MU.CarAWs Int
count Part
name, Part
powers]
partItemWsDetail :: DetailLevel
-> Int -> FactionId -> FactionDict -> Int -> Time -> ItemFull
-> ItemQuant
-> MU.Part
partItemWsDetail :: DetailLevel
-> Int
-> FactionId
-> FactionDict
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> Part
partItemWsDetail DetailLevel
DetailLow = \Int
_ FactionId
_ FactionDict
_ Int
_ Time
_ ItemFull
_ ItemQuant
_ -> Part
""
partItemWsDetail DetailLevel
DetailMedium = Int
-> FactionId
-> FactionDict
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> Part
partItemWsShortest
partItemWsDetail DetailLevel
DetailHigh = Int
-> FactionId
-> FactionDict
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> Part
partItemWs
partItemWsDetail DetailLevel
DetailAll = Int
-> FactionId
-> FactionDict
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> Part
partItemWsLong
partItemWs :: Int -> FactionId -> FactionDict -> Int -> Time -> ItemFull
-> ItemQuant
-> MU.Part
partItemWs :: Int
-> FactionId
-> FactionDict
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> Part
partItemWs Int
width FactionId
side FactionDict
factionD =
Int
-> FactionId
-> FactionDict
-> Bool
-> DetailLevel
-> Int
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> Part
partItemWsRanged Int
width FactionId
side FactionDict
factionD Bool
False DetailLevel
DetailMedium Int
4
partItemWsShortest :: Int -> FactionId -> FactionDict -> Int -> Time -> ItemFull
-> ItemQuant
-> MU.Part
partItemWsShortest :: Int
-> FactionId
-> FactionDict
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> Part
partItemWsShortest Int
width FactionId
side FactionDict
factionD =
Int
-> FactionId
-> FactionDict
-> Bool
-> DetailLevel
-> Int
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> Part
partItemWsRanged Int
width FactionId
side FactionDict
factionD Bool
False DetailLevel
DetailLow Int
1
partItemWsShort :: Int -> FactionId -> FactionDict -> Int -> Time -> ItemFull
-> ItemQuant
-> MU.Part
partItemWsShort :: Int
-> FactionId
-> FactionDict
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> Part
partItemWsShort Int
width FactionId
side FactionDict
factionD =
Int
-> FactionId
-> FactionDict
-> Bool
-> DetailLevel
-> Int
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> Part
partItemWsRanged Int
width FactionId
side FactionDict
factionD Bool
False DetailLevel
DetailLow Int
4
partItemWsLong :: Int -> FactionId -> FactionDict -> Int -> Time -> ItemFull
-> ItemQuant
-> MU.Part
partItemWsLong :: Int
-> FactionId
-> FactionDict
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> Part
partItemWsLong Int
width FactionId
side FactionDict
factionD =
Int
-> FactionId
-> FactionDict
-> Bool
-> DetailLevel
-> Int
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> Part
partItemWsRanged Int
width FactionId
side FactionDict
factionD Bool
False DetailLevel
DetailHigh Int
100
partItemShortAW :: Int -> FactionId -> FactionDict -> Time -> ItemFull
-> ItemQuant
-> MU.Part
partItemShortAW :: Int
-> FactionId
-> FactionDict
-> Time
-> ItemFull
-> ItemQuant
-> Part
partItemShortAW Int
width FactionId
side FactionDict
factionD Time
localTime ItemFull
itemFull ItemQuant
kit =
let (Part
name, Part
_) = Int
-> FactionId
-> FactionDict
-> Time
-> ItemFull
-> ItemQuant
-> (Part, Part)
partItemShort Int
width FactionId
side FactionDict
factionD Time
localTime ItemFull
itemFull ItemQuant
kit
arItem :: AspectRecord
arItem = ItemFull -> AspectRecord
aspectRecordFull ItemFull
itemFull
in if Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Unique AspectRecord
arItem then Part
name else Part -> Part
MU.AW Part
name
partItemMediumAW :: Int -> FactionId -> FactionDict -> Time -> ItemFull
-> ItemQuant
-> MU.Part
partItemMediumAW :: Int
-> FactionId
-> FactionDict
-> Time
-> ItemFull
-> ItemQuant
-> Part
partItemMediumAW Int
width FactionId
side FactionDict
factionD Time
localTime ItemFull
itemFull ItemQuant
kit =
let (Part
name, Part
powers) =
Int
-> FactionId
-> FactionDict
-> Bool
-> DetailLevel
-> Int
-> Time
-> ItemFull
-> ItemQuant
-> (Part, Part)
partItemN Int
width FactionId
side FactionDict
factionD Bool
False DetailLevel
DetailMedium Int
100 Time
localTime
ItemFull
itemFull ItemQuant
kit
arItem :: AspectRecord
arItem = ItemFull -> AspectRecord
aspectRecordFull ItemFull
itemFull
phrase :: Part
phrase = [Part] -> Part
MU.Phrase [Part
name, Part
powers]
in if Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Unique AspectRecord
arItem then Part
phrase else Part -> Part
MU.AW Part
phrase
partItemShortWownW :: Int -> FactionId -> FactionDict -> MU.Part -> Time
-> ItemFull -> ItemQuant
-> MU.Part
partItemShortWownW :: Int
-> FactionId
-> FactionDict
-> Part
-> Time
-> ItemFull
-> ItemQuant
-> Part
partItemShortWownW Int
width FactionId
side FactionDict
factionD Part
partA Time
localTime ItemFull
itemFull ItemQuant
kit =
let (Part
name, Part
_) = Int
-> FactionId
-> FactionDict
-> Time
-> ItemFull
-> ItemQuant
-> (Part, Part)
partItemShort Int
width FactionId
side FactionDict
factionD Time
localTime ItemFull
itemFull ItemQuant
kit
in Part -> Part -> Part
MU.WownW Part
partA Part
name
viewItem :: ItemFull -> Color.AttrCharW32
{-# INLINE viewItem #-}
viewItem :: ItemFull -> AttrCharW32
viewItem ItemFull
itemFull =
Color -> Char -> AttrCharW32
Color.attrChar2ToW32 (Flavour -> Color
flavourToColor (Flavour -> Color) -> Flavour -> Color
forall a b. (a -> b) -> a -> b
$ Item -> Flavour
jflavour (Item -> Flavour) -> Item -> Flavour
forall a b. (a -> b) -> a -> b
$ ItemFull -> Item
itemBase ItemFull
itemFull)
(Char -> Char
forall c. Char -> Char
displayContentSymbol (Char -> Char) -> Char -> Char
forall a b. (a -> b) -> a -> b
$ ItemKind -> Char
IK.isymbol (ItemKind -> Char) -> ItemKind -> Char
forall a b. (a -> b) -> a -> b
$ ItemFull -> ItemKind
itemKind ItemFull
itemFull)
viewItemBenefitColored :: DiscoveryBenefit -> ItemId -> ItemFull
-> Color.AttrCharW32
viewItemBenefitColored :: DiscoveryBenefit -> ItemId -> ItemFull -> AttrCharW32
viewItemBenefitColored DiscoveryBenefit
discoBenefit ItemId
iid ItemFull
itemFull =
let color :: Color
color = if Benefit -> Bool
benInEqp (DiscoveryBenefit
discoBenefit DiscoveryBenefit -> ItemId -> Benefit
forall k a. Enum k => EnumMap k a -> k -> a
EM.! ItemId
iid)
then Color
Color.BrGreen
else Color
Color.BrRed
in Color -> Char -> AttrCharW32
Color.attrChar2ToW32
Color
color (Char -> Char
forall c. Char -> Char
displayContentSymbol (Char -> Char) -> Char -> Char
forall a b. (a -> b) -> a -> b
$ ItemKind -> Char
IK.isymbol (ItemKind -> Char) -> ItemKind -> Char
forall a b. (a -> b) -> a -> b
$ ItemFull -> ItemKind
itemKind ItemFull
itemFull)
itemDesc :: Int -> Bool -> FactionId -> FactionDict -> Int -> CStore -> Time
-> LevelId -> ItemFull -> ItemQuant
-> AttrString
itemDesc :: Int
-> Bool
-> FactionId
-> FactionDict
-> Int
-> CStore
-> Time
-> LevelId
-> ItemFull
-> ItemQuant
-> AttrString
itemDesc Int
width Bool
markParagraphs FactionId
side FactionDict
factionD Int
aHurtMeleeOfOwner CStore
store Time
localTime
LevelId
jlid itemFull :: ItemFull
itemFull@ItemFull{Item
itemBase :: Item
itemBase :: ItemFull -> Item
itemBase, ItemKind
itemKind :: ItemKind
itemKind :: ItemFull -> ItemKind
itemKind, ItemDisco
itemDisco :: ItemDisco
itemDisco :: ItemFull -> ItemDisco
itemDisco, Bool
itemSuspect :: Bool
itemSuspect :: ItemFull -> Bool
itemSuspect}
ItemQuant
kit =
let ([Text]
orTs, Part
name, Part
powers) =
Int
-> FactionId
-> FactionDict
-> Time
-> ItemFull
-> ItemQuant
-> ([Text], Part, Part)
partItemHigh Int
width FactionId
side FactionDict
factionD Time
localTime ItemFull
itemFull ItemQuant
kit
arItem :: AspectRecord
arItem = ItemFull -> AspectRecord
aspectRecordFull ItemFull
itemFull
npowers :: Text
npowers = [Part] -> Text
makePhrase [Part
name, Part
powers]
IK.ThrowMod{Int
throwVelocity :: Int
throwVelocity :: ThrowMod -> Int
IK.throwVelocity, Int
throwLinger :: ThrowMod -> Int
throwLinger :: Int
IK.throwLinger} = AspectRecord -> ThrowMod
IA.aToThrow AspectRecord
arItem
speed :: Speed
speed = Int -> Int -> Speed
speedFromWeight (ItemKind -> Int
IK.iweight ItemKind
itemKind) Int
throwVelocity
range :: Int
range = Speed -> Int -> Int
rangeFromSpeedAndLinger Speed
speed Int
throwLinger
tspeed :: Text
tspeed | Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Condition AspectRecord
arItem
Bool -> Bool -> Bool
|| ItemKind -> Int
IK.iweight ItemKind
itemKind Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Text
""
| Speed
speed Speed -> Speed -> Bool
forall a. Ord a => a -> a -> Bool
< Speed
speedLimp = Text
"When thrown, it drops at once."
| Speed
speed Speed -> Speed -> Bool
forall a. Ord a => a -> a -> Bool
< Speed
speedWalk = Text
"When thrown, it drops after one meter."
| Bool
otherwise =
Text
"Can be thrown at"
Text -> Text -> Text
<+> [Char] -> Text
T.pack (Int -> [Char]
displaySpeed (Int -> [Char]) -> Int -> [Char]
forall a b. (a -> b) -> a -> b
$ Speed -> Int
fromSpeed Speed
speed)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> if Int
throwLinger Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
100
then Text
" dropping after" Text -> Text -> Text
<+> Int -> Text
forall a. Show a => a -> Text
tshow Int
range Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"m."
else Text
"."
tsuspect :: [Text]
tsuspect = [Text
"You are unsure what it does." | Bool
itemSuspect]
(Text
desc, Text
aspectSentences, Text
damageAnalysis) =
let aspects :: [Aspect]
aspects = case ItemDisco
itemDisco of
ItemDiscoMean IA.KindMean{Bool
AspectRecord
kmMean :: AspectRecord
kmConst :: Bool
kmMean :: KindMean -> AspectRecord
kmConst :: KindMean -> Bool
..} | Bool
kmConst ->
AspectRecord -> [Aspect]
IA.aspectRecordToList AspectRecord
kmMean
ItemDiscoMean{} -> ItemKind -> [Aspect]
IK.iaspects ItemKind
itemKind
ItemDiscoFull AspectRecord
iAspect -> AspectRecord -> [Aspect]
IA.aspectRecordToList AspectRecord
iAspect
sentences :: [Text]
sentences = [Text]
tsuspect [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ (Aspect -> Maybe Text) -> [Aspect] -> [Text]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Aspect -> Maybe Text
aspectToSentence [Aspect]
aspects
aHurtMeleeOfItem :: Int
aHurtMeleeOfItem = Skill -> AspectRecord -> Int
IA.getSkill Skill
Ability.SkHurtMelee AspectRecord
arItem
meanDmg :: Int
meanDmg = Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Double -> Int) -> Double -> Int
forall a b. (a -> b) -> a -> b
$ Dice -> Double
Dice.meanDice (ItemKind -> Dice
IK.idamage ItemKind
itemKind)
dmgAn :: Text
dmgAn = if Int
meanDmg Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 then Text
"" else
let multRaw :: Int
multRaw = Int
aHurtMeleeOfOwner
Int -> Int -> Int
forall a. Num a => a -> a -> a
+ if CStore
store CStore -> [CStore] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [CStore
CEqp, CStore
COrgan]
then Int
0
else Int
aHurtMeleeOfItem
mult :: Int
mult = Int
100 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
100 (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max (-Int
95) Int
multRaw)
percentDeltaHP :: Int64
percentDeltaHP = Int -> Int64
xM Int
meanDmg Int64 -> Int64 -> Int64
forall a. Integral a => a -> a -> a
`divUp` Int64
100
rawDeltaHP :: Int64
rawDeltaHP = Int -> Int64
forall target source. From source target => source -> target
into @Int64 Int
mult Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
* Int64
percentDeltaHP
pmult :: Int
pmult = Int
100 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
100 (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max (-Int
95) Int
aHurtMeleeOfItem)
prawDeltaHP :: Int64
prawDeltaHP = Int -> Int64
forall target source. From source target => source -> target
into @Int64 Int
pmult Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
* Int64
percentDeltaHP
pdeltaHP :: Int64
pdeltaHP = Int64 -> Speed -> Int64
modifyDamageBySpeed Int64
prawDeltaHP Speed
speed
minDeltaHP :: Int64
minDeltaHP = Int64
5 Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
* Int64
percentDeltaHP
mDeltaHP :: Int64
mDeltaHP = Int64 -> Speed -> Int64
modifyDamageBySpeed Int64
minDeltaHP Speed
speed
in
Text
"Against defenceless foes you'd inflict around"
Text -> Text -> Text
<+> Int -> Text
forall a. Show a => a -> Text
tshow Int
meanDmg
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"*" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
tshow Int
mult Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"%"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"=" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int64 -> Text
show64With2 Int64
rawDeltaHP
Text -> Text -> Text
<+> Text
"melee damage (min" Text -> Text -> Text
<+> Int64 -> Text
show64With2 Int64
minDeltaHP Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
Text -> Text -> Text
<+> (if Int64
pdeltaHP Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
0 then Text
"" else
Text
"and"
Text -> Text -> Text
<+> Int -> Text
forall a. Show a => a -> Text
tshow Int
meanDmg
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"*" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
tshow Int
pmult Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"%"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"*" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"speed^2"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
tshow (Speed -> Int
fromSpeed Speed
speedThrust
Int -> Int -> Int
forall a. Integral a => a -> a -> a
`divUp` Int
10) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"^2"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"=" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int64 -> Text
show64With2 Int64
pdeltaHP
Text -> Text -> Text
<+> Text
"ranged damage (min" Text -> Text -> Text
<+> Int64 -> Text
show64With2 Int64
mDeltaHP Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")")
Text -> Text -> Text
<+> Text
"with it"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> if Dice -> Int
Dice.infDice (ItemKind -> Dice
IK.idamage ItemKind
itemKind)
Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Dice -> Int
Dice.supDice (ItemKind -> Dice
IK.idamage ItemKind
itemKind)
then Text
"."
else Text
"on average."
in (ItemKind -> Text
IK.idesc ItemKind
itemKind, Text -> [Text] -> Text
T.intercalate Text
" " [Text]
sentences, Text
tspeed Text -> Text -> Text
<+> Text
dmgAn)
weight :: Int
weight = ItemKind -> Int
IK.iweight ItemKind
itemKind
(Text
scaledWeight, Part
unitWeight)
| Int
weight Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1000 =
(Double -> Text
forall a. Show a => a -> Text
tshow (Double -> Text) -> Double -> Text
forall a b. (a -> b) -> a -> b
$ Int -> Double
intToDouble Int
weight Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
1000, Part
"kg")
| Bool
otherwise = (Int -> Text
forall a. Show a => a -> Text
tshow Int
weight, Part
"g")
onLevel :: Text
onLevel = Text
"on level" Text -> Text -> Text
<+> Int -> Text
forall a. Show a => a -> Text
tshow (Int -> Int
forall a. Num a => a -> a
abs (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ LevelId -> Int
forall a. Enum a => a -> Int
fromEnum LevelId
jlid) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"."
discoFirst :: Text
discoFirst = (if Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Unique AspectRecord
arItem
then Text
"Discovered"
else Text
"First seen")
Text -> Text -> Text
<+> Text
onLevel
whose :: FactionId -> Text
whose FactionId
fid = Faction -> Text
gname (FactionDict
factionD FactionDict -> FactionId -> Faction
forall k a. Enum k => EnumMap k a -> k -> a
EM.! FactionId
fid)
sourceDesc :: Text
sourceDesc =
case Item -> Maybe FactionId
jfid Item
itemBase of
Just FactionId
fid | Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Condition AspectRecord
arItem ->
Text
"Caused by" Text -> Text -> Text
<+> (if FactionId
fid FactionId -> FactionId -> Bool
forall a. Eq a => a -> a -> Bool
== FactionId
side then Text
"us" else FactionId -> Text
whose FactionId
fid)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
". First observed" Text -> Text -> Text
<+> Text
onLevel
Just FactionId
fid ->
Text
"Coming from" Text -> Text -> Text
<+> FactionId -> Text
whose FactionId
fid
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"." Text -> Text -> Text
<+> Text
discoFirst
Maybe FactionId
_ -> Text
discoFirst
ikitToPart :: [(GroupName c, b)] -> Part
ikitToPart = Text -> Part
MU.Text (Text -> Part)
-> ([(GroupName c, b)] -> Text) -> [(GroupName c, b)] -> Part
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text] -> Text
T.intercalate Text
", " ([Text] -> Text)
-> ([(GroupName c, b)] -> [Text]) -> [(GroupName c, b)] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((GroupName c, b) -> Text) -> [(GroupName c, b)] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (GroupName c -> Text
forall c. GroupName c -> Text
displayGroupName (GroupName c -> Text)
-> ((GroupName c, b) -> GroupName c) -> (GroupName c, b) -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (GroupName c, b) -> GroupName c
forall a b. (a, b) -> a
fst)
([(GroupName ItemKind, CStore)]
ikitOrganNames, [(GroupName ItemKind, CStore)]
ikitOtherNames) =
((GroupName ItemKind, CStore) -> Bool)
-> [(GroupName ItemKind, CStore)]
-> ([(GroupName ItemKind, CStore)], [(GroupName ItemKind, CStore)])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition ((CStore -> CStore -> Bool
forall a. Eq a => a -> a -> Bool
== CStore
COrgan) (CStore -> Bool)
-> ((GroupName ItemKind, CStore) -> CStore)
-> (GroupName ItemKind, CStore)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (GroupName ItemKind, CStore) -> CStore
forall a b. (a, b) -> b
snd) ([(GroupName ItemKind, CStore)]
-> ([(GroupName ItemKind, CStore)],
[(GroupName ItemKind, CStore)]))
-> [(GroupName ItemKind, CStore)]
-> ([(GroupName ItemKind, CStore)], [(GroupName ItemKind, CStore)])
forall a b. (a -> b) -> a -> b
$ ItemKind -> [(GroupName ItemKind, CStore)]
IK.ikit ItemKind
itemKind
ikitDesc :: Text
ikitDesc | [(GroupName ItemKind, CStore)] -> Bool
forall a. [a] -> Bool
null [(GroupName ItemKind, CStore)]
ikitOrganNames = Text
""
| Bool
otherwise =
[Part] -> Text
makeSentence
[ Part
"the actor has organs of this kind:"
, [(GroupName ItemKind, CStore)] -> Part
forall c b. [(GroupName c, b)] -> Part
ikitToPart [(GroupName ItemKind, CStore)]
ikitOrganNames ]
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> if [(GroupName ItemKind, CStore)] -> Bool
forall a. [a] -> Bool
null [(GroupName ItemKind, CStore)]
ikitOtherNames
then Text
""
else Text
"\n\n"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Part] -> Text
makeSentence
[ Part
"the actor starts in possession of the following:"
, [(GroupName ItemKind, CStore)] -> Part
forall c b. [(GroupName c, b)] -> Part
ikitToPart [(GroupName ItemKind, CStore)]
ikitOtherNames ]
colorSymbol :: AttrCharW32
colorSymbol = ItemFull -> AttrCharW32
viewItem ItemFull
itemFull
blurb :: Text
blurb =
(((Text
" "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
npowers
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (if Bool
markParagraphs then Text
"\n\n" else Text
" ")
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> [Text] -> Text
T.intercalate Text
"\n\n" [Text]
orTs
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (if Bool
markParagraphs Bool -> Bool -> Bool
&& Bool -> Bool
not ([Text] -> Bool
forall a. [a] -> Bool
null [Text]
orTs) then Text
"\n\n" else Text
"")
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
desc
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (if Bool
markParagraphs Bool -> Bool -> Bool
&& Bool -> Bool
not (Text -> Bool
T.null Text
desc) then Text
"\n\n" else Text
""))
Text -> Text -> Text
<+> (if Int
weight Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
then [Part] -> Text
makeSentence
[Part
"Weighs around", Text -> Part
MU.Text Text
scaledWeight Part -> Part -> Part
forall a. Semigroup a => a -> a -> a
<> Part
unitWeight]
else Text
""))
Text -> Text -> Text
<+> Text
aspectSentences
Text -> Text -> Text
<+> Text
sourceDesc
Text -> Text -> Text
<+> Text
damageAnalysis)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (if Bool
markParagraphs Bool -> Bool -> Bool
&& Bool -> Bool
not (Text -> Bool
T.null Text
ikitDesc) then Text
"\n\n" else Text
"\n")
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
ikitDesc
in AttrCharW32
colorSymbol AttrCharW32 -> AttrString -> AttrString
forall a. a -> [a] -> [a]
: Text -> AttrString
textToAS Text
blurb