-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPlayer.hs
75 lines (57 loc) · 2.52 KB
/
Player.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
module Player(performSkills) where
import Data.List
import Types.World
import Helpers
import Random
import Messages
-- performSkills [Skill] and helper functions.
performSkills :: World -> World
performSkills w =
foldl' performSkill w indexedSkills
where
h = wHero w
skills = toList $ hSkillQueue h
index = [1..]
indexedSkills = zip index skills
performSkill :: World -> (Int, Skill) -> World
performSkill w (i,s)
| energyCost > hEnergy = w { wMessageBuffer = skillMessage FAT s h h:wMessageBuffer w}
| null targets = w' { wMessageBuffer = skillMessage (FAIL NoTarget) s h h:wMessageBuffer w} -- Drain energy on fail? yes? Use Turn? For now YES. (change w' -> w to change to NO)
| otherwise = w''
where
l = wLevel w
h = wHero w
energyCost = skillEnergyCost s h i
hEnergy = hCurrEnergy h
speedCost = skillSpeedCost s h
effects :: [SkillEffect]
effects = sEffect s
-- find all targets, attempt to apply skill effects on said targets. with a fold.
targets :: [Entity]
targets = sTarget s w
-- calculate world with updated nextMove and currEnergy (not used if out of energy.
w' = w { wHero = h { hCurrEnergy = hEnergy - energyCost, eNextMove = eSpeed h + speedCost }, wTimeElapsed = fromIntegral speedCost + wTimeElapsed w }
-- s is sent for constant parameters, foldl because there might be several effects.
w'' = foldl' applyEffect w' $ zip3 effects (repeat targets) (repeat s)
applyEffect :: World -> (SkillEffect, [Entity], Skill) -> World
applyEffect world (effect, targets, skill) =
case effect of
FinalConstant { } ->
foldl' applyEffectToTarget w' $ zip5 (repeat effect) (repeat skill) (repeat hitRoll) (repeat dmgRoll) targets
FinalScaling _ scale ->
let scaledDmg = round $ scale * fromIntegral dmgRoll
in foldl' applyEffectToTarget w' $ zip5 (repeat effect) (repeat skill) (repeat hitRoll) (repeat scaledDmg) targets
_ -> error "he"
where
h = wHero world
(hitRoll, g') = rollDie (eHitDie h) (wStdGen world)
(dmgRoll, g'') = rollDie (eDamageDie h) g'
w' = world { wStdGen = g'' }
applyEffectToTarget :: World -> (SkillEffect, Skill, Int, Int, Entity) -> World
applyEffectToTarget world (effect, skill, dmgRoll, hitRoll, targetEntity) =
func skill hitRoll evdRoll dmgRoll mit targetEntity w'
where
(evdRoll, g') = rollDie (eEvadeDie targetEntity) (wStdGen world)
mit = eMitigation targetEntity
w' = world { wStdGen = g' }
func = seFunc effect