diff options
-rw-r--r-- | default.nix | 3 | ||||
-rw-r--r-- | sequence.cabal | 2 | ||||
-rw-r--r-- | src/Main.hs | 24 | ||||
-rw-r--r-- | src/Sequence/Contact/Archetypes.hs | 59 | ||||
-rw-r--r-- | src/Sequence/Contact/Types.hs | 66 | ||||
-rw-r--r-- | src/Sequence/Contact/Types/Internal.hs | 22 | ||||
-rw-r--r-- | src/Sequence/Types.hs | 52 |
7 files changed, 160 insertions, 68 deletions
diff --git a/default.nix b/default.nix index c96e43f..4b974c3 100644 --- a/default.nix +++ b/default.nix | |||
@@ -1,8 +1,9 @@ | |||
1 | { pkgs ? (import <nixpkgs> {}) | 1 | { pkgs ? (import <nixpkgs> {}) |
2 | , compilerName ? "ghc7103" | 2 | , compilerName ? "ghc801" |
3 | }: | 3 | }: |
4 | 4 | ||
5 | rec { | 5 | rec { |
6 | # haskellPackages = pkgs.haskell.packages."${compilerName}"; | ||
6 | haskellPackages = pkgs.haskell.packages."${compilerName}".override { | 7 | haskellPackages = pkgs.haskell.packages."${compilerName}".override { |
7 | overrides = self: super: { | 8 | overrides = self: super: { |
8 | Shellac = pkgs.haskell.lib.appendPatch super.Shellac (pkgs.writeText "build.patch" '' | 9 | Shellac = pkgs.haskell.lib.appendPatch super.Shellac (pkgs.writeText "build.patch" '' |
diff --git a/sequence.cabal b/sequence.cabal index 2def576..931cba6 100644 --- a/sequence.cabal +++ b/sequence.cabal | |||
@@ -19,7 +19,7 @@ executable sequence | |||
19 | main-is: Main.hs | 19 | main-is: Main.hs |
20 | other-modules: Sequence.Types | 20 | other-modules: Sequence.Types |
21 | -- other-extensions: | 21 | -- other-extensions: |
22 | build-depends: base >=4.8 && <5 | 22 | build-depends: base >=4.9 && <5 |
23 | , Shellac | 23 | , Shellac |
24 | , Shellac-haskeline | 24 | , Shellac-haskeline |
25 | , data-default | 25 | , data-default |
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 | |||
32 | import Data.Function | 32 | import Data.Function |
33 | 33 | ||
34 | import Control.Monad.State.Strict | 34 | import Control.Monad.State.Strict |
35 | import Control.Monad.Trans.Maybe | ||
35 | 36 | ||
36 | import Sequence.Types | 37 | import Sequence.Types |
37 | import Sequence.Contact.Types | 38 | import 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 |
102 | listFactions, listEntities :: Sh GameState () | 103 | listFactions, listEntities :: Sh GameState () |
@@ -195,12 +196,13 @@ factionSeqVal :: Completable Faction -> Sh GameState () | |||
195 | factionSeqVal = withArg $ \qFaction -> use gEntities >>= mapM_ (entitySeqVal') . Map.keys . Map.filter ((==) qFaction . view eFaction) | 196 | factionSeqVal = withArg $ \qFaction -> use gEntities >>= mapM_ (entitySeqVal') . Map.keys . Map.filter ((==) qFaction . view eFaction) |
196 | 197 | ||
197 | entitySeqVal' :: EntityIdentifier -> Sh GameState () | 198 | entitySeqVal' :: EntityIdentifier -> Sh GameState () |
198 | entitySeqVal' ident = do | 199 | entitySeqVal' 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 | ||
5 | import Control.Lens | 5 | import Control.Lens |
6 | 6 | ||
7 | import Control.Monad.Except | ||
8 | import Control.Monad.State | ||
9 | import Control.Monad.Trans | ||
10 | import Control.Monad.Trans.Maybe | ||
11 | |||
7 | import Sequence.Contact.Types | 12 | import Sequence.Contact.Types |
8 | import Sequence.Formula | 13 | import Sequence.Formula |
9 | 14 | ||
@@ -14,6 +19,8 @@ import Data.Map (Map) | |||
14 | import qualified Data.Map as Map | 19 | import qualified Data.Map as Map |
15 | 20 | ||
16 | import Data.Default | 21 | import Data.Default |
22 | import Data.Maybe | ||
23 | import Data.Ratio | ||
17 | 24 | ||
18 | import Data.List | 25 | import Data.List |
19 | 26 | ||
@@ -37,6 +44,9 @@ archetypes = [ ("Mensch", human) | |||
37 | , ("Milizenschläger", milizenschlaeger) | 44 | , ("Milizenschläger", milizenschlaeger) |
38 | ] | 45 | ] |
39 | 46 | ||
47 | cTable :: Ord v => [(Integer, Integer, v)] -> Table v | ||
48 | cTable = Map.fromList . map (\(from, to, value) -> (value, (abs (to - from) + 1) % 100)) | ||
49 | |||
40 | 50 | ||
41 | human = Humanoid | 51 | human = 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 | ||
101 | dog = Quadruped | 142 | dog = 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 | ||
3 | module Sequence.Contact.Types | 3 | module Sequence.Contact.Types |
4 | ( module Sequence.Contact.Types | 4 | ( module Sequence.Contact.Types |
@@ -22,6 +22,8 @@ import Data.String (IsString(..)) | |||
22 | import Data.Function (on) | 22 | import Data.Function (on) |
23 | import Data.Maybe | 23 | import Data.Maybe |
24 | import Data.Ratio | 24 | import Data.Ratio |
25 | import Data.List | ||
26 | import Data.Ord | ||
25 | 27 | ||
26 | import Control.Monad.Reader (ask) | 28 | import Control.Monad.Reader (ask) |
27 | import Control.Monad.State | 29 | import Control.Monad.State |
@@ -73,21 +75,36 @@ instance Default Modifier where | |||
73 | 75 | ||
74 | makePrisms ''Effect | 76 | makePrisms ''Effect |
75 | 77 | ||
78 | effectName :: Lens' Effect String | ||
79 | effectName = _Effect . _1 . iso CI.original CI.mk | ||
80 | |||
76 | instance Eq Effect where | 81 | instance Eq Effect where |
77 | (==) = (==) `on` (view $ _Effect . _1) | 82 | (==) = (==) `on` (view effectName) |
78 | 83 | ||
79 | instance Ord Effect where | 84 | instance Ord Effect where |
80 | compare = compare `on` (view $ _Effect . _1) | 85 | compare = compare `on` (view effectName) |
81 | 86 | ||
82 | instance Default Effect where | 87 | instance Default Effect where |
83 | def = Effect "" pure | 88 | def = Effect "" $ preview ctx |
89 | |||
90 | effect :: String -> Effect | ||
91 | effect str = def & set effectName str | ||
92 | |||
93 | makePrisms ''SeqVal | ||
94 | makeLenses ''SeqVal | ||
95 | |||
96 | instance Default SeqVal where | ||
97 | def = SeqVal { _seqRound = 0 | ||
98 | , _seqVal = Nothing | ||
99 | , _seqEpsilon = False | ||
100 | } | ||
84 | 101 | ||
85 | makeLenses ''ShockEffect | 102 | makeLenses ''ShockEffect |
86 | 103 | ||
87 | instance Default ShockEffect where | 104 | instance 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 | |||
96 | instance Default Stats where | 113 | instance 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 | ||
108 | applyModifier :: String -> (Test -> FormulaM Stats Test) -> Effect | 131 | applyModifier :: String -> (Test -> FormulaM Stats Test) -> Effect |
109 | applyModifier effectName modifier = Effect (CI.mk effectName) $ return . apply | 132 | applyModifier 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 | |||
121 | vPerception = val sAPerception "Wahrnehmung?" True | 144 | vPerception = val sAPerception "Wahrnehmung?" True |
122 | vWillpower = val sAWillpower "Entschlossenheit?" True | 145 | vWillpower = val sAWillpower "Entschlossenheit?" True |
123 | 146 | ||
124 | scaled :: (Real a, Fractional a, Integral b) => Ratio b -> Iso' a a | 147 | scaled :: Ratio Int -> Iso' Int Int |
125 | scaled (realToFrac -> ratio) = iso (* ratio) (/ ratio) | 148 | scaled r = iso (\x -> floor $ x % 1 * r) (\x -> round $ x % 1 / r) |
126 | 149 | ||
127 | sDamage' :: String -> Traversal' Stats Int | 150 | sDamage' :: Hitzone -> Traversal' Stats Int |
128 | sDamage' (view hitzone -> zone) = sDamage . ix zone | 151 | sDamage' zone = sDamage . ix zone |
129 | 152 | ||
130 | sCripple' :: String -> Traversal' Stats ShockEffect | 153 | sCripple' :: Hitzone -> Traversal' Stats ShockEffect |
131 | sCripple' (view hitzone -> zone) = sCripple . ix zone | 154 | sCripple' zone = sCripple . ix zone |
132 | 155 | ||
133 | sTotalDamage :: Lens' Stats Int | 156 | sTotalDamage :: Lens' Stats Int |
134 | sTotalDamage = lens retrieve undefined | 157 | sTotalDamage = 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 | ||
141 | sDead :: Fold Stats (FormulaM Stats Bool) | 175 | sDead :: Fold Stats (FormulaM Stats Bool) |
142 | sDead = folding $ do | 176 | sDead = 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) | |||
7 | import Data.Map (Map) | 7 | import Data.Map (Map) |
8 | import Data.Set (Set) | 8 | import Data.Set (Set) |
9 | import Data.Ratio | 9 | import Data.Ratio |
10 | import Data.Monoid | ||
10 | 11 | ||
11 | import Control.Lens | 12 | import Control.Lens |
12 | 13 | ||
@@ -42,12 +43,19 @@ data Test = Test | |||
42 | 43 | ||
43 | data Modifier = Modifier (CI String) (Test -> FormulaM Stats Test) | 44 | data Modifier = Modifier (CI String) (Test -> FormulaM Stats Test) |
44 | 45 | ||
45 | data Effect = Effect (CI String) (Stats -> FormulaM Stats Stats) | 46 | data Effect = Effect (CI String) (FormulaM Stats (Maybe Stats)) |
47 | |||
48 | data SeqVal = SeqVal | ||
49 | { _seqRound :: Int | ||
50 | , _seqVal :: Maybe Int | ||
51 | , _seqEpsilon :: Bool | ||
52 | } | ||
53 | deriving (Show, Ord, Eq) | ||
46 | 54 | ||
47 | data ShockEffect = ShockEffect | 55 | data 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 @@ | |||
3 | module Sequence.Types | 3 | module 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 | ||
13 | import Control.Lens | 12 | import Control.Lens |
@@ -26,11 +25,14 @@ import qualified Data.Bimap as Bimap | |||
26 | 25 | ||
27 | import Control.Monad.Reader | 26 | import Control.Monad.Reader |
28 | import Control.Monad.State | 27 | import Control.Monad.State |
28 | import Control.Monad.Trans.Maybe | ||
29 | 29 | ||
30 | import Data.List | 30 | import Data.List |
31 | import Data.Maybe | 31 | import Data.Maybe |
32 | import Data.Tuple | 32 | import Data.Tuple |
33 | import Data.Ord | 33 | import Data.Ord |
34 | import Data.Semigroup (Min(..)) | ||
35 | import Data.Monoid | ||
34 | 36 | ||
35 | import Sequence.Contact.Types | 37 | import Sequence.Contact.Types |
36 | import Sequence.Formula ((:<:)(..)) | 38 | import 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 | ||
62 | newtype SeqVal = SeqVal { _seqVal :: Int } | ||
63 | deriving (Show, Ord, Eq, Num, Integral, Enum, Real) | ||
64 | |||
65 | seqVal :: Integral a => Iso' a SeqVal | ||
66 | seqVal = iso (SeqVal . fromIntegral) (fromIntegral . _seqVal) | ||
67 | |||
68 | seqVal' :: Prism' String SeqVal | ||
69 | seqVal' = _Show . seqVal | ||
70 | |||
71 | |||
72 | data Entity = Entity | 64 | data Entity = Entity |
73 | { _eSeqVal :: Maybe SeqVal | 65 | { _eFaction :: Faction |
74 | , _eFaction :: Faction | ||
75 | , _eStats :: Stats | 66 | , _eStats :: Stats |
67 | , _eNotes :: [String] | ||
76 | } | 68 | } |
77 | makeLenses ''Entity | 69 | makeLenses ''Entity |
78 | 70 | ||
79 | instance Default Entity where | 71 | instance 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 | ||
78 | eSeqVal :: Lens' Entity (Maybe SeqVal) | ||
79 | eSeqVal = eStats . sSequence | ||
80 | |||
86 | instance (Entity :<: a) => Stats :<: a where | 81 | instance (Entity :<: a) => Stats :<: a where |
87 | ctx' = ctx' . eStats | 82 | ctx' = ctx' . eStats |
88 | 83 | ||
@@ -132,17 +127,11 @@ tip :: Fold GameState EntityIdentifier | |||
132 | tip = priorityQueue . folding (fmap snd . listToMaybe) | 127 | tip = priorityQueue . folding (fmap snd . listToMaybe) |
133 | 128 | ||
134 | gFocus' :: Traversal' GameState Entity | 129 | gFocus' :: Traversal' GameState Entity |
135 | gFocus' modifyFocus = do | 130 | gFocus' 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 | ||
155 | gRound :: Lens' GameState Int | ||
156 | gRound = 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 | ||