module Game.LambdaHack.Client.Preferences
( totalUsefulness
#ifdef EXPOSE_INTERNAL
, effectToBenefit
, averageTurnValue, avgItemDelay, avgItemLife, durabilityMult
, organBenefit, recBenefit, fakeItem
, aspectToBenefit, capStat, aspectRecordToBenefit
#endif
) where
import Prelude ()
import Game.LambdaHack.Core.Prelude
import qualified Data.EnumMap.Strict as EM
import Game.LambdaHack.Common.Faction
import Game.LambdaHack.Common.Item
import qualified Game.LambdaHack.Common.ItemAspect as IA
import Game.LambdaHack.Common.Kind
import Game.LambdaHack.Common.Misc
import Game.LambdaHack.Common.Time
import Game.LambdaHack.Common.Types
import Game.LambdaHack.Content.ItemKind (ItemKind)
import qualified Game.LambdaHack.Content.ItemKind as IK
import Game.LambdaHack.Content.ModeKind
import qualified Game.LambdaHack.Core.Dice as Dice
import qualified Game.LambdaHack.Definition.Ability as Ability
import Game.LambdaHack.Definition.Defs
import Game.LambdaHack.Definition.Flavour
effectToBenefit :: COps -> FactionId -> FactionDict -> IK.Effect
-> (Double, Double)
effectToBenefit :: COps -> FactionId -> FactionDict -> Effect -> (Double, Double)
effectToBenefit COps
cops FactionId
fid FactionDict
factionD Effect
eff =
let delta :: b -> (b, b)
delta b
x = (b
x, b
x)
in case Effect
eff of
IK.Burn Dice
d -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (Double -> (Double, Double)) -> Double -> (Double, Double)
forall a b. (a -> b) -> a -> b
$ -(Double -> Double -> Double
forall a. Ord a => a -> a -> a
min Double
1000 (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Double
10 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Dice -> Double
Dice.meanDice Dice
d)
IK.Explode GroupName ItemKind
IK.S_SINGLE_SPARK -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (-Double
1)
IK.Explode GroupName ItemKind
IK.S_SPARK -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (-Double
9)
IK.Explode GroupName ItemKind
IK.S_FRAGRANCE -> (Double
1, -Double
5)
IK.Explode GroupName ItemKind
_ ->
Double -> (Double, Double)
forall b. b -> (b, b)
delta (-Double
50)
IK.RefillHP Int
p ->
Double -> (Double, Double)
forall b. b -> (b, b)
delta (Double -> (Double, Double)) -> Double -> (Double, Double)
forall a b. (a -> b) -> a -> b
$ if Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
then Double -> Double -> Double
forall a. Ord a => a -> a -> a
min Double
2000 (Double
20 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Int -> Double
intToDouble Int
p)
else Double -> Double -> Double
forall a. Ord a => a -> a -> a
max (-Double
1000) (Double
10 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Int -> Double
intToDouble Int
p)
IK.RefillCalm Int
p ->
( if Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
then Double -> Double -> Double
forall a. Ord a => a -> a -> a
min Double
100 (Int -> Double
intToDouble Int
p)
else if Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= -Int
5
then Double -> Double -> Double
forall a. Ord a => a -> a -> a
max (-Double
100) (Int -> Double
intToDouble Int
p)
else Double -> Double -> Double
forall a. Ord a => a -> a -> a
max (-Double
1500) (Double
15 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Int -> Double
intToDouble Int
p)
, if Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
then Double -> Double -> Double
forall a. Ord a => a -> a -> a
min Double
100 (Int -> Double
intToDouble Int
p)
else Double -> Double -> Double
forall a. Ord a => a -> a -> a
max (-Double
500) (Double
5 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Int -> Double
intToDouble Int
p) )
Effect
IK.Dominate -> (Double
0, -Double
100)
Effect
IK.Impress -> (Double
0, -Double
20)
Effect
IK.PutToSleep -> (-Double
10, -Double
50)
Effect
IK.Yell -> (-Double
1, -Double
2)
IK.Summon GroupName ItemKind
grp Dice
d ->
let ben :: Double
ben = Dice -> Double
Dice.meanDice Dice
d Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
200
fact :: Faction
fact = FactionDict
factionD FactionDict -> FactionId -> Faction
forall k a. Enum k => EnumMap k a -> k -> a
EM.! FactionId
fid
friendlyHasGrp :: FactionId -> Bool
friendlyHasGrp FactionId
fid2 =
FactionId -> Faction -> FactionId -> Bool
isFriend FactionId
fid Faction
fact FactionId
fid2
Bool -> Bool -> Bool
&& GroupName ItemKind
grp GroupName ItemKind -> [GroupName ItemKind] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` Player -> [GroupName ItemKind]
fgroups (Faction -> Player
gplayer (Faction -> Player) -> Faction -> Player
forall a b. (a -> b) -> a -> b
$ FactionDict
factionD FactionDict -> FactionId -> Faction
forall k a. Enum k => EnumMap k a -> k -> a
EM.! FactionId
fid2)
in
if (FactionId -> Bool) -> [FactionId] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any FactionId -> Bool
friendlyHasGrp ([FactionId] -> Bool) -> [FactionId] -> Bool
forall a b. (a -> b) -> a -> b
$ FactionDict -> [FactionId]
forall k a. Enum k => EnumMap k a -> [k]
EM.keys FactionDict
factionD
then (Double
ben, -Double
1)
else (-Double
ben Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
3, Double
1)
IK.Ascend{} -> (Double
0, Double
0)
IK.Escape{} -> (-Double
9999, Double
9999)
IK.Paralyze Dice
d -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (Double -> (Double, Double)) -> Double -> (Double, Double)
forall a b. (a -> b) -> a -> b
$ -Double
20 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Dice -> Double
Dice.meanDice Dice
d
IK.ParalyzeInWater Dice
d -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (Double -> (Double, Double)) -> Double -> (Double, Double)
forall a b. (a -> b) -> a -> b
$ -Double
10 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Dice -> Double
Dice.meanDice Dice
d
IK.InsertMove Dice
d -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (Double -> (Double, Double)) -> Double -> (Double, Double)
forall a b. (a -> b) -> a -> b
$ Double
10 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Dice -> Double
Dice.meanDice Dice
d
IK.Teleport{} -> (-Double
9, -Double
1)
IK.CreateItem Maybe Int
_ CStore
COrgan GroupName ItemKind
IK.CONDITION TimerDice
_ ->
(Double
1, -Double
1)
IK.CreateItem Maybe Int
_ CStore
COrgan GroupName ItemKind
grp TimerDice
timer ->
let turnTimer :: Double
turnTimer = Double
-> (Dice -> Double) -> (Dice -> Double) -> TimerDice -> Double
forall a. a -> (Dice -> a) -> (Dice -> a) -> TimerDice -> a
IK.foldTimer Double
1 Dice -> Double
Dice.meanDice Dice -> Double
Dice.meanDice TimerDice
timer
(Double
total, Int
count) = Double
-> GroupName ItemKind
-> COps
-> FactionId
-> FactionDict
-> (Double, Int)
organBenefit Double
turnTimer GroupName ItemKind
grp COps
cops FactionId
fid FactionDict
factionD
in Double -> (Double, Double)
forall b. b -> (b, b)
delta (Double -> (Double, Double)) -> Double -> (Double, Double)
forall a b. (a -> b) -> a -> b
$ Double
total Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Int -> Double
intToDouble Int
count
IK.CreateItem Maybe Int
_ CStore
_ GroupName ItemKind
IK.TREASURE TimerDice
_ -> (Double
100, Double
0)
IK.CreateItem Maybe Int
_ CStore
_ GroupName ItemKind
IK.COMMON_ITEM TimerDice
_ -> (Double
70, Double
0)
IK.CreateItem Maybe Int
_ CStore
_ GroupName ItemKind
IK.CRAWL_ITEM TimerDice
_ -> (Double
70, Double
0)
IK.CreateItem Maybe Int
_ CStore
_ GroupName ItemKind
IK.ANY_SCROLL TimerDice
_ -> (Double
50, Double
0)
IK.CreateItem Maybe Int
_ CStore
_ GroupName ItemKind
IK.ANY_GLASS TimerDice
_ -> (Double
75, Double
0)
IK.CreateItem Maybe Int
_ CStore
_ GroupName ItemKind
IK.ANY_POTION TimerDice
_ -> (Double
100, Double
0)
IK.CreateItem Maybe Int
_ CStore
_ GroupName ItemKind
IK.ANY_FLASK TimerDice
_ -> (Double
50, Double
0)
IK.CreateItem Maybe Int
_ CStore
_ GroupName ItemKind
IK.EXPLOSIVE TimerDice
_ -> (Double
50, Double
0)
IK.CreateItem Maybe Int
_ CStore
_ GroupName ItemKind
IK.ANY_JEWELRY TimerDice
_ -> (Double
100, Double
0)
IK.CreateItem Maybe Int
_ CStore
_ GroupName ItemKind
grp TimerDice
_ ->
let (Double
total, Int
count) = GroupName ItemKind
-> COps -> FactionId -> FactionDict -> (Double, Int)
recBenefit GroupName ItemKind
grp COps
cops FactionId
fid FactionDict
factionD
in (Double
total Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Int -> Double
intToDouble Int
count, Double
0)
IK.DestroyItem{} -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (-Double
10)
IK.ConsumeItems{} -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (-Double
10)
IK.DropItem Int
_ Int
_ CStore
COrgan GroupName ItemKind
IK.CONDITION ->
(Double
0, -Double
1)
IK.DropItem Int
ngroup Int
kcopy CStore
COrgan GroupName ItemKind
grp ->
let turnTimer :: Double
turnTimer = Double
20
(Double
total, Int
count) = Double
-> GroupName ItemKind
-> COps
-> FactionId
-> FactionDict
-> (Double, Int)
organBenefit Double
turnTimer GroupName ItemKind
grp COps
cops FactionId
fid FactionDict
factionD
boundBonus :: a -> p
boundBonus a
n = if a
n a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
forall a. Bounded a => a
maxBound then p
10 else p
0
in Double -> (Double, Double)
forall b. b -> (b, b)
delta (Double -> (Double, Double)) -> Double -> (Double, Double)
forall a b. (a -> b) -> a -> b
$ Int -> Double
forall a p. (Eq a, Bounded a, Num p) => a -> p
boundBonus Int
ngroup Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Int -> Double
forall a p. (Eq a, Bounded a, Num p) => a -> p
boundBonus Int
kcopy
Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
total Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Int -> Double
intToDouble Int
count
IK.DropItem{} -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (-Double
10)
IK.Recharge Int
n Dice
d -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (Double -> (Double, Double)) -> Double -> (Double, Double)
forall a b. (a -> b) -> a -> b
$ Int -> Double
intToDouble Int
n Double -> Double -> Double
forall a. Num a => a -> a -> a
* Dice -> Double
Dice.meanDice Dice
d Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
10
IK.Discharge Int
n Dice
d -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (Double -> (Double, Double)) -> Double -> (Double, Double)
forall a b. (a -> b) -> a -> b
$ - Int -> Double
intToDouble Int
n Double -> Double -> Double
forall a. Num a => a -> a -> a
* Dice -> Double
Dice.meanDice Dice
d Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
10
Effect
IK.PolyItem -> (Double
1, Double
0)
Effect
IK.RerollItem -> (Double
1, Double
0)
Effect
IK.DupItem -> (Double
1, Double
0)
Effect
IK.Identify -> (Double
1, Double
0)
IK.Detect DetectKind
IK.DetectAll Int
radius -> (Int -> Double
intToDouble Int
radius Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
2, Double
0)
IK.Detect DetectKind
IK.DetectLoot Int
radius -> (Int -> Double
intToDouble Int
radius Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
2, Double
0)
IK.Detect DetectKind
IK.DetectExit Int
radius -> (Int -> Double
intToDouble Int
radius Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
2, Double
0)
IK.Detect DetectKind
_ Int
radius -> (Int -> Double
intToDouble Int
radius, Double
0)
IK.SendFlying ThrowMod
_ -> (Double
0, -Double
1)
IK.PullActor ThrowMod
_ -> (Double
0, -Double
1)
IK.PushActor ThrowMod
_ -> (Double
0, -Double
100)
Effect
IK.ApplyPerfume -> Double -> (Double, Double)
forall b. b -> (b, b)
delta Double
0
IK.AtMostOneOf [Effect]
effs ->
let bs :: [(Double, Double)]
bs = (Effect -> (Double, Double)) -> [Effect] -> [(Double, Double)]
forall a b. (a -> b) -> [a] -> [b]
map (COps -> FactionId -> FactionDict -> Effect -> (Double, Double)
effectToBenefit COps
cops FactionId
fid FactionDict
factionD) [Effect]
effs
f :: (a, b) -> (a, b) -> (a, b)
f (a
self, b
foe) (a
accSelf, b
accFoe) = (a
self a -> a -> a
forall a. Num a => a -> a -> a
+ a
accSelf, b
foe b -> b -> b
forall a. Num a => a -> a -> a
+ b
accFoe)
(Double
effSelf, Double
effFoe) = ((Double, Double) -> (Double, Double) -> (Double, Double))
-> (Double, Double) -> [(Double, Double)] -> (Double, Double)
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (Double, Double) -> (Double, Double) -> (Double, Double)
forall a b. (Num a, Num b) => (a, b) -> (a, b) -> (a, b)
f (Double
0, Double
0) [(Double, Double)]
bs
in (Double
effSelf Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Int -> Double
intToDouble ([(Double, Double)] -> Int
forall a. [a] -> Int
length [(Double, Double)]
bs), Double
effFoe Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Int -> Double
intToDouble ([(Double, Double)] -> Int
forall a. [a] -> Int
length [(Double, Double)]
bs))
IK.OneOf [Effect]
effs ->
let bs :: [(Double, Double)]
bs = (Effect -> (Double, Double)) -> [Effect] -> [(Double, Double)]
forall a b. (a -> b) -> [a] -> [b]
map (COps -> FactionId -> FactionDict -> Effect -> (Double, Double)
effectToBenefit COps
cops FactionId
fid FactionDict
factionD) [Effect]
effs
f :: (a, b) -> (a, b) -> (a, b)
f (a
self, b
foe) (a
accSelf, b
accFoe) = (a
self a -> a -> a
forall a. Num a => a -> a -> a
+ a
accSelf, b
foe b -> b -> b
forall a. Num a => a -> a -> a
+ b
accFoe)
(Double
effSelf, Double
effFoe) = ((Double, Double) -> (Double, Double) -> (Double, Double))
-> (Double, Double) -> [(Double, Double)] -> (Double, Double)
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (Double, Double) -> (Double, Double) -> (Double, Double)
forall a b. (Num a, Num b) => (a, b) -> (a, b) -> (a, b)
f (Double
0, Double
0) [(Double, Double)]
bs
in (Double
effSelf Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Int -> Double
intToDouble ([(Double, Double)] -> Int
forall a. [a] -> Int
length [(Double, Double)]
bs), Double
effFoe Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Int -> Double
intToDouble ([(Double, Double)] -> Int
forall a. [a] -> Int
length [(Double, Double)]
bs))
IK.OnSmash Effect
_ -> Double -> (Double, Double)
forall b. b -> (b, b)
delta Double
0
IK.OnCombine Effect
eff1 -> COps -> FactionId -> FactionDict -> Effect -> (Double, Double)
effectToBenefit COps
cops FactionId
fid FactionDict
factionD Effect
eff1
IK.OnUser Effect
eff1 ->
let (Double
effSelf, Double
_) = COps -> FactionId -> FactionDict -> Effect -> (Double, Double)
effectToBenefit COps
cops FactionId
fid FactionDict
factionD Effect
eff1
in (Double
effSelf, - Double
effSelf)
Effect
IK.NopEffect -> Double -> (Double, Double)
forall b. b -> (b, b)
delta Double
0
IK.AndEffect Effect
eff1 Effect
_ -> COps -> FactionId -> FactionDict -> Effect -> (Double, Double)
effectToBenefit COps
cops FactionId
fid FactionDict
factionD Effect
eff1
IK.OrEffect Effect
eff1 Effect
_ -> COps -> FactionId -> FactionDict -> Effect -> (Double, Double)
effectToBenefit COps
cops FactionId
fid FactionDict
factionD Effect
eff1
IK.SeqEffect [Effect]
effs -> COps -> FactionId -> FactionDict -> [Effect] -> (Double, Double)
effectToBenefits COps
cops FactionId
fid FactionDict
factionD [Effect]
effs
IK.When Condition
_cond Effect
eff1 ->
COps -> FactionId -> FactionDict -> Effect -> (Double, Double)
effectToBenefit COps
cops FactionId
fid FactionDict
factionD Effect
eff1
IK.Unless Condition
_cond Effect
eff1 ->
COps -> FactionId -> FactionDict -> Effect -> (Double, Double)
effectToBenefit COps
cops FactionId
fid FactionDict
factionD Effect
eff1
IK.IfThenElse Condition
_cond Effect
eff1 Effect
_eff2 ->
COps -> FactionId -> FactionDict -> Effect -> (Double, Double)
effectToBenefit COps
cops FactionId
fid FactionDict
factionD Effect
eff1
IK.VerbNoLonger{} -> Double -> (Double, Double)
forall b. b -> (b, b)
delta Double
0
IK.VerbMsg{} -> Double -> (Double, Double)
forall b. b -> (b, b)
delta Double
0
IK.VerbMsgFail{} -> Double -> (Double, Double)
forall b. b -> (b, b)
delta Double
0
effectToBenefits :: COps -> FactionId -> FactionDict -> [IK.Effect]
-> (Double, Double)
effectToBenefits :: COps -> FactionId -> FactionDict -> [Effect] -> (Double, Double)
effectToBenefits COps
cops FactionId
fid FactionDict
factionD [Effect]
effs =
let effPairs :: [(Double, Double)]
effPairs = (Effect -> (Double, Double)) -> [Effect] -> [(Double, Double)]
forall a b. (a -> b) -> [a] -> [b]
map (COps -> FactionId -> FactionDict -> Effect -> (Double, Double)
effectToBenefit COps
cops FactionId
fid FactionDict
factionD) [Effect]
effs
f :: (a, b) -> (a, b) -> (a, b)
f (a
self, b
foe) (a
accSelf, b
accFoe) = (a
self a -> a -> a
forall a. Num a => a -> a -> a
+ a
accSelf, b
foe b -> b -> b
forall a. Num a => a -> a -> a
+ b
accFoe)
in ((Double, Double) -> (Double, Double) -> (Double, Double))
-> (Double, Double) -> [(Double, Double)] -> (Double, Double)
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (Double, Double) -> (Double, Double) -> (Double, Double)
forall a b. (Num a, Num b) => (a, b) -> (a, b) -> (a, b)
f (Double
0, Double
0) [(Double, Double)]
effPairs
averageTurnValue :: Double
averageTurnValue :: Double
averageTurnValue = Double
10
avgItemDelay :: Double
avgItemDelay :: Double
avgItemDelay = Double
3
avgItemLife :: Double
avgItemLife :: Double
avgItemLife = Double
30
durabilityMult :: Double
durabilityMult :: Double
durabilityMult = Double
avgItemLife Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
avgItemDelay
organBenefit :: Double -> GroupName ItemKind -> COps -> FactionId -> FactionDict
-> (Double, Int)
organBenefit :: Double
-> GroupName ItemKind
-> COps
-> FactionId
-> FactionDict
-> (Double, Int)
organBenefit Double
turnTimer GroupName ItemKind
grp cops :: COps
cops@COps{ContentData ItemKind
coitem :: COps -> ContentData ItemKind
coitem :: ContentData ItemKind
coitem} FactionId
fid FactionDict
factionD =
let f :: (Double, Int)
-> Int -> ContentId ItemKind -> ItemKind -> (Double, Int)
f (!Double
sacc, !Int
pacc) !Int
p ContentId ItemKind
_ !ItemKind
kind =
let count :: Double
count = Dice -> Double
Dice.meanDice (ItemKind -> Dice
IK.icount ItemKind
kind)
paspect :: Aspect -> Double
paspect Aspect
asp =
Int -> Double
intToDouble Int
p
Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
count Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
turnTimer
Double -> Double -> Double
forall a. Num a => a -> a -> a
* Aspect -> Double
aspectToBenefit Aspect
asp
peffect :: Effect -> Double
peffect Effect
eff =
Int -> Double
intToDouble Int
p
Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
count
Double -> Double -> Double
forall a. Num a => a -> a -> a
* (Double, Double) -> Double
forall a b. (a, b) -> a
fst (COps -> FactionId -> FactionDict -> Effect -> (Double, Double)
effectToBenefit COps
cops FactionId
fid FactionDict
factionD Effect
eff)
in ( Double
sacc Double -> Double -> Double
forall a. Num a => a -> a -> a
+ ([Double] -> Double
forall a. Num a => [a] -> a
sum ((Aspect -> Double) -> [Aspect] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map Aspect -> Double
paspect ([Aspect] -> [Double]) -> [Aspect] -> [Double]
forall a b. (a -> b) -> a -> b
$ ItemKind -> [Aspect]
IK.iaspects ItemKind
kind)
Double -> Double -> Double
forall a. Num a => a -> a -> a
+ [Double] -> Double
forall a. Num a => [a] -> a
sum ((Effect -> Double) -> [Effect] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map Effect -> Double
peffect ([Effect] -> [Double]) -> [Effect] -> [Double]
forall a b. (a -> b) -> a -> b
$ ItemKind -> [Effect]
IK.ieffects ItemKind
kind))
Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
averageTurnValue
, Int
pacc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
p )
in ContentData ItemKind
-> GroupName ItemKind
-> ((Double, Int)
-> Int -> ContentId ItemKind -> ItemKind -> (Double, Int))
-> (Double, Int)
-> (Double, Int)
forall a b.
ContentData a
-> GroupName a -> (b -> Int -> ContentId a -> a -> b) -> b -> b
ofoldlGroup' ContentData ItemKind
coitem GroupName ItemKind
grp (Double, Int)
-> Int -> ContentId ItemKind -> ItemKind -> (Double, Int)
f (Double
0, Int
0)
recBenefit :: GroupName ItemKind -> COps -> FactionId -> FactionDict
-> (Double, Int)
recBenefit :: GroupName ItemKind
-> COps -> FactionId -> FactionDict -> (Double, Int)
recBenefit GroupName ItemKind
grp cops :: COps
cops@COps{ContentData ItemKind
coitem :: ContentData ItemKind
coitem :: COps -> ContentData ItemKind
coitem, ItemSpeedup
coItemSpeedup :: COps -> ItemSpeedup
coItemSpeedup :: ItemSpeedup
coItemSpeedup} FactionId
fid FactionDict
factionD =
let f :: (Double, Int)
-> Int -> ContentId ItemKind -> ItemKind -> (Double, Int)
f (!Double
sacc, !Int
pacc) !Int
p !ContentId ItemKind
kindId !ItemKind
kind =
let km :: KindMean
km = ContentId ItemKind -> ItemSpeedup -> KindMean
getKindMean ContentId ItemKind
kindId ItemSpeedup
coItemSpeedup
recPickup :: Double
recPickup =
Benefit -> Double
benPickup (Benefit -> Double) -> Benefit -> Double
forall a b. (a -> b) -> a -> b
$ COps -> FactionId -> FactionDict -> ItemFull -> Benefit
totalUsefulness COps
cops FactionId
fid FactionDict
factionD
(ContentId ItemKind -> ItemKind -> KindMean -> ItemFull
fakeItem ContentId ItemKind
kindId ItemKind
kind KindMean
km)
in ( Double
sacc Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Dice -> Double
Dice.meanDice (ItemKind -> Dice
IK.icount ItemKind
kind) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
recPickup
, Int
pacc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
p )
in ContentData ItemKind
-> GroupName ItemKind
-> ((Double, Int)
-> Int -> ContentId ItemKind -> ItemKind -> (Double, Int))
-> (Double, Int)
-> (Double, Int)
forall a b.
ContentData a
-> GroupName a -> (b -> Int -> ContentId a -> a -> b) -> b -> b
ofoldlGroup' ContentData ItemKind
coitem GroupName ItemKind
grp (Double, Int)
-> Int -> ContentId ItemKind -> ItemKind -> (Double, Int)
f (Double
0, Int
0)
fakeItem :: ContentId IK.ItemKind -> IK.ItemKind -> IA.KindMean -> ItemFull
fakeItem :: ContentId ItemKind -> ItemKind -> KindMean -> ItemFull
fakeItem ContentId ItemKind
kindId ItemKind
kind KindMean
km =
let jkind :: ItemIdentity
jkind = ContentId ItemKind -> ItemIdentity
IdentityObvious ContentId ItemKind
kindId
jfid :: Maybe a
jfid = Maybe a
forall a. Maybe a
Nothing
jflavour :: Flavour
jflavour = Flavour
dummyFlavour
itemBase :: Item
itemBase = Item :: ItemIdentity -> Maybe FactionId -> Flavour -> Item
Item{Maybe FactionId
Flavour
ItemIdentity
forall a. Maybe a
jflavour :: Flavour
jfid :: Maybe FactionId
jkind :: ItemIdentity
jflavour :: Flavour
jfid :: forall a. Maybe a
jkind :: ItemIdentity
..}
itemDisco :: ItemDisco
itemDisco = KindMean -> ItemDisco
ItemDiscoMean KindMean
km
in Item
-> ContentId ItemKind -> ItemKind -> ItemDisco -> Bool -> ItemFull
ItemFull Item
itemBase ContentId ItemKind
kindId ItemKind
kind ItemDisco
itemDisco Bool
True
aspectToBenefit :: IK.Aspect -> Double
aspectToBenefit :: Aspect -> Double
aspectToBenefit Aspect
asp =
case Aspect
asp of
IK.Timeout{} -> Double
0
IK.AddSkill Skill
Ability.SkMove Dice
p -> Double -> Double
capStat (Dice -> Double
Dice.meanDice Dice
p) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
5
IK.AddSkill Skill
Ability.SkMelee Dice
p -> Double -> Double
capStat (Dice -> Double
Dice.meanDice Dice
p) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
5
IK.AddSkill Skill
Ability.SkDisplace Dice
p -> Double -> Double
capStat (Dice -> Double
Dice.meanDice Dice
p)
IK.AddSkill Skill
Ability.SkAlter Dice
p -> Double -> Double
capStat (Dice -> Double
Dice.meanDice Dice
p)
IK.AddSkill Skill
Ability.SkWait Dice
p -> Double -> Double
capStat (Dice -> Double
Dice.meanDice Dice
p)
IK.AddSkill Skill
Ability.SkMoveItem Dice
p -> Double -> Double
capStat (Dice -> Double
Dice.meanDice Dice
p)
IK.AddSkill Skill
Ability.SkProject Dice
p -> Double -> Double
capStat (Dice -> Double
Dice.meanDice Dice
p) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
2
IK.AddSkill Skill
Ability.SkApply Dice
p -> Double -> Double
capStat (Dice -> Double
Dice.meanDice Dice
p) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
2
IK.AddSkill Skill
Ability.SkSwimming Dice
p -> Dice -> Double
Dice.meanDice Dice
p
IK.AddSkill Skill
Ability.SkFlying Dice
p -> Dice -> Double
Dice.meanDice Dice
p
IK.AddSkill Skill
Ability.SkHurtMelee Dice
p -> Dice -> Double
Dice.meanDice Dice
p
IK.AddSkill Skill
Ability.SkArmorMelee Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
4
IK.AddSkill Skill
Ability.SkArmorRanged Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
4
IK.AddSkill Skill
Ability.SkMaxHP Dice
p -> Dice -> Double
Dice.meanDice Dice
p
IK.AddSkill Skill
Ability.SkMaxCalm Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
5
IK.AddSkill Skill
Ability.SkSpeed Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
25
IK.AddSkill Skill
Ability.SkSight Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
5
IK.AddSkill Skill
Ability.SkSmell Dice
p -> Dice -> Double
Dice.meanDice Dice
p
IK.AddSkill Skill
Ability.SkShine Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
2
IK.AddSkill Skill
Ability.SkNocto Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
30
IK.AddSkill Skill
Ability.SkHearing Dice
p -> Dice -> Double
Dice.meanDice Dice
p
IK.AddSkill Skill
Ability.SkAggression Dice
_ -> Double
0
IK.AddSkill Skill
Ability.SkOdor Dice
p -> - Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
4
IK.AddSkill Skill
Ability.SkDeflectRanged Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
100
IK.AddSkill Skill
Ability.SkDeflectMelee Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
100
IK.SetFlag{} -> Double
0
IK.ELabel{} -> Double
0
IK.ToThrow{} -> Double
0
IK.PresentAs{} -> Double
0
IK.EqpSlot{} -> Double
0
IK.Odds{} -> Double
0
capStat :: Double -> Double
capStat :: Double -> Double
capStat Double
x = Double -> Double -> Double
forall a. Ord a => a -> a -> a
max (-Double
10) (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double
forall a. Ord a => a -> a -> a
min Double
10 Double
x
aspectRecordToBenefit :: IA.AspectRecord -> [Double]
aspectRecordToBenefit :: AspectRecord -> [Double]
aspectRecordToBenefit AspectRecord
arItem =
(Aspect -> Double) -> [Aspect] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map Aspect -> Double
aspectToBenefit ([Aspect] -> [Double]) -> [Aspect] -> [Double]
forall a b. (a -> b) -> a -> b
$ AspectRecord -> [Aspect]
IA.aspectRecordToList AspectRecord
arItem
totalUsefulness :: COps -> FactionId -> FactionDict -> ItemFull -> Benefit
totalUsefulness :: COps -> FactionId -> FactionDict -> ItemFull -> Benefit
totalUsefulness COps
cops FactionId
fid FactionDict
factionD itemFull :: ItemFull
itemFull@ItemFull{ItemKind
itemKind :: ItemFull -> ItemKind
itemKind :: ItemKind
itemKind, Bool
itemSuspect :: ItemFull -> Bool
itemSuspect :: Bool
itemSuspect} =
let arItem :: AspectRecord
arItem = ItemFull -> AspectRecord
aspectRecordFull ItemFull
itemFull
periodic :: Bool
periodic = Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Periodic AspectRecord
arItem
timeout :: Double
timeout = Int -> Double
intToDouble (Int -> Double) -> Int -> Double
forall a b. (a -> b) -> a -> b
$ AspectRecord -> Int
IA.aTimeout AspectRecord
arItem
scalePeriodic :: Double -> Double
scalePeriodic Double
value = Double
value Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double -> Double -> Double
forall a. Ord a => a -> a -> a
max Double
1 Double
timeout
timeoutSqrt :: Double
timeoutSqrt = Double -> Double
forall a. Floating a => a -> a
sqrt (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double
forall a. Ord a => a -> a -> a
max Double
2 Double
timeout
scaleTimeout :: Double -> Double
scaleTimeout Double
v = Double
v Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
timeoutSqrt
(Double
effSelf, Double
effFoe) =
COps -> FactionId -> FactionDict -> [Effect] -> (Double, Double)
effectToBenefits COps
cops FactionId
fid FactionDict
factionD (ItemKind -> [Effect]
IK.ieffects ItemKind
itemKind)
durable :: Bool
durable = Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Durable AspectRecord
arItem
benApply :: Double
benApply = Double -> Double -> Double
forall a. Ord a => a -> a -> a
max Double
0 (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$
if Bool
periodic
then Double
0
else Double -> Double
scaleTimeout (Double
effSelf Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
effDice)
Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ if Bool
durable then Double
1 else Double
durabilityMult
effDice :: Double
effDice = - ItemKind -> Double
IK.damageUsefulness ItemKind
itemKind
benMelee :: Double
benMelee = if Bool
periodic
then Double
0
else Double
effFoe Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
effDice
benMeleeAvg :: Double
benMeleeAvg = Double -> Double
scaleTimeout Double
benMelee
Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ if Bool
durable then Double
1 else Double
durabilityMult
benFling :: Double
benFling = Double -> Double -> Double
forall a. Ord a => a -> a -> a
min Double
benFlingRaw (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ if Bool
itemSuspect then -Double
10 else Double
0
benFlingRaw :: Double
benFlingRaw = Double -> Double -> Double
forall a. Ord a => a -> a -> a
min Double
0 (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$
if Bool
periodic then Double
0 else Double
effFoe Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
benFlingDice
benFlingDice :: Double
benFlingDice | ItemKind -> Dice
IK.idamage ItemKind
itemKind Dice -> Dice -> Bool
forall a. Eq a => a -> a -> Bool
== Dice
0 = Double
0
| Bool
otherwise = Bool -> Double -> Double
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Double
v Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
<= Double
0) Double
v
where
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
v :: Double
v = - Int64 -> Double
int64ToDouble (Int64 -> Speed -> Int64
modifyDamageBySpeed Int64
rawDeltaHP Speed
speed) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
10 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double -> Double
xD Double
1
aspectBenefits :: [Double]
aspectBenefits = AspectRecord -> [Double]
aspectRecordToBenefit AspectRecord
arItem
eqpBens :: Double
eqpBens =
[Double] -> Double
forall a. Num a => [a] -> a
sum ([Double] -> Double) -> [Double] -> Double
forall a b. (a -> b) -> a -> b
$ [Double]
aspectBenefits [Double] -> [Double] -> [Double]
forall a. [a] -> [a] -> [a]
++ [Double -> Double
scalePeriodic (Double
effSelf Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
effDice) | Bool
periodic]
cripplingDrawback :: Bool
cripplingDrawback = Bool -> Bool
not ([Double] -> Bool
forall a. [a] -> Bool
null [Double]
aspectBenefits)
Bool -> Bool -> Bool
&& [Double] -> Double
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum [Double]
aspectBenefits Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< -Double
25
eqpSum :: Double
eqpSum = Double
eqpBens Double -> Double -> Double
forall a. Num a => a -> a -> a
- if Bool
cripplingDrawback then Double
100 else Double
0
vApplyFling :: Double
vApplyFling = Double -> Double -> Double
forall a. Ord a => a -> a -> a
max Double
benApply (- Double
benFling)
(Bool
benInEqp, Double
benPickupRaw)
| Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Meleeable AspectRecord
arItem
Bool -> Bool -> Bool
&& (Double
benMelee Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
0 Bool -> Bool -> Bool
|| Bool
itemSuspect)
Bool -> Bool -> Bool
&& Double
eqpSum Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
>= -Double
20 =
let vEqp :: Double
vEqp = Double
eqpSum Double -> Double -> Double
forall a. Num a => a -> a -> a
+ [Double] -> Double
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [Double
benApply, - Double
benMeleeAvg, Double
0]
v :: Double
v = if | Double
vEqp Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
0 -> Double
vEqp
| Double
vApplyFling Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
0 -> Double
vApplyFling
| Bool
otherwise -> Double
vEqp
in (Bool
True, Double
v)
| (AspectRecord -> Bool
IA.goesIntoEqp AspectRecord
arItem
Bool -> Bool -> Bool
|| Flag -> AspectRecord -> Bool
IA.checkFlag Flag
Ability.Condition AspectRecord
arItem)
Bool -> Bool -> Bool
&& (Double
eqpSum Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
0 Bool -> Bool -> Bool
|| Bool
itemSuspect) =
( Bool
True
, Double
eqpSum
Double -> Double -> Double
forall a. Num a => a -> a -> a
+ if Bool
durable
then Double
benApply
else Double
0)
| Bool
otherwise = (Bool
False, Double
vApplyFling)
benPickupRaw2 :: Double
benPickupRaw2 = Double -> Double -> Double
forall a. Ord a => a -> a -> a
max Double
benPickupRaw (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ if Bool
itemSuspect then Double
10 else Double
0
benPickup :: Double
benPickup = if Bool
periodic then Double -> Double -> Double
forall a. Ord a => a -> a -> a
max Double
1 Double
benPickupRaw2 else Double
benPickupRaw2
in Benefit :: Bool -> Double -> Double -> Double -> Double -> Benefit
Benefit{Bool
Double
benFling :: Double
benMelee :: Double
benApply :: Double
benInEqp :: Bool
benPickup :: Double
benInEqp :: Bool
benFling :: Double
benMelee :: Double
benApply :: Double
benPickup :: Double
..}