858 lines
21 KiB
Rust
858 lines
21 KiB
Rust
use crate::gui::Ancestry;
|
|
use crate::gui::Class;
|
|
use bracket_lib::prelude::*;
|
|
use serde::{ Deserialize, Serialize };
|
|
use specs::error::NoError;
|
|
use specs::prelude::*;
|
|
use specs::saveload::{ ConvertSaveload, Marker };
|
|
use specs_derive::*;
|
|
use std::collections::{ HashMap, HashSet };
|
|
|
|
// Serialization helper code. We need to implement ConvertSaveload for each type that contains an
|
|
// Entity.
|
|
pub struct SerializeMe;
|
|
// Special component that exists to help serialize the game data
|
|
#[derive(Component, Serialize, Deserialize, Clone)]
|
|
pub struct SerializationHelper {
|
|
pub map: super::map::Map,
|
|
}
|
|
|
|
#[derive(Component, Serialize, Deserialize, Clone)]
|
|
pub struct DMSerializationHelper {
|
|
pub map: super::map::MasterDungeonMap,
|
|
pub log: std::collections::BTreeMap<i32, Vec<crate::gamelog::LogFragment>>,
|
|
pub event_counts: HashMap<String, i32>,
|
|
pub events: HashMap<u32, Vec<String>>,
|
|
}
|
|
|
|
#[derive(Component, ConvertSaveload, Clone)]
|
|
pub struct Position {
|
|
pub x: i32,
|
|
pub y: i32,
|
|
}
|
|
|
|
#[derive(Component, Serialize, Deserialize, Clone)]
|
|
pub struct OtherLevelPosition {
|
|
pub x: i32,
|
|
pub y: i32,
|
|
pub id: i32,
|
|
}
|
|
|
|
#[derive(Debug, Component, ConvertSaveload, Clone)]
|
|
pub struct Renderable {
|
|
pub glyph: FontCharType, // Legacy, and for drawing the morgue map.
|
|
pub sprite: String,
|
|
pub sprite_alt: Option<String>,
|
|
pub fg: RGB,
|
|
pub fg_alt: Option<RGB>,
|
|
pub render_order: i32,
|
|
pub render_order_alt: Option<i32>,
|
|
pub offset: (f32, f32),
|
|
pub offset_alt: Option<(f32, f32)>,
|
|
// 0 = always on top: particle effects
|
|
// 1 = things that should appear infront of the player: railings, etc.
|
|
// 2 = the player
|
|
// 3 = other mobs
|
|
// 4 = interactable items
|
|
// 5 = other props: table, etc.
|
|
}
|
|
|
|
impl Renderable {
|
|
pub fn new(glyph: FontCharType, sprite: String, fg: RGB, render_order: i32) -> Self {
|
|
Self {
|
|
glyph,
|
|
sprite,
|
|
sprite_alt: None,
|
|
fg,
|
|
fg_alt: None,
|
|
render_order,
|
|
render_order_alt: None,
|
|
offset: (0.0, 0.0),
|
|
offset_alt: None,
|
|
}
|
|
}
|
|
pub fn swap(&mut self) {
|
|
let sprite = self.swap_sprite();
|
|
let fg = self.swap_fg();
|
|
let render_order = self.swap_render_order();
|
|
let offset = self.swap_offset();
|
|
let did_something = sprite || fg || render_order || offset;
|
|
if !did_something {
|
|
unreachable!(
|
|
".swap() was called on a Renderable component, but nothing happened. {:?}",
|
|
self
|
|
);
|
|
}
|
|
}
|
|
pub fn swap_sprite(&mut self) -> bool {
|
|
if let Some(sprite_alt) = &mut self.sprite_alt {
|
|
std::mem::swap(&mut self.sprite, sprite_alt);
|
|
return true;
|
|
}
|
|
false
|
|
}
|
|
pub fn swap_fg(&mut self) -> bool {
|
|
if let Some(fg_alt) = &mut self.fg_alt {
|
|
std::mem::swap(&mut self.fg, fg_alt);
|
|
return true;
|
|
}
|
|
false
|
|
}
|
|
pub fn swap_render_order(&mut self) -> bool {
|
|
if let Some(render_order_alt) = &mut self.render_order_alt {
|
|
std::mem::swap(&mut self.render_order, render_order_alt);
|
|
return true;
|
|
}
|
|
false
|
|
}
|
|
pub fn swap_offset(&mut self) -> bool {
|
|
if let Some(offset_alt) = &mut self.offset_alt {
|
|
std::mem::swap(&mut self.offset, offset_alt);
|
|
return true;
|
|
}
|
|
false
|
|
}
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Bleeds {
|
|
pub colour: RGB,
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Player {}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Faction {
|
|
pub name: String,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)]
|
|
pub enum Movement {
|
|
Static,
|
|
Random,
|
|
RandomWaypoint {
|
|
path: Option<Vec<usize>>,
|
|
},
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct MoveMode {
|
|
pub mode: Movement,
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Prop {}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct LootTable {
|
|
pub table: String,
|
|
pub chance: f32,
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Energy {
|
|
pub current: i32,
|
|
pub speed: i32,
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Clock {}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct TakingTurn {}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Quips {
|
|
pub available: Vec<String>,
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Mind {}
|
|
|
|
#[derive(Component, ConvertSaveload, Clone)]
|
|
pub struct Viewshed {
|
|
pub visible_tiles: Vec<Point>,
|
|
pub range: i32,
|
|
pub dirty: bool,
|
|
}
|
|
|
|
#[derive(Component, ConvertSaveload, Clone)]
|
|
pub struct Telepath {
|
|
pub telepath_tiles: Vec<Point>,
|
|
pub range: i32,
|
|
pub dirty: bool,
|
|
}
|
|
|
|
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
|
pub struct Name {
|
|
pub name: String,
|
|
pub plural: String,
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct BlocksTile {}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct BlocksVisibility {}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Door {
|
|
pub open: bool,
|
|
pub locked: bool,
|
|
pub blocks_vis: bool,
|
|
pub blocks_move: bool,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Copy, Clone, PartialEq)]
|
|
pub enum HungerState {
|
|
Satiated,
|
|
Normal,
|
|
Hungry,
|
|
Weak,
|
|
Fainting,
|
|
Starving,
|
|
}
|
|
|
|
#[derive(Component, Serialize, Deserialize, Clone)]
|
|
pub struct HungerClock {
|
|
pub state: HungerState,
|
|
pub duration: i32,
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct ProvidesNutrition {}
|
|
|
|
#[derive(Component, Serialize, Deserialize, Clone)]
|
|
pub struct HasAncestry {
|
|
pub name: Ancestry,
|
|
}
|
|
|
|
#[derive(Component, Serialize, Deserialize, Clone)]
|
|
pub struct HasClass {
|
|
pub name: Class,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Pool {
|
|
pub max: i32,
|
|
pub current: i32,
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Pools {
|
|
pub hit_points: Pool,
|
|
pub mana: Pool,
|
|
pub xp: i32,
|
|
pub bac: i32,
|
|
pub level: i32,
|
|
pub weight: f32,
|
|
pub god: bool,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Attribute {
|
|
pub base: i32,
|
|
pub bonuses: i32,
|
|
pub exercise: i32,
|
|
}
|
|
|
|
impl Attribute {
|
|
pub fn new(base: i32) -> Self {
|
|
Self {
|
|
base,
|
|
bonuses: 0,
|
|
exercise: 0,
|
|
}
|
|
}
|
|
// Raw attribute score. e.g. 10 base, + 4 from armour: 14 strength.
|
|
pub fn current(&self) -> i32 {
|
|
self.base + self.bonuses
|
|
}
|
|
// Attribute bonus. e.g. 14 strength = +2, 8 strength = -1
|
|
pub fn modifier(&self) -> i32 {
|
|
crate::gamesystem::attr_bonus(self.current())
|
|
}
|
|
pub fn improve(&mut self) {
|
|
if self.exercise < 50 {
|
|
self.exercise += 1;
|
|
}
|
|
}
|
|
pub fn abuse(&mut self) {
|
|
if self.exercise > -50 {
|
|
self.exercise -= 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)]
|
|
pub enum Skill {
|
|
Melee,
|
|
Defence,
|
|
Magic,
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Skills {
|
|
pub skills: HashMap<Skill, i32>,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
|
pub struct KnownSpell {
|
|
pub display_name: String,
|
|
pub mana_cost: i32,
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct KnownSpells {
|
|
pub list: Vec<KnownSpell>,
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct GrantsSpell {
|
|
pub spell: String,
|
|
}
|
|
|
|
// TODO: GrantsIntrinsic, Intrinsics, etc. ? Done the same way as spells?
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Attributes {
|
|
pub strength: Attribute,
|
|
pub dexterity: Attribute,
|
|
pub constitution: Attribute,
|
|
pub intelligence: Attribute,
|
|
pub wisdom: Attribute,
|
|
pub charisma: Attribute,
|
|
}
|
|
|
|
impl Attributes {
|
|
pub const STR: i32 = 0;
|
|
pub const DEX: i32 = 1;
|
|
pub const CON: i32 = 2;
|
|
pub const INT: i32 = 3;
|
|
pub const WIS: i32 = 4;
|
|
pub const CHA: i32 = 5;
|
|
pub fn default() -> Self {
|
|
Self {
|
|
strength: Attribute::new(10),
|
|
dexterity: Attribute::new(10),
|
|
constitution: Attribute::new(10),
|
|
intelligence: Attribute::new(10),
|
|
wisdom: Attribute::new(10),
|
|
charisma: Attribute::new(10),
|
|
}
|
|
}
|
|
pub fn with_stats(str: i32, dex: i32, con: i32, int: i32, wis: i32, cha: i32) -> Self {
|
|
Self {
|
|
strength: Attribute::new(str),
|
|
dexterity: Attribute::new(dex),
|
|
constitution: Attribute::new(con),
|
|
intelligence: Attribute::new(int),
|
|
wisdom: Attribute::new(wis),
|
|
charisma: Attribute::new(cha),
|
|
}
|
|
}
|
|
pub fn attr_from_index(&self, attr: i32) -> &Attribute {
|
|
match attr {
|
|
Self::STR => &self.strength,
|
|
Self::DEX => &self.dexterity,
|
|
Self::CON => &self.constitution,
|
|
Self::INT => &self.intelligence,
|
|
Self::WIS => &self.wisdom,
|
|
Self::CHA => &self.charisma,
|
|
_ => unreachable!("Tried to get an attribute that doesn't exist."),
|
|
}
|
|
}
|
|
pub fn exercise(&mut self, attr: i32, improve: bool) {
|
|
match attr {
|
|
Self::STR => {
|
|
if improve {
|
|
self.strength.improve();
|
|
} else {
|
|
self.strength.abuse();
|
|
}
|
|
}
|
|
Self::DEX => {
|
|
if improve {
|
|
self.dexterity.improve();
|
|
} else {
|
|
self.dexterity.abuse();
|
|
}
|
|
}
|
|
Self::CON => {
|
|
if improve {
|
|
self.constitution.improve();
|
|
} else {
|
|
self.constitution.abuse();
|
|
}
|
|
}
|
|
Self::INT => {
|
|
if improve {
|
|
self.intelligence.improve();
|
|
} else {
|
|
self.intelligence.abuse();
|
|
}
|
|
}
|
|
Self::WIS => {
|
|
if improve {
|
|
self.wisdom.improve();
|
|
} else {
|
|
self.wisdom.abuse();
|
|
}
|
|
}
|
|
Self::CHA => {
|
|
if improve {
|
|
self.charisma.improve();
|
|
} else {
|
|
self.charisma.abuse();
|
|
}
|
|
}
|
|
_ => unreachable!("Tried to exercise an attribute that doesn't exist."),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
|
pub struct WantsToMelee {
|
|
pub target: Entity,
|
|
}
|
|
|
|
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
|
pub struct GrantsXP {
|
|
pub amount: i32,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)]
|
|
pub enum BUC {
|
|
Cursed,
|
|
Uncursed,
|
|
Blessed,
|
|
}
|
|
|
|
impl BUC {
|
|
pub fn noncursed(&self) -> bool {
|
|
match self {
|
|
BUC::Cursed => false,
|
|
_ => true,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Eq, PartialEq, Hash, Clone)]
|
|
pub struct Beatitude {
|
|
pub buc: BUC,
|
|
pub known: bool,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize, Copy, Clone, PartialEq, Eq)]
|
|
pub enum ItemType {
|
|
Amulet,
|
|
Weapon,
|
|
Armour,
|
|
Comestible,
|
|
Scroll,
|
|
Spellbook,
|
|
Potion,
|
|
Ring,
|
|
Wand,
|
|
}
|
|
|
|
impl ItemType {
|
|
pub fn string(&self) -> &str {
|
|
match self {
|
|
ItemType::Amulet => "Amulets",
|
|
ItemType::Weapon => "Weapons",
|
|
ItemType::Armour => "Armour",
|
|
ItemType::Comestible => "Comestibles",
|
|
ItemType::Scroll => "Scrolls",
|
|
ItemType::Spellbook => "Spellbooks",
|
|
ItemType::Potion => "Potions",
|
|
ItemType::Ring => "Rings",
|
|
ItemType::Wand => "Wands",
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Item {
|
|
pub weight: f32, // in lbs
|
|
pub value: f32, // base
|
|
pub category: ItemType,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)]
|
|
pub enum MagicItemClass {
|
|
Common,
|
|
Uncommon,
|
|
Rare,
|
|
VeryRare,
|
|
Legendary,
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct MagicItem {
|
|
pub class: MagicItemClass,
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct ObfuscatedName {
|
|
pub name: String,
|
|
pub plural: String,
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct IdentifiedItem {
|
|
pub name: String,
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Stackable {}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct EquipmentChanged {}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct WantsToRemoveKey {}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct WantsToDelete {}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Key {
|
|
pub idx: usize,
|
|
}
|
|
|
|
#[derive(PartialEq, Copy, Clone, Serialize, Deserialize)]
|
|
pub enum BurdenLevel {
|
|
Burdened,
|
|
Strained,
|
|
Overloaded,
|
|
}
|
|
|
|
#[derive(Component, Serialize, Deserialize, Clone)]
|
|
pub struct Burden {
|
|
pub level: BurdenLevel,
|
|
}
|
|
|
|
#[derive(PartialEq, Copy, Clone, Serialize, Deserialize)]
|
|
pub enum EquipmentSlot {
|
|
Melee,
|
|
Shield,
|
|
Head,
|
|
Body,
|
|
Hands,
|
|
Feet,
|
|
Neck,
|
|
Back,
|
|
}
|
|
|
|
#[derive(PartialEq, Copy, Clone, Serialize, Deserialize)]
|
|
pub enum WeaponAttribute {
|
|
Strength,
|
|
Dexterity,
|
|
Finesse,
|
|
}
|
|
|
|
#[derive(Component, Serialize, Deserialize, Clone)]
|
|
pub struct MeleeWeapon {
|
|
pub damage_type: DamageType,
|
|
pub attribute: WeaponAttribute,
|
|
pub damage_n_dice: i32,
|
|
pub damage_die_type: i32,
|
|
pub damage_bonus: i32,
|
|
pub hit_bonus: i32,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Clone)]
|
|
pub struct NaturalAttack {
|
|
pub name: String,
|
|
pub damage_type: DamageType,
|
|
pub damage_n_dice: i32,
|
|
pub damage_die_type: i32,
|
|
pub damage_bonus: i32,
|
|
pub hit_bonus: i32,
|
|
}
|
|
|
|
#[derive(Component, Serialize, Deserialize, Clone)]
|
|
pub struct NaturalAttacks {
|
|
pub attacks: Vec<NaturalAttack>,
|
|
}
|
|
|
|
#[derive(Component, ConvertSaveload, Clone)]
|
|
pub struct ArmourClassBonus {
|
|
pub amount: i32,
|
|
}
|
|
|
|
#[derive(Component, ConvertSaveload, Clone)]
|
|
pub struct ToHitBonus {
|
|
pub amount: i32,
|
|
}
|
|
|
|
#[derive(Component, Serialize, Deserialize, Clone)]
|
|
pub struct Equippable {
|
|
pub slot: EquipmentSlot,
|
|
}
|
|
|
|
#[derive(Component, ConvertSaveload, Clone)]
|
|
pub struct Equipped {
|
|
pub owner: Entity,
|
|
pub slot: EquipmentSlot,
|
|
}
|
|
|
|
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
|
pub struct ProvidesHealing {
|
|
pub n_dice: i32,
|
|
pub sides: i32,
|
|
pub modifier: i32,
|
|
}
|
|
|
|
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, Serialize, Deserialize)]
|
|
pub enum DamageType {
|
|
Physical,
|
|
Magic, // e.g. magic missiles, silvered weapons
|
|
Fire, // e.g. fireball
|
|
Cold, // e.g. cone of cold
|
|
Poison, // e.g. poison gas
|
|
Forced, // Bypasses any immunities. e.g. Hunger ticks.
|
|
}
|
|
|
|
impl DamageType {
|
|
pub fn is_magic(&self) -> bool {
|
|
match self {
|
|
DamageType::Magic | DamageType::Fire | DamageType::Cold => true,
|
|
_ => false,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, PartialEq, Copy, Clone, Serialize, Deserialize)]
|
|
pub enum DamageModifier {
|
|
None,
|
|
Weakness,
|
|
Resistance,
|
|
Immune,
|
|
}
|
|
|
|
impl DamageModifier {
|
|
const NONE_MOD: f32 = 1.0;
|
|
const WEAK_MOD: f32 = 2.0;
|
|
const RESIST_MOD: f32 = 0.5;
|
|
const IMMUNE_MOD: f32 = 0.0;
|
|
|
|
pub fn multiplier(&self) -> f32 {
|
|
match self {
|
|
DamageModifier::None => Self::NONE_MOD,
|
|
DamageModifier::Weakness => Self::WEAK_MOD,
|
|
DamageModifier::Resistance => Self::RESIST_MOD,
|
|
DamageModifier::Immune => Self::IMMUNE_MOD,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Component, Serialize, Deserialize, Debug, Clone)]
|
|
pub struct HasDamageModifiers {
|
|
pub modifiers: HashMap<DamageType, DamageModifier>,
|
|
}
|
|
|
|
impl HasDamageModifiers {
|
|
pub fn modifier(&self, damage_type: &DamageType) -> &DamageModifier {
|
|
self.modifiers.get(damage_type).unwrap_or(&DamageModifier::None)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
pub enum Intrinsic {
|
|
Regeneration, // Regenerate 1 HP on every tick
|
|
Speed, // 4/3x speed multiplier
|
|
}
|
|
|
|
impl Intrinsic {
|
|
pub fn describe(&self) -> &str {
|
|
match self {
|
|
Intrinsic::Regeneration => "regenerates health",
|
|
Intrinsic::Speed => "is hasted",
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Component, Serialize, Deserialize, Debug, Clone)]
|
|
pub struct Intrinsics {
|
|
pub list: HashSet<Intrinsic>,
|
|
}
|
|
|
|
impl Intrinsics {
|
|
pub fn describe(&self) -> String {
|
|
let mut descriptions = Vec::new();
|
|
for intrinsic in &self.list {
|
|
descriptions.push(intrinsic.describe());
|
|
}
|
|
match descriptions.len() {
|
|
0 =>
|
|
unreachable!("describe() should never be called on an empty Intrinsics component."),
|
|
1 => format!("It {}.", descriptions[0]),
|
|
_ => {
|
|
let last = descriptions.pop().unwrap();
|
|
let joined = descriptions.join(", ");
|
|
format!("It {}, and {}.", joined, last)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Component, Serialize, Deserialize, Debug, Clone)]
|
|
pub struct IntrinsicChanged {
|
|
pub gained: HashSet<Intrinsic>,
|
|
pub lost: HashSet<Intrinsic>,
|
|
}
|
|
|
|
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
|
pub struct InflictsDamage {
|
|
pub damage_type: DamageType,
|
|
pub n_dice: i32,
|
|
pub sides: i32,
|
|
pub modifier: i32,
|
|
}
|
|
|
|
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
|
pub struct Ranged {
|
|
pub range: i32,
|
|
}
|
|
|
|
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
|
pub struct AOE {
|
|
pub radius: i32,
|
|
}
|
|
|
|
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
|
pub struct Confusion {
|
|
pub turns: i32,
|
|
}
|
|
|
|
#[derive(Component, Serialize, Deserialize, Clone)]
|
|
pub struct Blind {}
|
|
|
|
#[derive(Component, Serialize, Deserialize, Clone)]
|
|
pub struct MagicMapper {}
|
|
|
|
#[derive(Component, Debug, ConvertSaveload)]
|
|
pub struct InBackpack {
|
|
pub owner: Entity,
|
|
}
|
|
|
|
#[derive(Component, Serialize, Deserialize, Clone)]
|
|
pub struct WantsToAssignKey {}
|
|
|
|
#[derive(Component, Debug, ConvertSaveload)]
|
|
pub struct WantsToPickupItem {
|
|
pub collected_by: Entity,
|
|
pub item: Entity,
|
|
}
|
|
|
|
#[derive(Component, Debug, ConvertSaveload)]
|
|
pub struct WantsToDropItem {
|
|
pub item: Entity,
|
|
}
|
|
|
|
#[derive(Component, Debug, ConvertSaveload)]
|
|
pub struct WantsToRemoveItem {
|
|
pub item: Entity,
|
|
}
|
|
|
|
#[derive(Component, Debug, ConvertSaveload)]
|
|
pub struct WantsToUseItem {
|
|
pub item: Entity,
|
|
pub target: Option<Point>,
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct WantsToApproach {
|
|
pub idx: i32,
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct WantsToFlee {
|
|
pub indices: Vec<usize>, // Dijkstra
|
|
}
|
|
|
|
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
|
pub struct Chasing {
|
|
pub target: Entity,
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Consumable {}
|
|
|
|
#[derive(Component, Debug, ConvertSaveload)]
|
|
pub struct Charges {
|
|
pub uses: i32,
|
|
pub max_uses: i32,
|
|
}
|
|
|
|
#[derive(Component, Serialize, Deserialize, Clone)]
|
|
pub struct SpawnParticleLine {
|
|
pub glyph: FontCharType,
|
|
pub sprite: String,
|
|
pub tail_glyph: FontCharType,
|
|
pub tail_sprite: String,
|
|
pub colour: RGB,
|
|
pub lifetime_ms: f32,
|
|
pub trail_colour: RGB,
|
|
pub trail_lifetime_ms: f32,
|
|
}
|
|
|
|
#[derive(Component, Serialize, Deserialize, Clone)]
|
|
pub struct SpawnParticleSimple {
|
|
pub glyph: FontCharType,
|
|
pub sprite: String,
|
|
pub colour: RGB,
|
|
pub lifetime_ms: f32,
|
|
}
|
|
|
|
#[derive(Component, Serialize, Deserialize, Clone)]
|
|
pub struct SpawnParticleBurst {
|
|
pub glyph: FontCharType,
|
|
pub sprite: String,
|
|
pub head_glyph: FontCharType,
|
|
pub head_sprite: String,
|
|
pub tail_glyph: FontCharType,
|
|
pub tail_sprite: String,
|
|
pub colour: RGB,
|
|
pub lerp: RGB,
|
|
pub lifetime_ms: f32,
|
|
pub trail_colour: RGB,
|
|
pub trail_lifetime_ms: f32,
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Destructible {}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct ProvidesRemoveCurse {}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct ProvidesIdentify {}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Digger {}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Hidden {}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct SingleActivation {}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct IdentifiedBeatitude {}
|
|
|
|
#[derive(Component, Clone, ConvertSaveload)]
|
|
pub struct ParticleLifetime {
|
|
pub lifetime_ms: f32,
|
|
}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct EntryTrigger {}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct EntityMoved {}
|
|
|
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
|
pub struct MultiAttack {}
|