diff --git a/raws/mobs.json b/raws/mobs.json
index 9a23720..c5423f1 100644
--- a/raws/mobs.json
+++ b/raws/mobs.json
@@ -44,8 +44,8 @@
"name": "priest",
"renderable": { "glyph": "@", "fg": "#FFFFFF", "bg": "#000000", "order": 1 },
"flags": ["BYSTANDER", "BLOCKS_TILE"],
- "quips": ["Light's givings.", "", "Bless you."],
- "vision_range": 4
+ "vision_range": 4,
+ "quips": ["Light's givings.", "", "Bless you."]
},
{
"id": "npc_miner",
@@ -53,8 +53,8 @@
"renderable": { "glyph": "@", "fg": "#946123", "bg": "#000000", "order": 1 },
"flags": ["BYSTANDER", "BLOCKS_TILE"],
"vision_range": 4,
- "quips": ["You're not borrowing my pick."],
- "attacks": [{ "name": "hits", "hit_bonus": 0, "damage": "1d8" }]
+ "attacks": [{ "name": "hits", "hit_bonus": 0, "damage": "1d8" }],
+ "quips": ["You're not borrowing my pick."]
},
{
"id": "npc_guard",
@@ -63,20 +63,9 @@
"flags": ["BYSTANDER", "BLOCKS_TILE"],
"level": 2,
"vision_range": 4,
- "quips": ["You wont catch me down the mine.", "Staying out of trouble?"],
"attacks": [{ "name": "hits", "hit_bonus": 0, "damage": "1d8" }],
- "equipped": ["equip_shortsword", "equip_body_leather"]
- },
- {
- "id": "dog_little",
- "name": "little dog",
- "renderable": { "glyph": "d", "fg": "#FFFFFF", "bg": "#000000", "order": 1 },
- "flags": ["BYSTANDER", "BLOCKS_TILE"],
- "level": 2,
- "bac": 6,
- "vision_range": 12,
- "quips": ["", "", ""],
- "attacks": [{ "name": "bites", "hit_bonus": 0, "damage": "1d6" }]
+ "equipped": ["equip_shortsword", "equip_body_leather"],
+ "quips": ["You wont catch me down the mine.", "Staying out of trouble?"]
},
{
"id": "rat",
@@ -86,8 +75,7 @@
"bac": 6,
"vision_range": 8,
"attacks": [{ "name": "bites", "hit_bonus": 0, "damage": "1d2" }],
- "equipped": ["equip_shortsword", "equip_body_leather"],
- "loot": { "table": "scrolls", "chance": 0.05 }
+ "loot": { "table": "food", "chance": 0.1 }
},
{
"id": "chicken",
@@ -111,7 +99,7 @@
"id": "sheep_little",
"name": "lamb",
"renderable": { "glyph": "q", "fg": "#e7e7e7", "bg": "#000000", "order": 1 },
- "flags": ["BYSTANDER", "BLOCKS_TILE"],
+ "flags": ["BYSTANDER", "BLOCKS_TILE", "SMALL_GROUP"],
"bac": 10,
"vision_range": 4,
"attacks": [{ "name": "kicks", "hit_bonus": 0, "damage": "1d2" }]
@@ -132,11 +120,13 @@
"flags": ["BYSTANDER", "BLOCKS_TILE", "MULTIATTACK"],
"level": 3,
"bac": 6,
+ "speed": 16,
"vision_range": 8,
"attacks": [
{ "name": "kicks", "hit_bonus": 0, "damage": "1d6" },
{ "name": "bites", "hit_bonus": 0, "damage": "1d2" }
- ]
+ ],
+ "quips": [""]
},
{
"id": "horse",
@@ -145,6 +135,7 @@
"flags": ["MONSTER", "BLOCKS_TILE", "MULTIATTACK"],
"level": 5,
"bac": 5,
+ "speed": 20,
"vision_range": 8,
"attacks": [
{ "name": "kicks", "hit_bonus": 0, "damage": "1d8" },
@@ -158,6 +149,7 @@
"flags": ["MONSTER", "BLOCKS_TILE", "MULTIATTACK"],
"level": 7,
"bac": 4,
+ "speed": 24,
"vision_range": 8,
"attacks": [
{ "name": "kicks", "hit_bonus": 0, "damage": "1d10" },
@@ -168,13 +160,25 @@
"id": "rat_giant",
"name": "giant rat",
"renderable": { "glyph": "r", "fg": "#bb8000", "bg": "#000000", "order": 1 },
- "flags": ["MONSTER", "BLOCKS_TILE"],
+ "flags": ["MONSTER", "BLOCKS_TILE", "SMALL_GROUP"],
"level": 1,
"bac": 7,
"vision_range": 8,
"attacks": [{ "name": "bites", "hit_bonus": 0, "damage": "1d3" }],
"loot": { "table": "scrolls", "chance": 0.05 }
},
+ {
+ "id": "dog_little",
+ "name": "little dog",
+ "renderable": { "glyph": "d", "fg": "#FFFFFF", "bg": "#000000", "order": 1 },
+ "flags": ["BYSTANDER", "BLOCKS_TILE"],
+ "level": 2,
+ "bac": 6,
+ "speed": 18,
+ "vision_range": 12,
+ "quips": ["", "", ""],
+ "attacks": [{ "name": "bites", "hit_bonus": 0, "damage": "1d6" }]
+ },
{
"id": "dog",
"name": "dog",
@@ -182,6 +186,7 @@
"flags": ["MONSTER", "BLOCKS_TILE"],
"level": 4,
"bac": 5,
+ "speed": 16,
"vision_range": 12,
"attacks": [{ "name": "bites", "hit_bonus": 0, "damage": "1d6" }]
},
@@ -192,6 +197,7 @@
"flags": ["MONSTER", "BLOCKS_TILE"],
"level": 6,
"bac": 4,
+ "speed": 15,
"vision_range": 12,
"attacks": [{ "name": "bites", "hit_bonus": 0, "damage": "2d4" }]
},
@@ -201,6 +207,7 @@
"renderable": { "glyph": "g", "fg": "#00FF00", "bg": "#000000", "order": 1 },
"flags": ["MONSTER", "BLOCKS_TILE"],
"level": 1,
+ "speed": 9,
"vision_range": 12,
"attacks": [{ "name": "hits", "hit_bonus": 0, "damage": "1d4" }]
},
@@ -218,7 +225,7 @@
"id": "jackal",
"name": "jackal",
"renderable": { "glyph": "d", "fg": "#AA5500", "bg": "#000000", "order": 1 },
- "flags": ["MONSTER", "BLOCKS_TILE"],
+ "flags": ["MONSTER", "BLOCKS_TILE", "SMALL_GROUP"],
"bac": 7,
"vision_range": 12,
"attacks": [{ "name": "bites", "hit_bonus": 0, "damage": "1d2" }]
@@ -236,7 +243,7 @@
"id": "coyote",
"name": "coyote",
"renderable": { "glyph": "d", "fg": "#6E3215", "bg": "#000000", "order": 1 },
- "flags": ["MONSTER", "BLOCKS_TILE"],
+ "flags": ["MONSTER", "BLOCKS_TILE", "SMALL_GROUP"],
"level": 1,
"bac": 7,
"vision_range": 12,
@@ -258,6 +265,7 @@
"renderable": { "glyph": "G", "fg": "#00FF00", "bg": "#000000", "order": 1 },
"flags": ["MONSTER", "BLOCKS_TILE"],
"level": 2,
+ "speed": 9,
"vision_range": 12,
"attacks": [{ "name": "hits", "hit_bonus": 0, "damage": "1d8" }],
"loot": { "table": "wands", "chance": 0.05 }
@@ -266,29 +274,48 @@
"id": "orc",
"name": "orc",
"renderable": { "glyph": "o", "fg": "#00FF00", "bg": "#000000", "order": 1 },
- "flags": ["MONSTER", "BLOCKS_TILE"],
+ "flags": ["MONSTER", "BLOCKS_TILE", "SMALL_GROUP"],
+ "level": 1,
+ "speed": 9,
"vision_range": 12,
"attacks": [{ "name": "hits", "hit_bonus": 0, "damage": "1d6" }],
"loot": { "table": "equipment", "chance": 0.05 }
},
{
- "id": "orc_large",
- "name": "large orc",
- "renderable": { "glyph": "o", "fg": "#008000", "bg": "#000000", "order": 1 },
- "flags": ["MONSTER", "BLOCKS_TILE"],
+ "id": "orc_hill",
+ "name": "hill orc",
+ "renderable": { "glyph": "o", "fg": "#dbd830", "bg": "#000000", "order": 1 },
+ "flags": ["MONSTER", "BLOCKS_TILE", "LARGE_GROUP"],
"level": 2,
- "vision_range": 12,
+ "speed": 9,
+ "vision_range": 11,
"attacks": [{ "name": "hits", "hit_bonus": 0, "damage": "1d6" }],
"loot": { "table": "equipment", "chance": 0.05 }
},
+ {
+ "id": "orc_captain",
+ "name": "orc captain",
+ "renderable": { "glyph": "o", "fg": "#9331ac", "bg": "#000000", "order": 1 },
+ "flags": ["MONSTER", "BLOCKS_TILE", "MULTIATTACK"],
+ "level": 5,
+ "speed": 5,
+ "vision_range": 12,
+ "attacks": [
+ { "name": "hits", "hit_bonus": 0, "damage": "2d4" },
+ { "name": "hits", "hit_bonus": 0, "damage": "2d4" }
+ ],
+ "loot": { "table": "equipment", "chance": 0.05 }
+ },
{
"id": "ogre",
"name": "ogre",
"renderable": { "glyph": "O", "fg": "#00FF00", "bg": "#000000", "order": 1 },
- "flags": ["MONSTER", "BLOCKS_TILE"],
+ "flags": ["MONSTER", "BLOCKS_TILE", "SMALL_GROUP"],
"level": 5,
"bac": 5,
+ "speed": 10,
"vision_range": 8,
+ "attacks": [{ "name": "hits", "hit_bonus": 0, "damage": "2d5" }],
"loot": { "table": "food", "chance": 0.05 }
}
]
diff --git a/raws/spawn_tables.json b/raws/spawn_tables.json
index c35d381..08f3c65 100644
--- a/raws/spawn_tables.json
+++ b/raws/spawn_tables.json
@@ -61,6 +61,7 @@
{
"id": "mobs",
"table": [
+ { "id": "sheep_little", "weight": 1, "difficulty": 0},
{ "id": "chicken", "weight": 1, "difficulty": 1},
{ "id": "rat", "weight": 1, "difficulty": 1},
{ "id": "goblin", "weight": 3, "difficulty": 1},
@@ -68,19 +69,19 @@
{ "id": "fox", "weight": 1, "difficulty": 1},
{ "id": "jackal", "weight": 4, "difficulty": 1},
{ "id": "deer_little", "weight": 1, "difficulty": 1},
- { "id": "sheep_little", "weight": 1, "difficulty": 1},
{ "id": "rat_giant", "weight": 2, "difficulty": 2},
{ "id": "coyote", "weight": 4, "difficulty": 2},
{ "id": "dog_little", "weight": 1, "difficulty": 3},
{ "id": "orc", "weight": 2, "difficulty": 3},
- { "id": "orc_large", "weight": 1, "difficulty": 3},
+ { "id": "orc_hill", "weight": 1, "difficulty": 4},
{ "id": "goblin_chieftain", "weight": 1, "difficulty": 3},
- { "id": "ogre", "weight": 1, "difficulty": 4},
{ "id": "horse_little", "weight": 2, "difficulty": 4},
{ "id": "dog", "weight": 1, "difficulty": 5},
{ "id": "wolf", "weight": 2, "difficulty": 6},
+ { "id": "orc_captain", "weight": 1, "difficulty": 7},
{ "id": "dog_large", "weight": 1, "difficulty": 7},
{ "id": "horse", "weight": 2, "difficulty": 7},
+ { "id": "ogre", "weight": 1, "difficulty": 7},
{ "id": "horse_large", "weight": 2, "difficulty": 9}
]
},
@@ -89,7 +90,7 @@
"table": [
{ "id": "trap_bear", "weight": 2, "difficulty": 1},
{ "id": "trap_confusion", "weight": 1, "difficulty": 1},
- { "id": "trap_stonefall", "weight": 1, "difficulty": 3}
+ { "id": "trap_stonefall", "weight": 1, "difficulty": 5}
]
}
]
diff --git a/src/ai/energy_system.rs b/src/ai/energy_system.rs
index 21cf723..6b50bf9 100644
--- a/src/ai/energy_system.rs
+++ b/src/ai/energy_system.rs
@@ -32,6 +32,7 @@ impl<'a> System<'a> for EnergySystem {
if energy.current >= TURN_COST {
energy.current -= TURN_COST;
crate::gamelog::record_event("turns", 1);
+ // Handle spawning mobs each turn
if LOG_TICKS {
console::log(format!("===== TURN {} =====", crate::gamelog::get_event_count("turns")));
}
diff --git a/src/ai/mod.rs b/src/ai/mod.rs
index b4d44db..6e480cf 100644
--- a/src/ai/mod.rs
+++ b/src/ai/mod.rs
@@ -1,4 +1,6 @@
mod energy_system;
pub use energy_system::{EnergySystem, NORMAL_SPEED};
-mod turn_status;
-pub use turn_status::TurnStatusSystem;
+mod turn_status_system;
+pub use turn_status_system::TurnStatusSystem;
+mod quip_system;
+pub use quip_system::QuipSystem;
diff --git a/src/ai/quip_system.rs b/src/ai/quip_system.rs
new file mode 100644
index 0000000..5f25cee
--- /dev/null
+++ b/src/ai/quip_system.rs
@@ -0,0 +1,38 @@
+use crate::{gamelog, Name, Quips, TakingTurn, Viewshed};
+use rltk::prelude::*;
+use specs::prelude::*;
+
+pub struct QuipSystem {}
+
+impl<'a> System<'a> for QuipSystem {
+ #[allow(clippy::type_complexity)]
+ type SystemData = (
+ WriteStorage<'a, Quips>,
+ ReadStorage<'a, Name>,
+ ReadStorage<'a, TakingTurn>,
+ ReadExpect<'a, Point>,
+ ReadStorage<'a, Viewshed>,
+ WriteExpect<'a, RandomNumberGenerator>,
+ );
+
+ fn run(&mut self, data: Self::SystemData) {
+ let (mut quips, names, turns, player_pos, viewsheds, mut rng) = data;
+ for (quip, name, viewshed, _turn) in (&mut quips, &names, &viewsheds, &turns).join() {
+ if !quip.available.is_empty() && viewshed.visible_tiles.contains(&player_pos) && rng.roll_dice(1, 6) == 1 {
+ let quip_index = if quip.available.len() == 1 {
+ 0
+ } else {
+ (rng.roll_dice(1, quip.available.len() as i32) - 1) as usize
+ };
+ gamelog::Logger::new()
+ .append("The")
+ .npc_name(&name.name)
+ .append_n("says \"")
+ .append_n(&quip.available[quip_index])
+ .append("\"")
+ .log();
+ quip.available.remove(quip_index);
+ }
+ }
+ }
+}
diff --git a/src/ai/turn_status.rs b/src/ai/turn_status_system.rs
similarity index 100%
rename from src/ai/turn_status.rs
rename to src/ai/turn_status_system.rs
diff --git a/src/bystander_ai_system.rs b/src/bystander_ai_system.rs
index 4856169..eaff950 100644
--- a/src/bystander_ai_system.rs
+++ b/src/bystander_ai_system.rs
@@ -1,4 +1,4 @@
-use super::{gamelog, Bystander, EntityMoved, Map, Name, Point, Position, Quips, TakingTurn, Viewshed};
+use super::{Bystander, EntityMoved, Map, Position, TakingTurn, Viewshed};
use specs::prelude::*;
pub struct BystanderAI {}
@@ -13,54 +13,15 @@ impl<'a> System<'a> for BystanderAI {
WriteStorage<'a, Position>,
WriteStorage<'a, EntityMoved>,
WriteExpect<'a, rltk::RandomNumberGenerator>,
- ReadExpect<'a, Point>,
- WriteStorage<'a, Quips>,
- ReadStorage<'a, Name>,
ReadStorage<'a, TakingTurn>,
);
fn run(&mut self, data: Self::SystemData) {
- let (
- mut map,
- entities,
- mut viewshed,
- bystander,
- mut position,
- mut entity_moved,
- mut rng,
- player_pos,
- mut quips,
- names,
- turns,
- ) = data;
+ let (mut map, entities, mut viewshed, bystander, mut position, mut entity_moved, mut rng, turns) = data;
for (entity, mut viewshed, _bystander, mut pos, _turn) in
(&entities, &mut viewshed, &bystander, &mut position, &turns).join()
{
- // Possibly quip
- let quip = quips.get_mut(entity);
- if let Some(quip) = quip {
- if !quip.available.is_empty()
- && viewshed.visible_tiles.contains(&player_pos)
- && rng.roll_dice(1, 20) == 1
- {
- let name = names.get(entity);
- let quip_index = if quip.available.len() == 1 {
- 0
- } else {
- (rng.roll_dice(1, quip.available.len() as i32) - 1) as usize
- };
- gamelog::Logger::new()
- .append("The")
- .npc_name(&name.unwrap().name)
- .append_n("says \"")
- .append_n(&quip.available[quip_index])
- .append("\"")
- .log();
- quip.available.remove(quip_index);
- }
- }
-
// Try to move randomly
let mut x = pos.x;
let mut y = pos.y;
diff --git a/src/gui/mod.rs b/src/gui/mod.rs
index f9e58f5..a14b5b0 100644
--- a/src/gui/mod.rs
+++ b/src/gui/mod.rs
@@ -468,7 +468,7 @@ pub fn remove_item_menu(gs: &mut State, ctx: &mut Rltk) -> (ItemMenuResult, Opti
1 + y_offset,
RGB::named(rltk::WHITE),
RGB::named(rltk::BLACK),
- "Drop what? [aA-zZ][Esc.]",
+ "Unequip what? [aA-zZ][Esc.]",
);
let mut equippable: Vec<(Entity, String)> = Vec::new();
diff --git a/src/gui/tooltip.rs b/src/gui/tooltip.rs
index e0271c1..37cee9d 100644
--- a/src/gui/tooltip.rs
+++ b/src/gui/tooltip.rs
@@ -1,23 +1,29 @@
-use super::{camera::get_screen_bounds, Attributes, Hidden, Map, Name, Pools, Position, Rltk, World, RGB};
+use super::{camera::get_screen_bounds, Attributes, Hidden, Map, Name, Pools, Position, Renderable, Rltk, World, RGB};
use rltk::prelude::*;
use specs::prelude::*;
struct Tooltip {
- lines: Vec,
+ lines: Vec<(String, RGB)>,
}
+const ATTRIBUTE_COLOUR: RGB = RGB { r: 1.0, g: 0.75, b: 0.8 };
+const RED_WARNING: RGB = RGB { r: 1.0, g: 0.0, b: 0.0 };
+const ORANGE_WARNING: RGB = RGB { r: 1.0, g: 0.65, b: 0.0 };
+const YELLOW_WARNING: RGB = RGB { r: 1.0, g: 1.0, b: 0.0 };
+const GREEN_WARNING: RGB = RGB { r: 0.0, g: 1.0, b: 0.0 };
+
impl Tooltip {
fn new() -> Tooltip {
return Tooltip { lines: Vec::new() };
}
- fn add(&mut self, line: S) {
- self.lines.push(line.to_string());
+ fn add(&mut self, line: S, fg: RGB) {
+ self.lines.push((line.to_string(), fg));
}
fn width(&self) -> i32 {
let mut max = 0;
for s in self.lines.iter() {
- if s.len() > max {
- max = s.len();
+ if s.0.len() > max {
+ max = s.0.len();
}
}
return max as i32 + 2i32;
@@ -26,23 +32,9 @@ impl Tooltip {
return self.lines.len() as i32 + 2i32;
}
fn render(&self, ctx: &mut Rltk, x: i32, y: i32) {
- let white = RGB::named(rltk::WHITE);
- let weak = RGB::named(rltk::CYAN);
- let strong = RGB::named(rltk::ORANGE);
- let attribute = RGB::named(rltk::PINK);
-
ctx.draw_box(x, y, self.width() - 1, self.height() - 1, RGB::named(WHITE), RGB::named(BLACK));
for (i, s) in self.lines.iter().enumerate() {
- let col = if i == 0 {
- white
- } else if s.starts_with('-') {
- weak
- } else if s.starts_with('*') {
- strong
- } else {
- attribute
- };
- ctx.print_color(x + 1, y + i as i32 + 1, col, RGB::named(BLACK), &s);
+ ctx.print_color(x + 1, y + i as i32 + 1, s.1, RGB::named(BLACK), &s.0);
}
}
}
@@ -53,6 +45,7 @@ pub fn draw_tooltips(ecs: &World, ctx: &mut Rltk) {
let map = ecs.fetch::