blindness improves telepathy, and reduces to-hit

This commit is contained in:
Llywelwyn 2023-08-22 16:16:56 +01:00
parent 0208dcac4c
commit 1714b94397
5 changed files with 45 additions and 15 deletions

View file

@ -63,7 +63,7 @@ pub fn render_camera(ecs: &World, ctx: &mut Rltk) {
if pos.x < max_x && pos.y < max_y && pos.x >= min_x && pos.y >= min_y {
let mut draw = false;
let mut fg = render.fg;
let bg = if render.bg == (RGB { r: 0.0, g: 0.0, b: 0.0 }) {
let mut bg = if render.bg == (RGB { r: 0.0, g: 0.0, b: 0.0 }) {
crate::map::themes::get_tile_renderables_for_id(idx, &*map).2
} else {
render.bg
@ -76,10 +76,15 @@ pub fn render_camera(ecs: &World, ctx: &mut Rltk) {
// We don't darken BG, because get_tile_renderables_for_id handles this.
}
// Draw entities with minds within telepath range
if !draw {
if map.telepath_tiles[idx] {
let has_mind = minds.get(*ent);
if let Some(_) = has_mind {
draw = true;
if !map.revealed_tiles[idx] {
bg = RGB::named(BLACK);
}
}
}
}
// Draw all props

View file

@ -361,6 +361,9 @@ pub struct Confusion {
pub turns: i32,
}
#[derive(Component, Serialize, Deserialize, Clone)]
pub struct Blind {}
#[derive(Component, Serialize, Deserialize, Clone)]
pub struct MagicMapper {}

View file

@ -619,6 +619,7 @@ fn main() -> rltk::BError {
gs.ecs.register::<AOE>();
gs.ecs.register::<Digger>();
gs.ecs.register::<Confusion>();
gs.ecs.register::<Blind>();
gs.ecs.register::<MagicMapper>();
gs.ecs.register::<InBackpack>();
gs.ecs.register::<WantsToApproach>();

View file

@ -2,8 +2,8 @@ use super::{
effects::{add_effect, EffectType, Targets},
gamelog, gamesystem,
gui::renderable_colour,
ArmourClassBonus, Attributes, EquipmentSlot, Equipped, HungerClock, HungerState, MeleeWeapon, MultiAttack, Name,
NaturalAttacks, ParticleBuilder, Pools, Position, Renderable, Skill, Skills, ToHitBonus, WantsToMelee,
ArmourClassBonus, Attributes, Blind, EquipmentSlot, Equipped, HungerClock, HungerState, MeleeWeapon, MultiAttack,
Name, NaturalAttacks, ParticleBuilder, Pools, Position, Renderable, Skill, Skills, ToHitBonus, WantsToMelee,
WeaponAttribute,
};
use rltk::prelude::*;
@ -30,6 +30,7 @@ impl<'a> System<'a> for MeleeCombatSystem {
ReadStorage<'a, ToHitBonus>,
ReadStorage<'a, HungerClock>,
ReadStorage<'a, MultiAttack>,
ReadStorage<'a, Blind>,
WriteExpect<'a, rltk::RandomNumberGenerator>,
);
@ -52,6 +53,7 @@ impl<'a> System<'a> for MeleeCombatSystem {
to_hit,
hunger_clock,
multi_attackers,
blind_entities,
mut rng,
) = data;
@ -119,10 +121,8 @@ impl<'a> System<'a> for MeleeCombatSystem {
if target_pools.hit_points.current <= 0 {
break;
}
let weapon_info = attack.0;
let attack_verb = attack.1;
// Get all offensive bonuses
let d20 = rng.roll_dice(1, 20);
let attribute_hit_bonus = attacker_attributes.dexterity.bonus;
@ -134,6 +134,9 @@ impl<'a> System<'a> for MeleeCombatSystem {
}
}
let mut status_hit_bonus = 0;
if let Some(_) = blind_entities.get(entity) {
status_hit_bonus -= 4;
};
let hc = hunger_clock.get(entity);
if let Some(hc) = hc {
match hc.state {

View file

@ -1,9 +1,11 @@
use super::{gamelog, BlocksVisibility, Hidden, Map, Name, Player, Position, Telepath, Viewshed};
use super::{gamelog, Blind, BlocksVisibility, Hidden, Map, Name, Player, Position, Telepath, Viewshed};
use rltk::{FieldOfViewAlg::SymmetricShadowcasting, Point};
use specs::prelude::*;
pub struct VisibilitySystem {}
const BLIND_TELEPATHY_RANGE_MULTIPLIER: i32 = 3;
impl<'a> System<'a> for VisibilitySystem {
type SystemData = (
WriteExpect<'a, Map>,
@ -15,12 +17,24 @@ impl<'a> System<'a> for VisibilitySystem {
ReadStorage<'a, Player>,
WriteStorage<'a, Hidden>,
ReadStorage<'a, Name>,
ReadStorage<'a, Blind>,
ReadStorage<'a, BlocksVisibility>,
);
fn run(&mut self, data: Self::SystemData) {
let (mut map, mut rng, entities, mut viewshed, mut telepath, pos, player, mut hidden, names, blocks_visibility) =
data;
let (
mut map,
mut rng,
entities,
mut viewshed,
mut telepath,
pos,
player,
mut hidden,
names,
blind_entities,
blocks_visibility,
) = data;
map.view_blocked.clear();
for (block_pos, _block) in (&pos, &blocks_visibility).join() {
@ -31,8 +45,9 @@ impl<'a> System<'a> for VisibilitySystem {
for (ent, viewshed, pos) in (&entities, &mut viewshed, &pos).join() {
if viewshed.dirty {
viewshed.dirty = false;
let mut range = if let Some(is_blind) = blind_entities.get(ent) { 1 } else { viewshed.range };
let origin = Point::new(pos.x, pos.y);
viewshed.visible_tiles = SymmetricShadowcasting.field_of_view(origin, viewshed.range, &*map);
viewshed.visible_tiles = SymmetricShadowcasting.field_of_view(origin, range, &*map);
viewshed.visible_tiles.retain(|p| {
p.x >= 0
&& p.x < map.width
@ -78,8 +93,11 @@ 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);
let mut range = telepath.range;
if let Some(is_blind) = blind_entities.get(ent) {
range *= BLIND_TELEPATHY_RANGE_MULTIPLIER;
}
telepath.telepath_tiles = fast_fov(pos.x, pos.y, 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