2022-02-02 14:43:09 -05:00
|
|
|
use ::rltk::prelude::*;
|
2022-01-19 13:31:06 -05:00
|
|
|
use ::specs::prelude::*;
|
|
|
|
|
2022-02-02 14:43:09 -05:00
|
|
|
use super::get_item_display_name;
|
2022-01-28 11:48:25 -05:00
|
|
|
use crate::components::{Attributes, Duration, Hidden, Name, Pools, StatusEffect};
|
2022-01-19 13:31:06 -05:00
|
|
|
use crate::{camera, colors, Map};
|
|
|
|
|
|
|
|
struct Tooltip {
|
|
|
|
lines: Vec<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Tooltip {
|
|
|
|
fn new() -> Tooltip {
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
max as i32 + 2
|
|
|
|
}
|
|
|
|
|
|
|
|
fn height(&self) -> i32 {
|
|
|
|
self.lines.len() as i32 + 2
|
|
|
|
}
|
|
|
|
|
2022-02-02 14:43:09 -05:00
|
|
|
fn render(&self, draw_batch: &mut DrawBatch, x: i32, y: i32) {
|
|
|
|
draw_batch.draw_box(
|
|
|
|
Rect::with_size(x, y, self.width() - 1, self.height() - 1),
|
|
|
|
ColorPair::new(colors::WHITE, colors::BOX_GRAY),
|
2022-01-19 13:31:06 -05:00
|
|
|
);
|
|
|
|
|
|
|
|
for (i, s) in self.lines.iter().enumerate() {
|
|
|
|
let col = if i == 0 {
|
|
|
|
colors::WHITE
|
|
|
|
} else {
|
|
|
|
colors::LIGHT_GRAY
|
|
|
|
};
|
2022-02-02 14:43:09 -05:00
|
|
|
draw_batch.print_color(
|
|
|
|
Point::new(x + 1, y + i as i32 + 1),
|
|
|
|
&s,
|
|
|
|
ColorPair::new(col, colors::BLACK),
|
|
|
|
);
|
2022-01-19 13:31:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-02 09:45:19 -05:00
|
|
|
pub fn draw_tooltips(ecs: &World, ctx: &mut Rltk) {
|
2022-02-02 14:43:09 -05:00
|
|
|
let mut draw_batch = DrawBatch::new();
|
2022-01-19 13:31:06 -05:00
|
|
|
|
|
|
|
let (min_x, _max_x, min_y, _max_y) = camera::get_screen_bounds(ecs, ctx);
|
|
|
|
let map = ecs.fetch::<Map>();
|
|
|
|
let hidden = ecs.read_storage::<Hidden>();
|
|
|
|
let attributes = ecs.read_storage::<Attributes>();
|
|
|
|
let pools = ecs.read_storage::<Pools>();
|
2022-01-19 14:35:13 -05:00
|
|
|
|
2022-01-19 13:31:06 -05:00
|
|
|
let mouse_pos = ctx.mouse_pos();
|
|
|
|
let mut mouse_map_pos = mouse_pos;
|
|
|
|
mouse_map_pos.0 += min_x;
|
|
|
|
mouse_map_pos.1 += min_y;
|
|
|
|
|
2022-01-28 11:48:25 -05:00
|
|
|
if mouse_pos.0 < 1 || mouse_pos.0 > 49 || mouse_pos.1 < 1 || mouse_pos.1 > 40 {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-01-19 13:31:06 -05:00
|
|
|
if mouse_map_pos.0 >= map.width - 1
|
|
|
|
|| mouse_map_pos.1 >= map.height - 1
|
|
|
|
|| mouse_map_pos.0 < 1
|
|
|
|
|| mouse_map_pos.1 < 1
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-01-28 11:48:25 -05:00
|
|
|
if !map.in_bounds(Point::new(mouse_map_pos.0, mouse_map_pos.1)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let mouse_idx = map.xy_idx(mouse_map_pos.0, mouse_map_pos.1);
|
|
|
|
if !map.visible_tiles[mouse_idx] {
|
2022-01-19 13:31:06 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut tip_boxes: Vec<Tooltip> = Vec::new();
|
2022-01-28 11:48:25 -05:00
|
|
|
crate::spatial::for_each_tile_content(mouse_idx, |entity| {
|
|
|
|
if hidden.get(entity).is_some() {
|
|
|
|
return;
|
|
|
|
}
|
2022-01-19 13:31:06 -05:00
|
|
|
|
2022-01-28 11:48:25 -05:00
|
|
|
let mut tip = Tooltip::new();
|
2022-02-02 14:43:09 -05:00
|
|
|
tip.add(get_item_display_name(ecs, entity));
|
2022-01-19 13:31:06 -05:00
|
|
|
|
2022-01-28 11:48:25 -05:00
|
|
|
// Comment on attributes
|
|
|
|
if let Some(attr) = attributes.get(entity) {
|
|
|
|
let mut s = String::new();
|
|
|
|
if attr.might.bonus < 0 {
|
|
|
|
s += "Weak. "
|
|
|
|
}
|
|
|
|
if attr.might.bonus > 0 {
|
|
|
|
s += "String. "
|
|
|
|
}
|
|
|
|
if attr.quickness.bonus < 0 {
|
|
|
|
s += "Clumsy. "
|
|
|
|
}
|
|
|
|
if attr.quickness.bonus > 0 {
|
|
|
|
s += "Agile. "
|
|
|
|
}
|
|
|
|
if attr.fitness.bonus < 0 {
|
|
|
|
s += "Unhealthy. "
|
|
|
|
}
|
|
|
|
if attr.fitness.bonus > 0 {
|
|
|
|
s += "Healthy. "
|
|
|
|
}
|
|
|
|
if attr.intelligence.bonus < 0 {
|
|
|
|
s += "Unintelligent. "
|
|
|
|
}
|
|
|
|
if attr.intelligence.bonus > 0 {
|
|
|
|
s += "Smart. "
|
|
|
|
}
|
|
|
|
if s.is_empty() {
|
|
|
|
s = "Quite Average".to_string();
|
2022-01-24 10:58:37 -05:00
|
|
|
}
|
|
|
|
|
2022-01-28 11:48:25 -05:00
|
|
|
tip.add(s);
|
2022-01-19 13:31:06 -05:00
|
|
|
}
|
2022-01-28 11:48:25 -05:00
|
|
|
|
|
|
|
// Comment on pools
|
|
|
|
if let Some(stat) = pools.get(entity) {
|
|
|
|
tip.add(format!("Level: {}", stat.level));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Status effects
|
|
|
|
let statuses = ecs.read_storage::<StatusEffect>();
|
|
|
|
let durations = ecs.read_storage::<Duration>();
|
|
|
|
let names = ecs.read_storage::<Name>();
|
|
|
|
for (status, duration, name) in (&statuses, &durations, &names).join() {
|
|
|
|
if status.target == entity {
|
|
|
|
tip.add(format!("{} ({})", name.name, duration.turns));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tip_boxes.push(tip);
|
|
|
|
});
|
2022-01-19 13:31:06 -05:00
|
|
|
|
|
|
|
if tip_boxes.is_empty() {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let arrow;
|
|
|
|
let arrow_x;
|
|
|
|
let arrow_y = mouse_pos.1;
|
|
|
|
if mouse_pos.0 < 40 {
|
|
|
|
// 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;
|
|
|
|
}
|
2022-02-02 14:43:09 -05:00
|
|
|
draw_batch.set(
|
|
|
|
Point::new(arrow_x, arrow_y),
|
|
|
|
ColorPair::new(colors::WHITE, colors::BOX_GRAY),
|
|
|
|
arrow,
|
|
|
|
);
|
2022-01-19 13:31:06 -05:00
|
|
|
|
|
|
|
let mut total_height = 0;
|
|
|
|
for tt in tip_boxes.iter() {
|
|
|
|
total_height += tt.height();
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut y = mouse_pos.1 - (total_height / 2);
|
|
|
|
while y + (total_height / 2) > 50 {
|
|
|
|
y -= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
for tt in tip_boxes.iter() {
|
|
|
|
let x = if mouse_pos.0 < 40 {
|
|
|
|
mouse_pos.0 - (1 + tt.width())
|
|
|
|
} else {
|
|
|
|
mouse_pos.0 + (1 + tt.width())
|
|
|
|
};
|
2022-02-02 14:43:09 -05:00
|
|
|
tt.render(&mut draw_batch, x, y);
|
2022-01-19 13:31:06 -05:00
|
|
|
y += tt.height();
|
|
|
|
}
|
2022-02-02 14:43:09 -05:00
|
|
|
|
|
|
|
draw_batch.submit(7000).expect("Failed to render tooltip");
|
2022-01-19 13:31:06 -05:00
|
|
|
}
|