Spawn items from JSON data
This commit is contained in:
parent
70494d8122
commit
98407d2c77
@ -7,6 +7,7 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
lazy_static = "1.4.0"
|
||||||
rltk = { version = "0.8.0", features=["serde"] }
|
rltk = { version = "0.8.0", features=["serde"] }
|
||||||
specs = { version = "0.16.1", features=["serde"] }
|
specs = { version = "0.16.1", features=["serde"] }
|
||||||
specs-derive = "0.4.1"
|
specs-derive = "0.4.1"
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"items": [{
|
"items": [
|
||||||
|
{
|
||||||
"name": "Health Potion",
|
"name": "Health Potion",
|
||||||
"renderable": {
|
"renderable": {
|
||||||
"glpyh": "!",
|
"glyph": "!",
|
||||||
"fg": "#FF00FF",
|
"fg": "#FF00FF",
|
||||||
"bg": "#000000",
|
"bg": "#000000",
|
||||||
"order": 2
|
"order": 2
|
||||||
@ -12,7 +13,8 @@
|
|||||||
"provides_healing": "8"
|
"provides_healing": "8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
"name": "Magic Missile Scroll",
|
"name": "Magic Missile Scroll",
|
||||||
"renderable": {
|
"renderable": {
|
||||||
"glyph": ")",
|
"glyph": ")",
|
||||||
@ -26,5 +28,66 @@
|
|||||||
"damage": "20"
|
"damage": "20"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}]
|
},
|
||||||
|
{
|
||||||
|
"name": "Fireball Scroll",
|
||||||
|
"renderable": {
|
||||||
|
"glyph": ")",
|
||||||
|
"fg": "#FFA500",
|
||||||
|
"bg": "#000000",
|
||||||
|
"order": 2
|
||||||
|
},
|
||||||
|
"consumable": {
|
||||||
|
"effects": {
|
||||||
|
"ranged": "6",
|
||||||
|
"damage": "20",
|
||||||
|
"area_of_effect": "3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Confusion Scroll",
|
||||||
|
"renderable": {
|
||||||
|
"glyph": ")",
|
||||||
|
"fg": "#FFAAAA",
|
||||||
|
"bg": "#000000",
|
||||||
|
"order": 2
|
||||||
|
},
|
||||||
|
"consumable": {
|
||||||
|
"effects": {
|
||||||
|
"ranged": "6",
|
||||||
|
"damage": "20",
|
||||||
|
"confusion": "4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Magic Mapping Scroll",
|
||||||
|
"renderable": {
|
||||||
|
"glyph": ")",
|
||||||
|
"fg": "#AAAAFF",
|
||||||
|
"bg": "#000000",
|
||||||
|
"order": 2
|
||||||
|
},
|
||||||
|
"consumable": {
|
||||||
|
"effects": {
|
||||||
|
"magic_mapping": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Rations",
|
||||||
|
"renderable": {
|
||||||
|
"glyph": "%",
|
||||||
|
"fg": "#00FF00",
|
||||||
|
"bg": "#000000",
|
||||||
|
"order": 2
|
||||||
|
},
|
||||||
|
"consumable": {
|
||||||
|
"effects": {
|
||||||
|
"food": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
10
src/main.rs
10
src/main.rs
@ -1,7 +1,3 @@
|
|||||||
use rltk::{GameState, Point, RandomNumberGenerator, Rltk};
|
|
||||||
use specs::prelude::*;
|
|
||||||
use specs::saveload::{SimpleMarker, SimpleMarkerAllocator};
|
|
||||||
|
|
||||||
pub mod camera;
|
pub mod camera;
|
||||||
mod components;
|
mod components;
|
||||||
mod damage_system;
|
mod damage_system;
|
||||||
@ -25,6 +21,9 @@ mod spawner;
|
|||||||
mod trigger_system;
|
mod trigger_system;
|
||||||
mod visibility_system;
|
mod visibility_system;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
|
|
||||||
use components::*;
|
use components::*;
|
||||||
use damage_system::DamageSystem;
|
use damage_system::DamageSystem;
|
||||||
pub use game_log::GameLog;
|
pub use game_log::GameLog;
|
||||||
@ -35,6 +34,9 @@ use melee_combat_system::MeleeCombatSystem;
|
|||||||
use monster_ai_system::MonsterAI;
|
use monster_ai_system::MonsterAI;
|
||||||
use player::*;
|
use player::*;
|
||||||
pub use rect::Rect;
|
pub use rect::Rect;
|
||||||
|
use rltk::{GameState, Point, RandomNumberGenerator, Rltk};
|
||||||
|
use specs::prelude::*;
|
||||||
|
use specs::saveload::{SimpleMarker, SimpleMarkerAllocator};
|
||||||
use visibility_system::VisibilitySystem;
|
use visibility_system::VisibilitySystem;
|
||||||
|
|
||||||
/// Cut down on the amount of syntax to register components
|
/// Cut down on the amount of syntax to register components
|
||||||
|
12
src/raws.rs
12
src/raws.rs
@ -1,10 +1,20 @@
|
|||||||
mod item_structs;
|
mod item_structs;
|
||||||
|
mod rawmaster;
|
||||||
|
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use item_structs::Raws;
|
use item_structs::Raws;
|
||||||
|
pub use rawmaster::*;
|
||||||
|
|
||||||
rltk::embedded_resource!(RAW_FILE, "../raws/spawns.json");
|
rltk::embedded_resource!(RAW_FILE, "../raws/spawns.json");
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref RAWS: Mutex<RawMaster> = Mutex::new(RawMaster::empty());
|
||||||
|
}
|
||||||
|
|
||||||
pub fn load_raws() {
|
pub fn load_raws() {
|
||||||
|
rltk::link_resource!(RAW_FILE, "../raws/spawns.json");
|
||||||
|
|
||||||
let raw_data = rltk::embedding::EMBED
|
let raw_data = rltk::embedding::EMBED
|
||||||
.lock()
|
.lock()
|
||||||
.get_resource("../raws/spawns.json".to_string())
|
.get_resource("../raws/spawns.json".to_string())
|
||||||
@ -14,5 +24,5 @@ pub fn load_raws() {
|
|||||||
std::str::from_utf8(&raw_data).expect("Unable to convert to a valid UTF-8 string.");
|
std::str::from_utf8(&raw_data).expect("Unable to convert to a valid UTF-8 string.");
|
||||||
let decoder: Raws = serde_json::from_str(&raw_string).expect("Unable to parse JSON");
|
let decoder: Raws = serde_json::from_str(&raw_string).expect("Unable to parse JSON");
|
||||||
|
|
||||||
rltk::console::log(format!("{:?}", decoder));
|
RAWS.lock().unwrap().load(decoder);
|
||||||
}
|
}
|
||||||
|
111
src/raws/rawmaster.rs
Normal file
111
src/raws/rawmaster.rs
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use specs::prelude::*;
|
||||||
|
|
||||||
|
use super::Raws;
|
||||||
|
use crate::components::*;
|
||||||
|
|
||||||
|
pub enum SpawnType {
|
||||||
|
AtPosition { x: i32, y: i32 },
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct RawMaster {
|
||||||
|
raws: Raws,
|
||||||
|
item_index: HashMap<String, usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RawMaster {
|
||||||
|
pub fn empty() -> RawMaster {
|
||||||
|
RawMaster {
|
||||||
|
raws: Raws { items: Vec::new() },
|
||||||
|
item_index: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load(&mut self, raws: Raws) {
|
||||||
|
self.raws = raws;
|
||||||
|
self.item_index = HashMap::new();
|
||||||
|
|
||||||
|
for (i, item) in self.raws.items.iter().enumerate() {
|
||||||
|
self.item_index.insert(item.name.clone(), i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spawn_named_item(
|
||||||
|
raws: &RawMaster,
|
||||||
|
new_entity: EntityBuilder,
|
||||||
|
key: &str,
|
||||||
|
pos: SpawnType,
|
||||||
|
) -> Option<Entity> {
|
||||||
|
if raws.item_index.contains_key(key) {
|
||||||
|
let item_template = &raws.raws.items[raws.item_index[key]];
|
||||||
|
|
||||||
|
let mut eb = new_entity;
|
||||||
|
|
||||||
|
// Spawn in the specified location
|
||||||
|
match pos {
|
||||||
|
SpawnType::AtPosition { x, y } => {
|
||||||
|
eb = eb.with(Position { x, y });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Renderable
|
||||||
|
if let Some(renderable) = &item_template.renderable {
|
||||||
|
eb = eb.with(Renderable {
|
||||||
|
glyph: rltk::to_cp437(renderable.glyph.chars().next().unwrap()),
|
||||||
|
fg: rltk::RGB::from_hex(&renderable.fg).expect("Invalid RGB"),
|
||||||
|
bg: rltk::RGB::from_hex(&renderable.bg).expect("Invalid RGB"),
|
||||||
|
render_order: renderable.order,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
eb = eb.with(Name::from(&item_template.name)).with(Item {});
|
||||||
|
|
||||||
|
if let Some(consumable) = &item_template.consumable {
|
||||||
|
eb = eb.with(Consumable {});
|
||||||
|
for effect in consumable.effects.iter() {
|
||||||
|
let effect_name = effect.0.as_str();
|
||||||
|
match effect_name {
|
||||||
|
"provides_healing" => {
|
||||||
|
eb = eb.with(ProvidesHealing {
|
||||||
|
heal_amount: effect.1.parse::<i32>().unwrap(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
"ranged" => {
|
||||||
|
eb = eb.with(Ranged {
|
||||||
|
range: effect.1.parse::<i32>().unwrap(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
"damage" => {
|
||||||
|
eb = eb.with(InflictsDamage {
|
||||||
|
damage: effect.1.parse::<i32>().unwrap(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
"area_of_effect" => {
|
||||||
|
eb = eb.with(AreaOfEffect {
|
||||||
|
radius: effect.1.parse::<i32>().unwrap(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
"confusion" => {
|
||||||
|
eb = eb.with(Confusion {
|
||||||
|
turns: effect.1.parse::<i32>().unwrap(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
"magic_mapping" => eb = eb.with(MagicMapper {}),
|
||||||
|
"food" => [eb = eb.with(ProvidesFood {})],
|
||||||
|
_ => {
|
||||||
|
rltk::console::log(format!(
|
||||||
|
"Warning: consumable effect {} not implemented.",
|
||||||
|
effect_name
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Some(eb.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
@ -6,6 +6,7 @@ use specs::saveload::{MarkedBuilder, SimpleMarker};
|
|||||||
|
|
||||||
use crate::components::*;
|
use crate::components::*;
|
||||||
use crate::random_table::RandomTable;
|
use crate::random_table::RandomTable;
|
||||||
|
use crate::raws::{spawn_named_item, SpawnType, RAWS};
|
||||||
use crate::{Map, Rect, TileType};
|
use crate::{Map, Rect, TileType};
|
||||||
|
|
||||||
/// Spawns the player and returns their entity object
|
/// Spawns the player and returns their entity object
|
||||||
@ -132,6 +133,16 @@ pub fn spawn_entity(ecs: &mut World, spawn: &(&usize, &String)) {
|
|||||||
// Drop this map reference to make the borrow checker happy
|
// Drop this map reference to make the borrow checker happy
|
||||||
std::mem::drop(map);
|
std::mem::drop(map);
|
||||||
|
|
||||||
|
let item_result = spawn_named_item(
|
||||||
|
&RAWS.lock().unwrap(),
|
||||||
|
ecs.create_entity(),
|
||||||
|
&spawn.1,
|
||||||
|
SpawnType::AtPosition { x, y },
|
||||||
|
);
|
||||||
|
if item_result.is_some() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
match spawn.1.as_ref() {
|
match spawn.1.as_ref() {
|
||||||
"Goblin" => goblin(ecs, x, y),
|
"Goblin" => goblin(ecs, x, y),
|
||||||
"Orc" => orc(ecs, x, y),
|
"Orc" => orc(ecs, x, y),
|
||||||
|
Loading…
Reference in New Issue
Block a user