fastfov and telepathy
currently no way to *gain* telepathy, but it works
This commit is contained in:
parent
58ab2e9aa5
commit
ec9127573c
12 changed files with 126 additions and 45 deletions
|
|
@ -37,6 +37,9 @@ pub struct Player {}
|
||||||
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct Monster {}
|
pub struct Monster {}
|
||||||
|
|
||||||
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct Mind {}
|
||||||
|
|
||||||
#[derive(Component, ConvertSaveload, Clone)]
|
#[derive(Component, ConvertSaveload, Clone)]
|
||||||
pub struct Viewshed {
|
pub struct Viewshed {
|
||||||
pub visible_tiles: Vec<rltk::Point>,
|
pub visible_tiles: Vec<rltk::Point>,
|
||||||
|
|
@ -44,6 +47,13 @@ pub struct Viewshed {
|
||||||
pub dirty: bool,
|
pub dirty: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component, ConvertSaveload, Clone)]
|
||||||
|
pub struct Telepath {
|
||||||
|
pub telepath_tiles: Vec<rltk::Point>,
|
||||||
|
pub range: i32,
|
||||||
|
pub dirty: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
||||||
pub struct Name {
|
pub struct Name {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use super::LogFragment;
|
use super::{events, LogFragment, Logger};
|
||||||
use rltk::prelude::*;
|
use rltk::prelude::*;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
|
@ -37,6 +37,21 @@ pub fn print_log(console: &mut Box<dyn Console>, pos: Point, descending: bool, l
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn setup_log() {
|
||||||
|
clear_log();
|
||||||
|
events::clear_events();
|
||||||
|
for _ in 0..5 {
|
||||||
|
Logger::new().log();
|
||||||
|
}
|
||||||
|
Logger::new()
|
||||||
|
.append("Welcome!")
|
||||||
|
.colour(rltk::CYAN)
|
||||||
|
.append("(")
|
||||||
|
.append("pretend i wrote a paragraph explaining why you're here")
|
||||||
|
.append(")")
|
||||||
|
.log();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn clone_log() -> Vec<Vec<crate::gamelog::LogFragment>> {
|
pub fn clone_log() -> Vec<Vec<crate::gamelog::LogFragment>> {
|
||||||
return LOG.lock().unwrap().clone();
|
return LOG.lock().unwrap().clone();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ mod builder;
|
||||||
pub use builder::*;
|
pub use builder::*;
|
||||||
mod logstore;
|
mod logstore;
|
||||||
use logstore::*;
|
use logstore::*;
|
||||||
pub use logstore::{clear_log, clone_log, print_log, restore_log};
|
pub use logstore::{clear_log, clone_log, print_log, restore_log, setup_log};
|
||||||
mod events;
|
mod events;
|
||||||
pub use events::*;
|
pub use events::*;
|
||||||
|
|
||||||
|
|
|
||||||
12
src/gui.rs
12
src/gui.rs
|
|
@ -6,29 +6,29 @@ use rltk::{Rltk, VirtualKeyCode, RGB};
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
|
|
||||||
pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
|
pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
|
||||||
ctx.draw_hollow_box_double(0, 45, 79, 14, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK));
|
ctx.draw_hollow_box_double(0, 43, 79, 7, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK));
|
||||||
|
|
||||||
// Render stats
|
// Render stats
|
||||||
let combat_stats = ecs.read_storage::<CombatStats>();
|
let combat_stats = ecs.read_storage::<CombatStats>();
|
||||||
let players = ecs.read_storage::<Player>();
|
let players = ecs.read_storage::<Player>();
|
||||||
for (_player, stats) in (&players, &combat_stats).join() {
|
for (_player, stats) in (&players, &combat_stats).join() {
|
||||||
let health = format!(" HP {}/{} ", stats.hp, stats.max_hp);
|
let health = format!(" HP {}/{} ", stats.hp, stats.max_hp);
|
||||||
ctx.print_color_right(36, 45, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), &health);
|
ctx.print_color_right(36, 43, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), &health);
|
||||||
ctx.draw_bar_horizontal(38, 45, 34, stats.hp, stats.max_hp, RGB::named(rltk::RED), RGB::named(rltk::BLACK));
|
ctx.draw_bar_horizontal(38, 43, 34, stats.hp, stats.max_hp, RGB::named(rltk::RED), RGB::named(rltk::BLACK));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the message log at [1, 46], descending, with 6 lines.
|
// Render the message log at [1, 46], descending, with 6 lines.
|
||||||
gamelog::print_log(&mut rltk::BACKEND_INTERNAL.lock().consoles[0].console, Point::new(1, 46), true, 13);
|
gamelog::print_log(&mut rltk::BACKEND_INTERNAL.lock().consoles[0].console, Point::new(1, 44), true, 6);
|
||||||
|
|
||||||
// Render depth
|
// Render depth
|
||||||
let map = ecs.fetch::<Map>();
|
let map = ecs.fetch::<Map>();
|
||||||
let depth = format!(" D{} ", map.depth);
|
let depth = format!(" D{} ", map.depth);
|
||||||
ctx.print_color_right(78, 45, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), &depth);
|
ctx.print_color_right(78, 43, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), &depth);
|
||||||
|
|
||||||
// Render turn
|
// Render turn
|
||||||
ctx.print_color_right(
|
ctx.print_color_right(
|
||||||
78,
|
78,
|
||||||
59,
|
50,
|
||||||
RGB::named(rltk::YELLOW),
|
RGB::named(rltk::YELLOW),
|
||||||
RGB::named(rltk::BLACK),
|
RGB::named(rltk::BLACK),
|
||||||
&format!(" T{} ", crate::gamelog::get_event_count("Turn")),
|
&format!(" T{} ", crate::gamelog::get_event_count("Turn")),
|
||||||
|
|
|
||||||
40
src/main.rs
40
src/main.rs
|
|
@ -220,6 +220,8 @@ impl State {
|
||||||
if let Some(vs) = vs {
|
if let Some(vs) = vs {
|
||||||
vs.dirty = true;
|
vs.dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gamelog::setup_log();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -242,21 +244,28 @@ 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 map = self.ecs.fetch::<Map>();
|
let map = self.ecs.fetch::<Map>();
|
||||||
|
let entities = self.ecs.entities();
|
||||||
|
|
||||||
let mut data = (&positions, &renderables).join().collect::<Vec<_>>();
|
let mut data = (&positions, &renderables, &entities).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) in data.iter() {
|
for (pos, render, ent) 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);
|
||||||
//bg = bg.add(offsets);
|
|
||||||
if map.bloodstains.contains(&idx) {
|
if map.bloodstains.contains(&idx) {
|
||||||
bg = bg.add(RGB::from_f32(0.6, 0., 0.));
|
bg = bg.add(RGB::from_f32(0.6, 0., 0.));
|
||||||
}
|
}
|
||||||
if map.visible_tiles[idx] {
|
if map.visible_tiles[idx] {
|
||||||
ctx.set(pos.x, pos.y, render.fg, bg, render.glyph);
|
ctx.set(pos.x, pos.y, render.fg, bg, render.glyph);
|
||||||
}
|
}
|
||||||
|
if map.telepath_tiles[idx] {
|
||||||
|
let has_mind = minds.get(*ent);
|
||||||
|
if let Some(_) = has_mind {
|
||||||
|
ctx.set(pos.x, pos.y, render.fg, RGB::named(rltk::BLACK), render.glyph);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
gui::draw_ui(&self.ecs, ctx);
|
gui::draw_ui(&self.ecs, ctx);
|
||||||
}
|
}
|
||||||
|
|
@ -450,17 +459,14 @@ impl GameState for State {
|
||||||
}
|
}
|
||||||
|
|
||||||
const DISPLAYWIDTH: i32 = 80;
|
const DISPLAYWIDTH: i32 = 80;
|
||||||
const DISPLAYHEIGHT: i32 = 60;
|
const DISPLAYHEIGHT: i32 = 51;
|
||||||
|
|
||||||
fn main() -> rltk::BError {
|
fn main() -> rltk::BError {
|
||||||
use rltk::RltkBuilder;
|
use rltk::RltkBuilder;
|
||||||
let mut context = RltkBuilder::new()
|
let mut context = RltkBuilder::simple(DISPLAYWIDTH, DISPLAYHEIGHT)
|
||||||
|
.unwrap()
|
||||||
.with_title("rust-rl")
|
.with_title("rust-rl")
|
||||||
.with_dimensions(DISPLAYWIDTH, DISPLAYHEIGHT)
|
|
||||||
.with_tile_dimensions(16, 16)
|
.with_tile_dimensions(16, 16)
|
||||||
.with_resource_path("resources/")
|
|
||||||
.with_font("terminal8x8.jpg", 8, 8)
|
|
||||||
.with_simple_console(DISPLAYWIDTH, DISPLAYHEIGHT, "terminal8x8.jpg")
|
|
||||||
//.with_simple_console_no_bg(DISPLAYWIDTH, DISPLAYHEIGHT, "terminal8x8.jpg")
|
//.with_simple_console_no_bg(DISPLAYWIDTH, DISPLAYHEIGHT, "terminal8x8.jpg")
|
||||||
.build()?;
|
.build()?;
|
||||||
context.with_post_scanlines(false);
|
context.with_post_scanlines(false);
|
||||||
|
|
@ -472,7 +478,9 @@ fn main() -> rltk::BError {
|
||||||
gs.ecs.register::<Renderable>();
|
gs.ecs.register::<Renderable>();
|
||||||
gs.ecs.register::<Player>();
|
gs.ecs.register::<Player>();
|
||||||
gs.ecs.register::<Monster>();
|
gs.ecs.register::<Monster>();
|
||||||
|
gs.ecs.register::<Mind>();
|
||||||
gs.ecs.register::<Viewshed>();
|
gs.ecs.register::<Viewshed>();
|
||||||
|
gs.ecs.register::<Telepath>();
|
||||||
gs.ecs.register::<Name>();
|
gs.ecs.register::<Name>();
|
||||||
gs.ecs.register::<BlocksTile>();
|
gs.ecs.register::<BlocksTile>();
|
||||||
gs.ecs.register::<CombatStats>();
|
gs.ecs.register::<CombatStats>();
|
||||||
|
|
@ -521,18 +529,8 @@ fn main() -> rltk::BError {
|
||||||
gs.ecs.insert(Point::new(player_x, player_y));
|
gs.ecs.insert(Point::new(player_x, player_y));
|
||||||
gs.ecs.insert(player_entity);
|
gs.ecs.insert(player_entity);
|
||||||
|
|
||||||
gamelog::clear_log();
|
gamelog::setup_log();
|
||||||
gamelog::clear_events();
|
|
||||||
for _ in 0..5 {
|
|
||||||
gamelog::Logger::new().log();
|
|
||||||
}
|
|
||||||
gamelog::Logger::new()
|
|
||||||
.append("Welcome!")
|
|
||||||
.colour(rltk::CYAN)
|
|
||||||
.append("(")
|
|
||||||
.append("pretend i wrote a paragraph explaining why you're here")
|
|
||||||
.append(")")
|
|
||||||
.log();
|
|
||||||
gs.ecs.insert(RunState::MainMenu { menu_selection: gui::MainMenuSelection::NewGame });
|
gs.ecs.insert(RunState::MainMenu { menu_selection: gui::MainMenuSelection::NewGame });
|
||||||
gs.ecs.insert(particle_system::ParticleBuilder::new());
|
gs.ecs.insert(particle_system::ParticleBuilder::new());
|
||||||
gs.ecs.insert(rex_assets::RexAssets::new());
|
gs.ecs.insert(rex_assets::RexAssets::new());
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ pub struct Map {
|
||||||
pub height: i32,
|
pub height: i32,
|
||||||
pub revealed_tiles: Vec<bool>,
|
pub revealed_tiles: Vec<bool>,
|
||||||
pub visible_tiles: Vec<bool>,
|
pub visible_tiles: Vec<bool>,
|
||||||
|
pub telepath_tiles: Vec<bool>,
|
||||||
pub red_offset: Vec<u8>,
|
pub red_offset: Vec<u8>,
|
||||||
pub green_offset: Vec<u8>,
|
pub green_offset: Vec<u8>,
|
||||||
pub blue_offset: Vec<u8>,
|
pub blue_offset: Vec<u8>,
|
||||||
|
|
@ -100,6 +101,7 @@ impl Map {
|
||||||
height: MAPHEIGHT as i32,
|
height: MAPHEIGHT as i32,
|
||||||
revealed_tiles: vec![false; MAPCOUNT],
|
revealed_tiles: vec![false; MAPCOUNT],
|
||||||
visible_tiles: vec![false; MAPCOUNT],
|
visible_tiles: vec![false; MAPCOUNT],
|
||||||
|
telepath_tiles: vec![false; MAPCOUNT],
|
||||||
red_offset: vec![0; MAPCOUNT],
|
red_offset: vec![0; MAPCOUNT],
|
||||||
green_offset: vec![0; MAPCOUNT],
|
green_offset: vec![0; MAPCOUNT],
|
||||||
blue_offset: vec![0; MAPCOUNT],
|
blue_offset: vec![0; MAPCOUNT],
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use super::{
|
use super::{
|
||||||
gamelog, CombatStats, Item, Map, Monster, Name, Player, Position, RunState, State, TileType, Viewshed,
|
gamelog, CombatStats, Item, Map, Monster, Name, Player, Position, RunState, State, Telepath, TileType, Viewshed,
|
||||||
WantsToMelee, WantsToPickupItem, MAPHEIGHT, MAPWIDTH,
|
WantsToMelee, WantsToPickupItem, MAPHEIGHT, MAPWIDTH,
|
||||||
};
|
};
|
||||||
use rltk::{Point, RandomNumberGenerator, Rltk, VirtualKeyCode};
|
use rltk::{Point, RandomNumberGenerator, Rltk, VirtualKeyCode};
|
||||||
|
|
@ -10,6 +10,7 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) {
|
||||||
let mut positions = ecs.write_storage::<Position>();
|
let mut positions = ecs.write_storage::<Position>();
|
||||||
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 combat_stats = ecs.read_storage::<CombatStats>();
|
let combat_stats = ecs.read_storage::<CombatStats>();
|
||||||
let map = ecs.fetch::<Map>();
|
let map = ecs.fetch::<Map>();
|
||||||
|
|
||||||
|
|
@ -62,7 +63,14 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) {
|
||||||
}
|
}
|
||||||
pos.x = min((MAPWIDTH as i32) - 1, max(0, pos.x + delta_x));
|
pos.x = min((MAPWIDTH as i32) - 1, max(0, pos.x + delta_x));
|
||||||
pos.y = min((MAPHEIGHT as i32) - 1, max(0, pos.y + delta_y));
|
pos.y = min((MAPHEIGHT as i32) - 1, max(0, pos.y + delta_y));
|
||||||
|
|
||||||
|
// Dirty viewsheds, and check only now if telepath viewshed exists
|
||||||
viewshed.dirty = true;
|
viewshed.dirty = true;
|
||||||
|
|
||||||
|
let is_telepath = telepaths.get_mut(entity);
|
||||||
|
if let Some(telepathy) = is_telepath {
|
||||||
|
telepathy.dirty = true;
|
||||||
|
}
|
||||||
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;
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,9 @@ pub fn save_game(ecs: &mut World) {
|
||||||
Renderable,
|
Renderable,
|
||||||
Player,
|
Player,
|
||||||
Viewshed,
|
Viewshed,
|
||||||
|
Telepath,
|
||||||
Monster,
|
Monster,
|
||||||
|
Mind,
|
||||||
Name,
|
Name,
|
||||||
BlocksTile,
|
BlocksTile,
|
||||||
CombatStats,
|
CombatStats,
|
||||||
|
|
@ -133,7 +135,9 @@ pub fn load_game(ecs: &mut World) {
|
||||||
Renderable,
|
Renderable,
|
||||||
Player,
|
Player,
|
||||||
Viewshed,
|
Viewshed,
|
||||||
|
Telepath,
|
||||||
Monster,
|
Monster,
|
||||||
|
Mind,
|
||||||
Name,
|
Name,
|
||||||
BlocksTile,
|
BlocksTile,
|
||||||
CombatStats,
|
CombatStats,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
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, InflictsDamage, Item, MagicMapper, MeleePowerBonus, Monster, Name, Player, Position,
|
EquipmentSlot, Equippable, InflictsDamage, Item, MagicMapper, MeleePowerBonus, Mind, Monster, Name, Player,
|
||||||
ProvidesHealing, Ranged, Rect, Renderable, SerializeMe, Viewshed, AOE, MAPWIDTH,
|
Position, ProvidesHealing, Ranged, Rect, Renderable, SerializeMe, Telepath, Viewshed, AOE, MAPWIDTH,
|
||||||
};
|
};
|
||||||
use rltk::{console, RandomNumberGenerator, RGB};
|
use rltk::{console, RandomNumberGenerator, RGB};
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
|
|
@ -27,7 +27,7 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32, player_name: String
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn monster<S: ToString>(ecs: &mut World, x: i32, y: i32, glyph: rltk::FontCharType, name: S, hit_die: i32) {
|
fn monster<S: ToString>(ecs: &mut World, x: i32, y: i32, glyph: rltk::FontCharType, name: S, hit_die: i32, power: i32) {
|
||||||
let rolled_hp = roll_hit_dice(ecs, 1, hit_die);
|
let rolled_hp = roll_hit_dice(ecs, 1, hit_die);
|
||||||
|
|
||||||
ecs.create_entity()
|
ecs.create_entity()
|
||||||
|
|
@ -35,23 +35,24 @@ fn monster<S: ToString>(ecs: &mut World, x: i32, y: i32, glyph: rltk::FontCharTy
|
||||||
.with(Renderable { glyph: glyph, fg: RGB::named(rltk::GREEN), bg: RGB::named(rltk::BLACK), render_order: 1 })
|
.with(Renderable { glyph: glyph, fg: RGB::named(rltk::GREEN), bg: RGB::named(rltk::BLACK), render_order: 1 })
|
||||||
.with(Viewshed { visible_tiles: Vec::new(), range: 12, dirty: true })
|
.with(Viewshed { visible_tiles: Vec::new(), range: 12, dirty: true })
|
||||||
.with(Monster {})
|
.with(Monster {})
|
||||||
|
.with(Mind {})
|
||||||
.with(Name { name: name.to_string() })
|
.with(Name { name: name.to_string() })
|
||||||
.with(BlocksTile {})
|
.with(BlocksTile {})
|
||||||
.with(CombatStats { max_hp: rolled_hp, hp: rolled_hp, defence: 0, power: 2 })
|
.with(CombatStats { max_hp: rolled_hp, hp: rolled_hp, defence: 0, power: power })
|
||||||
.marked::<SimpleMarker<SerializeMe>>()
|
.marked::<SimpleMarker<SerializeMe>>()
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn orc(ecs: &mut World, x: i32, y: i32) {
|
fn orc(ecs: &mut World, x: i32, y: i32) {
|
||||||
monster(ecs, x, y, rltk::to_cp437('o'), "orc", 8);
|
monster(ecs, x, y, rltk::to_cp437('o'), "orc", 8, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn goblin(ecs: &mut World, x: i32, y: i32) {
|
fn goblin(ecs: &mut World, x: i32, y: i32) {
|
||||||
monster(ecs, x, y, rltk::to_cp437('g'), "goblin", 6);
|
monster(ecs, x, y, rltk::to_cp437('g'), "goblin", 6, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn goblin_chieftain(ecs: &mut World, x: i32, y: i32) {
|
fn goblin_chieftain(ecs: &mut World, x: i32, y: i32) {
|
||||||
monster(ecs, x, y, rltk::to_cp437('G'), "goblin chieftain", 8);
|
monster(ecs, x, y, rltk::to_cp437('G'), "goblin chieftain", 8, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn roll_hit_dice(ecs: &mut World, n: i32, d: i32) -> i32 {
|
pub fn roll_hit_dice(ecs: &mut World, n: i32, d: i32) -> i32 {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{Map, Player, Position, Viewshed};
|
use super::{Map, Player, Position, Telepath, Viewshed};
|
||||||
use rltk::{FieldOfViewAlg::SymmetricShadowcasting, Point};
|
use rltk::{FieldOfViewAlg::SymmetricShadowcasting, Point};
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
|
|
||||||
|
|
@ -9,12 +9,13 @@ impl<'a> System<'a> for VisibilitySystem {
|
||||||
WriteExpect<'a, Map>,
|
WriteExpect<'a, Map>,
|
||||||
Entities<'a>,
|
Entities<'a>,
|
||||||
WriteStorage<'a, Viewshed>,
|
WriteStorage<'a, Viewshed>,
|
||||||
|
WriteStorage<'a, Telepath>,
|
||||||
WriteStorage<'a, Position>,
|
WriteStorage<'a, Position>,
|
||||||
ReadStorage<'a, Player>,
|
ReadStorage<'a, Player>,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn run(&mut self, data: Self::SystemData) {
|
fn run(&mut self, data: Self::SystemData) {
|
||||||
let (mut map, entities, mut viewshed, pos, player) = data;
|
let (mut map, entities, mut viewshed, mut telepath, pos, player) = 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 {
|
||||||
|
|
@ -40,5 +41,47 @@ impl<'a> System<'a> for VisibilitySystem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (ent, telepath, pos) in (&entities, &mut telepath, &pos).join() {
|
||||||
|
if telepath.dirty {
|
||||||
|
telepath.dirty = false;
|
||||||
|
|
||||||
|
telepath.telepath_tiles = fast_fov(pos.x, pos.y, telepath.range);
|
||||||
|
telepath.telepath_tiles.retain(|p| p.x >= 0 && p.x < map.width && p.y >= 0 && p.y < map.height);
|
||||||
|
|
||||||
|
// If this is the player, reveal what they can see
|
||||||
|
let _p: Option<&Player> = player.get(ent);
|
||||||
|
if let Some(_p) = _p {
|
||||||
|
for t in map.telepath_tiles.iter_mut() {
|
||||||
|
*t = false;
|
||||||
|
}
|
||||||
|
for vis in telepath.telepath_tiles.iter() {
|
||||||
|
let idx = map.xy_idx(vis.x, vis.y);
|
||||||
|
map.telepath_tiles[idx] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fast_fov(p_x: i32, p_y: i32, r: i32) -> Vec<Point> {
|
||||||
|
let mut visible_tiles: Vec<Point> = Vec::new();
|
||||||
|
|
||||||
|
let mut i = 0;
|
||||||
|
while i <= 360 {
|
||||||
|
let x: f32 = f32::cos(i as f32 * 0.01745 as f32);
|
||||||
|
let y: f32 = f32::sin(i as f32 * 0.01745 as f32);
|
||||||
|
|
||||||
|
let mut ox: f32 = p_x as f32 + 0.5 as f32;
|
||||||
|
let mut oy: f32 = p_y as f32 + 0.5 as f32;
|
||||||
|
for _i in 0..r {
|
||||||
|
visible_tiles.push(Point::new(ox as i32, oy as i32));
|
||||||
|
ox += x;
|
||||||
|
oy += y;
|
||||||
|
}
|
||||||
|
i += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
visible_tiles
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -801,16 +801,16 @@ function __wbg_get_imports() {
|
||||||
const ret = wasm.memory;
|
const ret = wasm.memory;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper429 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper533 = function(arg0, arg1, arg2) {
|
||||||
const ret = makeMutClosure(arg0, arg1, 73, __wbg_adapter_20);
|
const ret = makeMutClosure(arg0, arg1, 86, __wbg_adapter_20);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper1249 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper1314 = function(arg0, arg1, arg2) {
|
||||||
const ret = makeMutClosure(arg0, arg1, 270, __wbg_adapter_23);
|
const ret = makeMutClosure(arg0, arg1, 284, __wbg_adapter_23);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper1251 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper1316 = function(arg0, arg1, arg2) {
|
||||||
const ret = makeMutClosure(arg0, arg1, 270, __wbg_adapter_23);
|
const ret = makeMutClosure(arg0, arg1, 284, __wbg_adapter_23);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue