Skip to content
This repository
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 71 lines (62 sloc) 2.838 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
module Roguestar.Lib.CharacterAdvancement
    (CharacterBumpResult(..),
     characterFitness,
     bumpCharacter,
     characterLevel,
     newCharacterLevel,
     newCharacterClass)
    where

import qualified Data.Map as Map
import Roguestar.Lib.CreatureData
import Roguestar.Lib.PowerUpData
import Roguestar.Lib.PersistantData

data CharacterBumpResult =
    CharacterAwarded { character_points_awarded :: Integer,
                        character_new :: Creature }
  | CharacterAdvanced { character_new_level :: Integer,
                        character_new :: Creature }
  | CharacterForced { character_new_character_class :: CharacterClass,
                        character_new :: Creature }

-- |
-- Increases the character score by the set amount.
-- If the score is high enough that the character can advance to the next level,
-- this function will apply that advancement.
--
bumpCharacter :: PowerUpData -> Creature -> CharacterBumpResult
bumpCharacter (ForceCharacter character_class) c =
        if CharacterClass character_class `elem` Map.keys (creature_traits c)
            then bumpCharacter (AwardCharacter $ characterFitness new_character - characterFitness c) c
            else CharacterForced {
                character_new_character_class = character_class,
                character_new = new_character }
    where new_character = applyToCreature character_class c
bumpCharacter (AwardCharacter n) c =
        if fitness_gain >= bumped_score
            then CharacterAdvanced {
                character_new_level = characterLevel new_character,
                character_new = new_character { creature_points = bumped_score - fitness_gain } }
            else CharacterAwarded {
                character_points_awarded = n,
                character_new = c { creature_points = bumped_score } }
    where bumped_score = creature_points c + n
          fitness_gain = characterFitness new_character - characterFitness c
          new_character = applyToCreature (Map.keys $ creature_traits c) c

newCharacterClass :: CharacterBumpResult -> Maybe CharacterClass
newCharacterClass (CharacterForced character_class _) = Just character_class
newCharacterClass _ = Nothing

newCharacterLevel :: CharacterBumpResult -> Maybe Integer
newCharacterLevel (CharacterAdvanced new_level _) = Just new_level
newCharacterLevel _ = Nothing

-- |
-- Answers the character level. This is the maximum of the number
-- of levels the Character has in any class.
-- A rather arbitrary (non-representative of game balance)
-- measure of Character power.
--
characterLevel :: Creature -> Integer
characterLevel = maximum . Map.elems . creature_traits

-- |
-- Answers the estimated fitness (powerfulness) of the Character.
--
characterFitness :: Creature -> Integer
characterFitness c = sum $ (Map.elems $ creature_traits c)

Something went wrong with that request. Please try again.