Real object ids, fixed warping bug

This commit is contained in:
2026-06-06 20:01:07 -05:00
parent 374a69f0ca
commit ea18fe8fc2
6 changed files with 161 additions and 107 deletions
+14 -9
View File
@@ -1,9 +1,9 @@
use crate::floor::{FloorSpec, build_floor};
use crate::game::{Archetype, Board, FontSpec, Glyph, ObjectDef, Player, PortalDef};
use crate::game::{Archetype, Board, FontSpec, Glyph, ObjectDef, ObjectId, Player, PortalDef};
use crate::log::LogLine;
use color::Rgba8;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::collections::{BTreeMap, HashMap};
use std::convert::TryFrom;
use std::path::Path;
@@ -462,7 +462,10 @@ impl TryFrom<MapFile> for Board {
}
solid_occupied[pidx] = true;
let mut objects: Vec<ObjectDef> = Vec::new();
// Objects get sequential ids in load order (so BTreeMap iteration order ==
// load order, preserving the documented "lowest id wins a collision" rule).
let mut objects: BTreeMap<ObjectId, ObjectDef> = BTreeMap::new();
let mut next_object_id: ObjectId = 1;
for (i, e) in mf.objects.into_iter().enumerate() {
if skip[i] {
continue;
@@ -516,7 +519,8 @@ impl TryFrom<MapFile> for Board {
}
solid_occupied[idx] = true;
}
objects.push(obj);
objects.insert(next_object_id, obj);
next_object_id += 1;
}
Ok(Board {
@@ -531,6 +535,7 @@ impl TryFrom<MapFile> for Board {
y: py as i32,
},
objects,
next_object_id,
portals: mf.portals,
font,
zoom: mf.map.zoom,
@@ -621,7 +626,7 @@ impl From<&Board> for MapFile {
// Convert ObjectDef → MapFileObjectEntry, encoding the glyph as TOML-compatible fields.
let objects: Vec<MapFileObjectEntry> = board
.objects
.iter()
.values()
.map(|o| MapFileObjectEntry {
// Saving always emits concrete coordinates; the palette form is a
// load-time convenience only.
@@ -742,7 +747,7 @@ content = """
// `G` appears once, isn't a palette key → object lands there, cell is Empty.
let board = load_board(&map_3x1("G..", &obj_palette("G", "")));
assert_eq!(board.objects.len(), 1);
assert_eq!((board.objects[0].x, board.objects[0].y), (0, 0));
assert_eq!((board.objects[&1].x, board.objects[&1].y), (0, 0));
// The cell under the object is canonical Empty floor.
assert_eq!(board.get(0, 0).1, Archetype::Empty);
}
@@ -760,7 +765,7 @@ content = """
// map is flagged invalid (an extra appearance was reported).
let board = load_board(&map_3x1("G.G", &obj_palette("G", "")));
assert_eq!(board.objects.len(), 1);
assert_eq!((board.objects[0].x, board.objects[0].y), (0, 0));
assert_eq!((board.objects[&1].x, board.objects[&1].y), (0, 0));
assert!(!board.is_valid());
}
@@ -1009,7 +1014,7 @@ bg = "#000000"
let mf: MapFile = toml::from_str(toml).unwrap();
let board = Board::try_from(mf).unwrap();
assert_eq!(board.objects.len(), 1);
let obj = &board.objects[0];
let obj = &board.objects[&1];
assert_eq!(obj.x, 1);
assert_eq!(obj.y, 1);
assert_eq!(obj.glyph.tile, 64);
@@ -1037,7 +1042,7 @@ bg = "#000000"
let toml_out = toml::to_string_pretty(&map_file).unwrap();
let mf2: MapFile = toml::from_str(&toml_out).unwrap();
let board2 = Board::try_from(mf2).unwrap();
let obj2 = &board2.objects[0];
let obj2 = &board2.objects[&1];
assert_eq!(obj2.glyph.tile, obj.glyph.tile);
assert_eq!(obj2.glyph.fg, obj.glyph.fg);
assert_eq!(obj2.glyph.bg, obj.glyph.bg);