https://git.spwbk.site/swatson/rs-rl/raw/master/src/components.rs
___________________________________
use specs::prelude::*;
use specs_derive::*;
use rltk::{RGB};
use serde::{Serialize, Deserialize};
use specs::saveload::{Marker, ConvertSaveload};
use specs::error::NoError;

// COMPONENTS
#[derive(Component, Serialize, Deserialize, Clone)]
pub struct ParticleLifetime {
   pub lifetime_ms : f32
}

#[derive(Component, Debug, ConvertSaveload, Clone)]
pub struct WantsToRemoveItem {
   pub item : Entity
}

#[derive(Component, ConvertSaveload, Clone)]
pub struct MeleePowerBonus {
   pub power : i32
}

#[derive(Component, ConvertSaveload, Clone)]
pub struct DefenseBonus {
   pub defense : i32
}

#[derive(Component, ConvertSaveload, Clone)]
pub struct Equipped {
   pub owner : Entity,
   pub slot : EquipmentSlot
}

#[derive(PartialEq, Copy, Clone, Serialize, Deserialize)]
pub enum EquipmentSlot { Melee, Shield }

#[derive(Component, Serialize, Deserialize, Clone)]
pub struct Equippable {
   pub slot : EquipmentSlot
}

// Special component that exists to help serialize the game data
#[derive(Component, Serialize, Deserialize, Clone)]
pub struct SerializationHelper {
   pub map : super::map::Map
}

pub struct SerializeMe;

#[derive(Component, Debug, ConvertSaveload, Clone)]
pub struct AreaOfEffect {
   pub radius : i32
}

#[derive(Component, Debug, ConvertSaveload, Clone)]
pub struct Ranged {
   pub range : i32
}

#[derive(Component, Debug, ConvertSaveload, Clone)]
pub struct InflictsDamage {
   pub damage : i32
}

#[derive(Component, Debug, Serialize, Deserialize, Clone)]
pub struct Consumable {}

#[derive(Component, Debug, ConvertSaveload)]
pub struct WantsToDropItem {
   pub item : Entity
}

#[derive(Component, Debug, ConvertSaveload)]
pub struct WantsToUseItem {
   pub item : Entity,
   pub target: Option<rltk::Point>
}

#[derive(Component, Debug, ConvertSaveload)]
pub struct WantsToPickupItem {
   pub collected_by : Entity,
   pub item : Entity
}

#[derive(Component, Debug, ConvertSaveload)]
pub struct InBackpack {
   pub owner : Entity
}

#[derive(Component, Debug, Serialize, Deserialize, Clone)]
pub struct Item {}

#[derive(Component, Debug, ConvertSaveload, Clone)]
pub struct ProvidesHealing {
   pub heal_amount : i32
}

#[derive(Component, Debug, ConvertSaveload, Clone)]
pub struct SufferDamage {
   pub amount : Vec<i32>
}
impl SufferDamage {
   pub fn new_damage(store: &mut WriteStorage<SufferDamage>, victim: Entity, amount: i32) {
       if let Some(suffering) = store.get_mut(victim) {
           suffering.amount.push(amount);
       } else {
           let dmg = SufferDamage { amount : vec![amount] };
           store.insert(victim, dmg).expect("Unable to insert damage");
       }
   }
}

#[derive(Component, Debug, ConvertSaveload, Clone)]
pub struct WantsToMelee {
   pub target : Entity
}

#[derive(Component, Debug, ConvertSaveload, Clone)]
pub struct CombatStats {
   pub max_hp : i32,
   pub hp : i32,
   pub defense : i32,
   pub power : i32
}

#[derive(Component, Debug, Serialize, Deserialize, Clone)]
pub struct BlocksTile {}

#[derive(Component, Debug, ConvertSaveload, Clone)]
pub struct Name {
   pub name : String
}

#[derive(Component, Debug, Serialize, Deserialize, Clone)]
pub struct Monster {}

#[derive(Component, ConvertSaveload, Clone)]
pub struct Viewshed {
   pub visible_tiles : Vec<rltk::Point>,
   pub range : i32,
   pub dirty: bool
}

#[derive(Component, ConvertSaveload, Clone)]
pub struct Position {
   pub x: i32,
   pub y: i32,
}

#[derive(Component, ConvertSaveload, Clone)]
pub struct Renderable {
   pub glyph: rltk::FontCharType,
   pub fg: RGB,
   pub bg: RGB,
   pub render_order : i32
}

#[derive(Component, Serialize, Deserialize, Clone)]
pub struct Player {}