Use wielded items to calculate damage

Use whatever items the character has wielded, if any, to calculate the
damage they deal when attacking. Currently this shortcuts handedness to
just use the *first* item they have equipped, which is fine since it's
currently only possible to equip something in the right hand.
This commit is contained in:
Griffin Smith 2019-12-23 10:47:09 -05:00
parent 6622dd3018
commit 8ecefddbd4
2 changed files with 35 additions and 26 deletions

View file

@ -238,7 +238,7 @@ handleCommand ShowInventory = showPanel InventoryPanel >> continue
handleCommand Wield = do
uses (character . inventory . backpack)
(V.mapMaybe (\item ->
(WieldedItem item) <$> item ^. Item.itemType . wieldable))
WieldedItem item <$> item ^. Item.itemType . wieldable))
>>= \case
Empty -> say_ ["wield", "nothing"]
wieldables ->
@ -431,7 +431,7 @@ attackAt pos =
$ \(MenuResult creature) -> attackCreature creature
where
attackCreature (creatureID, creature) = do
charDamage <- use $ character . characterDamage
charDamage <- uses character characterDamage
let creature' = Creature.damage charDamage creature
msgParams = object ["creature" A..= creature']
if Creature.isDead creature'

View file

@ -37,20 +37,23 @@ module Xanthous.Entities.Character
--------------------------------------------------------------------------------
import Xanthous.Prelude
--------------------------------------------------------------------------------
import Test.QuickCheck
import Test.QuickCheck.Instances.Vector ()
import Test.QuickCheck.Arbitrary.Generic
import Brick
import Data.Aeson.Generic.DerivingVia
import Data.Aeson (ToJSON, FromJSON)
import Data.Coerce (coerce)
import Brick
import Data.Aeson.Generic.DerivingVia
import Data.Aeson (ToJSON, FromJSON)
import Data.Coerce (coerce)
import Test.QuickCheck
import Test.QuickCheck.Instances.Vector ()
import Test.QuickCheck.Arbitrary.Generic
--------------------------------------------------------------------------------
import Xanthous.Util.QuickCheck
import Xanthous.Game.State
import Xanthous.Entities.Item
import Xanthous.Data
(TicksPerTile, Hitpoints, Per, Ticks, (|*|), positioned, Positioned(..))
import Xanthous.Entities.RawTypes (WieldableItem, wieldable)
import Xanthous.Util.QuickCheck
import Xanthous.Game.State
import Xanthous.Entities.Item
import Xanthous.Data
( TicksPerTile, Hitpoints, Per, Ticks, (|*|), positioned
, Positioned(..)
)
import Xanthous.Entities.RawTypes (WieldableItem, wieldable)
import qualified Xanthous.Entities.RawTypes as Raw
--------------------------------------------------------------------------------
data WieldedItem = WieldedItem
@ -116,11 +119,9 @@ doubleHanded = prism' DoubleHanded $ \case
DoubleHanded i -> Just i
_ -> Nothing
wieldedItems :: Traversal' Wielded Item
wieldedItems k (DoubleHanded wielded) = DoubleHanded <$> wieldedItem k wielded
wieldedItems k (Hands l r) = Hands
<$> (_Just . wieldedItem) k l
<*> (_Just . wieldedItem) k r
wieldedItems :: Traversal' Wielded WieldedItem
wieldedItems k (DoubleHanded wielded) = DoubleHanded <$> k wielded
wieldedItems k (Hands l r) = Hands <$> _Just k l <*> _Just k r
data Inventory = Inventory
{ _backpack :: Vector Item
@ -137,7 +138,7 @@ makeFieldsNoPrefix ''Inventory
items :: Traversal' Inventory Item
items k (Inventory bp w) = Inventory
<$> traversed k bp
<*> wieldedItems k w
<*> (wieldedItems . wieldedItem) k w
type instance Element Inventory = Item
@ -165,15 +166,15 @@ instance Semigroup Inventory where
let backpack' = inv ^. backpack <> inv ^. backpack
(wielded', backpack'') = case (inv ^. wielded, inv ^. wielded) of
(wielded, wielded@(DoubleHanded _)) ->
(wielded, backpack' <> fromList (wielded ^.. wieldedItems))
(wielded, backpack' <> fromList (wielded ^.. wieldedItems . wieldedItem))
(wielded, wielded@(Hands (Just _) (Just _))) ->
(wielded, backpack' <> fromList (wielded ^.. wieldedItems))
(wielded, backpack' <> fromList (wielded ^.. wieldedItems . wieldedItem))
(wielded, Hands Nothing Nothing) -> (wielded, backpack')
(Hands Nothing Nothing, wielded) -> (wielded, backpack')
(Hands (Just l) Nothing, Hands Nothing (Just r)) ->
(Hands (Just l) (Just r), backpack')
(wielded@(DoubleHanded _), wielded) ->
(wielded, backpack' <> fromList (wielded ^.. wieldedItems))
(wielded, backpack' <> fromList (wielded ^.. wieldedItems . wieldedItem))
(Hands Nothing (Just r), Hands Nothing (Just r)) ->
(Hands Nothing (Just r), r ^. wieldedItem <| backpack')
(Hands Nothing r, Hands (Just l) Nothing) ->
@ -194,7 +195,6 @@ instance Monoid Inventory where
data Character = Character
{ _inventory :: !Inventory
, _characterName :: !(Maybe Text)
, _characterDamage :: !Hitpoints
, _characterHitpoints' :: !Double
, _speed :: TicksPerTile
}
@ -245,11 +245,20 @@ mkCharacter :: Character
mkCharacter = Character
{ _inventory = mempty
, _characterName = Nothing
, _characterDamage = 1
, _characterHitpoints' = fromIntegral initialHitpoints
, _speed = defaultSpeed
}
defaultCharacterDamage :: Hitpoints
defaultCharacterDamage = 1
-- | Returns the damage that the character currently does with an attack
-- TODO use double-handed/left-hand/right-hand here
characterDamage :: Character -> Hitpoints
characterDamage
= fromMaybe defaultCharacterDamage
. preview (inventory . wielded . wieldedItems . wieldableItem . Raw.damage)
isDead :: Character -> Bool
isDead = (== 0) . characterHitpoints