basic trap implementation
confusion on player is NYI
This commit is contained in:
parent
4dffdd361d
commit
d316a55818
11 changed files with 257 additions and 43 deletions
|
|
@ -209,7 +209,19 @@ pub struct Wand {
|
||||||
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct Destructible {}
|
pub struct Destructible {}
|
||||||
|
|
||||||
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct Hidden {}
|
||||||
|
|
||||||
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct SingleActivation {}
|
||||||
|
|
||||||
#[derive(Component, Clone, ConvertSaveload)]
|
#[derive(Component, Clone, ConvertSaveload)]
|
||||||
pub struct ParticleLifetime {
|
pub struct ParticleLifetime {
|
||||||
pub lifetime_ms: f32,
|
pub lifetime_ms: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct EntryTrigger {}
|
||||||
|
|
||||||
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct EntityMoved {}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use super::{
|
use super::{
|
||||||
gamelog, rex_assets::RexAssets, CombatStats, Equipped, HungerClock, HungerState, InBackpack, Map, Name, Player,
|
gamelog, rex_assets::RexAssets, CombatStats, Equipped, Hidden, HungerClock, HungerState, InBackpack, Map, Name,
|
||||||
Point, Position, RunState, State, Viewshed,
|
Player, Point, Position, RunState, State, Viewshed,
|
||||||
};
|
};
|
||||||
use rltk::{Rltk, VirtualKeyCode, RGB};
|
use rltk::{Rltk, VirtualKeyCode, RGB};
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
|
|
@ -61,13 +61,14 @@ fn draw_tooltips(ecs: &World, ctx: &mut Rltk) {
|
||||||
let map = ecs.fetch::<Map>();
|
let map = ecs.fetch::<Map>();
|
||||||
let names = ecs.read_storage::<Name>();
|
let names = ecs.read_storage::<Name>();
|
||||||
let positions = ecs.read_storage::<Position>();
|
let positions = ecs.read_storage::<Position>();
|
||||||
|
let hidden = ecs.read_storage::<Hidden>();
|
||||||
|
|
||||||
let mouse_pos = ctx.mouse_pos();
|
let mouse_pos = ctx.mouse_pos();
|
||||||
if mouse_pos.0 >= map.width || mouse_pos.1 >= map.height {
|
if mouse_pos.0 >= map.width || mouse_pos.1 >= map.height {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut tooltip: Vec<String> = Vec::new();
|
let mut tooltip: Vec<String> = Vec::new();
|
||||||
for (name, position) in (&names, &positions).join() {
|
for (name, position, _hidden) in (&names, &positions, !&hidden).join() {
|
||||||
let idx = map.xy_idx(position.x, position.y);
|
let idx = map.xy_idx(position.x, position.y);
|
||||||
if position.x == mouse_pos.0 && position.y == mouse_pos.1 && map.visible_tiles[idx] {
|
if position.x == mouse_pos.0 && position.y == mouse_pos.1 && map.visible_tiles[idx] {
|
||||||
tooltip.push(name.name.to_string());
|
tooltip.push(name.name.to_string());
|
||||||
|
|
|
||||||
42
src/main.rs
42
src/main.rs
|
|
@ -26,6 +26,7 @@ mod damage_system;
|
||||||
use damage_system::*;
|
use damage_system::*;
|
||||||
mod hunger_system;
|
mod hunger_system;
|
||||||
mod melee_combat_system;
|
mod melee_combat_system;
|
||||||
|
mod trigger_system;
|
||||||
use melee_combat_system::MeleeCombatSystem;
|
use melee_combat_system::MeleeCombatSystem;
|
||||||
mod inventory_system;
|
mod inventory_system;
|
||||||
use inventory_system::*;
|
use inventory_system::*;
|
||||||
|
|
@ -65,27 +66,31 @@ pub struct State {
|
||||||
impl State {
|
impl State {
|
||||||
fn run_systems(&mut self) {
|
fn run_systems(&mut self) {
|
||||||
let mut vis = VisibilitySystem {};
|
let mut vis = VisibilitySystem {};
|
||||||
vis.run_now(&self.ecs);
|
|
||||||
let mut mob = MonsterAI {};
|
let mut mob = MonsterAI {};
|
||||||
mob.run_now(&self.ecs);
|
|
||||||
let mut mapindex = MapIndexingSystem {};
|
let mut mapindex = MapIndexingSystem {};
|
||||||
mapindex.run_now(&self.ecs);
|
let mut trigger_system = trigger_system::TriggerSystem {};
|
||||||
let mut inventory_system = ItemCollectionSystem {};
|
|
||||||
inventory_system.run_now(&self.ecs);
|
|
||||||
let mut item_use_system = ItemUseSystem {};
|
|
||||||
item_use_system.run_now(&self.ecs);
|
|
||||||
let mut item_drop_system = ItemDropSystem {};
|
|
||||||
item_drop_system.run_now(&self.ecs);
|
|
||||||
let mut item_remove_system = ItemRemoveSystem {};
|
|
||||||
item_remove_system.run_now(&self.ecs);
|
|
||||||
let mut melee_system = MeleeCombatSystem {};
|
let mut melee_system = MeleeCombatSystem {};
|
||||||
melee_system.run_now(&self.ecs);
|
|
||||||
let mut damage_system = DamageSystem {};
|
let mut damage_system = DamageSystem {};
|
||||||
damage_system.run_now(&self.ecs);
|
let mut inventory_system = ItemCollectionSystem {};
|
||||||
|
let mut item_use_system = ItemUseSystem {};
|
||||||
|
let mut item_drop_system = ItemDropSystem {};
|
||||||
|
let mut item_remove_system = ItemRemoveSystem {};
|
||||||
let mut hunger_clock = hunger_system::HungerSystem {};
|
let mut hunger_clock = hunger_system::HungerSystem {};
|
||||||
hunger_clock.run_now(&self.ecs);
|
|
||||||
let mut particle_system = particle_system::ParticleSpawnSystem {};
|
let mut particle_system = particle_system::ParticleSpawnSystem {};
|
||||||
|
|
||||||
|
vis.run_now(&self.ecs);
|
||||||
|
mob.run_now(&self.ecs);
|
||||||
|
mapindex.run_now(&self.ecs);
|
||||||
|
trigger_system.run_now(&self.ecs);
|
||||||
|
melee_system.run_now(&self.ecs);
|
||||||
|
damage_system.run_now(&self.ecs);
|
||||||
|
inventory_system.run_now(&self.ecs);
|
||||||
|
item_use_system.run_now(&self.ecs);
|
||||||
|
item_drop_system.run_now(&self.ecs);
|
||||||
|
item_remove_system.run_now(&self.ecs);
|
||||||
|
hunger_clock.run_now(&self.ecs);
|
||||||
particle_system.run_now(&self.ecs);
|
particle_system.run_now(&self.ecs);
|
||||||
|
|
||||||
self.ecs.maintain();
|
self.ecs.maintain();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -248,12 +253,13 @@ impl GameState for State {
|
||||||
let positions = self.ecs.read_storage::<Position>();
|
let positions = self.ecs.read_storage::<Position>();
|
||||||
let renderables = self.ecs.read_storage::<Renderable>();
|
let renderables = self.ecs.read_storage::<Renderable>();
|
||||||
let minds = self.ecs.read_storage::<Mind>();
|
let minds = self.ecs.read_storage::<Mind>();
|
||||||
|
let hidden = self.ecs.read_storage::<Hidden>();
|
||||||
let map = self.ecs.fetch::<Map>();
|
let map = self.ecs.fetch::<Map>();
|
||||||
let entities = self.ecs.entities();
|
let entities = self.ecs.entities();
|
||||||
|
|
||||||
let mut data = (&positions, &renderables, &entities).join().collect::<Vec<_>>();
|
let mut data = (&positions, &renderables, &entities, !&hidden).join().collect::<Vec<_>>();
|
||||||
data.sort_by(|&a, &b| b.1.render_order.cmp(&a.1.render_order));
|
data.sort_by(|&a, &b| b.1.render_order.cmp(&a.1.render_order));
|
||||||
for (pos, render, ent) in data.iter() {
|
for (pos, render, ent, _hidden) in data.iter() {
|
||||||
let idx = map.xy_idx(pos.x, pos.y);
|
let idx = map.xy_idx(pos.x, pos.y);
|
||||||
let offsets = RGB::from_u8(map.red_offset[idx], map.green_offset[idx], map.blue_offset[idx]);
|
let offsets = RGB::from_u8(map.red_offset[idx], map.green_offset[idx], map.blue_offset[idx]);
|
||||||
let mut bg = render.bg.add(RGB::from_u8(26, 45, 45)).add(offsets);
|
let mut bg = render.bg.add(RGB::from_u8(26, 45, 45)).add(offsets);
|
||||||
|
|
@ -506,9 +512,13 @@ fn main() -> rltk::BError {
|
||||||
gs.ecs.register::<WantsToRemoveItem>();
|
gs.ecs.register::<WantsToRemoveItem>();
|
||||||
gs.ecs.register::<WantsToUseItem>();
|
gs.ecs.register::<WantsToUseItem>();
|
||||||
gs.ecs.register::<Consumable>();
|
gs.ecs.register::<Consumable>();
|
||||||
|
gs.ecs.register::<SingleActivation>();
|
||||||
gs.ecs.register::<Wand>();
|
gs.ecs.register::<Wand>();
|
||||||
gs.ecs.register::<ProvidesNutrition>();
|
gs.ecs.register::<ProvidesNutrition>();
|
||||||
gs.ecs.register::<Destructible>();
|
gs.ecs.register::<Destructible>();
|
||||||
|
gs.ecs.register::<Hidden>();
|
||||||
|
gs.ecs.register::<EntryTrigger>();
|
||||||
|
gs.ecs.register::<EntityMoved>();
|
||||||
gs.ecs.register::<ParticleLifetime>();
|
gs.ecs.register::<ParticleLifetime>();
|
||||||
gs.ecs.register::<SimpleMarker<SerializeMe>>();
|
gs.ecs.register::<SimpleMarker<SerializeMe>>();
|
||||||
gs.ecs.register::<SerializationHelper>();
|
gs.ecs.register::<SerializationHelper>();
|
||||||
|
|
|
||||||
|
|
@ -127,14 +127,7 @@ impl<'a> System<'a> for MeleeCombatSystem {
|
||||||
}
|
}
|
||||||
let pos = positions.get(wants_melee.target);
|
let pos = positions.get(wants_melee.target);
|
||||||
if let Some(pos) = pos {
|
if let Some(pos) = pos {
|
||||||
particle_builder.request(
|
particle_builder.damage_taken(pos.x, pos.y)
|
||||||
pos.x,
|
|
||||||
pos.y,
|
|
||||||
rltk::RGB::named(rltk::ORANGE),
|
|
||||||
rltk::RGB::named(rltk::BLACK),
|
|
||||||
rltk::to_cp437('‼'),
|
|
||||||
150.0,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
SufferDamage::new_damage(&mut inflict_damage, wants_melee.target, damage);
|
SufferDamage::new_damage(&mut inflict_damage, wants_melee.target, damage);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
use super::{gamelog, Confusion, Map, Monster, Name, ParticleBuilder, Position, RunState, Viewshed, WantsToMelee};
|
use super::{
|
||||||
|
gamelog, Confusion, EntityMoved, Map, Monster, Name, ParticleBuilder, Position, RunState, Viewshed, WantsToMelee,
|
||||||
|
};
|
||||||
use rltk::Point;
|
use rltk::Point;
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
|
|
||||||
|
|
@ -19,6 +21,7 @@ impl<'a> System<'a> for MonsterAI {
|
||||||
WriteStorage<'a, Confusion>,
|
WriteStorage<'a, Confusion>,
|
||||||
ReadStorage<'a, Name>,
|
ReadStorage<'a, Name>,
|
||||||
WriteExpect<'a, ParticleBuilder>,
|
WriteExpect<'a, ParticleBuilder>,
|
||||||
|
WriteStorage<'a, EntityMoved>,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn run(&mut self, data: Self::SystemData) {
|
fn run(&mut self, data: Self::SystemData) {
|
||||||
|
|
@ -35,6 +38,7 @@ impl<'a> System<'a> for MonsterAI {
|
||||||
mut confused,
|
mut confused,
|
||||||
name,
|
name,
|
||||||
mut particle_builder,
|
mut particle_builder,
|
||||||
|
mut entity_moved,
|
||||||
) = data;
|
) = data;
|
||||||
|
|
||||||
if *runstate != RunState::MonsterTurn {
|
if *runstate != RunState::MonsterTurn {
|
||||||
|
|
@ -88,6 +92,7 @@ impl<'a> System<'a> for MonsterAI {
|
||||||
idx = map.xy_idx(pos.x, pos.y);
|
idx = map.xy_idx(pos.x, pos.y);
|
||||||
map.blocked[idx] = true;
|
map.blocked[idx] = true;
|
||||||
viewshed.dirty = true;
|
viewshed.dirty = true;
|
||||||
|
entity_moved.insert(entity, EntityMoved {}).expect("Unable to insert marker");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,10 @@ impl ParticleBuilder {
|
||||||
self.requests.push(ParticleRequest { x, y, fg, bg, glyph, lifetime });
|
self.requests.push(ParticleRequest { x, y, fg, bg, glyph, lifetime });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn damage_taken(&mut self, x: i32, y: i32) {
|
||||||
|
self.request(x, y, rltk::RGB::named(rltk::ORANGE), rltk::RGB::named(rltk::BLACK), rltk::to_cp437('‼'), 200.0);
|
||||||
|
}
|
||||||
|
|
||||||
// Makes a particle request in the shape of an 'x'. Sort of.
|
// Makes a particle request in the shape of an 'x'. Sort of.
|
||||||
pub fn request_star(&mut self, x: i32, y: i32, fg: RGB, bg: RGB, glyph: rltk::FontCharType, lifetime: f32) {
|
pub fn request_star(&mut self, x: i32, y: i32, fg: RGB, bg: RGB, glyph: rltk::FontCharType, lifetime: f32) {
|
||||||
self.request(x, y, fg, bg, glyph, lifetime * 2.0);
|
self.request(x, y, fg, bg, glyph, lifetime * 2.0);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use super::{
|
use super::{
|
||||||
gamelog, CombatStats, HungerClock, HungerState, Item, Map, Monster, Name, Player, Position, RunState, State,
|
gamelog, CombatStats, EntityMoved, Hidden, HungerClock, HungerState, Item, Map, Monster, Name, Player, Position,
|
||||||
Telepath, TileType, Viewshed, WantsToMelee, WantsToPickupItem, MAPHEIGHT, MAPWIDTH,
|
RunState, State, Telepath, TileType, Viewshed, WantsToMelee, WantsToPickupItem, MAPHEIGHT, MAPWIDTH,
|
||||||
};
|
};
|
||||||
use rltk::{Point, RandomNumberGenerator, Rltk, VirtualKeyCode};
|
use rltk::{Point, RandomNumberGenerator, Rltk, VirtualKeyCode};
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
|
|
@ -11,6 +11,7 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) {
|
||||||
let mut players = ecs.write_storage::<Player>();
|
let mut players = ecs.write_storage::<Player>();
|
||||||
let mut viewsheds = ecs.write_storage::<Viewshed>();
|
let mut viewsheds = ecs.write_storage::<Viewshed>();
|
||||||
let mut telepaths = ecs.write_storage::<Telepath>();
|
let mut telepaths = ecs.write_storage::<Telepath>();
|
||||||
|
let mut entity_moved = ecs.write_storage::<EntityMoved>();
|
||||||
let combat_stats = ecs.read_storage::<CombatStats>();
|
let combat_stats = ecs.read_storage::<CombatStats>();
|
||||||
let map = ecs.fetch::<Map>();
|
let map = ecs.fetch::<Map>();
|
||||||
|
|
||||||
|
|
@ -37,14 +38,18 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) {
|
||||||
|
|
||||||
if !map.blocked[destination_idx] {
|
if !map.blocked[destination_idx] {
|
||||||
let names = ecs.read_storage::<Name>();
|
let names = ecs.read_storage::<Name>();
|
||||||
|
let hidden = ecs.read_storage::<Hidden>();
|
||||||
// Push every entity name in the pile to a vector of strings
|
// Push every entity name in the pile to a vector of strings
|
||||||
let mut item_names: Vec<String> = Vec::new();
|
let mut item_names: Vec<String> = Vec::new();
|
||||||
let mut some = false;
|
let mut some = false;
|
||||||
for entity in map.tile_content[destination_idx].iter() {
|
for entity in map.tile_content[destination_idx].iter() {
|
||||||
if let Some(name) = names.get(*entity) {
|
if let Some(_hidden) = hidden.get(*entity) {
|
||||||
let item_name = &name.name;
|
} else {
|
||||||
item_names.push(item_name.to_string());
|
if let Some(name) = names.get(*entity) {
|
||||||
some = true;
|
let item_name = &name.name;
|
||||||
|
item_names.push(item_name.to_string());
|
||||||
|
some = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If some names were found, append. Logger = logger is necessary
|
// If some names were found, append. Logger = logger is necessary
|
||||||
|
|
@ -74,6 +79,7 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) {
|
||||||
let mut ppos = ecs.write_resource::<Point>();
|
let mut ppos = ecs.write_resource::<Point>();
|
||||||
ppos.x = pos.x;
|
ppos.x = pos.x;
|
||||||
ppos.y = pos.y;
|
ppos.y = pos.y;
|
||||||
|
entity_moved.insert(entity, EntityMoved {}).expect("Unable to insert marker");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,11 @@ pub fn save_game(ecs: &mut World) {
|
||||||
Cursed,
|
Cursed,
|
||||||
DefenceBonus,
|
DefenceBonus,
|
||||||
Destructible,
|
Destructible,
|
||||||
|
EntityMoved,
|
||||||
|
EntryTrigger,
|
||||||
Equippable,
|
Equippable,
|
||||||
Equipped,
|
Equipped,
|
||||||
|
Hidden,
|
||||||
HungerClock,
|
HungerClock,
|
||||||
InBackpack,
|
InBackpack,
|
||||||
InflictsDamage,
|
InflictsDamage,
|
||||||
|
|
@ -73,6 +76,7 @@ pub fn save_game(ecs: &mut World) {
|
||||||
ProvidesNutrition,
|
ProvidesNutrition,
|
||||||
Ranged,
|
Ranged,
|
||||||
Renderable,
|
Renderable,
|
||||||
|
SingleActivation,
|
||||||
SufferDamage,
|
SufferDamage,
|
||||||
Telepath,
|
Telepath,
|
||||||
Viewshed,
|
Viewshed,
|
||||||
|
|
@ -143,8 +147,11 @@ pub fn load_game(ecs: &mut World) {
|
||||||
Cursed,
|
Cursed,
|
||||||
DefenceBonus,
|
DefenceBonus,
|
||||||
Destructible,
|
Destructible,
|
||||||
|
EntityMoved,
|
||||||
|
EntryTrigger,
|
||||||
Equippable,
|
Equippable,
|
||||||
Equipped,
|
Equipped,
|
||||||
|
Hidden,
|
||||||
HungerClock,
|
HungerClock,
|
||||||
InBackpack,
|
InBackpack,
|
||||||
InflictsDamage,
|
InflictsDamage,
|
||||||
|
|
@ -161,6 +168,7 @@ pub fn load_game(ecs: &mut World) {
|
||||||
ProvidesNutrition,
|
ProvidesNutrition,
|
||||||
Ranged,
|
Ranged,
|
||||||
Renderable,
|
Renderable,
|
||||||
|
SingleActivation,
|
||||||
SufferDamage,
|
SufferDamage,
|
||||||
Telepath,
|
Telepath,
|
||||||
Viewshed,
|
Viewshed,
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
use super::{
|
use super::{
|
||||||
random_table::RandomTable, BlocksTile, CombatStats, Confusion, Consumable, Cursed, DefenceBonus, Destructible,
|
random_table::RandomTable, BlocksTile, CombatStats, Confusion, Consumable, Cursed, DefenceBonus, Destructible,
|
||||||
EquipmentSlot, Equippable, HungerClock, HungerState, InflictsDamage, Item, MagicMapper, MeleePowerBonus, Mind,
|
EntryTrigger, EquipmentSlot, Equippable, Hidden, HungerClock, HungerState, InflictsDamage, Item, MagicMapper,
|
||||||
Monster, Name, Player, Position, ProvidesHealing, ProvidesNutrition, Ranged, Rect, Renderable, SerializeMe,
|
MeleePowerBonus, Mind, Monster, Name, Player, Position, ProvidesHealing, ProvidesNutrition, Ranged, Rect,
|
||||||
Viewshed, Wand, AOE, MAPWIDTH,
|
Renderable, SerializeMe, SingleActivation, Viewshed, Wand, AOE, MAPWIDTH,
|
||||||
};
|
};
|
||||||
use rltk::{console, RandomNumberGenerator, RGB};
|
use rltk::{console, RandomNumberGenerator, RGB};
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
|
|
@ -99,6 +99,7 @@ pub fn spawn_room(ecs: &mut World, room: &Rect, map_depth: i32) {
|
||||||
"mob" => spawn_table = mob_table(map_depth),
|
"mob" => spawn_table = mob_table(map_depth),
|
||||||
"item" => spawn_table = item_table(map_depth),
|
"item" => spawn_table = item_table(map_depth),
|
||||||
"food" => spawn_table = food_table(map_depth),
|
"food" => spawn_table = food_table(map_depth),
|
||||||
|
"trap" => spawn_table = trap_table(map_depth),
|
||||||
_ => spawn_table = debug_table(),
|
_ => spawn_table = debug_table(),
|
||||||
}
|
}
|
||||||
spawn_points.insert(idx, spawn_table.roll(&mut rng));
|
spawn_points.insert(idx, spawn_table.roll(&mut rng));
|
||||||
|
|
@ -138,16 +139,20 @@ pub fn spawn_room(ecs: &mut World, room: &Rect, map_depth: i32) {
|
||||||
// Wands
|
// Wands
|
||||||
"magic missile wand" => magic_missile_wand(ecs, x, y),
|
"magic missile wand" => magic_missile_wand(ecs, x, y),
|
||||||
"fireball wand" => fireball_wand(ecs, x, y),
|
"fireball wand" => fireball_wand(ecs, x, y),
|
||||||
|
"confusion wand" => confusion_wand(ecs, x, y),
|
||||||
// Food
|
// Food
|
||||||
"rations" => rations(ecs, x, y),
|
"rations" => rations(ecs, x, y),
|
||||||
|
// Traps
|
||||||
|
"bear trap" => bear_trap(ecs, x, y),
|
||||||
|
"confusion trap" => confusion_trap(ecs, x, y),
|
||||||
_ => console::log("Tried to spawn nothing. Bugfix needed!"),
|
_ => console::log("Tried to spawn nothing. Bugfix needed!"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10 mobs : 3 items : 1 food
|
// 20 mobs : 6 items : 2 food : 1 trap
|
||||||
fn category_table() -> RandomTable {
|
fn category_table() -> RandomTable {
|
||||||
return RandomTable::new().add("mob", 9).add("item", 3).add("food", 1);
|
return RandomTable::new().add("mob", 20).add("item", 6).add("food", 2).add("trap", 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn debug_table() -> RandomTable {
|
fn debug_table() -> RandomTable {
|
||||||
|
|
@ -183,13 +188,18 @@ fn item_table(_map_depth: i32) -> RandomTable {
|
||||||
.add("cursed magic map scroll", 2)
|
.add("cursed magic map scroll", 2)
|
||||||
// Wands
|
// Wands
|
||||||
.add("magic missile wand", 1)
|
.add("magic missile wand", 1)
|
||||||
.add("fireball wand", 1);
|
.add("fireball wand", 1)
|
||||||
|
.add("confusion wand", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn food_table(_map_depth: i32) -> RandomTable {
|
fn food_table(_map_depth: i32) -> RandomTable {
|
||||||
return RandomTable::new().add("rations", 1);
|
return RandomTable::new().add("rations", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn trap_table(_map_depth: i32) -> RandomTable {
|
||||||
|
return RandomTable::new().add("bear trap", 0).add("confusion trap", 1);
|
||||||
|
}
|
||||||
|
|
||||||
fn health_potion(ecs: &mut World, x: i32, y: i32) {
|
fn health_potion(ecs: &mut World, x: i32, y: i32) {
|
||||||
ecs.create_entity()
|
ecs.create_entity()
|
||||||
.with(Position { x, y })
|
.with(Position { x, y })
|
||||||
|
|
@ -478,7 +488,7 @@ fn magic_missile_wand(ecs: &mut World, x: i32, y: i32) {
|
||||||
ecs.create_entity()
|
ecs.create_entity()
|
||||||
.with(Position { x, y })
|
.with(Position { x, y })
|
||||||
.with(Renderable {
|
.with(Renderable {
|
||||||
glyph: rltk::to_cp437('?'),
|
glyph: rltk::to_cp437('/'),
|
||||||
fg: RGB::named(rltk::BLUE),
|
fg: RGB::named(rltk::BLUE),
|
||||||
bg: RGB::named(rltk::BLACK),
|
bg: RGB::named(rltk::BLACK),
|
||||||
render_order: 2,
|
render_order: 2,
|
||||||
|
|
@ -492,3 +502,59 @@ fn magic_missile_wand(ecs: &mut World, x: i32, y: i32) {
|
||||||
.marked::<SimpleMarker<SerializeMe>>()
|
.marked::<SimpleMarker<SerializeMe>>()
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn confusion_wand(ecs: &mut World, x: i32, y: i32) {
|
||||||
|
ecs.create_entity()
|
||||||
|
.with(Position { x, y })
|
||||||
|
.with(Renderable {
|
||||||
|
glyph: rltk::to_cp437('/'),
|
||||||
|
fg: RGB::named(rltk::PURPLE),
|
||||||
|
bg: RGB::named(rltk::BLACK),
|
||||||
|
render_order: 2,
|
||||||
|
})
|
||||||
|
.with(Name { name: "wand of confusion".to_string() })
|
||||||
|
.with(Item {})
|
||||||
|
.with(Wand { uses: 3, max_uses: 3 })
|
||||||
|
.with(Destructible {})
|
||||||
|
.with(Ranged { range: 10 })
|
||||||
|
.with(Confusion { turns: 4 })
|
||||||
|
.marked::<SimpleMarker<SerializeMe>>()
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TRAPS
|
||||||
|
fn bear_trap(ecs: &mut World, x: i32, y: i32) {
|
||||||
|
ecs.create_entity()
|
||||||
|
.with(Position { x, y })
|
||||||
|
.with(Renderable {
|
||||||
|
glyph: rltk::to_cp437('^'),
|
||||||
|
fg: RGB::named(rltk::GREY),
|
||||||
|
bg: RGB::named(rltk::BLACK),
|
||||||
|
render_order: 2,
|
||||||
|
})
|
||||||
|
.with(Name { name: "bear trap".to_string() })
|
||||||
|
.with(Hidden {})
|
||||||
|
.with(EntryTrigger {})
|
||||||
|
.with(SingleActivation {})
|
||||||
|
.with(InflictsDamage { amount: 6 })
|
||||||
|
.marked::<SimpleMarker<SerializeMe>>()
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn confusion_trap(ecs: &mut World, x: i32, y: i32) {
|
||||||
|
ecs.create_entity()
|
||||||
|
.with(Position { x, y })
|
||||||
|
.with(Renderable {
|
||||||
|
glyph: rltk::to_cp437('^'),
|
||||||
|
fg: RGB::named(rltk::PURPLE),
|
||||||
|
bg: RGB::named(rltk::BLACK),
|
||||||
|
render_order: 2,
|
||||||
|
})
|
||||||
|
.with(Name { name: "magic trap".to_string() })
|
||||||
|
.with(Hidden {})
|
||||||
|
.with(EntryTrigger {})
|
||||||
|
.with(SingleActivation {})
|
||||||
|
.with(Confusion { turns: 3 })
|
||||||
|
.marked::<SimpleMarker<SerializeMe>>()
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
|
||||||
88
src/trigger_system.rs
Normal file
88
src/trigger_system.rs
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
use super::{
|
||||||
|
gamelog, Confusion, EntityMoved, EntryTrigger, Hidden, InflictsDamage, Map, Name, ParticleBuilder, Position,
|
||||||
|
SingleActivation, SufferDamage,
|
||||||
|
};
|
||||||
|
use specs::prelude::*;
|
||||||
|
|
||||||
|
pub struct TriggerSystem {}
|
||||||
|
|
||||||
|
impl<'a> System<'a> for TriggerSystem {
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
|
type SystemData = (
|
||||||
|
ReadExpect<'a, Map>,
|
||||||
|
WriteStorage<'a, EntityMoved>,
|
||||||
|
ReadStorage<'a, Position>,
|
||||||
|
ReadStorage<'a, EntryTrigger>,
|
||||||
|
ReadStorage<'a, InflictsDamage>,
|
||||||
|
WriteStorage<'a, Confusion>,
|
||||||
|
WriteStorage<'a, SufferDamage>,
|
||||||
|
WriteStorage<'a, Hidden>,
|
||||||
|
ReadStorage<'a, SingleActivation>,
|
||||||
|
ReadStorage<'a, Name>,
|
||||||
|
WriteExpect<'a, ParticleBuilder>,
|
||||||
|
Entities<'a>,
|
||||||
|
);
|
||||||
|
|
||||||
|
fn run(&mut self, data: Self::SystemData) {
|
||||||
|
let (
|
||||||
|
map,
|
||||||
|
mut entity_moved,
|
||||||
|
position,
|
||||||
|
entry_trigger,
|
||||||
|
inflicts_damage,
|
||||||
|
mut confusion,
|
||||||
|
mut inflict_damage,
|
||||||
|
mut hidden,
|
||||||
|
single_activation,
|
||||||
|
names,
|
||||||
|
mut particle_builder,
|
||||||
|
entities,
|
||||||
|
) = data;
|
||||||
|
|
||||||
|
// Iterate entities that moved, and their final position
|
||||||
|
let mut remove_entities: Vec<Entity> = Vec::new();
|
||||||
|
for (entity, mut _entity_moved, pos) in (&entities, &mut entity_moved, &position).join() {
|
||||||
|
let idx = map.xy_idx(pos.x, pos.y);
|
||||||
|
for entity_id in map.tile_content[idx].iter() {
|
||||||
|
if entity != *entity_id {
|
||||||
|
let maybe_trigger = entry_trigger.get(*entity_id);
|
||||||
|
match maybe_trigger {
|
||||||
|
None => {}
|
||||||
|
Some(_trigger) => {
|
||||||
|
// Something on this pos had a trigger
|
||||||
|
let name = names.get(*entity_id);
|
||||||
|
hidden.remove(*entity_id);
|
||||||
|
if let Some(name) = name {
|
||||||
|
gamelog::Logger::new().item_name(&name.name).append("triggers!").log();
|
||||||
|
}
|
||||||
|
|
||||||
|
let damage = inflicts_damage.get(*entity_id);
|
||||||
|
if let Some(damage) = damage {
|
||||||
|
particle_builder.damage_taken(pos.x, pos.y);
|
||||||
|
SufferDamage::new_damage(&mut inflict_damage, entity, damage.amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
let confuses = confusion.get(*entity_id);
|
||||||
|
if let Some(confuses) = confuses {
|
||||||
|
confusion
|
||||||
|
.insert(entity, Confusion { turns: confuses.turns })
|
||||||
|
.expect("Unable to insert confusion");
|
||||||
|
}
|
||||||
|
|
||||||
|
let sa = single_activation.get(*entity_id);
|
||||||
|
if let Some(_sa) = sa {
|
||||||
|
remove_entities.push(*entity_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for trap in remove_entities.iter() {
|
||||||
|
entities.delete(*trap).expect("Unable to delete trap");
|
||||||
|
}
|
||||||
|
|
||||||
|
entity_moved.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{Map, Player, Position, Telepath, Viewshed};
|
use super::{gamelog, Hidden, Map, Name, Player, Position, Telepath, Viewshed};
|
||||||
use rltk::{FieldOfViewAlg::SymmetricShadowcasting, Point};
|
use rltk::{FieldOfViewAlg::SymmetricShadowcasting, Point};
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
|
|
||||||
|
|
@ -7,15 +7,18 @@ pub struct VisibilitySystem {}
|
||||||
impl<'a> System<'a> for VisibilitySystem {
|
impl<'a> System<'a> for VisibilitySystem {
|
||||||
type SystemData = (
|
type SystemData = (
|
||||||
WriteExpect<'a, Map>,
|
WriteExpect<'a, Map>,
|
||||||
|
WriteExpect<'a, rltk::RandomNumberGenerator>,
|
||||||
Entities<'a>,
|
Entities<'a>,
|
||||||
WriteStorage<'a, Viewshed>,
|
WriteStorage<'a, Viewshed>,
|
||||||
WriteStorage<'a, Telepath>,
|
WriteStorage<'a, Telepath>,
|
||||||
WriteStorage<'a, Position>,
|
WriteStorage<'a, Position>,
|
||||||
ReadStorage<'a, Player>,
|
ReadStorage<'a, Player>,
|
||||||
|
WriteStorage<'a, Hidden>,
|
||||||
|
ReadStorage<'a, Name>,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn run(&mut self, data: Self::SystemData) {
|
fn run(&mut self, data: Self::SystemData) {
|
||||||
let (mut map, entities, mut viewshed, mut telepath, pos, player) = data;
|
let (mut map, mut rng, entities, mut viewshed, mut telepath, pos, player, mut hidden, names) = data;
|
||||||
|
|
||||||
for (ent, viewshed, pos) in (&entities, &mut viewshed, &pos).join() {
|
for (ent, viewshed, pos) in (&entities, &mut viewshed, &pos).join() {
|
||||||
if viewshed.dirty {
|
if viewshed.dirty {
|
||||||
|
|
@ -44,6 +47,24 @@ impl<'a> System<'a> for VisibilitySystem {
|
||||||
let idx = map.xy_idx(vis.x, vis.y);
|
let idx = map.xy_idx(vis.x, vis.y);
|
||||||
map.revealed_tiles[idx] = true;
|
map.revealed_tiles[idx] = true;
|
||||||
map.visible_tiles[idx] = true;
|
map.visible_tiles[idx] = true;
|
||||||
|
|
||||||
|
// Reveal hidden things
|
||||||
|
for thing in map.tile_content[idx].iter() {
|
||||||
|
let is_hidden = hidden.get(*thing);
|
||||||
|
if let Some(_is_hidden) = is_hidden {
|
||||||
|
if rng.roll_dice(1, 20) == 1 {
|
||||||
|
let name = names.get(*thing);
|
||||||
|
if let Some(name) = name {
|
||||||
|
gamelog::Logger::new()
|
||||||
|
.append("You spot a")
|
||||||
|
.item_name_n(&name.name)
|
||||||
|
.period()
|
||||||
|
.log();
|
||||||
|
}
|
||||||
|
hidden.remove(*thing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue