rawmaster macros
This commit is contained in:
parent
8c11951258
commit
fe19a449e3
3 changed files with 147 additions and 190 deletions
|
|
@ -6,7 +6,7 @@
|
||||||
"weight": 1,
|
"weight": 1,
|
||||||
"value": 50,
|
"value": 50,
|
||||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||||
"effects": { "provides_healing": "4d4+2" },
|
"effects": { "healing": "4d4+2" },
|
||||||
"magic": { "class": "uncommon", "naming": "potion" }
|
"magic": { "class": "uncommon", "naming": "potion" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
"weight": 1,
|
"weight": 1,
|
||||||
"value": 25,
|
"value": 25,
|
||||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||||
"effects": { "provides_healing": "2d4+2" },
|
"effects": { "healing": "2d4+2" },
|
||||||
"magic": { "class": "uncommon", "naming": "potion" }
|
"magic": { "class": "uncommon", "naming": "potion" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
"weight": 0.5,
|
"weight": 0.5,
|
||||||
"value": 50,
|
"value": 50,
|
||||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||||
"effects": { "ranged": "12", "provides_healing": "1d4+2" },
|
"effects": { "ranged": "12", "healing": "1d4+2" },
|
||||||
"magic": { "class": "uncommon", "naming": "scroll" }
|
"magic": { "class": "uncommon", "naming": "scroll" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
"weight": 0.5,
|
"weight": 0.5,
|
||||||
"value": 200,
|
"value": 200,
|
||||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||||
"effects": { "ranged": "12", "aoe": "3", "provides_healing": "1d4+2" },
|
"effects": { "ranged": "12", "aoe": "3", "healing": "1d4+2" },
|
||||||
"magic": { "class": "rare", "naming": "scroll" }
|
"magic": { "class": "rare", "naming": "scroll" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -125,8 +125,7 @@
|
||||||
"renderable": { "glyph": ")", "fg": "#808080", "bg": "#000000", "order": 2 },
|
"renderable": { "glyph": ")", "fg": "#808080", "bg": "#000000", "order": 2 },
|
||||||
"weight": 1,
|
"weight": 1,
|
||||||
"value": 2,
|
"value": 2,
|
||||||
"flags": ["EQUIP_MELEE", "FINESSE"],
|
"equip": { "slot": "EQUIP_MELEE", "flag": "FINESSE", "damage": "1d4", "to_hit": 0 }
|
||||||
"effects": { "base_damage": "1d4" }
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "equip_shortsword",
|
"id": "equip_shortsword",
|
||||||
|
|
@ -134,8 +133,7 @@
|
||||||
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 2 },
|
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 2 },
|
||||||
"weight": 2,
|
"weight": 2,
|
||||||
"value": 10,
|
"value": 10,
|
||||||
"flags": ["EQUIP_MELEE", "STRENGTH"],
|
"equip": { "slot": "EQUIP_MELEE", "flag": "STRENGTH", "damage": "1d6", "to_hit": 0 }
|
||||||
"effects": { "base_damage": "1d6" }
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "equip_rapier",
|
"id": "equip_rapier",
|
||||||
|
|
@ -143,8 +141,7 @@
|
||||||
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 2 },
|
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 2 },
|
||||||
"weight": 2,
|
"weight": 2,
|
||||||
"value": 10,
|
"value": 10,
|
||||||
"flags": ["EQUIP_MELEE", "FINESSE"],
|
"equip": { "slot": "EQUIP_MELEE", "flag": "FINESSE", "damage": "1d8", "to_hit": 0 }
|
||||||
"effects": { "base_damage": "1d8" }
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "equip_pitchfork",
|
"id": "equip_pitchfork",
|
||||||
|
|
@ -152,8 +149,7 @@
|
||||||
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 2 },
|
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 2 },
|
||||||
"weight": 2,
|
"weight": 2,
|
||||||
"value": 5,
|
"value": 5,
|
||||||
"flags": ["EQUIP_MELEE", "FINESSE"],
|
"equip": { "slot": "EQUIP_MELEE", "flag": "FINESSE", "damage": "1d6", "to_hit": 0 }
|
||||||
"effects": { "base_damage": "1d6" }
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "equip_sickle",
|
"id": "equip_sickle",
|
||||||
|
|
@ -161,8 +157,7 @@
|
||||||
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 2 },
|
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 2 },
|
||||||
"weight": 2,
|
"weight": 2,
|
||||||
"value": 5,
|
"value": 5,
|
||||||
"flags": ["EQUIP_MELEE", "FINESSE"],
|
"equip": { "slot": "EQUIP_MELEE", "flag": "FINESSE", "damage": "1d6", "to_hit": 0 }
|
||||||
"effects": { "base_damage": "1d6" }
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "equip_handaxe",
|
"id": "equip_handaxe",
|
||||||
|
|
@ -170,8 +165,7 @@
|
||||||
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 2 },
|
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 2 },
|
||||||
"weight": 2,
|
"weight": 2,
|
||||||
"value": 5,
|
"value": 5,
|
||||||
"flags": ["EQUIP_MELEE", "FINESSE"],
|
"equip": { "slot": "EQUIP_MELEE", "flag": "STRENGTH", "damage": "1d6", "to_hit": 0 }
|
||||||
"effects": { "base_damage": "1d6" }
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "equip_longsword",
|
"id": "equip_longsword",
|
||||||
|
|
@ -179,8 +173,7 @@
|
||||||
"renderable": { "glyph": ")", "fg": "#FFF8DC", "bg": "#000000", "order": 2 },
|
"renderable": { "glyph": ")", "fg": "#FFF8DC", "bg": "#000000", "order": 2 },
|
||||||
"weight": 3,
|
"weight": 3,
|
||||||
"value": 15,
|
"value": 15,
|
||||||
"flags": ["EQUIP_MELEE", "STRENGTH"],
|
"equip": { "slot": "EQUIP_MELEE", "flag": "STRENGTH", "damage": "1d8", "to_hit": 0 }
|
||||||
"effects": { "base_damage": "1d8" }
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "equip_smallshield",
|
"id": "equip_smallshield",
|
||||||
|
|
@ -198,7 +191,7 @@
|
||||||
"weight": 6,
|
"weight": 6,
|
||||||
"value": 10,
|
"value": 10,
|
||||||
"flags": ["EQUIP_SHIELD"],
|
"flags": ["EQUIP_SHIELD"],
|
||||||
"effects": { "ac": "2", "melee_power_bonus": "-1" }
|
"effects": { "ac": "2" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "equip_largeshield",
|
"id": "equip_largeshield",
|
||||||
|
|
@ -207,7 +200,7 @@
|
||||||
"weight": 12,
|
"weight": 12,
|
||||||
"value": 35,
|
"value": 35,
|
||||||
"flags": ["EQUIP_SHIELD"],
|
"flags": ["EQUIP_SHIELD"],
|
||||||
"effects": { "ac": "4", "melee_power_bonus": "-2" }
|
"effects": { "ac": "3" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "equip_body_weakleather",
|
"id": "equip_body_weakleather",
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ pub struct Item {
|
||||||
pub renderable: Option<Renderable>,
|
pub renderable: Option<Renderable>,
|
||||||
pub weight: Option<f32>,
|
pub weight: Option<f32>,
|
||||||
pub value: Option<f32>,
|
pub value: Option<f32>,
|
||||||
|
pub equip: Option<Equippable>,
|
||||||
pub flags: Option<Vec<String>>,
|
pub flags: Option<Vec<String>>,
|
||||||
pub effects: Option<HashMap<String, String>>,
|
pub effects: Option<HashMap<String, String>>,
|
||||||
pub magic: Option<MagicItem>,
|
pub magic: Option<MagicItem>,
|
||||||
|
|
@ -19,6 +20,14 @@ pub struct Name {
|
||||||
pub plural: String,
|
pub plural: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
pub struct Equippable {
|
||||||
|
pub slot: String,
|
||||||
|
pub flag: String,
|
||||||
|
pub damage: String,
|
||||||
|
pub to_hit: Option<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct Renderable {
|
pub struct Renderable {
|
||||||
pub glyph: String,
|
pub glyph: String,
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,85 @@ use specs::prelude::*;
|
||||||
use specs::saveload::{MarkedBuilder, SimpleMarker};
|
use specs::saveload::{MarkedBuilder, SimpleMarker};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
|
macro_rules! apply_effects {
|
||||||
|
($effects:expr, $eb:expr) => {
|
||||||
|
for effect in $effects.iter() {
|
||||||
|
let effect_name = effect.0.as_str();
|
||||||
|
match effect_name {
|
||||||
|
"healing" => {
|
||||||
|
let (n_dice, sides, modifier) = parse_dice_string(effect.1.as_str());
|
||||||
|
$eb = $eb.with(ProvidesHealing { n_dice, sides, modifier })
|
||||||
|
}
|
||||||
|
"ranged" => $eb = $eb.with(Ranged { range: effect.1.parse::<i32>().unwrap() }),
|
||||||
|
"damage" => {
|
||||||
|
let (n_dice, sides, modifier) = parse_dice_string(effect.1.as_str());
|
||||||
|
$eb = $eb.with(InflictsDamage { n_dice, sides, modifier })
|
||||||
|
}
|
||||||
|
"aoe" => $eb = $eb.with(AOE { radius: effect.1.parse::<i32>().unwrap() }),
|
||||||
|
"confusion" => $eb = $eb.with(Confusion { turns: effect.1.parse::<i32>().unwrap() }),
|
||||||
|
"ac" => $eb = $eb.with(ArmourClassBonus { amount: effect.1.parse::<i32>().unwrap() }),
|
||||||
|
"magicmapper" => $eb = $eb.with(MagicMapper {}),
|
||||||
|
"digger" => $eb = $eb.with(Digger {}),
|
||||||
|
_ => console::log(format!("Warning: effect {} not implemented.", effect_name)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! apply_flags {
|
||||||
|
($flags:expr, $eb:expr) => {
|
||||||
|
for flag in $flags.iter() {
|
||||||
|
match flag.as_str() {
|
||||||
|
// --- PROP/ITEM FLAGS BEGIN HERE ---
|
||||||
|
"HIDDEN" => $eb = $eb.with(Hidden {}),
|
||||||
|
"BLOCKS_TILE" => $eb = $eb.with(BlocksTile {}),
|
||||||
|
"BLOCKS_VISIBILITY" => $eb = $eb.with(BlocksVisibility {}),
|
||||||
|
"ENTRY_TRIGGER" => $eb = $eb.with(EntryTrigger {}),
|
||||||
|
"SINGLE_ACTIVATION" => $eb = $eb.with(SingleActivation {}),
|
||||||
|
"DOOR" => $eb = $eb.with(Door { open: false }),
|
||||||
|
// RESTORES NUTRITION
|
||||||
|
"FOOD" => $eb = $eb.with(ProvidesNutrition {}),
|
||||||
|
// IS DELETED ON USE
|
||||||
|
"CONSUMABLE" => $eb = $eb.with(Consumable {}),
|
||||||
|
// HAS CHARGES
|
||||||
|
"CHARGES" => $eb = $eb.with(Charges { uses: 3, max_uses: 3 }),
|
||||||
|
// CAN BE DESTROYED BY DAMAGE
|
||||||
|
"DESTRUCTIBLE" => $eb = $eb.with(Destructible {}),
|
||||||
|
// EQUIP SLOTS
|
||||||
|
"EQUIP_MELEE" => $eb = $eb.with(Equippable { slot: EquipmentSlot::Melee }),
|
||||||
|
"EQUIP_SHIELD" => $eb = $eb.with(Equippable { slot: EquipmentSlot::Shield }),
|
||||||
|
"EQUIP_HEAD" => $eb = $eb.with(Equippable { slot: EquipmentSlot::Head }),
|
||||||
|
"EQUIP_BODY" => $eb = $eb.with(Equippable { slot: EquipmentSlot::Body }),
|
||||||
|
"EQUIP_FEET" => $eb = $eb.with(Equippable { slot: EquipmentSlot::Feet }),
|
||||||
|
"EQUIP_HANDS" => $eb = $eb.with(Equippable { slot: EquipmentSlot::Hands }),
|
||||||
|
"EQUIP_NECK" => $eb = $eb.with(Equippable { slot: EquipmentSlot::Neck }),
|
||||||
|
"EQUIP_BACK" => $eb = $eb.with(Equippable { slot: EquipmentSlot::Back }),
|
||||||
|
// --- MOB FLAGS BEGIN HERE ---
|
||||||
|
// RACES
|
||||||
|
"IS_PLAYER" => $eb = $eb.with(Player {}),
|
||||||
|
"IS_HUMAN" => $eb = $eb.with(HasAncestry { name: Ancestry::Human }),
|
||||||
|
"IS_DWARF" => $eb = $eb.with(HasAncestry { name: Ancestry::Dwarf }),
|
||||||
|
"IS_ELF" => $eb = $eb.with(HasAncestry { name: Ancestry::Elf }),
|
||||||
|
"IS_CATFOLK" => $eb = $eb.with(HasAncestry { name: Ancestry::Catfolk }),
|
||||||
|
"IS_GNOME" => $eb = $eb.with(HasAncestry { name: Ancestry::Gnome }),
|
||||||
|
// FACTIONS
|
||||||
|
"MINDLESS" => $eb = $eb.with(Faction { name: "mindless".to_string() }),
|
||||||
|
"NEUTRAL" => $eb = $eb.with(Faction { name: "neutral".to_string() }),
|
||||||
|
"HERBIVORE" => $eb = $eb.with(Faction { name: "herbivore".to_string() }),
|
||||||
|
"CARNIVORE" => $eb = $eb.with(Faction { name: "carnivore".to_string() }),
|
||||||
|
// MOVEMENT FLAGS (DEFAULTS TO WANDERING)
|
||||||
|
"STATIC" => $eb = $eb.with(MoveMode { mode: Movement::Static }),
|
||||||
|
"RANDOM_PATH" => $eb = $eb.with(MoveMode { mode: Movement::RandomWaypoint { path: None } }),
|
||||||
|
// ATTRIBUTES/MISC
|
||||||
|
"SMALL_GROUP" => {} // These flags are for region spawning,
|
||||||
|
"LARGE_GROUP" => {} // and don't need to apply a component.
|
||||||
|
"MULTIATTACK" => $eb = $eb.with(MultiAttack {}),
|
||||||
|
_ => rltk::console::log(format!("Unrecognised flag: {}", flag.as_str())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub enum SpawnType {
|
pub enum SpawnType {
|
||||||
AtPosition { x: i32, y: i32 },
|
AtPosition { x: i32, y: i32 },
|
||||||
Equipped { by: Entity },
|
Equipped { by: Entity },
|
||||||
|
|
@ -159,7 +238,7 @@ pub fn spawn_named_item(
|
||||||
eb = eb.with(get_renderable_component(renderable));
|
eb = eb.with(get_renderable_component(renderable));
|
||||||
}
|
}
|
||||||
// BEATITUDE
|
// BEATITUDE
|
||||||
let mut buc = if let Some(buc_status) = buc {
|
let buc = if let Some(buc_status) = buc {
|
||||||
buc_status
|
buc_status
|
||||||
} else {
|
} else {
|
||||||
match roll {
|
match roll {
|
||||||
|
|
@ -168,60 +247,15 @@ pub fn spawn_named_item(
|
||||||
_ => BUC::Uncursed,
|
_ => BUC::Uncursed,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let mut weapon_type = -1;
|
|
||||||
if let Some(flags) = &item_template.flags {
|
|
||||||
for flag in flags.iter() {
|
|
||||||
match flag.as_str() {
|
|
||||||
"CONSUMABLE" => eb = eb.with(Consumable {}),
|
|
||||||
"DESTRUCTIBLE" => eb = eb.with(Destructible {}),
|
|
||||||
"CURSED" => buc = BUC::Cursed,
|
|
||||||
"BLESSED" => buc = BUC::Blessed,
|
|
||||||
"EQUIP_MELEE" => eb = eb.with(Equippable { slot: EquipmentSlot::Melee }),
|
|
||||||
"EQUIP_SHIELD" => eb = eb.with(Equippable { slot: EquipmentSlot::Shield }),
|
|
||||||
"EQUIP_HEAD" => eb = eb.with(Equippable { slot: EquipmentSlot::Head }),
|
|
||||||
"EQUIP_BODY" => eb = eb.with(Equippable { slot: EquipmentSlot::Body }),
|
|
||||||
"EQUIP_FEET" => eb = eb.with(Equippable { slot: EquipmentSlot::Feet }),
|
|
||||||
"EQUIP_HANDS" => eb = eb.with(Equippable { slot: EquipmentSlot::Hands }),
|
|
||||||
"EQUIP_NECK" => eb = eb.with(Equippable { slot: EquipmentSlot::Neck }),
|
|
||||||
"EQUIP_BACK" => eb = eb.with(Equippable { slot: EquipmentSlot::Back }),
|
|
||||||
"CHARGES" => eb = eb.with(Charges { uses: 3, max_uses: 3 }),
|
|
||||||
"FOOD" => eb = eb.with(ProvidesNutrition {}),
|
|
||||||
"STRENGTH" => weapon_type = 0,
|
|
||||||
"DEXTERITY" => weapon_type = 2,
|
|
||||||
"FINESSE" => weapon_type = 3,
|
|
||||||
_ => rltk::console::log(format!("Unrecognised flag: {}", flag.as_str())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
eb = eb.with(Beatitude { buc, known: true });
|
eb = eb.with(Beatitude { buc, known: true });
|
||||||
|
|
||||||
let mut base_damage = "1d4";
|
if let Some(flags) = &item_template.flags {
|
||||||
let mut hit_bonus = 0;
|
apply_flags!(flags, eb);
|
||||||
|
|
||||||
if let Some(effects_list) = &item_template.effects {
|
|
||||||
for effect in effects_list.iter() {
|
|
||||||
let effect_name = effect.0.as_str();
|
|
||||||
match effect_name {
|
|
||||||
"provides_healing" => {
|
|
||||||
let (n_dice, sides, modifier) = parse_dice_string(effect.1.as_str());
|
|
||||||
eb = eb.with(ProvidesHealing { n_dice, sides, modifier })
|
|
||||||
}
|
|
||||||
"ranged" => eb = eb.with(Ranged { range: effect.1.parse::<i32>().unwrap() }),
|
|
||||||
"damage" => {
|
|
||||||
let (n_dice, sides, modifier) = parse_dice_string(effect.1.as_str());
|
|
||||||
eb = eb.with(InflictsDamage { n_dice, sides, modifier })
|
|
||||||
}
|
|
||||||
"aoe" => eb = eb.with(AOE { radius: effect.1.parse::<i32>().unwrap() }),
|
|
||||||
"confusion" => eb = eb.with(Confusion { turns: effect.1.parse::<i32>().unwrap() }),
|
|
||||||
"base_damage" => base_damage = effect.1,
|
|
||||||
"hit_bonus" => hit_bonus = effect.1.parse::<i32>().unwrap(),
|
|
||||||
"ac" => eb = eb.with(ArmourClassBonus { amount: effect.1.parse::<i32>().unwrap() }),
|
|
||||||
"magicmapper" => eb = eb.with(MagicMapper {}),
|
|
||||||
"digger" => eb = eb.with(Digger {}),
|
|
||||||
_ => rltk::console::log(format!("Warning: effect {} not implemented.", effect_name)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if let Some(effects_list) = &item_template.effects {
|
||||||
|
apply_effects!(effects_list, eb);
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(magic_item) = &item_template.magic {
|
if let Some(magic_item) = &item_template.magic {
|
||||||
let item_class = match magic_item.class.as_str() {
|
let item_class = match magic_item.class.as_str() {
|
||||||
"common" => MagicItemClass::Common,
|
"common" => MagicItemClass::Common,
|
||||||
|
|
@ -231,7 +265,6 @@ pub fn spawn_named_item(
|
||||||
_ => MagicItemClass::Legendary,
|
_ => MagicItemClass::Legendary,
|
||||||
};
|
};
|
||||||
eb = eb.with(MagicItem { class: item_class });
|
eb = eb.with(MagicItem { class: item_class });
|
||||||
|
|
||||||
if !identified_items.contains(&item_template.name.name) {
|
if !identified_items.contains(&item_template.name.name) {
|
||||||
#[allow(clippy::single_match)]
|
#[allow(clippy::single_match)]
|
||||||
match magic_item.naming.as_str() {
|
match magic_item.naming.as_str() {
|
||||||
|
|
@ -263,20 +296,20 @@ pub fn spawn_named_item(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if weapon_type != -1 {
|
if let Some(weapon) = &item_template.equip {
|
||||||
let (n_dice, die_type, bonus) = parse_dice_string(base_damage);
|
let (n_dice, die_type, bonus) = parse_dice_string(weapon.damage.as_str());
|
||||||
let mut wpn = MeleeWeapon {
|
let weapon_attribute = match weapon.flag.as_str() {
|
||||||
attribute: WeaponAttribute::Strength,
|
"DEXTERITY" => WeaponAttribute::Dexterity,
|
||||||
|
"FINESSE" => WeaponAttribute::Finesse,
|
||||||
|
_ => WeaponAttribute::Strength,
|
||||||
|
};
|
||||||
|
let wpn = MeleeWeapon {
|
||||||
|
attribute: weapon_attribute,
|
||||||
damage_n_dice: n_dice,
|
damage_n_dice: n_dice,
|
||||||
damage_die_type: die_type,
|
damage_die_type: die_type,
|
||||||
damage_bonus: bonus,
|
damage_bonus: bonus,
|
||||||
hit_bonus: hit_bonus,
|
hit_bonus: weapon.to_hit.unwrap_or(0),
|
||||||
};
|
};
|
||||||
match weapon_type {
|
|
||||||
0 => wpn.attribute = WeaponAttribute::Strength,
|
|
||||||
1 => wpn.attribute = WeaponAttribute::Dexterity,
|
|
||||||
_ => wpn.attribute = WeaponAttribute::Finesse,
|
|
||||||
}
|
|
||||||
eb = eb.with(wpn);
|
eb = eb.with(wpn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -306,7 +339,6 @@ pub fn spawn_named_mob(
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut eb;
|
let mut eb;
|
||||||
let mut xp_value = 1;
|
|
||||||
// New entity with a position, name, combatstats, and viewshed
|
// New entity with a position, name, combatstats, and viewshed
|
||||||
eb = ecs.create_entity().marked::<SimpleMarker<SerializeMe>>();
|
eb = ecs.create_entity().marked::<SimpleMarker<SerializeMe>>();
|
||||||
eb = spawn_position(pos, eb, key, raws);
|
eb = spawn_position(pos, eb, key, raws);
|
||||||
|
|
@ -315,79 +347,23 @@ pub fn spawn_named_mob(
|
||||||
if let Some(renderable) = &mob_template.renderable {
|
if let Some(renderable) = &mob_template.renderable {
|
||||||
eb = eb.with(get_renderable_component(renderable));
|
eb = eb.with(get_renderable_component(renderable));
|
||||||
}
|
}
|
||||||
|
eb = eb.with(BlocksTile {});
|
||||||
|
eb = eb.with(Faction { name: "hostile".to_string() });
|
||||||
|
eb = eb.with(MoveMode { mode: Movement::Random });
|
||||||
|
let mut xp_value = 1;
|
||||||
let mut has_mind = true;
|
let mut has_mind = true;
|
||||||
let mut has_faction = false;
|
|
||||||
let mut blocks_tile = true;
|
|
||||||
let mut has_move_mode = false;
|
|
||||||
if let Some(flags) = &mob_template.flags {
|
if let Some(flags) = &mob_template.flags {
|
||||||
for flag in flags.iter() {
|
apply_flags!(flags, eb);
|
||||||
match flag.as_str() {
|
if flags.contains(&"MULTIATTACK".to_string()) {
|
||||||
"PASSABLE" => blocks_tile = false,
|
xp_value += 3;
|
||||||
"STATIC" => {
|
}
|
||||||
eb = eb.with(MoveMode { mode: Movement::Static });
|
if flags.contains(&"MINDLESS".to_string()) {
|
||||||
has_move_mode = true;
|
has_mind = false;
|
||||||
}
|
|
||||||
"RANDOM_PATH" => {
|
|
||||||
eb = eb.with(MoveMode { mode: Movement::RandomWaypoint { path: None } });
|
|
||||||
has_move_mode = true;
|
|
||||||
}
|
|
||||||
"MINDLESS" => {
|
|
||||||
eb = eb.with(Faction { name: "mindless".to_string() });
|
|
||||||
has_faction = true;
|
|
||||||
has_mind = false;
|
|
||||||
}
|
|
||||||
"NEUTRAL" => {
|
|
||||||
eb = eb.with(Faction { name: "neutral".to_string() });
|
|
||||||
has_faction = true;
|
|
||||||
}
|
|
||||||
"HERBIVORE" => {
|
|
||||||
eb = eb.with(Faction { name: "herbivore".to_string() });
|
|
||||||
has_faction = true;
|
|
||||||
}
|
|
||||||
"CARNIVORE" => {
|
|
||||||
eb = eb.with(Faction { name: "carnivore".to_string() });
|
|
||||||
has_faction = true;
|
|
||||||
}
|
|
||||||
"IS_GNOME" => {
|
|
||||||
eb = eb.with(HasAncestry { name: Ancestry::Gnome });
|
|
||||||
}
|
|
||||||
"IS_DWARF" => {
|
|
||||||
eb = eb.with(HasAncestry { name: Ancestry::Dwarf });
|
|
||||||
}
|
|
||||||
"IS_HUMAN" => {
|
|
||||||
eb = eb.with(HasAncestry { name: Ancestry::Human });
|
|
||||||
}
|
|
||||||
"IS_CATFOLK" => {
|
|
||||||
eb = eb.with(HasAncestry { name: Ancestry::Catfolk });
|
|
||||||
}
|
|
||||||
"IS_Elf" => {
|
|
||||||
eb = eb.with(HasAncestry { name: Ancestry::Elf });
|
|
||||||
}
|
|
||||||
"SMALL_GROUP" => {} // These flags are for region spawning,
|
|
||||||
"LARGE_GROUP" => {} // and don't matter here (yet)?
|
|
||||||
"MULTIATTACK" => {
|
|
||||||
eb = eb.with(MultiAttack {});
|
|
||||||
xp_value += 3;
|
|
||||||
}
|
|
||||||
_ => rltk::console::log(format!("Unrecognised flag: {}", flag.as_str())),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if blocks_tile {
|
|
||||||
eb = eb.with(BlocksTile {});
|
|
||||||
}
|
|
||||||
// If we didn't already add one, just move randomly.
|
|
||||||
if !has_move_mode {
|
|
||||||
eb = eb.with(MoveMode { mode: Movement::Random });
|
|
||||||
}
|
|
||||||
// If we're anything other than MINDLESS, add a mind.
|
|
||||||
if has_mind {
|
if has_mind {
|
||||||
eb = eb.with(Mind {});
|
eb = eb.with(Mind {});
|
||||||
}
|
}
|
||||||
// If we didn't add a faction flag, default to hostile (attacks everything except other hostiles).
|
|
||||||
if !has_faction {
|
|
||||||
eb = eb.with(Faction { name: "hostile".to_string() });
|
|
||||||
}
|
|
||||||
// Add quips, if we have some listed.
|
// Add quips, if we have some listed.
|
||||||
if let Some(quips) = &mob_template.quips {
|
if let Some(quips) = &mob_template.quips {
|
||||||
eb = eb.with(Quips { available: quips.clone() });
|
eb = eb.with(Quips { available: quips.clone() });
|
||||||
|
|
@ -554,57 +530,31 @@ pub fn spawn_named_mob(
|
||||||
|
|
||||||
pub fn spawn_named_prop(raws: &RawMaster, ecs: &mut World, key: &str, pos: SpawnType) -> Option<Entity> {
|
pub fn spawn_named_prop(raws: &RawMaster, ecs: &mut World, key: &str, pos: SpawnType) -> Option<Entity> {
|
||||||
if raws.prop_index.contains_key(key) {
|
if raws.prop_index.contains_key(key) {
|
||||||
|
// ENTITY BUILDER PREP
|
||||||
let prop_template = &raws.raws.props[raws.prop_index[key]];
|
let prop_template = &raws.raws.props[raws.prop_index[key]];
|
||||||
|
|
||||||
let mut eb = ecs.create_entity().marked::<SimpleMarker<SerializeMe>>();
|
let mut eb = ecs.create_entity().marked::<SimpleMarker<SerializeMe>>();
|
||||||
eb = spawn_position(pos, eb, key, raws);
|
eb = spawn_position(pos, eb, key, raws);
|
||||||
|
// APPLY MANDATORY COMPONENTS FOR A PROP:
|
||||||
|
// - Name
|
||||||
|
// - Prop {}
|
||||||
|
eb = eb.with(Name { name: prop_template.name.clone(), plural: prop_template.name.clone() });
|
||||||
|
eb = eb.with(Prop {});
|
||||||
|
// APPLY OPTIONAL COMPONENTS FOR A PROP:
|
||||||
|
// - Renderable
|
||||||
|
// - Flags
|
||||||
|
// - Effects
|
||||||
if let Some(renderable) = &prop_template.renderable {
|
if let Some(renderable) = &prop_template.renderable {
|
||||||
eb = eb.with(get_renderable_component(renderable));
|
eb = eb.with(get_renderable_component(renderable));
|
||||||
}
|
}
|
||||||
eb = eb.with(Name { name: prop_template.name.clone(), plural: prop_template.name.clone() });
|
|
||||||
eb = eb.with(Prop {});
|
|
||||||
|
|
||||||
if let Some(flags) = &prop_template.flags {
|
if let Some(flags) = &prop_template.flags {
|
||||||
for flag in flags.iter() {
|
apply_flags!(flags, eb);
|
||||||
match flag.as_str() {
|
|
||||||
"HIDDEN" => eb = eb.with(Hidden {}),
|
|
||||||
"BLOCKS_TILE" => eb = eb.with(BlocksTile {}),
|
|
||||||
"BLOCKS_VISIBILITY" => eb = eb.with(BlocksVisibility {}),
|
|
||||||
"ENTRY_TRIGGER" => eb = eb.with(EntryTrigger {}),
|
|
||||||
"SINGLE_ACTIVATION" => eb = eb.with(SingleActivation {}),
|
|
||||||
"DOOR" => {
|
|
||||||
// TODO: Spawn some doors open?
|
|
||||||
let open = false;
|
|
||||||
eb = eb.with(Door { open: open });
|
|
||||||
if !open {
|
|
||||||
eb = eb.with(BlocksTile {});
|
|
||||||
eb = eb.with(BlocksVisibility {});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => rltk::console::log(format!("Unrecognised flag: {}", flag.as_str())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(effects_list) = &prop_template.effects {
|
if let Some(effects_list) = &prop_template.effects {
|
||||||
for effect in effects_list.iter() {
|
apply_effects!(effects_list, eb);
|
||||||
let effect_name = effect.0.as_str();
|
|
||||||
match effect_name {
|
|
||||||
"damage" => {
|
|
||||||
let (n_dice, sides, modifier) = parse_dice_string(effect.1.as_str());
|
|
||||||
eb = eb.with(InflictsDamage { n_dice, sides, modifier })
|
|
||||||
}
|
|
||||||
"aoe" => eb = eb.with(AOE { radius: effect.1.parse::<i32>().unwrap() }),
|
|
||||||
"healing" => {
|
|
||||||
let (n_dice, sides, modifier) = parse_dice_string(effect.1.as_str());
|
|
||||||
eb = eb.with(ProvidesHealing { n_dice, sides, modifier })
|
|
||||||
}
|
|
||||||
"confusion" => eb = eb.with(Confusion { turns: effect.1.parse::<i32>().unwrap() }),
|
|
||||||
_ => rltk::console::log(format!("Warning: effect {} not implemented.", effect_name)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// BUILD THE ENTITY
|
||||||
return Some(eb.build());
|
return Some(eb.build());
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
|
@ -702,7 +652,6 @@ fn find_slot_for_equippable_item(tag: &str, raws: &RawMaster) -> EquipmentSlot {
|
||||||
if let Some(flags) = &item.flags {
|
if let Some(flags) = &item.flags {
|
||||||
for flag in flags {
|
for flag in flags {
|
||||||
match flag.as_str() {
|
match flag.as_str() {
|
||||||
"EQUIP_MELEE" => return EquipmentSlot::Melee,
|
|
||||||
"EQUIP_SHIELD" => return EquipmentSlot::Shield,
|
"EQUIP_SHIELD" => return EquipmentSlot::Shield,
|
||||||
"EQUIP_BODY" => return EquipmentSlot::Body,
|
"EQUIP_BODY" => return EquipmentSlot::Body,
|
||||||
"EQUIP_HEAD" => return EquipmentSlot::Head,
|
"EQUIP_HEAD" => return EquipmentSlot::Head,
|
||||||
|
|
@ -714,6 +663,12 @@ fn find_slot_for_equippable_item(tag: &str, raws: &RawMaster) -> EquipmentSlot {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let Some(equip) = &item.equip {
|
||||||
|
match equip.slot.as_str() {
|
||||||
|
"EQUIP_MELEE" => return EquipmentSlot::Melee,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
panic!("Trying to equip {}, but it has no slot tag.", tag);
|
panic!("Trying to equip {}, but it has no slot tag.", tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue