From 7b90b02049f891f752fff7e0e228511077bbcb84 Mon Sep 17 00:00:00 2001 From: Griffin Smith Date: Fri, 15 Nov 2019 21:20:01 -0500 Subject: Recover character hitpoints over time Wrap hitpoints in a newtype, and recover character hitpoints over time --- src/Xanthous/Entities/Character.hs | 33 +++++++++++++++++++++++---------- src/Xanthous/Entities/Creature.hs | 4 ++-- src/Xanthous/Entities/RawTypes.hs | 4 ++-- 3 files changed, 27 insertions(+), 14 deletions(-) (limited to 'src/Xanthous/Entities') diff --git a/src/Xanthous/Entities/Character.hs b/src/Xanthous/Entities/Character.hs index e3cbb2c038ff..271492d6ce26 100644 --- a/src/Xanthous/Entities/Character.hs +++ b/src/Xanthous/Entities/Character.hs @@ -1,10 +1,13 @@ +{-# LANGUAGE ViewPatterns #-} {-# LANGUAGE TemplateHaskell #-} module Xanthous.Entities.Character ( Character(..) , characterName , inventory , characterDamage + , characterHitpoints' , characterHitpoints + , hitpointRecoveryRate , speed -- * @@ -22,17 +25,18 @@ import Test.QuickCheck.Arbitrary.Generic import Brick import Data.Aeson.Generic.DerivingVia import Data.Aeson (ToJSON, FromJSON) +import Data.Coerce (coerce) -------------------------------------------------------------------------------- import Xanthous.Entities import Xanthous.Entities.Item -import Xanthous.Data (TicksPerTile) +import Xanthous.Data (TicksPerTile, Hitpoints, Per, Ticks, (|*|), positioned) -------------------------------------------------------------------------------- data Character = Character { _inventory :: !(Vector Item) , _characterName :: !(Maybe Text) - , _characterDamage :: !Word - , _characterHitpoints :: !Word + , _characterDamage :: !Hitpoints + , _characterHitpoints' :: !Double , _speed :: TicksPerTile } deriving stock (Show, Eq, Generic) @@ -42,6 +46,9 @@ data Character = Character Character makeLenses ''Character +characterHitpoints :: Character -> Hitpoints +characterHitpoints = views characterHitpoints' floor + scrollOffset :: Int scrollOffset = 5 @@ -52,8 +59,11 @@ instance Draw Character where rreg = (2 * scrollOffset, 2 * scrollOffset) drawPriority = const maxBound -- Character should always be on top, for now --- the character does not (yet) have a mind of its own -instance Brain Character where step = brainVia Brainless +instance Brain Character where + step ticks = (pure .) $ positioned . characterHitpoints' %~ \hp -> + if hp > fromIntegral initialHitpoints + then hp + else hp + hitpointRecoveryRate |*| ticks instance Entity Character where blocksVision _ = False @@ -62,9 +72,12 @@ instance Entity Character where instance Arbitrary Character where arbitrary = genericArbitrary -initialHitpoints :: Word +initialHitpoints :: Hitpoints initialHitpoints = 10 +hitpointRecoveryRate :: Double `Per` Ticks +hitpointRecoveryRate = 1.0 / (15 * coerce defaultSpeed) + defaultSpeed :: TicksPerTile defaultSpeed = 100 @@ -73,17 +86,17 @@ mkCharacter = Character { _inventory = mempty , _characterName = Nothing , _characterDamage = 1 - , _characterHitpoints = initialHitpoints + , _characterHitpoints' = fromIntegral initialHitpoints , _speed = defaultSpeed } isDead :: Character -> Bool -isDead = (== 0) . view characterHitpoints +isDead = (== 0) . characterHitpoints pickUpItem :: Item -> Character -> Character pickUpItem item = inventory %~ (item <|) -damage :: Word -> Character -> Character -damage amount = characterHitpoints %~ \case +damage :: Hitpoints -> Character -> Character +damage (fromIntegral -> amount) = characterHitpoints' %~ \case n | n <= amount -> 0 | otherwise -> n - amount diff --git a/src/Xanthous/Entities/Creature.hs b/src/Xanthous/Entities/Creature.hs index 4ad751a58240..11cad1ce6b8b 100644 --- a/src/Xanthous/Entities/Creature.hs +++ b/src/Xanthous/Entities/Creature.hs @@ -78,7 +78,7 @@ initialHippocampus = Hippocampus Nothing data Creature = Creature { _creatureType :: !CreatureType - , _hitpoints :: !Word + , _hitpoints :: !Hitpoints , _hippocampus :: !Hippocampus } deriving stock (Eq, Show, Generic) @@ -99,7 +99,7 @@ newWithType _creatureType = _hippocampus = initialHippocampus in Creature {..} -damage :: Word -> Creature -> Creature +damage :: Hitpoints -> Creature -> Creature damage amount = hitpoints %~ \hp -> if hp <= amount then 0 diff --git a/src/Xanthous/Entities/RawTypes.hs b/src/Xanthous/Entities/RawTypes.hs index fd66140376bb..09b250fb310d 100644 --- a/src/Xanthous/Entities/RawTypes.hs +++ b/src/Xanthous/Entities/RawTypes.hs @@ -29,13 +29,13 @@ import Data.Aeson (ToJSON, FromJSON) -------------------------------------------------------------------------------- import Xanthous.Entities (EntityChar, HasChar(..)) import Xanthous.Messages (Message(..)) -import Xanthous.Data (TicksPerTile) +import Xanthous.Data (TicksPerTile, Hitpoints) -------------------------------------------------------------------------------- data CreatureType = CreatureType { _name :: !Text , _description :: !Text , _char :: !EntityChar - , _maxHitpoints :: !Word + , _maxHitpoints :: !Hitpoints , _friendly :: !Bool , _speed :: !TicksPerTile } -- cgit 1.4.1