summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2016-06-10 02:14:31 +0200
committerGregor Kleen <gkleen@yggdrasil.li>2016-06-10 02:14:31 +0200
commit736e78441ae8b0cffa610de4baa7248f726cf69c (patch)
tree31a0bfec2f2df5e8e483553ae005012110e6cfd6 /src
parent85486c4838e23ca6d8b643c759d4e2a3035ef61d (diff)
download2017-01-16_17:13:37-736e78441ae8b0cffa610de4baa7248f726cf69c.tar
2017-01-16_17:13:37-736e78441ae8b0cffa610de4baa7248f726cf69c.tar.gz
2017-01-16_17:13:37-736e78441ae8b0cffa610de4baa7248f726cf69c.tar.bz2
2017-01-16_17:13:37-736e78441ae8b0cffa610de4baa7248f726cf69c.tar.xz
2017-01-16_17:13:37-736e78441ae8b0cffa610de4baa7248f726cf69c.zip
refactoring & combat rounds
Diffstat (limited to 'src')
-rw-r--r--src/Main.hs24
-rw-r--r--src/Sequence/Contact/Archetypes.hs59
-rw-r--r--src/Sequence/Contact/Types.hs66
-rw-r--r--src/Sequence/Contact/Types/Internal.hs22
-rw-r--r--src/Sequence/Types.hs52
5 files changed, 157 insertions, 66 deletions
diff --git a/src/Main.hs b/src/Main.hs
index b7c6a6e..f46fd3e 100644
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -32,6 +32,7 @@ import Data.Bool
32import Data.Function 32import Data.Function
33 33
34import Control.Monad.State.Strict 34import Control.Monad.State.Strict
35import Control.Monad.Trans.Maybe
35 36
36import Sequence.Types 37import Sequence.Types
37import Sequence.Contact.Types 38import Sequence.Contact.Types
@@ -92,11 +93,11 @@ stateOutline st
92 faction id = fromJust $ view eFaction <$> Map.lookup id (st ^. gEntities) 93 faction id = fromJust $ view eFaction <$> Map.lookup id (st ^. gEntities)
93 factionIndex id = fromJust $ elemIndex (view faction' $ faction id) factions 94 factionIndex id = fromJust $ elemIndex (view faction' $ faction id) factions
94 rowGs = do 95 rowGs = do
95 rowGroup'@((review seqVal' -> seqVal, _):_) <- protoRows 96 rowGroup'@((seq, _):_) <- protoRows
96 let 97 let
97 rowGroup = map snd rowGroup' 98 rowGroup = map snd rowGroup'
98 factionColumn i = [evalState ?? st $ toName x | x <- rowGroup, factionIndex x == i ] 99 factionColumn i = [evalState ?? st $ toName x | x <- rowGroup, factionIndex x == i ]
99 return . colsAllG top $ [seqVal] : map factionColumn [0..(length factions - 1)] 100 return . colsAllG top $ [show $ view seqVal seq] : map factionColumn [0..(length factions - 1)]
100 101
101-- Query state 102-- Query state
102listFactions, listEntities :: Sh GameState () 103listFactions, listEntities :: Sh GameState ()
@@ -195,12 +196,13 @@ factionSeqVal :: Completable Faction -> Sh GameState ()
195factionSeqVal = withArg $ \qFaction -> use gEntities >>= mapM_ (entitySeqVal') . Map.keys . Map.filter ((==) qFaction . view eFaction) 196factionSeqVal = withArg $ \qFaction -> use gEntities >>= mapM_ (entitySeqVal') . Map.keys . Map.filter ((==) qFaction . view eFaction)
196 197
197entitySeqVal' :: EntityIdentifier -> Sh GameState () 198entitySeqVal' :: EntityIdentifier -> Sh GameState ()
198entitySeqVal' ident = do 199entitySeqVal' ident = void . runMaybeT $ do
199 entity <- preuse (gEntities . ix ident) 200 entity <- MaybeT $ preuse (gEntities . ix ident)
200 let sVal = preview (eStats . sSeqVal) =<< entity 201 sVal <- MaybeT . return $ preview (eStats . sSeqVal) entity
201 case (,) <$> entity <*> sVal of 202 name <- toName ident
202 Nothing -> return () 203 round <- use gRound
203 Just (entity, sVal) -> do 204 (newEntity, sNum) <- evalFormula name entity sVal
204 name <- toName ident 205 let val = Just $ def
205 (newEntity, view (seqVal . re _Just) -> val) <- evalFormula name entity sVal 206 & set seqRound round
206 gEntities . at ident .= Just (newEntity & set eSeqVal val) 207 & set seqVal (Just sNum)
208 gEntities . at ident .= Just (newEntity & set eSeqVal val)
diff --git a/src/Sequence/Contact/Archetypes.hs b/src/Sequence/Contact/Archetypes.hs
index 3e9b416..ff37fdb 100644
--- a/src/Sequence/Contact/Archetypes.hs
+++ b/src/Sequence/Contact/Archetypes.hs
@@ -4,6 +4,11 @@ module Sequence.Contact.Archetypes where
4 4
5import Control.Lens 5import Control.Lens
6 6
7import Control.Monad.Except
8import Control.Monad.State
9import Control.Monad.Trans
10import Control.Monad.Trans.Maybe
11
7import Sequence.Contact.Types 12import Sequence.Contact.Types
8import Sequence.Formula 13import Sequence.Formula
9 14
@@ -14,6 +19,8 @@ import Data.Map (Map)
14import qualified Data.Map as Map 19import qualified Data.Map as Map
15 20
16import Data.Default 21import Data.Default
22import Data.Maybe
23import Data.Ratio
17 24
18import Data.List 25import Data.List
19 26
@@ -37,6 +44,9 @@ archetypes = [ ("Mensch", human)
37 , ("Milizenschläger", milizenschlaeger) 44 , ("Milizenschläger", milizenschlaeger)
38 ] 45 ]
39 46
47cTable :: Ord v => [(Integer, Integer, v)] -> Table v
48cTable = Map.fromList . map (\(from, to, value) -> (value, (abs (to - from) + 1) % 100))
49
40 50
41human = Humanoid 51human = Humanoid
42 { _sAStrength = vStrength 52 { _sAStrength = vStrength
@@ -86,17 +96,48 @@ human = Humanoid
86 , _sPainTolerance = vMass `quot'` 2 + vWillpower 96 , _sPainTolerance = vMass `quot'` 2 + vWillpower
87 , _sFatigueTolerance = vWillpower `quot'` 2 + vEndurance 97 , _sFatigueTolerance = vWillpower `quot'` 2 + vEndurance
88 98
89 , _sHitzones = [ ("Kopf", 0.05) 99 , _sHitzones = cTable [ (1, 5, "Kopf")
90 , ("Torso", 0.49) 100 , (6, 54, "Torso")
91 , ("Rechter Arm", 0.08) 101 , (55, 62, "Rechter Arm")
92 , ("Linker Arm", 0.08) 102 , (63, 70, "Linker Arm")
93 , ("Unterleib", 0.10) 103 , (71, 80, "Unterleib")
94 , ("Rechtes Bein", 0.10) 104 , (81, 90, "Rechtes Bein")
95 , ("Linkes Bein", 0.10) 105 , (91, 100, "Linkes Bein")
96 ] 106 ]
97 , _sDamage = const 0
98 , _sArmor = const def 107 , _sArmor = const def
108 , _sCripple = fromJust . flip Map.lookup [ ("Kopf", def
109 & set seVal (sDamage' "Kopf" . to return)
110 & set seBar (sMaxVitality . mapping (scaled 0.5))
111 & set seEffect (cTable [ (1, 10, Effect "Tod" headshot)
112 , (11, 25, effect "Blind")
113 , (26, 35, effect "Blind, Rechts")
114 , (36, 45, effect "Blind, Links")
115 , (46, 75, effect "Taub")
116 , (76, 100, effect "Bewusstlos – 1w10 Runden")
117 ])
118 )
119 , ("Torso", def)
120 , ("Rechter Arm", def)
121 , ("Linker Arm", def)
122 , ("Unterleib", def)
123 , ("Rechtes Bein", def)
124 , ("Linkes Bein", def)
125 ]
126
127 , _sDamage = const 0
128 , _sFatigue = 0
129
130 , _sPainShock = def
131 , _sFatigueShock = def
99 } 132 }
133 where
134 headshot = runMaybeT $ do
135 maxVitality <- (MaybeT . preview $ ctx . sMaxVitality) >>= lift
136 currentDmg <- MaybeT . preview $ ctx . sDamage' "Kopf"
137 allDmg <- MaybeT . preview $ ctx . sTotalDamage
138 let dmg = currentDmg + (maxVitality - allDmg)
139 dmg' = if dmg >= 0 then dmg else 0
140 MaybeT . previews ctx $ set (sDamage' "Kopf") dmg'
100 141
101dog = Quadruped 142dog = Quadruped
102 { _sAStrength = vStrength 143 { _sAStrength = vStrength
diff --git a/src/Sequence/Contact/Types.hs b/src/Sequence/Contact/Types.hs
index cd1bc02..a0add1a 100644
--- a/src/Sequence/Contact/Types.hs
+++ b/src/Sequence/Contact/Types.hs
@@ -1,4 +1,4 @@
1{-# LANGUAGE TemplateHaskell, RecordWildCards, OverloadedStrings, OverloadedLists, ViewPatterns, RankNTypes, ImpredicativeTypes #-} 1{-# LANGUAGE TemplateHaskell, RecordWildCards, OverloadedStrings, OverloadedLists, ViewPatterns, RankNTypes, ImpredicativeTypes, FlexibleContexts #-}
2 2
3module Sequence.Contact.Types 3module Sequence.Contact.Types
4 ( module Sequence.Contact.Types 4 ( module Sequence.Contact.Types
@@ -22,6 +22,8 @@ import Data.String (IsString(..))
22import Data.Function (on) 22import Data.Function (on)
23import Data.Maybe 23import Data.Maybe
24import Data.Ratio 24import Data.Ratio
25import Data.List
26import Data.Ord
25 27
26import Control.Monad.Reader (ask) 28import Control.Monad.Reader (ask)
27import Control.Monad.State 29import Control.Monad.State
@@ -73,21 +75,36 @@ instance Default Modifier where
73 75
74makePrisms ''Effect 76makePrisms ''Effect
75 77
78effectName :: Lens' Effect String
79effectName = _Effect . _1 . iso CI.original CI.mk
80
76instance Eq Effect where 81instance Eq Effect where
77 (==) = (==) `on` (view $ _Effect . _1) 82 (==) = (==) `on` (view effectName)
78 83
79instance Ord Effect where 84instance Ord Effect where
80 compare = compare `on` (view $ _Effect . _1) 85 compare = compare `on` (view effectName)
81 86
82instance Default Effect where 87instance Default Effect where
83 def = Effect "" pure 88 def = Effect "" $ preview ctx
89
90effect :: String -> Effect
91effect str = def & set effectName str
92
93makePrisms ''SeqVal
94makeLenses ''SeqVal
95
96instance Default SeqVal where
97 def = SeqVal { _seqRound = 0
98 , _seqVal = Nothing
99 , _seqEpsilon = False
100 }
84 101
85makeLenses ''ShockEffect 102makeLenses ''ShockEffect
86 103
87instance Default ShockEffect where 104instance Default ShockEffect where
88 def = ShockEffect { _seApplied = False 105 def = ShockEffect { _seApplied = False
89 , _seVal = pure Nothing 106 , _seVal = ignored
90 , _seBar = pure Nothing 107 , _seBar = ignored
91 , _seEffect = def 108 , _seEffect = def
92 } 109 }
93 110
@@ -96,17 +113,23 @@ makeLenses ''Stats
96instance Default Stats where 113instance Default Stats where
97 def = Prop 114 def = Prop
98 { _sHitzones = [("Volumen", 1)] 115 { _sHitzones = [("Volumen", 1)]
116 , _sArmor = const def
117 , _sCripple = const def
118
99 , _sDamage = const 0 119 , _sDamage = const 0
100 , _sFatigue = 0 120 , _sFatigue = 0
101 , _sCripple = const def 121
102 , _sArmor = const def 122 , _sSequence = Nothing
123
124 , _sPainShock = def
125 , _sFatigueShock = def
103 126
104 , _sExtraSkills = [] 127 , _sExtraSkills = []
105 , _sModifiers = [] 128 , _sModifiers = []
106 } 129 }
107 130
108applyModifier :: String -> (Test -> FormulaM Stats Test) -> Effect 131applyModifier :: String -> (Test -> FormulaM Stats Test) -> Effect
109applyModifier effectName modifier = Effect (CI.mk effectName) $ return . apply 132applyModifier effectName modifier = Effect (CI.mk effectName) $ previews ctx apply
110 where 133 where
111 apply = sModifiers <>~ [Modifier (CI.mk $ effectName ++ " (modifier)") modifier] 134 apply = sModifiers <>~ [Modifier (CI.mk $ effectName ++ " (modifier)") modifier]
112 135
@@ -121,22 +144,33 @@ vCharisma = val sACharisma "Charisma?" True
121vPerception = val sAPerception "Wahrnehmung?" True 144vPerception = val sAPerception "Wahrnehmung?" True
122vWillpower = val sAWillpower "Entschlossenheit?" True 145vWillpower = val sAWillpower "Entschlossenheit?" True
123 146
124scaled :: (Real a, Fractional a, Integral b) => Ratio b -> Iso' a a 147scaled :: Ratio Int -> Iso' Int Int
125scaled (realToFrac -> ratio) = iso (* ratio) (/ ratio) 148scaled r = iso (\x -> floor $ x % 1 * r) (\x -> round $ x % 1 / r)
126 149
127sDamage' :: String -> Traversal' Stats Int 150sDamage' :: Hitzone -> Traversal' Stats Int
128sDamage' (view hitzone -> zone) = sDamage . ix zone 151sDamage' zone = sDamage . ix zone
129 152
130sCripple' :: String -> Traversal' Stats ShockEffect 153sCripple' :: Hitzone -> Traversal' Stats ShockEffect
131sCripple' (view hitzone -> zone) = sCripple . ix zone 154sCripple' zone = sCripple . ix zone
132 155
133sTotalDamage :: Lens' Stats Int 156sTotalDamage :: Lens' Stats Int
134sTotalDamage = lens retrieve undefined 157sTotalDamage = lens retrieve $ flip spread
135 where 158 where
136 retrieve = do 159 retrieve = do
137 hitzones <- Map.keys <$> view sHitzones 160 hitzones <- Map.keys <$> view sHitzones
138 damageMap <- view sDamage 161 damageMap <- view sDamage
139 return . sum $ pure damageMap <*> hitzones 162 return . sum $ pure damageMap <*> hitzones
163 spread dmg = execState $ do
164 hitzones <- Map.keys <$> use sHitzones
165 damageMap <- use sDamage
166 totalDamage <- use sTotalDamage
167 let dmg' = dmg - totalDamage
168 (d, r) = dmg' `divMod` length hitzones
169 min = snd $ (if dmg' < 0 then maximumBy else minimumBy) (compare `on` fst) [(damageMap zone, zone) | zone <- hitzones]
170 damageMap' z
171 | z == min = damageMap z + d + r
172 | otherwise = damageMap z + d
173 sDamage .= damageMap'
140 174
141sDead :: Fold Stats (FormulaM Stats Bool) 175sDead :: Fold Stats (FormulaM Stats Bool)
142sDead = folding $ do 176sDead = folding $ do
diff --git a/src/Sequence/Contact/Types/Internal.hs b/src/Sequence/Contact/Types/Internal.hs
index 9929801..7e9be2b 100644
--- a/src/Sequence/Contact/Types/Internal.hs
+++ b/src/Sequence/Contact/Types/Internal.hs
@@ -7,6 +7,7 @@ import Sequence.Formula (Formula, FormulaM, Table)
7import Data.Map (Map) 7import Data.Map (Map)
8import Data.Set (Set) 8import Data.Set (Set)
9import Data.Ratio 9import Data.Ratio
10import Data.Monoid
10 11
11import Control.Lens 12import Control.Lens
12 13
@@ -42,12 +43,19 @@ data Test = Test
42 43
43data Modifier = Modifier (CI String) (Test -> FormulaM Stats Test) 44data Modifier = Modifier (CI String) (Test -> FormulaM Stats Test)
44 45
45data Effect = Effect (CI String) (Stats -> FormulaM Stats Stats) 46data Effect = Effect (CI String) (FormulaM Stats (Maybe Stats))
47
48data SeqVal = SeqVal
49 { _seqRound :: Int
50 , _seqVal :: Maybe Int
51 , _seqEpsilon :: Bool
52 }
53 deriving (Show, Ord, Eq)
46 54
47data ShockEffect = ShockEffect 55data ShockEffect = ShockEffect
48 { _seApplied :: Bool 56 { _seApplied :: Bool
49 , _seVal :: FormulaM Stats (Maybe Int) 57 , _seVal :: Getting (First (Formula Stats)) Stats (Formula Stats)
50 , _seBar :: FormulaM Stats (Maybe Int) 58 , _seBar :: Getting (First (Formula Stats)) Stats (Formula Stats)
51 , _seEffect :: Table Effect 59 , _seEffect :: Table Effect
52 } 60 }
53 61
@@ -62,6 +70,8 @@ data Stats = Prop
62 , _sPainShock :: ShockEffect 70 , _sPainShock :: ShockEffect
63 , _sFatigueShock :: ShockEffect 71 , _sFatigueShock :: ShockEffect
64 72
73 , _sSequence :: Maybe SeqVal
74
65 , _sExtraSkills :: Map (CI String) (FormulaM Stats Test) 75 , _sExtraSkills :: Map (CI String) (FormulaM Stats Test)
66 , _sModifiers :: Set Modifier 76 , _sModifiers :: Set Modifier
67 } 77 }
@@ -120,6 +130,8 @@ data Stats = Prop
120 , _sDamage :: Hitzone -> Int 130 , _sDamage :: Hitzone -> Int
121 , _sFatigue :: Int 131 , _sFatigue :: Int
122 132
133 , _sSequence :: Maybe SeqVal
134
123 , _sPainShock :: ShockEffect 135 , _sPainShock :: ShockEffect
124 , _sFatigueShock :: ShockEffect 136 , _sFatigueShock :: ShockEffect
125 137
@@ -156,6 +168,8 @@ data Stats = Prop
156 , _sDamage :: Hitzone -> Int 168 , _sDamage :: Hitzone -> Int
157 , _sFatigue :: Int 169 , _sFatigue :: Int
158 170
171 , _sSequence :: Maybe SeqVal
172
159 , _sPainShock :: ShockEffect 173 , _sPainShock :: ShockEffect
160 , _sFatigueShock :: ShockEffect 174 , _sFatigueShock :: ShockEffect
161 175
@@ -192,6 +206,8 @@ data Stats = Prop
192 , _sDamage :: Hitzone -> Int 206 , _sDamage :: Hitzone -> Int
193 , _sFatigue :: Int 207 , _sFatigue :: Int
194 208
209 , _sSequence :: Maybe SeqVal
210
195 , _sPainShock :: ShockEffect 211 , _sPainShock :: ShockEffect
196 , _sFatigueShock :: ShockEffect 212 , _sFatigueShock :: ShockEffect
197 213
diff --git a/src/Sequence/Types.hs b/src/Sequence/Types.hs
index 02389a1..33bbc2a 100644
--- a/src/Sequence/Types.hs
+++ b/src/Sequence/Types.hs
@@ -3,11 +3,10 @@
3module Sequence.Types 3module Sequence.Types
4 ( GameState, gEntities, gEntityNames, gFocus, gNextId' 4 ( GameState, gEntities, gEntityNames, gFocus, gNextId'
5 , Faction, faction, faction' 5 , Faction, faction, faction'
6 , SeqVal(..), seqVal, seqVal'
7 , Entity(..), eFaction, eSeqVal, eStats 6 , Entity(..), eFaction, eSeqVal, eStats
8 , EntityName(..), entityName 7 , EntityName(..), entityName
9 , EntityIdentifier(..), entityId, entityId' 8 , EntityIdentifier(..), entityId, entityId'
10 , inhabitedFactions, priorityQueue, tip, insertEntity, gFocus' 9 , inhabitedFactions, priorityQueue, tip, insertEntity, gFocus', gRound
11 ) where 10 ) where
12 11
13import Control.Lens 12import Control.Lens
@@ -26,11 +25,14 @@ import qualified Data.Bimap as Bimap
26 25
27import Control.Monad.Reader 26import Control.Monad.Reader
28import Control.Monad.State 27import Control.Monad.State
28import Control.Monad.Trans.Maybe
29 29
30import Data.List 30import Data.List
31import Data.Maybe 31import Data.Maybe
32import Data.Tuple 32import Data.Tuple
33import Data.Ord 33import Data.Ord
34import Data.Semigroup (Min(..))
35import Data.Monoid
34 36
35import Sequence.Contact.Types 37import Sequence.Contact.Types
36import Sequence.Formula ((:<:)(..)) 38import Sequence.Formula ((:<:)(..))
@@ -59,30 +61,23 @@ faction' = lens (CI.original . fromMaybe unaligned . view faction) (\s a -> s {
59 | otherwise = Just str' 61 | otherwise = Just str'
60 62
61 63
62newtype SeqVal = SeqVal { _seqVal :: Int }
63 deriving (Show, Ord, Eq, Num, Integral, Enum, Real)
64
65seqVal :: Integral a => Iso' a SeqVal
66seqVal = iso (SeqVal . fromIntegral) (fromIntegral . _seqVal)
67
68seqVal' :: Prism' String SeqVal
69seqVal' = _Show . seqVal
70
71
72data Entity = Entity 64data Entity = Entity
73 { _eSeqVal :: Maybe SeqVal 65 { _eFaction :: Faction
74 , _eFaction :: Faction
75 , _eStats :: Stats 66 , _eStats :: Stats
67 , _eNotes :: [String]
76 } 68 }
77makeLenses ''Entity 69makeLenses ''Entity
78 70
79instance Default Entity where 71instance Default Entity where
80 def = Entity 72 def = Entity
81 { _eSeqVal = def 73 { _eFaction = def
82 , _eFaction = def
83 , _eStats = def 74 , _eStats = def
75 , _eNotes = []
84 } 76 }
85 77
78eSeqVal :: Lens' Entity (Maybe SeqVal)
79eSeqVal = eStats . sSequence
80
86instance (Entity :<: a) => Stats :<: a where 81instance (Entity :<: a) => Stats :<: a where
87 ctx' = ctx' . eStats 82 ctx' = ctx' . eStats
88 83
@@ -132,17 +127,11 @@ tip :: Fold GameState EntityIdentifier
132tip = priorityQueue . folding (fmap snd . listToMaybe) 127tip = priorityQueue . folding (fmap snd . listToMaybe)
133 128
134gFocus' :: Traversal' GameState Entity 129gFocus' :: Traversal' GameState Entity
135gFocus' modifyFocus = do 130gFocus' modifyFocus st = (flip runReader st) . (maybe (asks pure) return =<<) . runMaybeT $ do
136 focusIdent <- view gFocus 131 focusIdent <- MaybeT $ view gFocus
137 case focusIdent of 132 focus <- MaybeT $ view (gEntities . at focusIdent)
138 Nothing -> pure <$> ask 133 st <- ask
139 Just focusIdent -> do 134 return $ flip (set $ gEntities . at focusIdent) st . Just <$> modifyFocus focus
140 focus <- view (gEntities . at focusIdent)
141 case focus of
142 Nothing -> pure <$> ask
143 Just focus -> do
144 st <- ask
145 return $ flip (set $ gEntities . at focusIdent) st . Just <$> modifyFocus focus
146 135
147-- gFocus' = prism' getFocus setFocus 136-- gFocus' = prism' getFocus setFocus
148-- where 137-- where
@@ -163,3 +152,12 @@ insertEntity entity = execState $ do
163 gEntities . at identifier ?= entity 152 gEntities . at identifier ?= entity
164 gNextId %= succ 153 gNextId %= succ
165 154
155gRound :: Lens' GameState Int
156gRound = lens lowestRound $ flip trimBelow
157 where
158 lowestRound = getMin . (<> Min 0) . view (gEntities . each . eStats . sSequence . _Just . seqRound . _Unwrapped)
159 trimBelow = over (gEntities . each . eStats . sSequence) . trimBelow'
160 trimBelow' cutoff = runReader . runMaybeT $ do
161 round <- MaybeT . preview $ _Just . seqRound
162 guard $ round >= cutoff
163 MaybeT ask