{-# 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