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
cops fid :: FactionId
fid factionD :: FactionDict
factionD eff :: Effect
eff =
let delta :: b -> (b, b)
delta x :: b
x = (b
x, b
x)
in case Effect
eff of
IK.Burn d :: 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 1000 (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ 10 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Dice -> Double
Dice.meanDice Dice
d)
IK.Explode IK.S_SINGLE_SPARK -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (-1)
IK.Explode IK.S_SPARK -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (-9)
IK.Explode IK.S_FRAGRANCE -> (1, -5)
IK.Explode _ ->
Double -> (Double, Double)
forall b. b -> (b, b)
delta (-50)
IK.RefillHP p :: 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
> 0
then Double -> Double -> Double
forall a. Ord a => a -> a -> a
min 2000 (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 (-1000) (10 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Int -> Double
intToDouble Int
p)
IK.RefillCalm p :: Int
p ->
( if Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> 0
then Double -> Double -> Double
forall a. Ord a => a -> a -> a
min 100 (Int -> Double
intToDouble Int
p)
else if Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= -5
then Double -> Double -> Double
forall a. Ord a => a -> a -> a
max (-100) (Int -> Double
intToDouble Int
p)
else Double -> Double -> Double
forall a. Ord a => a -> a -> a
max (-1500) (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
> 0
then Double -> Double -> Double
forall a. Ord a => a -> a -> a
min 100 (Int -> Double
intToDouble Int
p)
else Double -> Double -> Double
forall a. Ord a => a -> a -> a
max (-500) (5 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Int -> Double
intToDouble Int
p) )
IK.Dominate -> (0, -100)
IK.Impress -> (0, -20)
IK.PutToSleep -> (-10, -50)
IK.Yell -> (-1, -2)
IK.Summon grp :: GroupName ItemKind
grp d :: Dice
d ->
let ben :: Double
ben = Dice -> Double
Dice.meanDice Dice
d Double -> Double -> Double
forall a. Num a => a -> a -> a
* 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 fid2 :: 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, -1)
else (-Double
ben Double -> Double -> Double
forall a. Num a => a -> a -> a
* 3, 1)
IK.Ascend{} -> (0, 0)
IK.Escape{} -> (-9999, 9999)
IK.Paralyze d :: Dice
d -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (Double -> (Double, Double)) -> Double -> (Double, Double)
forall a b. (a -> b) -> a -> b
$ -20 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Dice -> Double
Dice.meanDice Dice
d
IK.ParalyzeInWater d :: Dice
d -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (Double -> (Double, Double)) -> Double -> (Double, Double)
forall a b. (a -> b) -> a -> b
$ -10 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Dice -> Double
Dice.meanDice Dice
d
IK.InsertMove d :: Dice
d -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (Double -> (Double, Double)) -> Double -> (Double, Double)
forall a b. (a -> b) -> a -> b
$ 10 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Dice -> Double
Dice.meanDice Dice
d
IK.Teleport{} -> (-9, -1)
IK.CreateItem _ COrgan IK.CONDITION _ ->
(1, -1)
IK.CreateItem _ COrgan grp :: GroupName ItemKind
grp timer :: TimerDice
timer ->
let turnTimer :: Double
turnTimer = Double
-> (Dice -> Double) -> (Dice -> Double) -> TimerDice -> Double
forall a. a -> (Dice -> a) -> (Dice -> a) -> TimerDice -> a
IK.foldTimer 1 Dice -> Double
Dice.meanDice Dice -> Double
Dice.meanDice TimerDice
timer
(total :: Double
total, count :: 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 _ _ IK.TREASURE _ -> (100, 0)
IK.CreateItem _ _ IK.COMMON_ITEM _ -> (70, 0)
IK.CreateItem _ _ IK.CRAWL_ITEM _ -> (70, 0)
IK.CreateItem _ _ IK.ANY_SCROLL _ -> (50, 0)
IK.CreateItem _ _ IK.ANY_GLASS _ -> (75, 0)
IK.CreateItem _ _ IK.ANY_POTION _ -> (100, 0)
IK.CreateItem _ _ IK.ANY_FLASK _ -> (50, 0)
IK.CreateItem _ _ IK.EXPLOSIVE _ -> (50, 0)
IK.CreateItem _ _ IK.ANY_JEWELRY _ -> (100, 0)
IK.CreateItem _ _ grp :: GroupName ItemKind
grp _ ->
let (total :: Double
total, count :: 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, 0)
IK.DestroyItem{} -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (-10)
IK.ConsumeItems{} -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (-10)
IK.DropItem _ _ COrgan IK.CONDITION ->
(0, -1)
IK.DropItem ngroup :: Int
ngroup kcopy :: Int
kcopy COrgan grp :: GroupName ItemKind
grp ->
let turnTimer :: Double
turnTimer = 20
(total :: Double
total, count :: 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 n :: a
n = if a
n a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
forall a. Bounded a => a
maxBound then 10 else 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 (-10)
IK.Recharge n :: Int
n d :: 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
/ 10
IK.Discharge n :: Int
n d :: 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
/ 10
IK.PolyItem -> (1, 0)
IK.RerollItem -> (1, 0)
IK.DupItem -> (1, 0)
IK.Identify -> (1, 0)
IK.Detect IK.DetectAll radius :: Int
radius -> (Int -> Double
intToDouble Int
radius Double -> Double -> Double
forall a. Num a => a -> a -> a
* 2, 0)
IK.Detect IK.DetectLoot radius :: Int
radius -> (Int -> Double
intToDouble Int
radius Double -> Double -> Double
forall a. Num a => a -> a -> a
* 2, 0)
IK.Detect IK.DetectExit radius :: Int
radius -> (Int -> Double
intToDouble Int
radius Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ 2, 0)
IK.Detect _ radius :: Int
radius -> (Int -> Double
intToDouble Int
radius, 0)
IK.SendFlying _ -> (0, -1)
IK.PullActor _ -> (0, -1)
IK.PushActor _ -> (0, -100)
IK.ApplyPerfume -> Double -> (Double, Double)
forall b. b -> (b, b)
delta 0
IK.AtMostOneOf effs :: [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 (self :: a
self, foe :: b
foe) (accSelf :: a
accSelf, accFoe :: 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)
(effSelf :: Double
effSelf, effFoe :: 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 (0, 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 effs :: [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 (self :: a
self, foe :: b
foe) (accSelf :: a
accSelf, accFoe :: 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)
(effSelf :: Double
effSelf, effFoe :: 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 (0, 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 _ -> Double -> (Double, Double)
forall b. b -> (b, b)
delta 0
IK.OnCombine eff1 :: Effect
eff1 -> COps -> FactionId -> FactionDict -> Effect -> (Double, Double)
effectToBenefit COps
cops FactionId
fid FactionDict
factionD Effect
eff1
IK.OnUser eff1 :: Effect
eff1 ->
let (effSelf :: Double
effSelf, _) = COps -> FactionId -> FactionDict -> Effect -> (Double, Double)
effectToBenefit COps
cops FactionId
fid FactionDict
factionD Effect
eff1
in (Double
effSelf, - Double
effSelf)
IK.NopEffect -> Double -> (Double, Double)
forall b. b -> (b, b)
delta 0
IK.AndEffect eff1 :: Effect
eff1 _ -> COps -> FactionId -> FactionDict -> Effect -> (Double, Double)
effectToBenefit COps
cops FactionId
fid FactionDict
factionD Effect
eff1
IK.OrEffect eff1 :: Effect
eff1 _ -> COps -> FactionId -> FactionDict -> Effect -> (Double, Double)
effectToBenefit COps
cops FactionId
fid FactionDict
factionD Effect
eff1
IK.SeqEffect effs :: [Effect]
effs -> COps -> FactionId -> FactionDict -> [Effect] -> (Double, Double)
effectToBenefits COps
cops FactionId
fid FactionDict
factionD [Effect]
effs
IK.When _cond :: Condition
_cond eff1 :: Effect
eff1 ->
COps -> FactionId -> FactionDict -> Effect -> (Double, Double)
effectToBenefit COps
cops FactionId
fid FactionDict
factionD Effect
eff1
IK.Unless _cond :: Condition
_cond eff1 :: Effect
eff1 ->
COps -> FactionId -> FactionDict -> Effect -> (Double, Double)
effectToBenefit COps
cops FactionId
fid FactionDict
factionD Effect
eff1
IK.IfThenElse _cond :: Condition
_cond eff1 :: Effect
eff1 _eff2 :: 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 0
IK.VerbMsg{} -> Double -> (Double, Double)
forall b. b -> (b, b)
delta 0
IK.VerbMsgFail{} -> Double -> (Double, Double)
forall b. b -> (b, b)
delta 0
effectToBenefits :: COps -> FactionId -> FactionDict -> [IK.Effect]
-> (Double, Double)
effectToBenefits :: COps -> FactionId -> FactionDict -> [Effect] -> (Double, Double)
effectToBenefits cops :: COps
cops fid :: FactionId
fid factionD :: FactionDict
factionD effs :: [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 (self :: a
self, foe :: b
foe) (accSelf :: a
accSelf, accFoe :: 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 (0, 0) [(Double, Double)]
effPairs
averageTurnValue :: Double
averageTurnValue :: Double
averageTurnValue = 10
avgItemDelay :: Double
avgItemDelay :: Double
avgItemDelay = 3
avgItemLife :: Double
avgItemLife :: Double
avgItemLife = 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 turnTimer :: Double
turnTimer grp :: GroupName ItemKind
grp cops :: COps
cops@COps{ContentData ItemKind
coitem :: COps -> ContentData ItemKind
coitem :: ContentData ItemKind
coitem} fid :: FactionId
fid factionD :: FactionDict
factionD =
let f :: (Double, Int)
-> Int -> ContentId ItemKind -> ItemKind -> (Double, Int)
f (!Double
sacc, !Int
pacc) !Int
p _ !ItemKind
kind =
let count :: Double
count = Dice -> Double
Dice.meanDice (ItemKind -> Dice
IK.icount ItemKind
kind)
paspect :: Aspect -> Double
paspect asp :: 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 eff :: 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 (0, 0)
recBenefit :: GroupName ItemKind -> COps -> FactionId -> FactionDict
-> (Double, Int)
recBenefit :: GroupName ItemKind
-> COps -> FactionId -> FactionDict -> (Double, Int)
recBenefit grp :: GroupName ItemKind
grp cops :: COps
cops@COps{ContentData ItemKind
coitem :: ContentData ItemKind
coitem :: COps -> ContentData ItemKind
coitem, ItemSpeedup
coItemSpeedup :: COps -> ItemSpeedup
coItemSpeedup :: ItemSpeedup
coItemSpeedup} fid :: FactionId
fid factionD :: 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 (0, 0)
fakeItem :: ContentId IK.ItemKind -> IK.ItemKind -> IA.KindMean -> ItemFull
fakeItem :: ContentId ItemKind -> ItemKind -> KindMean -> ItemFull
fakeItem kindId :: ContentId ItemKind
kindId kind :: ItemKind
kind km :: 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 = FancyName -> Color -> Flavour
Flavour (Int -> FancyName
forall a. Enum a => Int -> a
toEnum 0) (Int -> Color
forall a. Enum a => Int -> a
toEnum 0)
itemBase :: Item
itemBase = $WItem :: ItemIdentity -> Maybe FactionId -> Flavour -> Item
Item{..}
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 asp :: Aspect
asp =
case Aspect
asp of
IK.Timeout{} -> 0
IK.AddSkill Ability.SkMove p :: Dice
p -> Double -> Double
capStat (Dice -> Double
Dice.meanDice Dice
p) Double -> Double -> Double
forall a. Num a => a -> a -> a
* 5
IK.AddSkill Ability.SkMelee p :: Dice
p -> Double -> Double
capStat (Dice -> Double
Dice.meanDice Dice
p) Double -> Double -> Double
forall a. Num a => a -> a -> a
* 5
IK.AddSkill Ability.SkDisplace p :: Dice
p -> Double -> Double
capStat (Dice -> Double
Dice.meanDice Dice
p)
IK.AddSkill Ability.SkAlter p :: Dice
p -> Double -> Double
capStat (Dice -> Double
Dice.meanDice Dice
p)
IK.AddSkill Ability.SkWait p :: Dice
p -> Double -> Double
capStat (Dice -> Double
Dice.meanDice Dice
p)
IK.AddSkill Ability.SkMoveItem p :: Dice
p -> Double -> Double
capStat (Dice -> Double
Dice.meanDice Dice
p)
IK.AddSkill Ability.SkProject p :: Dice
p -> Double -> Double
capStat (Dice -> Double
Dice.meanDice Dice
p) Double -> Double -> Double
forall a. Num a => a -> a -> a
* 2
IK.AddSkill Ability.SkApply p :: Dice
p -> Double -> Double
capStat (Dice -> Double
Dice.meanDice Dice
p) Double -> Double -> Double
forall a. Num a => a -> a -> a
* 2
IK.AddSkill Ability.SkSwimming p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p
IK.AddSkill Ability.SkFlying p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p
IK.AddSkill Ability.SkHurtMelee p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p
IK.AddSkill Ability.SkArmorMelee p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ 4
IK.AddSkill Ability.SkArmorRanged p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ 4
IK.AddSkill Ability.SkMaxHP p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p
IK.AddSkill Ability.SkMaxCalm p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ 5
IK.AddSkill Ability.SkSpeed p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Num a => a -> a -> a
* 25
IK.AddSkill Ability.SkSight p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Num a => a -> a -> a
* 5
IK.AddSkill Ability.SkSmell p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p
IK.AddSkill Ability.SkShine p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Num a => a -> a -> a
* 2
IK.AddSkill Ability.SkNocto p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Num a => a -> a -> a
* 30
IK.AddSkill Ability.SkHearing p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p
IK.AddSkill Ability.SkAggression _ -> 0
IK.AddSkill Ability.SkOdor p :: Dice
p -> - Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ 4
IK.AddSkill Ability.SkDeflectRanged p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Num a => a -> a -> a
* 100
IK.AddSkill Ability.SkDeflectMelee p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Num a => a -> a -> a
* 100
IK.SetFlag{} -> 0
IK.ELabel{} -> 0
IK.ToThrow{} -> 0
IK.PresentAs{} -> 0
IK.EqpSlot{} -> 0
IK.Odds{} -> 0
capStat :: Double -> Double
capStat :: Double -> Double
capStat x :: Double
x = Double -> Double -> Double
forall a. Ord a => a -> a -> a
max (-10) (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double
forall a. Ord a => a -> a -> a
min 10 Double
x
aspectRecordToBenefit :: IA.AspectRecord -> [Double]
aspectRecordToBenefit :: AspectRecord -> [Double]
aspectRecordToBenefit arItem :: 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
cops fid :: FactionId
fid factionD :: 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 value :: 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 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 2 Double
timeout
scaleTimeout :: Double -> Double
scaleTimeout v :: Double
v = Double
v Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
timeoutSqrt
(effSelf :: Double
effSelf, effFoe :: 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 0 (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$
if Bool
periodic
then 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 1 else Double
durabilityMult
effDice :: Double
effDice = - ItemKind -> Double
IK.damageUsefulness ItemKind
itemKind
benMelee :: Double
benMelee = if Bool
periodic
then 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 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 -10 else 0
benFlingRaw :: Double
benFlingRaw = Double -> Double -> Double
forall a. Ord a => a -> a -> a
min 0 (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$
if Bool
periodic then 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
== 0 = 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
<= 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
/ 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
* 10 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double -> Double
xD 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
< -25
eqpSum :: Double
eqpSum = Double
eqpBens Double -> Double -> Double
forall a. Num a => a -> a -> a
- if Bool
cripplingDrawback then 100 else 0
vApplyFling :: Double
vApplyFling = Double -> Double -> Double
forall a. Ord a => a -> a -> a
max Double
benApply (- Double
benFling)
(benInEqp :: Bool
benInEqp, benPickupRaw :: 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
< 0 Bool -> Bool -> Bool
|| Bool
itemSuspect)
Bool -> Bool -> Bool
&& Double
eqpSum Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
>= -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, 0]
v :: Double
v = if | Double
vEqp Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> 0 -> Double
vEqp
| Double
vApplyFling Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> 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
> 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 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 10 else 0
benPickup :: Double
benPickup = if Bool
periodic then Double -> Double -> Double
forall a. Ord a => a -> a -> a
max 1 Double
benPickupRaw2 else Double
benPickupRaw2
in $WBenefit :: Bool -> Double -> Double -> Double -> Double -> Benefit
Benefit{..}