diff options
author | Griffin Smith <root@gws.fyi> | 2019-10-13T16·37-0400 |
---|---|---|
committer | Griffin Smith <root@gws.fyi> | 2019-10-13T16·37-0400 |
commit | 8a4220df830adb6f1616ca02dd06902474fd25df (patch) | |
tree | b78e5eea207e77ca82759bf05a26a77ae3729c09 /src/Xanthous/AI/Gormlak.hs | |
parent | 8d36fb4af2f938d96c8d6c22ccc575d0a98d0d38 (diff) |
Implement speed and ticks
Gormlaks now move 1/8th the speed of the character, which means we can run away from them - yay! Unfortunately this also introduces a bug where they'll eventually get stuck and not do anything, so I'll be tackling that next.
Diffstat (limited to 'src/Xanthous/AI/Gormlak.hs')
-rw-r--r-- | src/Xanthous/AI/Gormlak.hs | 72 |
1 files changed, 48 insertions, 24 deletions
diff --git a/src/Xanthous/AI/Gormlak.hs b/src/Xanthous/AI/Gormlak.hs index db504c1e7d3a..e13eb8ffe71a 100644 --- a/src/Xanthous/AI/Gormlak.hs +++ b/src/Xanthous/AI/Gormlak.hs @@ -10,10 +10,17 @@ import Control.Monad.Random import Data.Aeson (object) import qualified Data.Aeson as A -------------------------------------------------------------------------------- -import Xanthous.Data (Positioned(..), diffPositions, stepTowards, isUnit) +import Xanthous.Data + ( Positioned(..), positioned, position + , diffPositions, stepTowards, isUnit + , Ticks, (|*|), invertedRate + ) import Xanthous.Data.EntityMap import qualified Xanthous.Entities.Creature as Creature -import Xanthous.Entities.Creature (Creature) +import Xanthous.Entities.Creature + ( Creature, hippocampus, creatureType + , destination, destinationProgress, destinationPosition + ) import Xanthous.Entities.Character (Character) import qualified Xanthous.Entities.Character as Character import qualified Xanthous.Entities.RawTypes as Raw @@ -28,30 +35,47 @@ import Xanthous.Monad (say) stepGormlak :: (MonadState GameState m, MonadRandom m) - => Positioned Creature + => Ticks + -> Positioned Creature -> m (Positioned Creature) -stepGormlak pe@(Positioned pos creature) = do - newPos <- do - canSeeCharacter <- uses entities $ canSee (entityIs @Character) pos vision - if canSeeCharacter - then do - charPos <- use characterPosition - if isUnit (pos `diffPositions` charPos) - then attackCharacter $> pos - else pure $ pos `stepTowards` charPos +stepGormlak ticks pe@(Positioned pos creature) = do + dest <- maybe (selectDestination pos creature) pure + $ creature ^. hippocampus . destination + let progress' = + dest ^. destinationProgress + + creature ^. creatureType . Raw.speed . invertedRate |*| ticks + if progress' < 1 + then pure + $ pe + & positioned . hippocampus . destination + ?~ (dest & destinationProgress .~ progress') else do - lines <- uses entities $ linesOfSight pos (Creature.visionRadius creature) - line <- choose $ weightedBy length lines - pure $ fromMaybe pos $ fmap fst . headMay =<< tailMay =<< line - collisionAt newPos >>= \case - Nothing -> pure $ Positioned newPos creature - Just Stop -> pure pe - Just Combat -> do - ents <- use $ entities . atPosition newPos - when (any (entityIs @Character) ents) attackCharacter - pure pe - + let newPos = dest ^. destinationPosition + remainingSpeed = progress' - 1 + newDest <- selectDestination newPos creature + <&> destinationProgress +~ remainingSpeed + let pe' = pe & positioned . hippocampus . destination ?~ newDest + collisionAt newPos >>= \case + Nothing -> pure $ pe' & position .~ newPos + Just Stop -> pure pe' + Just Combat -> do + ents <- use $ entities . atPosition newPos + when (any (entityIs @Character) ents) attackCharacter + pure pe' where + selectDestination pos' creature' = Creature.destinationFromPos <$> do + canSeeCharacter <- uses entities $ canSee (entityIs @Character) pos' vision + if canSeeCharacter + then do + charPos <- use characterPosition + if isUnit (pos' `diffPositions` charPos) + then attackCharacter $> pos' + else pure $ pos' `stepTowards` charPos + else do + lines <- uses entities $ linesOfSight pos' (Creature.visionRadius creature') + line <- choose $ weightedBy length lines + pure $ fromMaybe pos' $ fmap fst . headMay =<< tailMay =<< line + vision = Creature.visionRadius creature attackCharacter = do say ["combat", "creatureAttack"] $ object [ "creature" A..= creature ] @@ -60,7 +84,7 @@ stepGormlak pe@(Positioned pos creature) = do newtype GormlakBrain = GormlakBrain Creature instance Brain GormlakBrain where - step = fmap coerce . stepGormlak . coerce + step ticks = fmap coerce . stepGormlak ticks . coerce -------------------------------------------------------------------------------- |