diff options
author | Gregor Kleen <pngwjpgh@users.noreply.github.com> | 2016-07-09 14:45:28 +0200 |
---|---|---|
committer | Gregor Kleen <pngwjpgh@users.noreply.github.com> | 2016-07-09 14:45:28 +0200 |
commit | a016d9c507e906cba12f8d39d42a93e09ab4e7ec (patch) | |
tree | 4b13e71cfde0b1ec5488165c30045241fb0e1923 /src | |
parent | 90c94957cb7f1fef4df051d18700a34ecb797293 (diff) | |
download | 2017-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
Diffstat (limited to 'src')
-rw-r--r-- | src/Main.hs | 9 | ||||
-rw-r--r-- | src/Sequence/Contact/Types.hs | 28 | ||||
-rw-r--r-- | src/Sequence/Contact/Types/Internal.hs | 21 |
3 files changed, 44 insertions, 14 deletions
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 | |||
24 | import Data.Ratio | 24 | import Data.Ratio |
25 | import Data.List | 25 | import Data.List |
26 | import Data.Ord | 26 | import Data.Ord |
27 | import Data.ExtendedReal | ||
27 | 28 | ||
28 | import Control.Monad.Reader (ask) | 29 | import Control.Monad.Reader (ask) |
29 | import Control.Monad.State | 30 | import Control.Monad.State |
@@ -41,7 +42,7 @@ makePrisms ''Hitzone | |||
41 | makePrisms ''DamageType | 42 | makePrisms ''DamageType |
42 | 43 | ||
43 | instance {-# OVERLAPS #-} Default Armor where | 44 | instance {-# OVERLAPS #-} Default Armor where |
44 | def = const 0 | 45 | def = const $ return 0 |
45 | 46 | ||
46 | makeLenses ''TestResult | 47 | makeLenses ''TestResult |
47 | 48 | ||
@@ -107,7 +108,9 @@ makeLenses ''Stats | |||
107 | 108 | ||
108 | instance Default Stats where | 109 | instance 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 | ||
172 | sDead :: Fold Stats (FormulaM Stats Bool) | 175 | sDead, sUnconscious, sDestroyed :: Fold Stats (FormulaM Stats Bool) |
173 | sDead = folding $ do | 176 | sDead = 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 | |||
178 | sUnconscious :: Fold Stats (FormulaM Stats Bool) | ||
179 | sUnconscious = folding $ do | 180 | sUnconscious = 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 |
184 | sDestroyed = folding $ do | ||
185 | robustness <- preview $ sRobustness . _Just | ||
186 | damage <- view sTotalDamage | ||
187 | return $ liftM2 (>=) <$> Just (return damage) <*> robustness | ||
183 | 188 | ||
184 | absorb :: Armor -> DamageType -> Int -> FormulaM Stats (Map DamageType Int) | 189 | absorb :: Armor -> DamageType -> Int -> FormulaM Stats (Map DamageType Int) |
185 | absorb armor = absorb' Map.empty | 190 | absorb 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 | ||
15 | import Data.CaseInsensitive (CI) | 15 | import Data.CaseInsensitive (CI) |
16 | 16 | ||
17 | import Data.ExtendedReal | ||
18 | |||
17 | newtype Hitzone = Hitzone { _hitzone :: CI String } | 19 | newtype Hitzone = Hitzone { _hitzone :: CI String } |
18 | deriving (Eq, Ord) | 20 | deriving (Eq, Ord) |
19 | 21 | ||
20 | type Armor = DamageType -> Formula Stats | 22 | type Int' = Extended Int |
23 | |||
24 | type Armor = DamageType -> FormulaM Stats Int' | ||
25 | |||
26 | instance 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 | |||
31 | instance Real a => Real (Extended a) where | ||
32 | toRational (Finite r) = toRational r | ||
33 | toRational _ = error "Connot convert infinite value to Rational" | ||
34 | |||
35 | instance 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 | ||
22 | data DamageType = Ballistic | 41 | data DamageType = Ballistic |
23 | | Piercing | 42 | | Piercing |