various fixes: moved turnloss handling into energy system, anims
This commit is contained in:
parent
7b5cd0ec70
commit
1b12d70b23
11 changed files with 235 additions and 53 deletions
|
|
@ -1,5 +1,16 @@
|
|||
use crate::data::entity::*;
|
||||
use crate::{ Burden, BurdenLevel, Clock, Energy, Name, Position, RunState, Map, TakingTurn };
|
||||
use crate::{
|
||||
Burden,
|
||||
BurdenLevel,
|
||||
Clock,
|
||||
Energy,
|
||||
Name,
|
||||
Position,
|
||||
RunState,
|
||||
Map,
|
||||
TakingTurn,
|
||||
Confusion,
|
||||
};
|
||||
use rltk::prelude::*;
|
||||
use specs::prelude::*;
|
||||
use crate::config::CONFIG;
|
||||
|
|
@ -24,6 +35,7 @@ impl<'a> System<'a> for EnergySystem {
|
|||
ReadExpect<'a, Entity>,
|
||||
ReadStorage<'a, Name>,
|
||||
ReadExpect<'a, Point>,
|
||||
ReadStorage<'a, Confusion>,
|
||||
);
|
||||
|
||||
fn run(&mut self, data: Self::SystemData) {
|
||||
|
|
@ -40,6 +52,7 @@ impl<'a> System<'a> for EnergySystem {
|
|||
player,
|
||||
names,
|
||||
player_pos,
|
||||
confusion,
|
||||
) = data;
|
||||
// If not ticking, do nothing.
|
||||
if *runstate != RunState::Ticking {
|
||||
|
|
@ -51,17 +64,29 @@ impl<'a> System<'a> for EnergySystem {
|
|||
for (entity, _clock, energy) in (&entities, &clock, &mut energies).join() {
|
||||
energy.current += NORMAL_SPEED;
|
||||
if energy.current >= TURN_COST {
|
||||
turns.insert(entity, TakingTurn {}).expect("Unable to insert turn for turn counter.");
|
||||
turns
|
||||
.insert(entity, TakingTurn {})
|
||||
.expect("Unable to insert turn for turn counter.");
|
||||
energy.current -= TURN_COST;
|
||||
crate::gamelog::record_event(EVENT::TURN(1));
|
||||
// Handle spawning mobs each turn
|
||||
if CONFIG.logging.log_ticks {
|
||||
console::log(format!("===== TURN {} =====", crate::gamelog::get_event_count(EVENT::COUNT_TURN)));
|
||||
console::log(
|
||||
format!(
|
||||
"===== TURN {} =====",
|
||||
crate::gamelog::get_event_count(EVENT::COUNT_TURN)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
// EVERYTHING ELSE
|
||||
for (entity, energy, pos) in (&entities, &mut energies, &positions).join() {
|
||||
for (entity, energy, pos, _c) in (
|
||||
&entities,
|
||||
&mut energies,
|
||||
&positions,
|
||||
!&confusion,
|
||||
).join() {
|
||||
let burden_modifier = if let Some(burden) = burdens.get(entity) {
|
||||
match burden.level {
|
||||
BurdenLevel::Burdened => SPEED_MOD_BURDENED,
|
||||
|
|
@ -73,7 +98,9 @@ impl<'a> System<'a> for EnergySystem {
|
|||
};
|
||||
let overmap_mod = if map.overmap { SPEED_MOD_OVERMAP_TRAVEL } else { 1.0 };
|
||||
// Every entity has a POTENTIAL equal to their speed.
|
||||
let mut energy_potential: i32 = ((energy.speed as f32) * burden_modifier * overmap_mod) as i32;
|
||||
let mut energy_potential: i32 = ((energy.speed as f32) *
|
||||
burden_modifier *
|
||||
overmap_mod) as i32;
|
||||
// Increment current energy by NORMAL_SPEED for every
|
||||
// whole number of NORMAL_SPEEDS in their POTENTIAL.
|
||||
while energy_potential >= NORMAL_SPEED {
|
||||
|
|
@ -99,7 +126,10 @@ impl<'a> System<'a> for EnergySystem {
|
|||
if entity == *player {
|
||||
*runstate = RunState::AwaitingInput;
|
||||
} else {
|
||||
let distance = rltk::DistanceAlg::Pythagoras.distance2d(*player_pos, Point::new(pos.x, pos.y));
|
||||
let distance = rltk::DistanceAlg::Pythagoras.distance2d(
|
||||
*player_pos,
|
||||
Point::new(pos.x, pos.y)
|
||||
);
|
||||
if distance > 20.0 {
|
||||
my_turn = false;
|
||||
}
|
||||
|
|
@ -107,9 +137,17 @@ impl<'a> System<'a> for EnergySystem {
|
|||
if my_turn {
|
||||
turns.insert(entity, TakingTurn {}).expect("Unable to insert turn.");
|
||||
if CONFIG.logging.log_ticks {
|
||||
let name = if let Some(name) = names.get(entity) { &name.name } else { "Unknown entity" };
|
||||
let name = if let Some(name) = names.get(entity) {
|
||||
&name.name
|
||||
} else {
|
||||
"Unknown entity"
|
||||
};
|
||||
console::log(
|
||||
format!("ENERGY SYSTEM: {} granted a turn. [leftover energy: {}].", name, energy.current)
|
||||
format!(
|
||||
"ENERGY SYSTEM: {} granted a turn. [leftover energy: {}].",
|
||||
name,
|
||||
energy.current
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ use crate::{
|
|||
Name,
|
||||
Renderable,
|
||||
TakingTurn,
|
||||
Item,
|
||||
Prop,
|
||||
};
|
||||
use rltk::prelude::*;
|
||||
use specs::prelude::*;
|
||||
|
|
@ -24,10 +26,22 @@ impl<'a> System<'a> for TurnStatusSystem {
|
|||
ReadStorage<'a, Name>,
|
||||
ReadExpect<'a, Entity>,
|
||||
ReadStorage<'a, Renderable>,
|
||||
ReadStorage<'a, Item>,
|
||||
ReadStorage<'a, Prop>,
|
||||
);
|
||||
|
||||
fn run(&mut self, data: Self::SystemData) {
|
||||
let (mut turns, clock, mut confusion, entities, names, player_entity, renderables) = data;
|
||||
let (
|
||||
mut turns,
|
||||
clock,
|
||||
mut confusion,
|
||||
entities,
|
||||
names,
|
||||
player_entity,
|
||||
renderables,
|
||||
items,
|
||||
props,
|
||||
) = data;
|
||||
let mut clock_tick = false;
|
||||
for (_e, _c, _t) in (&entities, &clock, &turns).join() {
|
||||
clock_tick = true;
|
||||
|
|
@ -39,7 +53,13 @@ impl<'a> System<'a> for TurnStatusSystem {
|
|||
let mut log = false;
|
||||
let mut not_my_turn: Vec<Entity> = Vec::new();
|
||||
let mut not_confused: Vec<Entity> = Vec::new();
|
||||
for (entity, _turn, confused, name) in (&entities, &mut turns, &mut confusion, &names).join() {
|
||||
for (entity, confused, name, _i, _p) in (
|
||||
&entities,
|
||||
&mut confusion,
|
||||
&names,
|
||||
!&items,
|
||||
!&props,
|
||||
).join() {
|
||||
confused.turns -= 1;
|
||||
if confused.turns < 1 {
|
||||
not_confused.push(entity);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,11 @@ pub fn inflict_damage(ecs: &mut World, damage: &EffectSpawner, target: Entity) {
|
|||
target_pool.hit_points.current -= amount;
|
||||
let bleeders = ecs.read_storage::<Bleeds>();
|
||||
if let Some(bleeds) = bleeders.get(target) {
|
||||
add_effect(None, EffectType::Bloodstain { colour: bleeds.colour }, Targets::Entity { target });
|
||||
add_effect(
|
||||
None,
|
||||
EffectType::Bloodstain { colour: bleeds.colour },
|
||||
Targets::Entity { target }
|
||||
);
|
||||
}
|
||||
add_effect(
|
||||
None,
|
||||
|
|
@ -60,7 +64,10 @@ pub fn heal_damage(ecs: &mut World, heal: &EffectSpawner, target: Entity) {
|
|||
if let Some(pool) = pools.get_mut(target) {
|
||||
if let EffectType::Healing { amount, increment_max } = &heal.effect_type {
|
||||
let before = pool.hit_points.current;
|
||||
pool.hit_points.current = i32::min(pool.hit_points.max, pool.hit_points.current + amount);
|
||||
pool.hit_points.current = i32::min(
|
||||
pool.hit_points.max,
|
||||
pool.hit_points.current + amount
|
||||
);
|
||||
if pool.hit_points.current - before < *amount && *increment_max {
|
||||
// If the heal was not fully effective, and healing source was noncursed, increase max HP by 1.
|
||||
pool.hit_points.max += 1;
|
||||
|
|
@ -83,6 +90,12 @@ pub fn heal_damage(ecs: &mut World, heal: &EffectSpawner, target: Entity) {
|
|||
|
||||
pub fn add_confusion(ecs: &mut World, effect: &EffectSpawner, target: Entity) {
|
||||
if let EffectType::Confusion { turns } = &effect.effect_type {
|
||||
let name = if let Some(name) = ecs.read_storage::<Name>().get(target) {
|
||||
name.name.clone()
|
||||
} else {
|
||||
"Something".to_string()
|
||||
};
|
||||
console::log(format!("adding confusion to: {}", name));
|
||||
ecs.write_storage::<Confusion>()
|
||||
.insert(target, Confusion { turns: *turns })
|
||||
.expect("Unable to insert Confusion");
|
||||
|
|
@ -168,7 +181,9 @@ fn get_death_message(ecs: &World, source: Entity) -> String {
|
|||
if source == *player {
|
||||
result.push_str(format!("{}", PLAYER_DIED_SUICIDE).as_str());
|
||||
} else if let Some(name) = ecs.read_storage::<Name>().get(source) {
|
||||
result.push_str(format!("{} {}", PLAYER_DIED_NAMED_ATTACKER, with_article(name.name.clone())).as_str());
|
||||
result.push_str(
|
||||
format!("{} {}", PLAYER_DIED_NAMED_ATTACKER, with_article(name.name.clone())).as_str()
|
||||
);
|
||||
} else {
|
||||
result.push_str(format!("{}", PLAYER_DIED_UNKNOWN).as_str());
|
||||
}
|
||||
|
|
@ -238,7 +253,12 @@ pub fn entity_death(ecs: &mut World, effect: &EffectSpawner, target: Entity) {
|
|||
// If it was the PLAYER that levelled up:
|
||||
if ecs.read_storage::<Player>().get(source).is_some() {
|
||||
gamelog::record_event(EVENT::LEVEL(1));
|
||||
gamelog::Logger::new().append(LEVELUP_PLAYER).append_n(source_pools.level).append("!").log();
|
||||
gamelog::Logger
|
||||
::new()
|
||||
.append(LEVELUP_PLAYER)
|
||||
.append_n(source_pools.level)
|
||||
.append("!")
|
||||
.log();
|
||||
let player_pos = ecs.fetch::<Point>();
|
||||
let map = ecs.fetch_mut::<Map>();
|
||||
for i in 0..5 {
|
||||
|
|
@ -264,7 +284,12 @@ pub fn entity_death(ecs: &mut World, effect: &EffectSpawner, target: Entity) {
|
|||
lifespan: LONG_PARTICLE_LIFETIME,
|
||||
delay: (i as f32) * 100.0,
|
||||
},
|
||||
Targets::Tile { target: map.xy_idx(player_pos.x + (i - 2), player_pos.y - i) }
|
||||
Targets::Tile {
|
||||
target: map.xy_idx(
|
||||
player_pos.x + (i - 2),
|
||||
player_pos.y - i
|
||||
),
|
||||
}
|
||||
);
|
||||
add_effect(
|
||||
None,
|
||||
|
|
@ -275,7 +300,12 @@ pub fn entity_death(ecs: &mut World, effect: &EffectSpawner, target: Entity) {
|
|||
lifespan: LONG_PARTICLE_LIFETIME,
|
||||
delay: (i as f32) * 100.0,
|
||||
},
|
||||
Targets::Tile { target: map.xy_idx(player_pos.x - (i - 2), player_pos.y - i) }
|
||||
Targets::Tile {
|
||||
target: map.xy_idx(
|
||||
player_pos.x - (i - 2),
|
||||
player_pos.y - i
|
||||
),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -307,7 +337,9 @@ pub fn entity_death(ecs: &mut World, effect: &EffectSpawner, target: Entity) {
|
|||
gamelog::record_event(EVENT::PLAYER_DIED("You starved to death!".to_string()));
|
||||
}
|
||||
} else {
|
||||
gamelog::record_event(EVENT::PLAYER_DIED("You died from unknown causes!".to_string()));
|
||||
gamelog::record_event(
|
||||
EVENT::PLAYER_DIED("You died from unknown causes!".to_string())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,9 +121,11 @@ fn target_applicator(ecs: &mut World, effect: &EffectSpawner) {
|
|||
// Otherwise, just match the effect and enact it directly.
|
||||
match &effect.target {
|
||||
Targets::Tile { target } => affect_tile(ecs, effect, *target),
|
||||
Targets::TileList { targets } => targets.iter().for_each(|target| affect_tile(ecs, effect, *target)),
|
||||
Targets::TileList { targets } =>
|
||||
targets.iter().for_each(|target| affect_tile(ecs, effect, *target)),
|
||||
Targets::Entity { target } => affect_entity(ecs, effect, *target),
|
||||
Targets::EntityList { targets } => targets.iter().for_each(|target| affect_entity(ecs, effect, *target)),
|
||||
Targets::EntityList { targets } =>
|
||||
targets.iter().for_each(|target| affect_entity(ecs, effect, *target)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,12 @@
|
|||
use super::{ gamesystem::attr_bonus, gamesystem::get_attribute_rolls, Attributes, Pools, Renderable, RunState, State };
|
||||
use super::{
|
||||
gamesystem::attr_bonus,
|
||||
gamesystem::get_attribute_rolls,
|
||||
Attributes,
|
||||
Pools,
|
||||
Renderable,
|
||||
RunState,
|
||||
State,
|
||||
};
|
||||
use crate::data::entity;
|
||||
use crate::data::char_create::*;
|
||||
use crate::{
|
||||
|
|
@ -248,7 +256,9 @@ pub fn setup_player_ancestry(ecs: &mut World, ancestry: Ancestry) {
|
|||
let player_skills = if let Some(skills) = skills.get_mut(*player) {
|
||||
skills
|
||||
} else {
|
||||
skills.insert(*player, Skills { skills: HashMap::new() }).expect("Unable to insert skills component");
|
||||
skills
|
||||
.insert(*player, Skills { skills: HashMap::new() })
|
||||
.expect("Unable to insert skills component");
|
||||
skills.get_mut(*player).unwrap()
|
||||
};
|
||||
let mut ancestries = ecs.write_storage::<HasAncestry>();
|
||||
|
|
@ -277,11 +287,18 @@ pub fn setup_player_ancestry(ecs: &mut World, ancestry: Ancestry) {
|
|||
.expect("Unable to insert renderable component");
|
||||
let mut telepaths = ecs.write_storage::<Telepath>();
|
||||
telepaths
|
||||
.insert(*player, Telepath { telepath_tiles: Vec::new(), range: ELF_TELEPATH_RANGE, dirty: true })
|
||||
.insert(*player, Telepath {
|
||||
telepath_tiles: Vec::new(),
|
||||
range: ELF_TELEPATH_RANGE,
|
||||
dirty: true,
|
||||
})
|
||||
.expect("Unable to insert telepath component");
|
||||
let mut speeds = ecs.write_storage::<Energy>();
|
||||
speeds
|
||||
.insert(*player, Energy { current: 0, speed: entity::NORMAL_SPEED + ELF_SPEED_BONUS })
|
||||
.insert(*player, Energy {
|
||||
current: 0,
|
||||
speed: entity::NORMAL_SPEED + ELF_SPEED_BONUS,
|
||||
})
|
||||
.expect("Unable to insert energy component");
|
||||
}
|
||||
Ancestry::Catfolk => {
|
||||
|
|
@ -295,7 +312,10 @@ pub fn setup_player_ancestry(ecs: &mut World, ancestry: Ancestry) {
|
|||
.expect("Unable to insert renderable component");
|
||||
let mut speeds = ecs.write_storage::<Energy>();
|
||||
speeds
|
||||
.insert(*player, Energy { current: 0, speed: entity::NORMAL_SPEED + CATFOLK_SPEED_BONUS })
|
||||
.insert(*player, Energy {
|
||||
current: 0,
|
||||
speed: entity::NORMAL_SPEED + CATFOLK_SPEED_BONUS,
|
||||
})
|
||||
.expect("Unable to insert energy component");
|
||||
}
|
||||
_ => {}
|
||||
|
|
@ -334,8 +354,14 @@ pub fn setup_player_class(ecs: &mut World, class: Class, ancestry: Ancestry) {
|
|||
let mut pools = ecs.write_storage::<Pools>();
|
||||
pools
|
||||
.insert(player, Pools {
|
||||
hit_points: Pool { current: 8 + attr_bonus(con), max: entity::STANDARD_HIT_DIE + attr_bonus(con) },
|
||||
mana: Pool { current: 1 + attr_bonus(int), max: entity::MINIMUM_MANA_PLAYER + attr_bonus(int) },
|
||||
hit_points: Pool {
|
||||
current: 8 + attr_bonus(con),
|
||||
max: entity::STANDARD_HIT_DIE + attr_bonus(con),
|
||||
},
|
||||
mana: Pool {
|
||||
current: 1 + attr_bonus(int),
|
||||
max: entity::MINIMUM_MANA_PLAYER + attr_bonus(int),
|
||||
},
|
||||
xp: 0,
|
||||
level: 1,
|
||||
bac: entity::STANDARD_BAC,
|
||||
|
|
@ -371,7 +397,10 @@ pub fn setup_player_class(ecs: &mut World, class: Class, ancestry: Ancestry) {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_starting_inventory(class: Class, rng: &mut RandomNumberGenerator) -> (Vec<String>, Vec<String>) {
|
||||
fn get_starting_inventory(
|
||||
class: Class,
|
||||
rng: &mut RandomNumberGenerator
|
||||
) -> (Vec<String>, Vec<String>) {
|
||||
let mut equipped: Vec<String> = Vec::new();
|
||||
let mut carried: Vec<String> = Vec::new();
|
||||
let starting_food: &str;
|
||||
|
|
@ -387,13 +416,32 @@ fn get_starting_inventory(class: Class, rng: &mut RandomNumberGenerator) -> (Vec
|
|||
Class::Rogue => {
|
||||
starting_food = ROGUE_STARTING_FOOD;
|
||||
equipped = vec![ROGUE_STARTING_WEAPON.to_string(), ROGUE_STARTING_ARMOUR.to_string()];
|
||||
carried = vec!["equip_dagger".to_string(), "equip_dagger".to_string()];
|
||||
carried = vec![
|
||||
"equip_dagger".to_string(),
|
||||
"equip_dagger".to_string(),
|
||||
"scroll_confusion".to_string(),
|
||||
"scroll_confusion".to_string(),
|
||||
"scroll_confusion".to_string(),
|
||||
"scroll_confusion".to_string()
|
||||
];
|
||||
}
|
||||
Class::Wizard => {
|
||||
starting_food = WIZARD_STARTING_FOOD;
|
||||
equipped = vec![WIZARD_STARTING_WEAPON.to_string(), WIZARD_STARTING_ARMOUR.to_string()];
|
||||
pick_random_table_item(rng, &mut carried, "scrolls", WIZARD_SCROLL_AMOUNT, Some(WIZARD_MAX_SCROLL_LVL));
|
||||
pick_random_table_item(rng, &mut carried, "potions", WIZARD_POTION_AMOUNT, Some(WIZARD_MAX_SCROLL_LVL));
|
||||
pick_random_table_item(
|
||||
rng,
|
||||
&mut carried,
|
||||
"scrolls",
|
||||
WIZARD_SCROLL_AMOUNT,
|
||||
Some(WIZARD_MAX_SCROLL_LVL)
|
||||
);
|
||||
pick_random_table_item(
|
||||
rng,
|
||||
&mut carried,
|
||||
"potions",
|
||||
WIZARD_POTION_AMOUNT,
|
||||
Some(WIZARD_MAX_SCROLL_LVL)
|
||||
);
|
||||
}
|
||||
Class::Villager => {
|
||||
starting_food = VILLAGER_STARTING_FOOD;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use super::{ BuilderMap, MetaMapBuilder, TileType };
|
||||
use crate::tile_walkable;
|
||||
use rltk::RandomNumberGenerator;
|
||||
|
||||
pub struct CullUnreachable {}
|
||||
|
|
@ -28,7 +29,7 @@ impl CullUnreachable {
|
|||
1000.0
|
||||
);
|
||||
for (i, tile) in build_data.map.tiles.iter_mut().enumerate() {
|
||||
if *tile == TileType::Floor {
|
||||
if tile_walkable(*tile) {
|
||||
let distance_to_start = dijkstra_map.map[i];
|
||||
// We can't get to this tile - so we'll make it a wall
|
||||
if distance_to_start == std::f32::MAX {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use super::{ BuilderMap, MetaMapBuilder, TileType };
|
||||
use crate::tile_walkable;
|
||||
use rltk::RandomNumberGenerator;
|
||||
|
||||
pub struct DistantExit {}
|
||||
|
|
@ -29,7 +30,7 @@ impl DistantExit {
|
|||
);
|
||||
let mut exit_tile = (0, 0.0f32);
|
||||
for (i, tile) in build_data.map.tiles.iter_mut().enumerate() {
|
||||
if *tile == TileType::Floor {
|
||||
if tile_walkable(*tile) {
|
||||
let distance_to_start = dijkstra_map.map[i];
|
||||
if distance_to_start != std::f32::MAX {
|
||||
// If it is further away than our current exit candidate, move the exit
|
||||
|
|
|
|||
|
|
@ -39,9 +39,9 @@ pub fn forest_builder(
|
|||
chain.with(CullUnreachable::new());
|
||||
chain.with(AreaStartingPosition::new(XStart::LEFT, YStart::CENTRE));
|
||||
// Setup an exit and spawn mobs
|
||||
chain.with(VoronoiSpawning::new());
|
||||
chain.with(RoadExit::new());
|
||||
chain.with(Foliage::percent(TileType::Grass, 30));
|
||||
chain.with(VoronoiSpawning::new());
|
||||
return chain;
|
||||
}
|
||||
|
||||
|
|
@ -66,7 +66,10 @@ impl RoadExit {
|
|||
available_floors.push((
|
||||
idx,
|
||||
DistanceAlg::PythagorasSquared.distance2d(
|
||||
Point::new((idx as i32) % build_data.map.width, (idx as i32) / build_data.map.width),
|
||||
Point::new(
|
||||
(idx as i32) % build_data.map.width,
|
||||
(idx as i32) / build_data.map.width
|
||||
),
|
||||
Point::new(seed_x, seed_y)
|
||||
),
|
||||
));
|
||||
|
|
@ -94,7 +97,11 @@ impl RoadExit {
|
|||
fn build(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||
let starting_pos = build_data.starting_position.as_ref().unwrap().clone();
|
||||
let start_idx = build_data.map.xy_idx(starting_pos.x, starting_pos.y);
|
||||
let (end_x, end_y) = self.find_exit(build_data, build_data.map.width - 2, build_data.height / 2);
|
||||
let (end_x, end_y) = self.find_exit(
|
||||
build_data,
|
||||
build_data.map.width - 2,
|
||||
build_data.height / 2
|
||||
);
|
||||
let end_idx = build_data.map.xy_idx(end_x, end_y);
|
||||
build_data.map.populate_blocked();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use super::{ spawner, BuilderMap, MetaMapBuilder, TileType };
|
||||
use crate::tile_walkable;
|
||||
use rltk::RandomNumberGenerator;
|
||||
use std::collections::HashMap;
|
||||
|
||||
|
|
@ -27,7 +28,7 @@ impl VoronoiSpawning {
|
|||
for y in 1..build_data.map.height - 1 {
|
||||
for x in 1..build_data.map.width - 1 {
|
||||
let idx = build_data.map.xy_idx(x, y);
|
||||
if build_data.map.tiles[idx] == TileType::Floor {
|
||||
if tile_walkable(build_data.map.tiles[idx]) {
|
||||
let cell_value_f = noise.get_noise(x as f32, y as f32) * 10240.0;
|
||||
let cell_value = cell_value_f as i32;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ use super::{
|
|||
Skill,
|
||||
Skills,
|
||||
TileType,
|
||||
tile_walkable,
|
||||
Viewshed,
|
||||
BlocksTile,
|
||||
Bleeds,
|
||||
|
|
@ -42,7 +43,10 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
|
|||
skills.skills.insert(Skill::Magic, 0);
|
||||
let (int, con) = (10, 10);
|
||||
// We only create the player once, so create the Clock here for counting turns too.
|
||||
ecs.create_entity().with(Clock {}).with(Energy { current: 0, speed: entity::NORMAL_SPEED }).build();
|
||||
ecs.create_entity()
|
||||
.with(Clock {})
|
||||
.with(Energy { current: 0, speed: entity::NORMAL_SPEED })
|
||||
.build();
|
||||
let player = ecs
|
||||
.create_entity()
|
||||
.with(Position { x: player_x, y: player_y })
|
||||
|
|
@ -57,7 +61,11 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
|
|||
.with(Player {})
|
||||
.with(Mind {})
|
||||
.with(Faction { name: "player".to_string() })
|
||||
.with(Viewshed { visible_tiles: Vec::new(), range: entity::DEFAULT_VIEWSHED_STANDARD, dirty: true })
|
||||
.with(Viewshed {
|
||||
visible_tiles: Vec::new(),
|
||||
range: entity::DEFAULT_VIEWSHED_STANDARD,
|
||||
dirty: true,
|
||||
})
|
||||
.with(Name { name: "you".to_string(), plural: "you".to_string() })
|
||||
.with(HungerClock { state: HungerState::Satiated, duration: 1200 })
|
||||
.with(Attributes {
|
||||
|
|
@ -102,7 +110,7 @@ pub fn spawn_room(
|
|||
for y in room.y1 + 1..room.y2 {
|
||||
for x in room.x1 + 1..room.x2 {
|
||||
let idx = map.xy_idx(x, y);
|
||||
if map.tiles[idx] == TileType::Floor {
|
||||
if tile_walkable(map.tiles[idx]) {
|
||||
possible_targets.push(idx);
|
||||
}
|
||||
}
|
||||
|
|
@ -209,14 +217,22 @@ pub fn spawn_entity(ecs: &mut World, spawn: &(&usize, &String)) {
|
|||
|
||||
// 3 scrolls : 3 potions : 1 equipment : 1 wand?
|
||||
fn item_category_table() -> RandomTable {
|
||||
return RandomTable::new().add("equipment", 20).add("food", 20).add("potion", 16).add("scroll", 16).add("wand", 4);
|
||||
return RandomTable::new()
|
||||
.add("equipment", 20)
|
||||
.add("food", 20)
|
||||
.add("potion", 16)
|
||||
.add("scroll", 16)
|
||||
.add("wand", 4);
|
||||
}
|
||||
|
||||
fn debug_table() -> RandomTable {
|
||||
return RandomTable::new().add("debug", 1);
|
||||
}
|
||||
|
||||
fn get_random_item_category(rng: &mut RandomNumberGenerator, difficulty: Option<i32>) -> RandomTable {
|
||||
fn get_random_item_category(
|
||||
rng: &mut RandomNumberGenerator,
|
||||
difficulty: Option<i32>
|
||||
) -> RandomTable {
|
||||
let item_category = item_category_table().roll(rng);
|
||||
match item_category.as_ref() {
|
||||
"equipment" => {
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ impl State {
|
|||
let mut encumbrance_system = ai::EncumbranceSystem {}; // Must run first, as it affects energy regen.
|
||||
let mut energy = ai::EnergySystem {}; // Figures out who deserves a turn.
|
||||
let mut regen_system = ai::RegenSystem {}; // Restores HP on appropriate clock ticks.
|
||||
let mut turn_status_system = ai::TurnStatusSystem {}; // Ticks stasuses. Should anyone now lose their turn? i.e. confusion
|
||||
let mut turn_status_system = ai::TurnStatusSystem {}; // Ticks statuses. Should anyone now lose their turn? i.e. confusion
|
||||
let mut quip_system = ai::QuipSystem {}; // Quipping is "free". It doesn't use up a turn.
|
||||
let mut adjacent_ai = ai::AdjacentAI {}; // AdjacentAI -> DefaultAI are all exclusive. If one acts, the entity's turn is over.
|
||||
let mut visible_ai = ai::VisibleAI {};
|
||||
|
|
@ -300,10 +300,8 @@ impl GameState for State {
|
|||
if let Some(ranged_item) = ranged_item {
|
||||
let is_aoe = self.ecs.read_storage::<AOE>();
|
||||
let aoe_item = is_aoe.get(item_entity);
|
||||
let (min_x, _max_x, min_y, _max_y, x_offset, y_offset) = camera::get_screen_bounds(
|
||||
&self.ecs,
|
||||
ctx
|
||||
);
|
||||
let (min_x, _max_x, min_y, _max_y, x_offset, y_offset) =
|
||||
camera::get_screen_bounds(&self.ecs, ctx);
|
||||
let ppos = self.ecs.fetch::<Point>();
|
||||
if let Some(aoe_item) = aoe_item {
|
||||
new_runstate = RunState::ShowTargeting {
|
||||
|
|
@ -325,7 +323,10 @@ impl GameState for State {
|
|||
} else {
|
||||
let mut intent = self.ecs.write_storage::<WantsToUseItem>();
|
||||
intent
|
||||
.insert(*self.ecs.fetch::<Entity>(), WantsToUseItem { item: item_entity, target: None })
|
||||
.insert(*self.ecs.fetch::<Entity>(), WantsToUseItem {
|
||||
item: item_entity,
|
||||
target: None,
|
||||
})
|
||||
.expect("Unable to insert intent.");
|
||||
new_runstate = RunState::Ticking;
|
||||
}
|
||||
|
|
@ -343,7 +344,9 @@ impl GameState for State {
|
|||
let item_entity = result.1.unwrap();
|
||||
let mut intent = self.ecs.write_storage::<WantsToDropItem>();
|
||||
intent
|
||||
.insert(*self.ecs.fetch::<Entity>(), WantsToDropItem { item: item_entity })
|
||||
.insert(*self.ecs.fetch::<Entity>(), WantsToDropItem {
|
||||
item: item_entity,
|
||||
})
|
||||
.expect("Unable to insert intent");
|
||||
new_runstate = RunState::Ticking;
|
||||
}
|
||||
|
|
@ -360,7 +363,9 @@ impl GameState for State {
|
|||
let item_entity = result.1.unwrap();
|
||||
let mut intent = self.ecs.write_storage::<WantsToRemoveItem>();
|
||||
intent
|
||||
.insert(*self.ecs.fetch::<Entity>(), WantsToRemoveItem { item: item_entity })
|
||||
.insert(*self.ecs.fetch::<Entity>(), WantsToRemoveItem {
|
||||
item: item_entity,
|
||||
})
|
||||
.expect("Unable to insert intent");
|
||||
new_runstate = RunState::Ticking;
|
||||
}
|
||||
|
|
@ -378,7 +383,10 @@ impl GameState for State {
|
|||
gui::TargetResult::Selected => {
|
||||
let mut intent = self.ecs.write_storage::<WantsToUseItem>();
|
||||
intent
|
||||
.insert(*self.ecs.fetch::<Entity>(), WantsToUseItem { item, target: result.1 })
|
||||
.insert(*self.ecs.fetch::<Entity>(), WantsToUseItem {
|
||||
item,
|
||||
target: result.1,
|
||||
})
|
||||
.expect("Unable to insert intent.");
|
||||
new_runstate = RunState::Ticking;
|
||||
}
|
||||
|
|
@ -414,7 +422,11 @@ impl GameState for State {
|
|||
let mut dm = self.ecs.fetch_mut::<MasterDungeonMap>();
|
||||
dm.identified_items.insert(name.name.clone());
|
||||
}
|
||||
if let Some(beatitude) = self.ecs.write_storage::<Beatitude>().get_mut(item_entity) {
|
||||
if
|
||||
let Some(beatitude) = self.ecs
|
||||
.write_storage::<Beatitude>()
|
||||
.get_mut(item_entity)
|
||||
{
|
||||
beatitude.known = true;
|
||||
}
|
||||
new_runstate = RunState::Ticking;
|
||||
|
|
@ -457,7 +469,9 @@ impl GameState for State {
|
|||
}
|
||||
gui::CharCreateResult::Selected { ancestry, class } => {
|
||||
if ancestry == gui::Ancestry::NULL {
|
||||
new_runstate = RunState::MainMenu { menu_selection: gui::MainMenuSelection::NewGame };
|
||||
new_runstate = RunState::MainMenu {
|
||||
menu_selection: gui::MainMenuSelection::NewGame,
|
||||
};
|
||||
} else {
|
||||
gui::setup_player_ancestry(&mut self.ecs, ancestry);
|
||||
gui::setup_player_class(&mut self.ecs, class, ancestry);
|
||||
|
|
@ -468,7 +482,9 @@ impl GameState for State {
|
|||
}
|
||||
RunState::SaveGame => {
|
||||
saveload_system::save_game(&mut self.ecs);
|
||||
new_runstate = RunState::MainMenu { menu_selection: gui::MainMenuSelection::LoadGame };
|
||||
new_runstate = RunState::MainMenu {
|
||||
menu_selection: gui::MainMenuSelection::LoadGame,
|
||||
};
|
||||
}
|
||||
RunState::GameOver => {
|
||||
let result = gui::game_over(ctx);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue