title image, ui tweaks
This commit is contained in:
parent
2d4758ced1
commit
be2c8a35a5
11 changed files with 238 additions and 171 deletions
Binary file not shown.
BIN
resources/title_image.xp
Normal file
BIN
resources/title_image.xp
Normal file
Binary file not shown.
|
|
@ -35,7 +35,7 @@ impl Logger {
|
|||
|
||||
/// Appends a period to the current message logger.
|
||||
pub fn period(mut self) -> Self {
|
||||
self.fragments.push(LogFragment { colour: self.current_colour, text: ".".to_string() });
|
||||
self.fragments.push(LogFragment { colour: self.current_colour, text: ". ".to_string() });
|
||||
return self;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ pub fn skill_bonus(skill: Skill, skills: &Skills) -> i32 {
|
|||
}
|
||||
}
|
||||
|
||||
/// Roll 4d6 and drop the lowest, for rolling d20-style stats
|
||||
pub fn roll_4d6(rng: &mut rltk::RandomNumberGenerator) -> i32 {
|
||||
let mut rolls: Vec<i32> = Vec::new();
|
||||
for _i in 0..4 {
|
||||
|
|
@ -55,10 +56,8 @@ pub fn roll_4d6(rng: &mut rltk::RandomNumberGenerator) -> i32 {
|
|||
rolls.sort_unstable();
|
||||
|
||||
let mut roll = 0;
|
||||
rltk::console::log(format!("roll 0"));
|
||||
for i in 1..rolls.len() {
|
||||
roll += rolls[i];
|
||||
rltk::console::log(format!("+ {}", rolls[i]));
|
||||
}
|
||||
|
||||
return roll;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use super::{
|
|||
use rltk::{Rltk, VirtualKeyCode, RGB};
|
||||
use specs::prelude::*;
|
||||
use std::collections::BTreeMap;
|
||||
mod tooltip;
|
||||
|
||||
pub fn draw_lerping_bar(
|
||||
ctx: &mut Rltk,
|
||||
|
|
@ -38,7 +39,7 @@ pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
|
|||
ctx.draw_hollow_box(0, 0, 70, 8, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK)); // Log box
|
||||
ctx.draw_hollow_box(0, 9, 70, 42, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK)); // Camera box
|
||||
ctx.draw_hollow_box(0, 52, 70, 3, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK)); // Stats box
|
||||
ctx.draw_hollow_box(71, 0, 28, 55, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK)); // Side box
|
||||
ctx.draw_hollow_box(71, 0, 33, 55, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK)); // Side box
|
||||
|
||||
// Render stats
|
||||
let pools = ecs.read_storage::<Pools>();
|
||||
|
|
@ -144,14 +145,10 @@ pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
|
|||
}
|
||||
|
||||
// Draw consumables
|
||||
ctx.print_color(72, y, RGB::named(rltk::BLACK), RGB::named(rltk::WHITE), "Consumables");
|
||||
let consumables = ecs.read_storage::<Consumable>();
|
||||
for (_entity, _pack, name) in
|
||||
(&consumables, &backpack, &names).join().filter(|item| item.1.owner == *player_entity)
|
||||
{
|
||||
ctx.print_color(72, y, RGB::named(rltk::BLACK), RGB::named(rltk::WHITE), "Backpack");
|
||||
y += 1;
|
||||
ctx.print_color(72, y, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK), format!("- {}", &name.name));
|
||||
}
|
||||
let (player_inventory, _inventory_ids) = get_player_inventory(&ecs);
|
||||
y = print_options(player_inventory, 72, y, ctx);
|
||||
|
||||
// Draw entities seen on screen
|
||||
let viewsheds = ecs.read_storage::<Viewshed>();
|
||||
|
|
@ -188,8 +185,8 @@ pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
|
|||
seen_entities.sort_by(|a, b| b.0.cmp(&a.0));
|
||||
|
||||
if !seen_entities.is_empty() {
|
||||
y += 2;
|
||||
ctx.print_color(72, y, RGB::named(rltk::BLACK), RGB::named(rltk::WHITE), "You see");
|
||||
y += 1;
|
||||
ctx.print_color(72, y, RGB::named(rltk::BLACK), RGB::named(rltk::WHITE), "In View");
|
||||
for entity in seen_entities {
|
||||
y += 1;
|
||||
ctx.print_color(72, y, entity.1, RGB::named(rltk::BLACK), entity.0);
|
||||
|
|
@ -214,7 +211,7 @@ pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
|
|||
&format!("T{}", crate::gamelog::get_event_count("turns")),
|
||||
);
|
||||
|
||||
draw_tooltips(ecs, ctx);
|
||||
tooltip::draw_tooltips(ecs, ctx);
|
||||
}
|
||||
|
||||
pub fn get_input_direction(
|
||||
|
|
@ -249,89 +246,6 @@ pub fn get_input_direction(
|
|||
}
|
||||
}
|
||||
|
||||
fn draw_tooltips(ecs: &World, ctx: &mut Rltk) {
|
||||
let (min_x, _max_x, min_y, _max_y, x_offset, y_offset) = camera::get_screen_bounds(ecs, ctx);
|
||||
let map = ecs.fetch::<Map>();
|
||||
let names = ecs.read_storage::<Name>();
|
||||
let positions = ecs.read_storage::<Position>();
|
||||
let hidden = ecs.read_storage::<Hidden>();
|
||||
|
||||
let mouse_pos = ctx.mouse_pos();
|
||||
let mut mouse_pos_adjusted = mouse_pos;
|
||||
mouse_pos_adjusted.0 += min_x - x_offset;
|
||||
mouse_pos_adjusted.1 += min_y - y_offset;
|
||||
if mouse_pos_adjusted.0 >= map.width
|
||||
|| mouse_pos_adjusted.1 >= map.height
|
||||
|| mouse_pos_adjusted.1 < 0 // Might need to be 1, and -1 from map height/width.
|
||||
|| mouse_pos_adjusted.0 < 0
|
||||
{
|
||||
return;
|
||||
}
|
||||
if !(map.visible_tiles[map.xy_idx(mouse_pos_adjusted.0, mouse_pos_adjusted.1)]
|
||||
|| map.telepath_tiles[map.xy_idx(mouse_pos_adjusted.0, mouse_pos_adjusted.1)])
|
||||
{
|
||||
return;
|
||||
}
|
||||
let mut tooltip: Vec<String> = Vec::new();
|
||||
for (name, position, _hidden) in (&names, &positions, !&hidden).join() {
|
||||
if position.x == mouse_pos_adjusted.0 && position.y == mouse_pos_adjusted.1 {
|
||||
tooltip.push(name.name.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
if !tooltip.is_empty() {
|
||||
if mouse_pos.0 > 40 {
|
||||
let arrow_pos = Point::new(mouse_pos.0 - 2, mouse_pos.1);
|
||||
let left_x = mouse_pos.0 - 3;
|
||||
let mut y = mouse_pos.1;
|
||||
for s in tooltip.iter() {
|
||||
for i in 0..2 {
|
||||
ctx.print_color(
|
||||
arrow_pos.x + i,
|
||||
y,
|
||||
RGB::named(rltk::WHITE),
|
||||
RGB::named(rltk::GREY),
|
||||
&" ".to_string(),
|
||||
);
|
||||
}
|
||||
ctx.print_color_right(left_x, y, RGB::named(rltk::WHITE), RGB::named(rltk::GREY), s);
|
||||
y += 1;
|
||||
}
|
||||
ctx.print_color(
|
||||
arrow_pos.x,
|
||||
arrow_pos.y,
|
||||
RGB::named(rltk::WHITE),
|
||||
RGB::named(rltk::GREY),
|
||||
&"->".to_string(),
|
||||
);
|
||||
} else {
|
||||
let arrow_pos = Point::new(mouse_pos.0 + 1, mouse_pos.1);
|
||||
let left_x = mouse_pos.0 + 3;
|
||||
let mut y = mouse_pos.1;
|
||||
for s in tooltip.iter() {
|
||||
for i in 0..2 {
|
||||
ctx.print_color(
|
||||
arrow_pos.x + 1 + i,
|
||||
y,
|
||||
RGB::named(rltk::WHITE),
|
||||
RGB::named(rltk::GREY),
|
||||
&" ".to_string(),
|
||||
);
|
||||
}
|
||||
ctx.print_color(left_x + 1, y, RGB::named(rltk::WHITE), RGB::named(rltk::DARKGREY), s);
|
||||
y += 1;
|
||||
}
|
||||
ctx.print_color(
|
||||
arrow_pos.x,
|
||||
arrow_pos.y,
|
||||
RGB::named(rltk::WHITE),
|
||||
RGB::named(rltk::GREY),
|
||||
&"<-".to_string(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Copy, Clone)]
|
||||
pub enum ItemMenuResult {
|
||||
Cancel,
|
||||
|
|
@ -339,15 +253,16 @@ pub enum ItemMenuResult {
|
|||
Selected,
|
||||
}
|
||||
|
||||
pub fn print_options(inventory: BTreeMap<(String, String), i32>, mut y: i32, ctx: &mut Rltk) {
|
||||
pub fn print_options(inventory: BTreeMap<(String, String), i32>, mut x: i32, mut y: i32, ctx: &mut Rltk) -> i32 {
|
||||
let mut j = 0;
|
||||
let initial_x: i32 = x;
|
||||
for (name, item_count) in &inventory {
|
||||
x = initial_x;
|
||||
// Print the character required to access this item. i.e. (a)
|
||||
ctx.set(17, y, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK), rltk::to_cp437('('));
|
||||
ctx.set(18, y, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), 97 + j as rltk::FontCharType);
|
||||
ctx.set(19, y, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK), rltk::to_cp437(')'));
|
||||
ctx.set(x, y, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), 97 + j as rltk::FontCharType);
|
||||
|
||||
x += 2;
|
||||
|
||||
let mut x = 21;
|
||||
if item_count > &1 {
|
||||
// If more than one, print the number and pluralise
|
||||
// i.e. (a) 3 daggers
|
||||
|
|
@ -374,6 +289,8 @@ pub fn print_options(inventory: BTreeMap<(String, String), i32>, mut y: i32, ctx
|
|||
y += 1;
|
||||
j += 1;
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
pub fn show_help(ctx: &mut Rltk) -> YesNoResult {
|
||||
|
|
@ -423,14 +340,12 @@ pub fn show_help(ctx: &mut Rltk) -> YesNoResult {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn show_inventory(gs: &mut State, ctx: &mut Rltk) -> (ItemMenuResult, Option<Entity>) {
|
||||
let player_entity = gs.ecs.fetch::<Entity>();
|
||||
let names = gs.ecs.read_storage::<Name>();
|
||||
let backpack = gs.ecs.read_storage::<InBackpack>();
|
||||
let entities = gs.ecs.entities();
|
||||
pub fn get_player_inventory(ecs: &World) -> (BTreeMap<(String, String), i32>, BTreeMap<String, Entity>) {
|
||||
let player_entity = ecs.fetch::<Entity>();
|
||||
let names = ecs.read_storage::<Name>();
|
||||
let backpack = ecs.read_storage::<InBackpack>();
|
||||
let entities = ecs.entities();
|
||||
|
||||
// FIXME: This is unwieldy. Having a separate data structure for (name, id) and (name, count) is not good.
|
||||
// But it works, and this might get cut anyway as I get further along in the design, so leaving as is atm.
|
||||
let mut inventory_ids: BTreeMap<String, Entity> = BTreeMap::new();
|
||||
let mut player_inventory: BTreeMap<(String, String), i32> = BTreeMap::new();
|
||||
for (entity, _pack, name) in (&entities, &backpack, &names).join().filter(|item| item.1.owner == *player_entity) {
|
||||
|
|
@ -441,13 +356,18 @@ pub fn show_inventory(gs: &mut State, ctx: &mut Rltk) -> (ItemMenuResult, Option
|
|||
inventory_ids.entry(name.name.to_string()).or_insert(entity);
|
||||
}
|
||||
|
||||
return (player_inventory, inventory_ids);
|
||||
}
|
||||
|
||||
pub fn show_inventory(gs: &mut State, ctx: &mut Rltk) -> (ItemMenuResult, Option<Entity>) {
|
||||
let (player_inventory, inventory_ids) = get_player_inventory(&gs.ecs);
|
||||
let count = player_inventory.len();
|
||||
let y = (25 - (count / 2)) as i32;
|
||||
ctx.draw_box(15, y - 2, 45, (count + 3) as i32, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK));
|
||||
ctx.print_color(18, y - 2, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), "Inventory");
|
||||
ctx.print_color(18, y + count as i32 + 1, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), "ESC to cancel");
|
||||
|
||||
print_options(player_inventory, y, ctx);
|
||||
print_options(player_inventory, 17, y, ctx);
|
||||
|
||||
match ctx.key {
|
||||
None => (ItemMenuResult::NoResponse, None),
|
||||
|
|
@ -465,28 +385,14 @@ pub fn show_inventory(gs: &mut State, ctx: &mut Rltk) -> (ItemMenuResult, Option
|
|||
}
|
||||
|
||||
pub fn drop_item_menu(gs: &mut State, ctx: &mut Rltk) -> (ItemMenuResult, Option<Entity>) {
|
||||
let player_entity = gs.ecs.fetch::<Entity>();
|
||||
let names = gs.ecs.read_storage::<Name>();
|
||||
let backpack = gs.ecs.read_storage::<InBackpack>();
|
||||
let entities = gs.ecs.entities();
|
||||
|
||||
let mut inventory_ids: BTreeMap<String, Entity> = BTreeMap::new();
|
||||
let mut player_inventory: BTreeMap<(String, String), i32> = BTreeMap::new();
|
||||
for (entity, _pack, name) in (&entities, &backpack, &names).join().filter(|item| item.1.owner == *player_entity) {
|
||||
player_inventory
|
||||
.entry((name.name.to_string(), name.plural.to_string()))
|
||||
.and_modify(|count| *count += 1)
|
||||
.or_insert(1);
|
||||
inventory_ids.entry(name.name.to_string()).or_insert(entity);
|
||||
}
|
||||
|
||||
let (player_inventory, inventory_ids) = get_player_inventory(&gs.ecs);
|
||||
let count = player_inventory.len();
|
||||
let y = (25 - (count / 2)) as i32;
|
||||
ctx.draw_box(15, y - 2, 45, (count + 3) as i32, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK));
|
||||
ctx.print_color(18, y - 2, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), "Drop what?");
|
||||
ctx.print_color(18, y + count as i32 + 1, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), "ESC to cancel");
|
||||
|
||||
print_options(player_inventory, y, ctx);
|
||||
print_options(player_inventory, 17, y, ctx);
|
||||
|
||||
match ctx.key {
|
||||
None => (ItemMenuResult::NoResponse, None),
|
||||
|
|
@ -636,34 +542,41 @@ pub fn main_menu(gs: &mut State, ctx: &mut Rltk) -> MainMenuResult {
|
|||
|
||||
ctx.render_xp_sprite(&assets.menu, 0, 0);
|
||||
|
||||
ctx.print_color(50, 26, RGB::named(rltk::GREEN), RGB::from_f32(0.11, 0.11, 0.11), "RUST-RL");
|
||||
let x = 46;
|
||||
let mut y = 26;
|
||||
let mut height = 8;
|
||||
if !save_exists {
|
||||
height -= 1;
|
||||
}
|
||||
|
||||
ctx.draw_box_double(x, y - 4, 13, height, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK));
|
||||
ctx.print_color(x + 3, y - 2, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), "RUST-RL!");
|
||||
|
||||
if let RunState::MainMenu { menu_selection: selection } = *runstate {
|
||||
let mut y = 29;
|
||||
if selection == MainMenuSelection::NewGame {
|
||||
ctx.print_color(47, y, RGB::named(rltk::YELLOW), RGB::from_f32(0.11, 0.11, 0.11), "[");
|
||||
ctx.print_color(49, y, RGB::named(rltk::GREEN), RGB::from_f32(0.11, 0.11, 0.11), "new game");
|
||||
ctx.print_color(58, y, RGB::named(rltk::YELLOW), RGB::from_f32(0.11, 0.11, 0.11), "]");
|
||||
} else {
|
||||
ctx.print_color(49, y, RGB::named(rltk::WHITE), RGB::from_f32(0.11, 0.11, 0.11), "new game");
|
||||
}
|
||||
y += 2;
|
||||
if save_exists {
|
||||
if selection == MainMenuSelection::LoadGame {
|
||||
ctx.print_color(46, y, RGB::named(rltk::YELLOW), RGB::from_f32(0.11, 0.11, 0.11), "[");
|
||||
ctx.print_color(48, y, RGB::named(rltk::GREEN), RGB::from_f32(0.11, 0.11, 0.11), "load game");
|
||||
ctx.print_color(58, y, RGB::named(rltk::YELLOW), RGB::from_f32(0.11, 0.11, 0.11), "]");
|
||||
ctx.print_color(x + 2, y, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), "[");
|
||||
ctx.print_color(x + 3, y, RGB::named(rltk::GREEN), RGB::named(rltk::BLACK), "continue");
|
||||
ctx.print_color(x + 11, y, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), "]");
|
||||
} else {
|
||||
ctx.print_color(48, y, RGB::named(rltk::WHITE), RGB::from_f32(0.11, 0.11, 0.11), "load game");
|
||||
ctx.print_color(x + 3, y, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK), "continue");
|
||||
}
|
||||
y += 2;
|
||||
y += 1;
|
||||
}
|
||||
if selection == MainMenuSelection::NewGame {
|
||||
ctx.print_color(x + 2, y, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), "[");
|
||||
ctx.print_color(x + 3, y, RGB::named(rltk::GREEN), RGB::named(rltk::BLACK), "new game");
|
||||
ctx.print_color(x + 11, y, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), "]");
|
||||
} else {
|
||||
ctx.print_color(x + 3, y, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK), "new game");
|
||||
}
|
||||
y += 1;
|
||||
if selection == MainMenuSelection::Quit {
|
||||
ctx.print_color(47, y, RGB::named(rltk::YELLOW), RGB::from_f32(0.11, 0.11, 0.11), "[");
|
||||
ctx.print_color(49, y, RGB::named(rltk::GREEN), RGB::from_f32(0.11, 0.11, 0.11), "goodbye!");
|
||||
ctx.print_color(58, y, RGB::named(rltk::YELLOW), RGB::from_f32(0.11, 0.11, 0.11), "]");
|
||||
ctx.print_color(x + 2, y, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), "[");
|
||||
ctx.print_color(x + 3, y, RGB::named(rltk::GREEN), RGB::named(rltk::BLACK), "goodbye!");
|
||||
ctx.print_color(x + 11, y, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), "]");
|
||||
} else {
|
||||
ctx.print_color(53, y, RGB::named(rltk::WHITE), RGB::from_f32(0.11, 0.11, 0.11), "quit");
|
||||
ctx.print_color(x + 5, y, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK), "quit");
|
||||
}
|
||||
|
||||
match ctx.key {
|
||||
|
|
@ -677,9 +590,9 @@ pub fn main_menu(gs: &mut State, ctx: &mut Rltk) -> MainMenuResult {
|
|||
VirtualKeyCode::Up | VirtualKeyCode::Numpad8 | VirtualKeyCode::K => {
|
||||
let mut new_selection;
|
||||
match selection {
|
||||
MainMenuSelection::NewGame => new_selection = MainMenuSelection::Quit,
|
||||
MainMenuSelection::LoadGame => new_selection = MainMenuSelection::NewGame,
|
||||
MainMenuSelection::Quit => new_selection = MainMenuSelection::LoadGame,
|
||||
MainMenuSelection::NewGame => new_selection = MainMenuSelection::LoadGame,
|
||||
MainMenuSelection::LoadGame => new_selection = MainMenuSelection::Quit,
|
||||
MainMenuSelection::Quit => new_selection = MainMenuSelection::NewGame,
|
||||
}
|
||||
if new_selection == MainMenuSelection::LoadGame && !save_exists {
|
||||
new_selection = MainMenuSelection::NewGame;
|
||||
|
|
@ -689,9 +602,9 @@ pub fn main_menu(gs: &mut State, ctx: &mut Rltk) -> MainMenuResult {
|
|||
VirtualKeyCode::Down | VirtualKeyCode::Numpad2 | VirtualKeyCode::J => {
|
||||
let mut new_selection;
|
||||
match selection {
|
||||
MainMenuSelection::NewGame => new_selection = MainMenuSelection::LoadGame,
|
||||
MainMenuSelection::LoadGame => new_selection = MainMenuSelection::Quit,
|
||||
MainMenuSelection::Quit => new_selection = MainMenuSelection::NewGame,
|
||||
MainMenuSelection::NewGame => new_selection = MainMenuSelection::Quit,
|
||||
MainMenuSelection::LoadGame => new_selection = MainMenuSelection::NewGame,
|
||||
MainMenuSelection::Quit => new_selection = MainMenuSelection::LoadGame,
|
||||
}
|
||||
if new_selection == MainMenuSelection::LoadGame && !save_exists {
|
||||
new_selection = MainMenuSelection::Quit;
|
||||
153
src/gui/tooltip.rs
Normal file
153
src/gui/tooltip.rs
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
use super::{camera::get_screen_bounds, Attributes, Hidden, Map, Name, Pools, Position, Rltk, World, RGB};
|
||||
use rltk::prelude::*;
|
||||
use specs::prelude::*;
|
||||
|
||||
struct Tooltip {
|
||||
lines: Vec<String>,
|
||||
}
|
||||
|
||||
impl Tooltip {
|
||||
fn new() -> Tooltip {
|
||||
return Tooltip { lines: Vec::new() };
|
||||
}
|
||||
fn add<S: ToString>(&mut self, line: S) {
|
||||
self.lines.push(line.to_string());
|
||||
}
|
||||
fn width(&self) -> i32 {
|
||||
let mut max = 0;
|
||||
for s in self.lines.iter() {
|
||||
if s.len() > max {
|
||||
max = s.len();
|
||||
}
|
||||
}
|
||||
return max as i32 + 2i32;
|
||||
}
|
||||
fn height(&self) -> i32 {
|
||||
return self.lines.len() as i32 + 2i32;
|
||||
}
|
||||
fn render(&self, ctx: &mut Rltk, x: i32, y: i32) {
|
||||
let weak = RGB::named(rltk::CYAN);
|
||||
let strong = RGB::named(rltk::ORANGE);
|
||||
|
||||
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 {
|
||||
RGB::named(WHITE)
|
||||
} else if s.starts_with('-') {
|
||||
weak
|
||||
} else {
|
||||
strong
|
||||
};
|
||||
ctx.print_color(x + 1, y + i as i32 + 1, col, RGB::named(BLACK), &s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub fn draw_tooltips(ecs: &World, ctx: &mut Rltk) {
|
||||
let (min_x, _max_x, min_y, _max_y, x_offset, y_offset) = get_screen_bounds(ecs, ctx);
|
||||
let map = ecs.fetch::<Map>();
|
||||
let names = ecs.read_storage::<Name>();
|
||||
let positions = ecs.read_storage::<Position>();
|
||||
let hidden = ecs.read_storage::<Hidden>();
|
||||
let attributes = ecs.read_storage::<Attributes>();
|
||||
let pools = ecs.read_storage::<Pools>();
|
||||
let entities = ecs.entities();
|
||||
let player_entity = ecs.fetch::<Entity>();
|
||||
|
||||
let mouse_pos = ctx.mouse_pos();
|
||||
let mut mouse_pos_adjusted = mouse_pos;
|
||||
mouse_pos_adjusted.0 += min_x - x_offset;
|
||||
mouse_pos_adjusted.1 += min_y - y_offset;
|
||||
if mouse_pos_adjusted.0 >= map.width
|
||||
|| mouse_pos_adjusted.1 >= map.height
|
||||
|| mouse_pos_adjusted.1 < 0 // Might need to be 1, and -1 from map height/width.
|
||||
|| mouse_pos_adjusted.0 < 0
|
||||
{
|
||||
return;
|
||||
}
|
||||
if !(map.visible_tiles[map.xy_idx(mouse_pos_adjusted.0, mouse_pos_adjusted.1)]
|
||||
|| map.telepath_tiles[map.xy_idx(mouse_pos_adjusted.0, mouse_pos_adjusted.1)])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let mut tooltips: Vec<Tooltip> = Vec::new();
|
||||
for (entity, name, position, _hidden) in (&entities, &names, &positions, !&hidden).join() {
|
||||
if position.x == mouse_pos_adjusted.0 && position.y == mouse_pos_adjusted.1 {
|
||||
let mut tip = Tooltip::new();
|
||||
tip.add(name.name.to_string());
|
||||
// Attributes
|
||||
let attr = attributes.get(entity);
|
||||
if let Some(a) = attr {
|
||||
let mut s = "".to_string();
|
||||
if a.strength.bonus < -2 { s += "weak "};
|
||||
if a.strength.bonus > 2 { s += "strong "};
|
||||
if a.dexterity.bonus < -2 { s += "clumsy "};
|
||||
if a.dexterity.bonus > 2 { s += "agile "};
|
||||
if a.constitution.bonus < -2 { s += "frail "};
|
||||
if a.constitution.bonus > 2 { s += "hardy "};
|
||||
if a.intelligence.bonus < -2 { s += "dim "};
|
||||
if a.intelligence.bonus > 2 { s += "smart "};
|
||||
if a.wisdom.bonus < -2 { s += "unwise "};
|
||||
if a.wisdom.bonus > 2 { s += "wisened "};
|
||||
if a.charisma.bonus < -2 { s += "ugly "};
|
||||
if a.charisma.bonus > 2 { s += "attractive "};
|
||||
if !s.is_empty() {
|
||||
tip.add(s);
|
||||
}
|
||||
}
|
||||
// Pools
|
||||
let pool = pools.get(entity);
|
||||
let player_pool = pools.get(*player_entity).unwrap();
|
||||
if let Some(p) = pool {
|
||||
let level_diff: i32 = p.level - player_pool.level;
|
||||
if level_diff <= -2 {
|
||||
tip.add("-weak-");
|
||||
} else if level_diff >= 2 {
|
||||
tip.add("*threatening*");
|
||||
}
|
||||
}
|
||||
tooltips.push(tip);
|
||||
}
|
||||
}
|
||||
|
||||
if tooltips.is_empty() { return ; }
|
||||
|
||||
let box_gray : RGB = RGB::from_hex("#999999").expect("Oops");
|
||||
let white = RGB::named(rltk::WHITE);
|
||||
|
||||
let arrow;
|
||||
let arrow_x;
|
||||
let arrow_y = mouse_pos.1;
|
||||
if mouse_pos.0 < 50 {
|
||||
// Render to the left
|
||||
arrow = to_cp437('→');
|
||||
arrow_x = mouse_pos.0 - 1;
|
||||
} else {
|
||||
// Render to the right
|
||||
arrow = to_cp437('←');
|
||||
arrow_x = mouse_pos.0 + 1;
|
||||
}
|
||||
ctx.set(arrow_x, arrow_y, white, box_gray, arrow);
|
||||
|
||||
let mut total_height = 0;
|
||||
for t in tooltips.iter() {
|
||||
total_height += t.height();
|
||||
}
|
||||
|
||||
let mut y = mouse_pos.1 - (total_height / 2);
|
||||
while y + (total_height / 2) > 50 {
|
||||
y -= 1;
|
||||
}
|
||||
|
||||
for t in tooltips.iter() {
|
||||
let x = if mouse_pos.0 < 40 {
|
||||
mouse_pos.0 - (1 + t.width())
|
||||
} else {
|
||||
mouse_pos.0 + (1 + t.width())
|
||||
};
|
||||
t.render(ctx, x, y);
|
||||
y += t.height();
|
||||
}
|
||||
}
|
||||
|
|
@ -303,12 +303,7 @@ impl<'a> System<'a> for ItemUseSystem {
|
|||
damage_logger = damage_logger
|
||||
.append("The")
|
||||
.npc_name(&entity_name.name)
|
||||
.colour(rltk::WHITE)
|
||||
.append("takes")
|
||||
.damage(damage.amount)
|
||||
.colour(rltk::WHITE)
|
||||
.append("damage from the")
|
||||
.item_name_n(format!("{}", &item_being_used.name))
|
||||
.append("is hit!")
|
||||
.period();
|
||||
needs_damage_log = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -482,7 +482,7 @@ impl GameState for State {
|
|||
}
|
||||
}
|
||||
|
||||
const DISPLAYWIDTH: i32 = 100;
|
||||
const DISPLAYWIDTH: i32 = 105;
|
||||
const DISPLAYHEIGHT: i32 = 56;
|
||||
|
||||
fn main() -> rltk::BError {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use super::{BuilderChain, BuilderMap, InitialMapBuilder, Position, TileType};
|
|||
use std::collections::HashSet;
|
||||
|
||||
pub fn town_builder(new_id: i32, _rng: &mut rltk::RandomNumberGenerator, width: i32, height: i32) -> BuilderChain {
|
||||
let difficulty = 0;
|
||||
let difficulty = 7;
|
||||
rltk::console::log(format!("DEBUGINFO: Building town (ID:{}, DIFF:{})", new_id, difficulty));
|
||||
let mut chain = BuilderChain::new(new_id, width, height, difficulty);
|
||||
chain.start_with(TownBuilder::new());
|
||||
|
|
|
|||
|
|
@ -416,7 +416,7 @@ pub fn table_by_name(raws: &RawMaster, key: &str, difficulty: i32) -> RandomTabl
|
|||
use super::SpawnTableEntry;
|
||||
|
||||
let upper_bound = difficulty;
|
||||
let lower_bound = 1;
|
||||
let lower_bound = difficulty / 6;
|
||||
|
||||
let available_options: Vec<&SpawnTableEntry> = spawn_table
|
||||
.table
|
||||
|
|
@ -425,14 +425,21 @@ pub fn table_by_name(raws: &RawMaster, key: &str, difficulty: i32) -> RandomTabl
|
|||
.collect();
|
||||
|
||||
let mut rt = RandomTable::new();
|
||||
if !available_options.is_empty() {
|
||||
for e in available_options.iter() {
|
||||
rt = rt.add(e.id.clone(), e.weight);
|
||||
}
|
||||
|
||||
return rt;
|
||||
} else {
|
||||
return RandomTable::new().add("debug", 1);
|
||||
}
|
||||
}
|
||||
if SPAWN_LOGGING {
|
||||
rltk::console::log(format!(
|
||||
"SPAWNLOG: Something went wrong when trying to spawn {} @ map difficulty {}. Returned debug entry.",
|
||||
key, difficulty
|
||||
));
|
||||
}
|
||||
return RandomTable::new().add("debug", 1);
|
||||
}
|
||||
|
||||
pub fn parse_dice_string(dice: &str) -> (i32, i32, i32) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use rltk::rex::XpFile;
|
||||
|
||||
rltk::embedded_resource!(CAVE_TUNNEL, "../resources/cave_tunnel80x60.xp");
|
||||
rltk::embedded_resource!(TITLEIMAGE_105_56_BYTES, "../resources/title_image.xp");
|
||||
rltk::embedded_resource!(WFC_DEMO_IMAGE1, "../resources/wfc-demo1.xp");
|
||||
rltk::embedded_resource!(WFC_POPULATED, "../resources/wfc-populated.xp");
|
||||
|
||||
|
|
@ -11,10 +11,10 @@ pub struct RexAssets {
|
|||
impl RexAssets {
|
||||
#[allow(clippy::new_without_default)]
|
||||
pub fn new() -> RexAssets {
|
||||
rltk::link_resource!(CAVE_TUNNEL, "../resources/cave_tunnel80x60.xp");
|
||||
rltk::link_resource!(TITLEIMAGE_105_56_BYTES, "../resources/title_image.xp");
|
||||
rltk::link_resource!(WFC_DEMO_IMAGE1, "../resources/wfc-demo1.xp");
|
||||
rltk::link_resource!(WFC_POPULATED, "../resources/wfc-populated.xp");
|
||||
|
||||
RexAssets { menu: XpFile::from_resource("../resources/cave_tunnel80x60.xp").unwrap() }
|
||||
RexAssets { menu: XpFile::from_resource("../resources/title_image.xp").unwrap() }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue