packages feed

roguestar-engine-0.4.0.0: src/ToolData.hs

{-# LANGUAGE OverloadedStrings #-}
module ToolData 
    (Tool(..),
     fromSphere,
     sphere,
     Device,
     PseudoDevice(..),
     DeviceKind(..),
     DeviceFunction(..),
     DeviceType(..),
     deviceName,
     deviceOutput,
     deviceAccuracy,
     deviceSpeed,
     deviceDurability,
     deviceSize,
     deviceChromalite,
     deviceMaterial,
     deviceGas,
     improvised,
     phase_pistol,
     phaser,
     phase_rifle,
     kinetic_fleuret,
     kinetic_sabre)
    where

import Substances
import qualified Data.ByteString.Char8 as B

data Tool = DeviceTool DeviceFunction Device
          | Sphere Substance
    deriving (Read,Show,Eq)

-- | Get the substance type of a material sphere, if it is one.
fromSphere :: Tool -> Maybe Substance
fromSphere (Sphere s) = Just s
fromSphere _ = Nothing

sphere :: (SubstanceType a) => a -> Tool
sphere = Sphere . toSubstance

data DeviceFunction = Gun | Sword
            deriving (Read,Show,Eq)

data DeviceKind =
    Pistol
  | Carbine
  | Rifle
  | Fleuret
  | Sabre
        deriving (Read,Show,Eq)

kindToFunction :: DeviceKind -> (DeviceFunction,Integer)
kindToFunction Pistol = (Gun,1)
kindToFunction Carbine = (Gun,3)
kindToFunction Rifle = (Gun,5)
kindToFunction Fleuret = (Sword,2)
kindToFunction Sabre = (Sword,4) 

-- | Any kind of device that is constructed from a power cell, materal, and gas medium,
-- using the various device rules to determine it's power.
data Device = Device {
   device_name :: B.ByteString,
   device_chromalite :: Chromalite,
   device_material :: Material,
   device_gas :: Gas,
   device_size :: Integer }
     deriving (Eq,Read,Show)

-- | Anything that operates like a device, but isn't.  For example, an unarmed attack.
data PseudoDevice = PseudoDevice {
    pdevice_accuracy :: Integer,
    pdevice_output :: Integer,
    pdevice_speed :: Integer,
    pdevice_size :: Integer }

class DeviceType d where
    toPseudoDevice :: d -> PseudoDevice

instance DeviceType Device where
    toPseudoDevice d = let chromalite = chromalitePotency $ device_chromalite d
                           gas = gasValue $ device_gas d
                           material = material_critical_value $ materialValue $ device_material d
                           size = device_size d
        in PseudoDevice {
               pdevice_accuracy = min chromalite material + chromalite,
               pdevice_output = min chromalite gas + chromalite,
               pdevice_speed = gas + material,
               pdevice_size = size }

instance DeviceType PseudoDevice where
    toPseudoDevice = id

device :: B.ByteString -> DeviceKind -> Chromalite -> Material -> Gas -> Tool
device s dk c m g = DeviceTool func (Device s c m g size)
    where (func,size) = kindToFunction dk

improvised :: DeviceKind -> Chromalite -> Material -> Gas -> Tool
improvised dk c m g = device ("improvised_" `B.append` B.pack (show dk)) dk c m g

phase_pistol :: Tool
phase_pistol = device "phase_pistol" Pistol Caerulite Zinc Flourine

phaser :: Tool
phaser = device "phaser" Carbine Caerulite Zinc Flourine

phase_rifle :: Tool
phase_rifle = device "phase_rifle" Rifle Caerulite Zinc Flourine

kinetic_fleuret :: Tool
kinetic_fleuret = device "kinetic_fleuret" Fleuret Ionidium Aluminum Nitrogen

kinetic_sabre :: Tool
kinetic_sabre = device "kinetic_sabre" Sabre Ionidium Aluminum Nitrogen

deviceName :: Device -> B.ByteString
deviceName = device_name

deviceDurability :: Device -> Integer
deviceDurability d = device_size d * (material_construction_value $ materialValue $ device_material d)

deviceOutput :: (DeviceType d) => d -> Integer
deviceOutput = pdevice_output . toPseudoDevice

deviceAccuracy :: (DeviceType d) => d -> Integer
deviceAccuracy = pdevice_accuracy . toPseudoDevice

deviceSpeed :: (DeviceType d) => d -> Integer
deviceSpeed = pdevice_speed . toPseudoDevice

deviceSize :: (DeviceType d) => d -> Integer
deviceSize = pdevice_size . toPseudoDevice

deviceChromalite :: Device -> Chromalite
deviceChromalite = device_chromalite

deviceMaterial :: Device -> Material
deviceMaterial = device_material

deviceGas :: Device -> Gas
deviceGas = device_gas