summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregor Kleen <pngwjpgh@users.noreply.github.com>2016-07-09 14:45:28 +0200
committerGregor Kleen <pngwjpgh@users.noreply.github.com>2016-07-09 14:45:28 +0200
commita016d9c507e906cba12f8d39d42a93e09ab4e7ec (patch)
tree4b13e71cfde0b1ec5488165c30045241fb0e1923
parent90c94957cb7f1fef4df051d18700a34ecb797293 (diff)
download2017-01-16_17:13:37-a016d9c507e906cba12f8d39d42a93e09ab4e7ec.tar
2017-01-16_17:13:37-a016d9c507e906cba12f8d39d42a93e09ab4e7ec.tar.gz
2017-01-16_17:13:37-a016d9c507e906cba12f8d39d42a93e09ab4e7ec.tar.bz2
2017-01-16_17:13:37-a016d9c507e906cba12f8d39d42a93e09ab4e7ec.tar.xz
2017-01-16_17:13:37-a016d9c507e906cba12f8d39d42a93e09ab4e7ec.zip
Transfinite armor
-rw-r--r--sequence.cabal1
-rw-r--r--sequence.nix14
-rw-r--r--src/Main.hs9
-rw-r--r--src/Sequence/Contact/Types.hs28
-rw-r--r--src/Sequence/Contact/Types/Internal.hs21
5 files changed, 52 insertions, 21 deletions
diff --git a/sequence.cabal b/sequence.cabal
index 740a975..d47291e 100644
--- a/sequence.cabal
+++ b/sequence.cabal
@@ -40,5 +40,6 @@ executable sequence
40 , text 40 , text
41 , template 41 , template
42 , regex-compat 42 , regex-compat
43 , extended-reals
43 hs-source-dirs: src 44 hs-source-dirs: src
44 default-language: Haskell2010 \ No newline at end of file 45 default-language: Haskell2010 \ No newline at end of file
diff --git a/sequence.nix b/sequence.nix
index e0d93b7..1dc252a 100644
--- a/sequence.nix
+++ b/sequence.nix
@@ -1,8 +1,8 @@
1{ mkDerivation, ansi-terminal, base, bimap, case-insensitive 1{ mkDerivation, ansi-terminal, base, bimap, case-insensitive
2, containers, data-default, directory, filepath, game-probability 2, containers, data-default, directory, extended-reals, filepath
3, lens, mtl, readline, regex-compat, Shellac, Shellac-haskeline 3, game-probability, lens, mtl, readline, regex-compat, Shellac
4, stdenv, table-layout, template, text, transformers 4, Shellac-haskeline, stdenv, table-layout, template, text
5, transformers-base, xdg-basedir 5, transformers, transformers-base, xdg-basedir
6}: 6}:
7mkDerivation { 7mkDerivation {
8 pname = "sequence"; 8 pname = "sequence";
@@ -12,9 +12,9 @@ mkDerivation {
12 isExecutable = true; 12 isExecutable = true;
13 executableHaskellDepends = [ 13 executableHaskellDepends = [
14 ansi-terminal base bimap case-insensitive containers data-default 14 ansi-terminal base bimap case-insensitive containers data-default
15 directory filepath game-probability lens mtl readline regex-compat 15 directory extended-reals filepath game-probability lens mtl
16 Shellac Shellac-haskeline table-layout template text transformers 16 readline regex-compat Shellac Shellac-haskeline table-layout
17 transformers-base xdg-basedir 17 template text transformers transformers-base xdg-basedir
18 ]; 18 ];
19 license = stdenv.lib.licenses.mit; 19 license = stdenv.lib.licenses.mit;
20} 20}
diff --git a/src/Main.hs b/src/Main.hs
index 4b78ae2..3d098e2 100644
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -165,9 +165,12 @@ stateMaintenance = do
165 return x 165 return x
166 isDead <- evalF =<< MaybeT (preuse $ lStats . sDead) 166 isDead <- evalF =<< MaybeT (preuse $ lStats . sDead)
167 isUnconscious <- evalF =<< MaybeT (preuse $ lStats . sUnconscious) 167 isUnconscious <- evalF =<< MaybeT (preuse $ lStats . sUnconscious)
168 guard $ isDead || isUnconscious 168 isDestroyed <- evalF =<< MaybeT (preuse $ lStats . sDestroyed)
169 when isDead . lift . shellPutStrLn $ name ++ " is dead" 169 guard $ isDead || isUnconscious || isDestroyed
170 when (isUnconscious && not isDead) . lift . shellPutStrLn $ name ++ " is unconscious" 170 case (isDead, isDestroyed, isUnconscious) of
171 (True, _, _) -> lift . shellPutStrLn $ name ++ " is dead"
172 (_, True, _) -> lift . shellPutStrLn $ name ++ " is unconscious"
173 (_, _, True) -> lift . shellPutStrLn $ name ++ " is destroyed"
171 gFocus' . eSeqVal .= Nothing 174 gFocus' . eSeqVal .= Nothing
172 -- gFocus .= Nothing 175 -- gFocus .= Nothing
173 void $ do 176 void $ do
diff --git a/src/Sequence/Contact/Types.hs b/src/Sequence/Contact/Types.hs
index 2e8adcb..1d057fd 100644
--- a/src/Sequence/Contact/Types.hs
+++ b/src/Sequence/Contact/Types.hs
@@ -24,6 +24,7 @@ import Data.Maybe
24import Data.Ratio 24import Data.Ratio
25import Data.List 25import Data.List
26import Data.Ord 26import Data.Ord
27import Data.ExtendedReal
27 28
28import Control.Monad.Reader (ask) 29import Control.Monad.Reader (ask)
29import Control.Monad.State 30import Control.Monad.State
@@ -41,7 +42,7 @@ makePrisms ''Hitzone
41makePrisms ''DamageType 42makePrisms ''DamageType
42 43
43instance {-# OVERLAPS #-} Default Armor where 44instance {-# OVERLAPS #-} Default Armor where
44 def = const 0 45 def = const $ return 0
45 46
46makeLenses ''TestResult 47makeLenses ''TestResult
47 48
@@ -107,7 +108,9 @@ makeLenses ''Stats
107 108
108instance Default Stats where 109instance Default Stats where
109 def = Prop 110 def = Prop
110 { _sSeqEpsilon = False 111 { _sRobustness = Nothing
112
113 , _sSeqEpsilon = False
111 114
112 , _sHitzones = [("Volumen", 1)] 115 , _sHitzones = [("Volumen", 1)]
113 , _sArmor = const def 116 , _sArmor = const def
@@ -169,31 +172,36 @@ sTotalDamage = lens retrieve $ flip spread
169 | otherwise = damageMap z + d 172 | otherwise = damageMap z + d
170 sDamage .= damageMap' 173 sDamage .= damageMap'
171 174
172sDead :: Fold Stats (FormulaM Stats Bool) 175sDead, sUnconscious, sDestroyed :: Fold Stats (FormulaM Stats Bool)
173sDead = folding $ do 176sDead = folding $ do
174 maxVitality <- preview sMaxVitality 177 maxVitality <- preview sMaxVitality
175 damage <- view sTotalDamage 178 damage <- view sTotalDamage
176 return $ liftM2 (>=) <$> Just (return damage) <*> maxVitality 179 return $ liftM2 (>=) <$> Just (return damage) <*> maxVitality
177
178sUnconscious :: Fold Stats (FormulaM Stats Bool)
179sUnconscious = folding $ do 180sUnconscious = folding $ do
180 maxVitality <- preview sMaxVitality 181 maxVitality <- preview sMaxVitality
181 damage <- view sFatigue 182 damage <- view sFatigue
182 return $ liftM2 (>=) <$> Just (return damage) <*> maxVitality 183 return $ liftM2 (>=) <$> Just (return damage) <*> maxVitality
184sDestroyed = folding $ do
185 robustness <- preview $ sRobustness . _Just
186 damage <- view sTotalDamage
187 return $ liftM2 (>=) <$> Just (return damage) <*> robustness
183 188
184absorb :: Armor -> DamageType -> Int -> FormulaM Stats (Map DamageType Int) 189absorb :: Armor -> DamageType -> Int -> FormulaM Stats (Map DamageType Int)
185absorb armor = absorb' Map.empty 190absorb armor dType (Finite -> dmg) = fmap ensureFinite <$> absorb' Map.empty dType dmg
186 where 191 where
187 absorb' :: Map DamageType Int -> DamageType -> Int -> FormulaM Stats (Map DamageType Int) 192 absorb' :: Map DamageType Int' -> DamageType -> Int' -> FormulaM Stats (Map DamageType Int')
188 absorb' old dType dmg = do 193 absorb' old dType dmg = do
189 mass <- maybe (return (Nothing :: Maybe Int)) (fmap Just) =<< preview (ctx . sAMass) 194 mass <- maybe (return (Nothing :: Maybe Int')) (fmap $ Just . Finite) =<< preview (ctx . sAMass)
190 armor' <- wArmor dType 195 armor' <- wArmor dType
191 let 196 let
192 current = transmit mass dType $ min dmg armor' 197 current = transmit mass dType $ min dmg armor'
193 new <- Map.unionsWith (+) <$> (sequence . Map.elems $ Map.mapWithKey (absorb' current) current) 198 new <- Map.unionsWith (+) <$> (sequence . Map.elems $ Map.mapWithKey (absorb' current) current)
194 return . Map.unionWith (+) (leftover mass dType . clamp $ dmg - armor') $ if old /= current then new else current 199 return . Map.unionWith (+) (leftover mass dType . clamp $ dmg - armor') $ if old /= current then new else current
195 200
196 wArmor :: DamageType -> Formula Stats 201 ensureFinite (Finite n) = n
202 ensureFinite _ = error "Infinite amounts of damage should not occur"
203
204 wArmor :: DamageType -> FormulaM Stats Int'
197 wArmor Passthrough = 0 205 wArmor Passthrough = 0
198 wArmor Fatigue = 0 206 wArmor Fatigue = 0
199 wArmor Electric = (2 *) . maximum <$> mapM wArmor ([minBound..maxBound] \\ [Electric] :: [DamageType]) 207 wArmor Electric = (2 *) . maximum <$> mapM wArmor ([minBound..maxBound] \\ [Electric] :: [DamageType])
@@ -203,7 +211,7 @@ absorb armor = absorb' Map.empty
203 | n <= 0 = 0 211 | n <= 0 = 0
204 | otherwise = n 212 | otherwise = n
205 213
206 transmit, leftover :: Maybe Int -> DamageType -> Int -> Map DamageType Int 214 transmit, leftover :: Maybe Int' -> DamageType -> Int' -> Map DamageType Int'
207 transmit _ Ballistic n = [ (Blunt, n) ] 215 transmit _ Ballistic n = [ (Blunt, n) ]
208 transmit _ Piercing n = [ (Blunt, n) ] 216 transmit _ Piercing n = [ (Blunt, n) ]
209 transmit _ _ _ = [] 217 transmit _ _ _ = []
diff --git a/src/Sequence/Contact/Types/Internal.hs b/src/Sequence/Contact/Types/Internal.hs
index 6fde09d..fef2792 100644
--- a/src/Sequence/Contact/Types/Internal.hs
+++ b/src/Sequence/Contact/Types/Internal.hs
@@ -14,10 +14,29 @@ import Control.Lens
14 14
15import Data.CaseInsensitive (CI) 15import Data.CaseInsensitive (CI)
16 16
17import Data.ExtendedReal
18
17newtype Hitzone = Hitzone { _hitzone :: CI String } 19newtype Hitzone = Hitzone { _hitzone :: CI String }
18 deriving (Eq, Ord) 20 deriving (Eq, Ord)
19 21
20type Armor = DamageType -> Formula Stats 22type Int' = Extended Int
23
24type Armor = DamageType -> FormulaM Stats Int'
25
26instance Enum a => Enum (Extended a) where
27 toEnum = Finite . toEnum
28 fromEnum (Finite n) = fromEnum n
29 fromEnum _ = error "Cannot convert infinite value to Int"
30
31instance Real a => Real (Extended a) where
32 toRational (Finite r) = toRational r
33 toRational _ = error "Connot convert infinite value to Rational"
34
35instance Integral a => Integral (Extended a) where
36 toInteger (Finite n) = toInteger n
37 toInteger _ = error "Connot convert infinite value to Integer"
38 quotRem (Finite x) (Finite y) = quotRem x y & over each Finite
39 quotRem x _ = (0, x)
21 40
22data DamageType = Ballistic 41data DamageType = Ballistic
23 | Piercing 42 | Piercing