diff options
Diffstat (limited to 'src/Main.hs')
-rw-r--r-- | src/Main.hs | 53 |
1 files changed, 49 insertions, 4 deletions
diff --git a/src/Main.hs b/src/Main.hs index f4a863f..8d74def 100644 --- a/src/Main.hs +++ b/src/Main.hs | |||
@@ -1,4 +1,4 @@ | |||
1 | {-# LANGUAGE ViewPatterns, RecordWildCards #-} | 1 | {-# LANGUAGE ViewPatterns, RecordWildCards, OverloadedStrings, FlexibleContexts #-} |
2 | 2 | ||
3 | import Control.Monad | 3 | import Control.Monad |
4 | 4 | ||
@@ -43,6 +43,12 @@ import Text.Layout.Table | |||
43 | 43 | ||
44 | import Text.Read (readMaybe) | 44 | import Text.Read (readMaybe) |
45 | 45 | ||
46 | import Data.Text (Text) | ||
47 | import qualified Data.Text as Text | ||
48 | import qualified Data.Text.Lazy as Lazy (Text) | ||
49 | import qualified Data.Text.Lazy as Lazy.Text | ||
50 | import Data.Text.Template | ||
51 | |||
46 | main :: IO () | 52 | main :: IO () |
47 | main = do | 53 | main = do |
48 | historyFile <- getUserCacheFile "sequence" "history" | 54 | historyFile <- getUserCacheFile "sequence" "history" |
@@ -65,7 +71,10 @@ main = do | |||
65 | , cmd "align" alignEntity "Align the focused entity to a faction – creating it, if necessary" | 71 | , cmd "align" alignEntity "Align the focused entity to a faction – creating it, if necessary" |
66 | , cmd "name" nameEntity "Name the current entity overriding previous name assignments" | 72 | , cmd "name" nameEntity "Name the current entity overriding previous name assignments" |
67 | , cmd "spawn" spawnEntity "Create a new entity from an archetype focusing on it" | 73 | , cmd "spawn" spawnEntity "Create a new entity from an archetype focusing on it" |
68 | , cmd "roll" rollTest "Roll a test using the stats of the currently focused entity" | 74 | , cmd "spawn'" spawnFaction "Create a new faction and spawn multiple copies of an archetype in it" |
75 | , cmd "test" rollTest "Roll a test using the stats of the currently focused entity" | ||
76 | , cmd "combat" entitySeqVal "Roll sequence value for the current focus and enter combat" | ||
77 | , cmd "combat'" factionSeqVal "Roll sequence values for all members of a faction and have them enter combat" | ||
69 | ] | 78 | ] |
70 | } | 79 | } |
71 | void $ runShell description haskelineBackend (def :: GameState) | 80 | void $ runShell description haskelineBackend (def :: GameState) |
@@ -81,11 +90,11 @@ stateOutline st | |||
81 | faction id = fromJust $ view eFaction <$> Map.lookup id (st ^. gEntities) | 90 | faction id = fromJust $ view eFaction <$> Map.lookup id (st ^. gEntities) |
82 | factionIndex id = fromJust $ elemIndex (view faction' $ faction id) factions | 91 | factionIndex id = fromJust $ elemIndex (view faction' $ faction id) factions |
83 | rowGs = do | 92 | rowGs = do |
84 | rowGroup'@((seqVal', _):_) <- protoRows | 93 | rowGroup'@((review seqVal' -> seqVal, _):_) <- protoRows |
85 | let | 94 | let |
86 | rowGroup = map snd rowGroup' | 95 | rowGroup = map snd rowGroup' |
87 | factionColumn i = [evalState ?? st $ toName x | x <- rowGroup, factionIndex x == i ] | 96 | factionColumn i = [evalState ?? st $ toName x | x <- rowGroup, factionIndex x == i ] |
88 | return . colsAllG top $ [show (seqVal' ^. seqVal)] : map factionColumn [0..(length factions - 1)] | 97 | return . colsAllG top $ [seqVal] : map factionColumn [0..(length factions - 1)] |
89 | 98 | ||
90 | -- Query state | 99 | -- Query state |
91 | listFactions, listEntities :: Sh GameState () | 100 | listFactions, listEntities :: Sh GameState () |
@@ -127,6 +136,27 @@ nameEntity :: String -> Sh GameState () | |||
127 | nameEntity ('#':_) = shellPutErrLn "We do not allow names that might shadow explicit access to entities via their number (‘#<n>’)" | 136 | nameEntity ('#':_) = shellPutErrLn "We do not allow names that might shadow explicit access to entities via their number (‘#<n>’)" |
128 | nameEntity name = withFocus $ \ident -> modifying gEntityNames $ Bimap.insert ident (name ^. entityName) | 137 | nameEntity name = withFocus $ \ident -> modifying gEntityNames $ Bimap.insert ident (name ^. entityName) |
129 | 138 | ||
139 | spawnFaction :: Completable Faction -> Integer -> Completable Entity -> String -> Sh GameState () | ||
140 | spawnFaction cFaction num cEntity nameTemplate | ||
141 | | ('#':_) <- nameTemplate = shellPutErrLn "We do not allow names that might shadow explicit access to entities via their number (‘#<n>’)" | ||
142 | | otherwise = do | ||
143 | let nameTemplate' = templateSafe $ Text.pack nameTemplate | ||
144 | case nameTemplate' of | ||
145 | Left _ -> shellPutErrLn "Invalid template – ‘$n’ gets replaced by [1..<n>], ‘$faction’ gets replaced by name of faction, and ‘$i’ gets replaced by a numerical identifier – quote ‘$’ as ‘$$’" | ||
146 | Right nameTemplate -> withArg (\faction -> withArg (\entity -> mapM_ (spawnFaction' faction entity nameTemplate) [1..num]) cEntity) cFaction | ||
147 | where | ||
148 | spawnFaction' faction entity nameTemplate num = do | ||
149 | identifier <- use gNextId' | ||
150 | let name = Lazy.Text.unpack <$> renderA nameTemplate (context num) | ||
151 | context num "i" = Just . Text.pack $ review entityId' identifier | ||
152 | context num "n" = Just . Text.pack $ show num | ||
153 | context num "faction" = Just . Text.pack $ faction ^. faction' | ||
154 | context num _ = Nothing | ||
155 | modify $ insertEntity entity | ||
156 | maybe (return ()) (nameEntity identifier) name | ||
157 | gEntities %= Map.adjust (set eFaction faction) identifier | ||
158 | nameEntity identifier name = modifying gEntityNames $ Bimap.insert identifier (name ^. entityName) | ||
159 | |||
130 | -- Dice rolls | 160 | -- Dice rolls |
131 | rollTest :: Completable (FormulaM Stats Test) -> Sh GameState () | 161 | rollTest :: Completable (FormulaM Stats Test) -> Sh GameState () |
132 | rollTest = withArg $ enactTest' >=> maybe (return ()) (shellPutStrLn . ppResult) | 162 | rollTest = withArg $ enactTest' >=> maybe (return ()) (shellPutStrLn . ppResult) |
@@ -150,3 +180,18 @@ enactTest' test = withFocus' $ \focus -> do | |||
150 | gFocus' .= newFocus | 180 | gFocus' .= newFocus |
151 | return result | 181 | return result |
152 | 182 | ||
183 | entitySeqVal :: Sh GameState () | ||
184 | entitySeqVal = withFocus entitySeqVal' | ||
185 | |||
186 | factionSeqVal :: Completable Faction -> Sh GameState () | ||
187 | factionSeqVal = withArg $ \qFaction -> use gEntities >>= mapM_ (entitySeqVal') . Map.keys . Map.filter ((==) qFaction . view eFaction) | ||
188 | |||
189 | entitySeqVal' :: EntityIdentifier -> Sh GameState () | ||
190 | entitySeqVal' ident = do | ||
191 | entity <- preuse (gEntities . ix ident) | ||
192 | let sVal = preview (eStats . sSeqVal) =<< entity | ||
193 | case (,) <$> entity <*> sVal of | ||
194 | Nothing -> return () | ||
195 | Just (entity, sVal) -> do | ||
196 | (newEntity, view (seqVal . re _Just) -> val) <- evalFormula entity sVal | ||
197 | gEntities . at ident .= Just (newEntity & set eSeqVal val) | ||