packages feed

roguestar-engine-0.4.0.1: src/DeviceActivation.hs

module DeviceActivation
    (DeviceActivationOutcomeType(..),
     DeviceActivationOutcome(..),
     resolveDeviceActivation)
    where

import DB
import Creature
import CreatureData
import ToolData
import Data.Ratio

data DeviceActivationOutcomeType = 
    DeviceActivated
  | DeviceFailed
  | DeviceCriticalFailed

data DeviceActivationOutcome = DeviceActivationOutcome {
    dao_outcome_type :: DeviceActivationOutcomeType,
    dao_skill_roll :: Integer,
    dao_energy :: Integer,
    dao_activation_time :: Rational }

-- | Given a device, and a primary and secondary roll, determine the outcome of activating the device.
-- The better the primary roll, the less likely that the device will fail, while the better the secondary 
-- roll, the more energy the device will output.
resolveDeviceActivation :: (DBReadable db,DeviceType d) => CreatureAbility -> CreatureAbility -> CreatureAbility -> d -> CreatureRef -> db DeviceActivationOutcome
resolveDeviceActivation primary_ability secondary_ability timing_ability device creature_ref =
    do primary_roll <- rollCreatureAbilityScore primary_ability (deviceAccuracy device) creature_ref
       secondary_roll <- rollCreatureAbilityScore secondary_ability (deviceOutput device) creature_ref
       timing_roll <- rollCreatureAbilityScore timing_ability (deviceSpeed device) creature_ref
       let timing = roll_ideal secondary_roll % (roll_ideal timing_roll + roll_ideal secondary_roll)
           daoF = case () of
                      () | roll_actual primary_roll == 0 -> DeviceActivationOutcome DeviceCriticalFailed 0 (deviceOutput device * deviceSize device)
                      () | roll_actual primary_roll <= deviceSize device -> DeviceActivationOutcome DeviceFailed (roll_actual primary_roll) (deviceOutput device)
                      () | otherwise -> DeviceActivationOutcome DeviceActivated (roll_actual primary_roll * deviceSize device) (roll_actual secondary_roll)
       return $ daoF timing