diff options
Diffstat (limited to 'src/Main.hs')
| -rw-r--r-- | src/Main.hs | 57 |
1 files changed, 49 insertions, 8 deletions
diff --git a/src/Main.hs b/src/Main.hs index 236e779..a0799e0 100644 --- a/src/Main.hs +++ b/src/Main.hs | |||
| @@ -19,6 +19,9 @@ import qualified Data.CaseInsensitive as CI | |||
| 19 | 19 | ||
| 20 | import Data.Map.Strict (Map) | 20 | import Data.Map.Strict (Map) |
| 21 | import qualified Data.Map.Strict as Map | 21 | import qualified Data.Map.Strict as Map |
| 22 | |||
| 23 | import Data.Map as Lazy (Map) | ||
| 24 | import qualified Data.Map as Lazy.Map | ||
| 22 | 25 | ||
| 23 | import Data.Set (Set) | 26 | import Data.Set (Set) |
| 24 | import qualified Data.Set as Set | 27 | import qualified Data.Set as Set |
| @@ -34,7 +37,7 @@ import Data.List | |||
| 34 | import Data.List | 37 | import Data.List |
| 35 | import Data.Maybe | 38 | import Data.Maybe |
| 36 | import Data.Bool | 39 | import Data.Bool |
| 37 | import Data.Monoid (All(..)) | 40 | import Data.Monoid (Monoid(..), (<>), All(..)) |
| 38 | import Data.Ord | 41 | import Data.Ord |
| 39 | import Data.Ratio | 42 | import Data.Ratio |
| 40 | 43 | ||
| @@ -67,6 +70,8 @@ import qualified Data.Text.Lazy as Lazy (Text) | |||
| 67 | import qualified Data.Text.Lazy as Lazy.Text | 70 | import qualified Data.Text.Lazy as Lazy.Text |
| 68 | import Data.Text.Template | 71 | import Data.Text.Template |
| 69 | 72 | ||
| 73 | import Debug.Trace | ||
| 74 | |||
| 70 | main :: IO () | 75 | main :: IO () |
| 71 | main = do | 76 | main = do |
| 72 | historyFile <- getUserCacheFile "sequence" "history" | 77 | historyFile <- getUserCacheFile "sequence" "history" |
| @@ -115,6 +120,7 @@ main = do | |||
| 115 | , cmd "log" dumpLog "Print the combat log" | 120 | , cmd "log" dumpLog "Print the combat log" |
| 116 | , cmd "val" printVal "Find the distribution of a specific value of the current entities" | 121 | , cmd "val" printVal "Find the distribution of a specific value of the current entities" |
| 117 | , cmd "summary" printVals "Find the averages of applicable all values" | 122 | , cmd "summary" printVals "Find the averages of applicable all values" |
| 123 | , cmd "burstfire" burstfire "Roll an automatic burst of <n> shots against given skill compensating for recoil with the given attribute" | ||
| 118 | ] | 124 | ] |
| 119 | , wordBreakChars = wordBreakChars initialShellDescription \\ [',', '\''] | 125 | , wordBreakChars = wordBreakChars initialShellDescription \\ [',', '\''] |
| 120 | } | 126 | } |
| @@ -385,7 +391,13 @@ spawnFaction cFaction num cEntity nameTemplate | |||
| 385 | 391 | ||
| 386 | -- Dice rolls | 392 | -- Dice rolls |
| 387 | rollTest :: Completable (FormulaM Stats Test) -> Sh GameState () | 393 | rollTest :: Completable (FormulaM Stats Test) -> Sh GameState () |
| 388 | rollTest = withArg $ maybe (return ()) ((>>) <$> outputResult <*> applyEffect) <=< enactTest' | 394 | rollTest = withArg rollTest' |
| 395 | |||
| 396 | rollTest' :: FormulaM Stats Test -> Sh GameState () | ||
| 397 | rollTest' = rollTest'' Nothing | ||
| 398 | |||
| 399 | rollTest'' :: Maybe (Formula Stats) -> FormulaM Stats Test -> Sh GameState () | ||
| 400 | rollTest'' testMod = maybe (return ()) ((>>) <$> outputResult <*> applyEffect) <=< enactTest' testMod | ||
| 389 | where | 401 | where |
| 390 | outputResult :: (String, TestResult) -> Sh GameState () | 402 | outputResult :: (String, TestResult) -> Sh GameState () |
| 391 | outputResult (test, view (rRoll . to ppResult) -> result) = do | 403 | outputResult (test, view (rRoll . to ppResult) -> result) = do |
| @@ -408,7 +420,8 @@ rollTest = withArg $ maybe (return ()) ((>>) <$> outputResult <*> applyEffect) < | |||
| 408 | 420 | ||
| 409 | 421 | ||
| 410 | applyEffect :: (String, TestResult) -> Sh GameState () | 422 | applyEffect :: (String, TestResult) -> Sh GameState () |
| 411 | applyEffect (test, view rResult -> (Effect (CI.original -> effectDesc) effect)) = void . runMaybeT $ do | 423 | applyEffect (_, view rResult -> Nothing) = return () |
| 424 | applyEffect (test, view rResult -> Just (Effect (CI.original -> effectDesc) effect)) = void . runMaybeT $ do | ||
| 412 | focusId <- MaybeT $ use gFocus | 425 | focusId <- MaybeT $ use gFocus |
| 413 | name <- toName focusId | 426 | name <- toName focusId |
| 414 | let | 427 | let |
| @@ -416,15 +429,15 @@ rollTest = withArg $ maybe (return ()) ((>>) <$> outputResult <*> applyEffect) < | |||
| 416 | lStats = gEntities . ix focusId . eStats | 429 | lStats = gEntities . ix focusId . eStats |
| 417 | evalF = MaybeT . focusState lStats . evalFormula' [name] | 430 | evalF = MaybeT . focusState lStats . evalFormula' [name] |
| 418 | guard =<< askBool ("Apply effects (" ++ effectDesc ++ ")?") True | 431 | guard =<< askBool ("Apply effects (" ++ effectDesc ++ ")?") True |
| 419 | lStats <~ (MaybeT . fmap join . runMaybeT $ evalF effect) | 432 | lStats <~ (MaybeT . fmap join . runMaybeT . evalF $ runMaybeT effect) |
| 420 | lift . outputLogged focusId $ test ++ " effects: " ++ effectDesc | 433 | lift . outputLogged focusId $ test ++ " effects: " ++ effectDesc |
| 421 | 434 | ||
| 422 | enactTest' :: FormulaM Stats Test -> Sh GameState (Maybe (String, TestResult)) | 435 | enactTest' :: Maybe (Formula Stats) -> FormulaM Stats Test -> Sh GameState (Maybe (String, TestResult)) |
| 423 | enactTest' test = runMaybeT $ do | 436 | enactTest' testMod test = runMaybeT $ do |
| 424 | focusName <- MaybeT (use gFocus) >>= lift . toName | 437 | focusName <- MaybeT (use gFocus) >>= lift . toName |
| 425 | let evalF = MaybeT . focusState (gFocus' . eStats) . evalFormula' [focusName] | 438 | let evalF = MaybeT . focusState (gFocus' . eStats) . evalFormula' [focusName] |
| 426 | test' <- evalF test | 439 | test' <- evalF test |
| 427 | result <- evalF $ enactTest test' | 440 | result <- evalF $ (maybe enactTest (flip enactTestMod) testMod) test' |
| 428 | return (view (tName . to CI.original) test', result) | 441 | return (view (tName . to CI.original) test', result) |
| 429 | 442 | ||
| 430 | entitySeqVal :: Sh GameState () | 443 | entitySeqVal :: Sh GameState () |
| @@ -502,7 +515,7 @@ doShock dmg efLens = withFocus $ \focusId -> do | |||
| 502 | else guard $ val >= bar | 515 | else guard $ val >= bar |
| 503 | lStats . efLens . seApplied .= True | 516 | lStats . efLens . seApplied .= True |
| 504 | Effect (CI.original -> effectName) effect <- evalF . table $ cripple ^. seEffect | 517 | Effect (CI.original -> effectName) effect <- evalF . table $ cripple ^. seEffect |
| 505 | lStats <~ (MaybeT . fmap join . runMaybeT $ evalF effect) | 518 | lStats <~ (MaybeT . fmap join . runMaybeT . evalF $ runMaybeT effect) |
| 506 | lift . outputLogged focusId $ "Effect: " ++ effectName | 519 | lift . outputLogged focusId $ "Effect: " ++ effectName |
| 507 | lift . addNote $ "Effect: " ++ effectName | 520 | lift . addNote $ "Effect: " ++ effectName |
| 508 | 521 | ||
| @@ -586,3 +599,31 @@ printVals = withFocus $ \focusId -> do | |||
| 586 | Just avg -> shellPutStrLn $ printf "%*s: %5.1f" maxLength (CI.original str) (fromRational avg :: Double) | 599 | Just avg -> shellPutStrLn $ printf "%*s: %5.1f" maxLength (CI.original str) (fromRational avg :: Double) |
| 587 | Nothing -> return () | 600 | Nothing -> return () |
| 588 | mapM_ printAvg $ Map.toList sheet | 601 | mapM_ printAvg $ Map.toList sheet |
| 602 | |||
| 603 | burstfire :: Int -> Completable (Formula Stats) -> Completable (Formula Stats) -> Sh GameState () | ||
| 604 | burstfire nShots skill' attr' = skill' <~> \skill -> attr' <~> \attr -> withFocus (burstfire' skill attr) | ||
| 605 | where | ||
| 606 | burstfire' skill attr focusId = void . runMaybeT $ do | ||
| 607 | name <- lift $ toName focusId | ||
| 608 | let | ||
| 609 | lStats :: Traversal' GameState Stats | ||
| 610 | lStats = gEntities . ix focusId . eStats | ||
| 611 | evalF formula = do | ||
| 612 | stats <- MaybeT $ preuse lStats | ||
| 613 | (nStats, x) <- (evalFormula [name] :: Stats -> FormulaM Stats a -> MaybeT (Sh GameState) (Stats, a)) stats formula | ||
| 614 | lStats .= nStats | ||
| 615 | return x | ||
| 616 | skillVal <- evalF skill | ||
| 617 | attrVal <- evalF attr | ||
| 618 | minStrRaw <- evalF $ val ignored ["Mindeststärke der Waffe"] False | ||
| 619 | minStrMod <- evalF $ val ignored ["Mindeststärke der Waffe", "Modifikator"] False | ||
| 620 | mod <- evalF $ val ignored ["Modifikator"] False | ||
| 621 | let | ||
| 622 | recoilMod = max 0 $ 10 + (minStr - attrVal) | ||
| 623 | minStr = minStrRaw + minStrMod | ||
| 624 | lift . forM_ [1..nShots] $ \n -> do | ||
| 625 | rollTest'' (Just $ fromIntegral mod) . return $ def | ||
| 626 | & tName . iso CI.original CI.mk .~ printf "Schuss %2d" n | ||
| 627 | & tBaseDifficulty .~ skillVal | ||
| 628 | & tMod .~ (n - 1) * (-recoilMod) | ||
| 629 | & tEffect .~ MaybeT . table . critTables "Fernkampfangriffe" | ||
