feat: items render as multi-cell pictures in graphics mode
- Item.shape() returns Vec<(dx, dy, color)> per type: Sword: 4-tall blade + crossguard + handle (6 cells) Dagger: blade + 2-cell handle (3 cells) Bow: curved arc + bowstring (4 cells) Leather/Plate Armor: 2x2 body shape (4 cells) Shield: 2x2 shield shape (4 cells) Health/Mana Potion: bottle with cork + body (4 cells) Food: 3-cell round shape Scroll: 3-cell horizontal scroll - Graphics renderer paints all shape cells per item - ASCII mode still uses 2-char glyph encoding in UI - Items in world have visual shape, not just single colored cell All 171 tests + 14 scenarios pass.
This commit is contained in:
@@ -74,6 +74,70 @@ impl Item {
|
||||
format!("{}{}", a, b)
|
||||
}
|
||||
|
||||
pub fn shape(&self) -> Vec<(i32, i32, [u8; 3])> {
|
||||
match self.typ {
|
||||
ItemType::Dagger => vec![
|
||||
(0, 0, [220, 220, 230]),
|
||||
(-1, 1, [120, 80, 40]),
|
||||
(0, 1, [120, 80, 40]),
|
||||
],
|
||||
ItemType::Sword => vec![
|
||||
(0, -2, [235, 235, 245]),
|
||||
(0, -1, [240, 240, 250]),
|
||||
(-1, 0, [180, 130, 60]),
|
||||
(1, 0, [180, 130, 60]),
|
||||
(0, 0, [160, 110, 50]),
|
||||
(0, 1, [100, 70, 30]),
|
||||
],
|
||||
ItemType::Bow => vec![
|
||||
(0, -1, [170, 130, 70]),
|
||||
(1, 0, [180, 140, 80]),
|
||||
(0, 1, [170, 130, 70]),
|
||||
(-1, 0, [220, 220, 220]),
|
||||
],
|
||||
ItemType::LeatherArmor => vec![
|
||||
(-1, -1, [150, 100, 55]),
|
||||
(0, -1, [160, 110, 60]),
|
||||
(-1, 0, [140, 90, 50]),
|
||||
(0, 0, [130, 80, 45]),
|
||||
],
|
||||
ItemType::PlateArmor => vec![
|
||||
(-1, -1, [190, 195, 205]),
|
||||
(0, -1, [200, 205, 215]),
|
||||
(-1, 0, [180, 185, 195]),
|
||||
(0, 0, [170, 175, 185]),
|
||||
],
|
||||
ItemType::Shield => vec![
|
||||
(-1, -1, [170, 150, 70]),
|
||||
(0, -1, [180, 160, 80]),
|
||||
(-1, 0, [160, 140, 60]),
|
||||
(0, 0, [150, 130, 50]),
|
||||
],
|
||||
ItemType::HealthPotion => vec![
|
||||
(0, -1, [60, 40, 30]),
|
||||
(0, 0, [220, 30, 30]),
|
||||
(-1, 0, [180, 20, 20]),
|
||||
(1, 0, [200, 25, 25]),
|
||||
],
|
||||
ItemType::ManaPotion => vec![
|
||||
(0, -1, [60, 40, 30]),
|
||||
(0, 0, [30, 30, 220]),
|
||||
(-1, 0, [20, 20, 180]),
|
||||
(1, 0, [25, 25, 200]),
|
||||
],
|
||||
ItemType::Food => vec![
|
||||
(0, 0, [80, 200, 60]),
|
||||
(-1, 0, [60, 180, 40]),
|
||||
(1, 0, [70, 190, 50]),
|
||||
],
|
||||
ItemType::Scroll => vec![
|
||||
(-1, 0, [240, 220, 120]),
|
||||
(0, 0, [250, 230, 130]),
|
||||
(1, 0, [240, 220, 120]),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn color(&self) -> [u8; 3] {
|
||||
match self.typ {
|
||||
ItemType::Dagger => [200, 200, 200],
|
||||
|
||||
@@ -800,9 +800,13 @@ impl GraphicsRenderer {
|
||||
for item in items.all() {
|
||||
let sx = item.x - cam_x;
|
||||
let sy = item.y - cam_y;
|
||||
if sx >= 0 && sx < self.grid_w as i32 && sy >= 0 && sy < self.grid_h as i32 {
|
||||
let idx = sy as usize * self.grid_w + sx as usize;
|
||||
item_color[idx] = [item.color()[0], item.color()[1], item.color()[2], 255];
|
||||
for (dx, dy, col) in item.shape() {
|
||||
let px = sx + dx;
|
||||
let py = sy + dy;
|
||||
if px >= 0 && px < self.grid_w as i32 && py >= 0 && py < self.grid_h as i32 {
|
||||
let idx = py as usize * self.grid_w + px as usize;
|
||||
item_color[idx] = [col[0], col[1], col[2], 255];
|
||||
}
|
||||
}
|
||||
}
|
||||
for e in entities.all() {
|
||||
|
||||
Reference in New Issue
Block a user