module Game.LambdaHack.Client.Preferences
( totalUsefulness
#ifdef EXPOSE_INTERNAL
, effectToBenefit
, averageTurnValue, avgItemDelay, avgItemLife, durabilityMult
, organBenefit, recBenefit, fakeItem, aspectToBenefit, 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 1500 (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ 15 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Dice -> Double
Dice.meanDice Dice
d)
IK.Explode "single spark" -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (-1)
IK.Explode "fragrance" -> (1, -5)
IK.Explode _ ->
Double -> (Double, Double)
forall b. b -> (b, b)
delta (-100)
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
forall a b. (Integral a, Num b) => a -> b
fromIntegral 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
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
p)
IK.RefillCalm 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 100 (Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral 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
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
p)
IK.Dominate -> (0, -100)
IK.Impress -> (0, -20)
IK.PutToSleep -> (10, -50)
IK.Yell -> (-5, -10)
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{} -> (-99, 99)
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 d :: Dice
d -> if Dice -> Double
Dice.meanDice Dice
d Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
<= 8
then (0, 0)
else (-9, -1)
IK.CreateItem COrgan "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
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
count
IK.CreateItem _ "treasure" _ -> (100, 0)
IK.CreateItem _ "common item" _ -> (70, 0)
IK.CreateItem _ "curious item" _ -> (70, 0)
IK.CreateItem _ "any scroll" _ -> (50, 0)
IK.CreateItem _ "any vial" _ -> (50, 0)
IK.CreateItem _ "potion" _ -> (50, 0)
IK.CreateItem _ "explosive" _ -> (50, 0)
IK.CreateItem _ "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
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
count, 0)
IK.DropItem _ _ COrgan "condition" ->
Double -> (Double, Double)
forall b. b -> (b, b)
delta 30
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
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
count
IK.DropItem{} -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (-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
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
radius Double -> Double -> Double
forall a. Num a => a -> a -> a
* 2, 0)
IK.Detect IK.DetectLoot radius :: Int
radius -> (Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
radius Double -> Double -> Double
forall a. Num a => a -> a -> a
* 2, 0)
IK.Detect IK.DetectExit radius :: Int
radius -> (Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
radius Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ 2, 0)
IK.Detect _ radius :: Int
radius -> (Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
radius, 0)
IK.SendFlying _ -> (0, -100)
IK.PushActor _ -> (0, -100)
IK.PullActor _ -> (0, -100)
IK.DropBestWeapon -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (Double -> (Double, Double)) -> Double -> (Double, Double)
forall a b. (a -> b) -> a -> b
$ -50
IK.ActivateInv ' ' -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (Double -> (Double, Double)) -> Double -> (Double, Double)
forall a b. (a -> b) -> a -> b
$ -200
IK.ActivateInv _ -> Double -> (Double, Double)
forall b. b -> (b, b)
delta (Double -> (Double, Double)) -> Double -> (Double, Double)
forall a b. (a -> b) -> a -> b
$ -50
IK.ApplyPerfume -> Double -> (Double, Double)
forall b. b -> (b, b)
delta 0
IK.OneOf efs :: [Effect]
efs ->
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]
efs
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
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([(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
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([(Double, Double)] -> Int
forall a. [a] -> Int
length [(Double, Double)]
bs))
IK.OnSmash _ -> Double -> (Double, Double)
forall b. b -> (b, b)
delta 0
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.Composite [] -> Double -> (Double, Double)
forall b. b -> (b, b)
delta 0
IK.Composite (eff1 :: Effect
eff1 : _) -> COps -> FactionId -> FactionDict -> Effect -> (Double, Double)
effectToBenefit COps
cops FactionId
fid FactionDict
factionD Effect
eff1
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
forall a b. (Integral a, Num b) => a -> b
fromIntegral 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
forall a b. (Integral a, Num b) => a -> b
fromIntegral 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 -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Num a => a -> a -> a
* 5
IK.AddSkill Ability.SkMelee p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Num a => a -> a -> a
* 5
IK.AddSkill Ability.SkDisplace p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Num a => a -> a -> a
* 5
IK.AddSkill Ability.SkAlter p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Num a => a -> a -> a
* 5
IK.AddSkill Ability.SkWait p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Num a => a -> a -> a
* 5
IK.AddSkill Ability.SkMoveItem p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Num a => a -> a -> a
* 5
IK.AddSkill Ability.SkProject p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Num a => a -> a -> a
* 5
IK.AddSkill Ability.SkApply p :: Dice
p -> Dice -> Double
Dice.meanDice Dice
p Double -> Double -> Double
forall a. Num a => a -> a -> a
* 5
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
/ 8
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
* 10
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
IK.SetFlag{} -> 0
IK.ELabel{} -> 0
IK.ToThrow{} -> 0
IK.HideAs{} -> 0
IK.EqpSlot{} -> 0
IK.Odds{} -> 0
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
forall a b. (Integral a, Num b) => a -> b
fromIntegral (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) =
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)
(ItemKind -> [Effect]
IK.ieffects ItemKind
itemKind)
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
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
forall a b. (Integral a, Num b) => a -> b
fromIntegral 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
forall a b. (Integral a, Num b) => a -> b
fromIntegral (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
< -20
eqpSum :: Double
eqpSum = Double
eqpBens Double -> Double -> Double
forall a. Num a => a -> a -> a
- if Bool
cripplingDrawback then 100 else 0
(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 =
( Bool
True
, 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] )
| (AspectRecord -> Bool
IA.goesIntoEqp AspectRecord
arItem
Bool -> Bool -> Bool
|| Maybe Int -> Bool
forall a. Maybe a -> Bool
isJust (GroupName ItemKind -> [(GroupName ItemKind, Int)] -> Maybe Int
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup "condition" ([(GroupName ItemKind, Int)] -> Maybe Int)
-> [(GroupName ItemKind, Int)] -> Maybe Int
forall a b. (a -> b) -> a -> b
$ ItemKind -> [(GroupName ItemKind, Int)]
IK.ifreq ItemKind
itemKind))
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 -> Double -> Double
forall a. Ord a => a -> a -> a
max Double
benApply (- Double
benFling))
benPickup :: Double
benPickup = 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
in $WBenefit :: Bool -> Double -> Double -> Double -> Double -> Benefit
Benefit{..}