Configurable map size (64-256, non-square), one portal per 64x64 tiles, guarded treasure caves, glowing dig-mark blocks
- New Game dialog with map width/height (steps of 32), remembered in settings - map dimensions are per game; renderer chunks, minimap and camera follow them - content scales with area; grace period grows with the distance to the Hero Gate - treasure caves with rich gold, guarded by hero squads that hold their post - marked blocks: translucent yellow box with outline on all edges - savegame v2: packed run-length encoded tiles (256x256 map ~320 KB), v1 still loads - tests: savegame round trip on 96x128, 256x256 generation/simulation/save Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
925be17e82
commit
f710a19351
12 files changed
+588
-137
No files matched your search
@@ -170,7 +170,7 @@ fn mmss(t: f32) -> String {
|
||||
|
||||
impl Ui {
|
||||
pub fn new() -> Ui {
|
||||
let img = Image::gen_image_color(MW as u16, MH as u16, BLACK);
|
||||
let img = Image::gen_image_color(64, 64, BLACK);
|
||||
let tex = Texture2D::from_image(&img);
|
||||
tex.set_filter(FilterMode::Nearest);
|
||||
Ui {
|
||||
@@ -199,7 +199,7 @@ impl Ui {
|
||||
|
||||
pub fn minimap_world(&self, x: f32, y: f32) -> (f32, f32) {
|
||||
let r = self.minimap_rect;
|
||||
((x - r.x) / r.w * MW as f32, (y - r.y) / r.h * MH as f32)
|
||||
((x - r.x) / r.w * mw() as f32, (y - r.y) / r.h * mh() as f32)
|
||||
}
|
||||
|
||||
pub fn click(&mut self, x: f32, y: f32, g: &Game) -> UiAction {
|
||||
@@ -344,6 +344,13 @@ impl Ui {
|
||||
let mm_y = tb_y - mm_h;
|
||||
gfx.window_titled(mm_x, mm_y, mm_cols, mm_rows, S(), false, FRAME, BG, &tr("ui.map"), FRAME_HI);
|
||||
self.rects.push(Rect::new(mm_x, mm_y, mm_w, mm_h));
|
||||
// the minimap image follows the map size
|
||||
if self.minimap_img.width as usize != mw() || self.minimap_img.height as usize != mh() {
|
||||
self.minimap_img = Image::gen_image_color(mw() as u16, mh() as u16, BLACK);
|
||||
self.minimap_tex = Texture2D::from_image(&self.minimap_img);
|
||||
self.minimap_tex.set_filter(FilterMode::Nearest);
|
||||
self.minimap_t = -1.0;
|
||||
}
|
||||
if now - self.minimap_t > 0.25 {
|
||||
self.minimap_t = now;
|
||||
for (i, t) in g.map.t.iter().enumerate() {
|
||||
@@ -356,12 +363,14 @@ impl Ui {
|
||||
}
|
||||
self.minimap_tex.update(&self.minimap_img);
|
||||
}
|
||||
let map_px = (mm_w - CW() * 2.0).min(mm_h - CH() * 2.0);
|
||||
let mrx = mm_x + (mm_w - map_px) * 0.5;
|
||||
let mry = mm_y + CH() + (mm_h - CH() * 2.0 - map_px) * 0.5;
|
||||
self.minimap_rect = Rect::new(mrx, mry, map_px, map_px);
|
||||
draw_texture_ex(&self.minimap_tex, mrx, mry, WHITE, DrawTextureParams { dest_size: Some(vec2(map_px, map_px)), ..Default::default() });
|
||||
let ms = map_px / MW as f32;
|
||||
// keep the map's aspect ratio inside the window
|
||||
let avail = (mm_w - CW() * 2.0).min(mm_h - CH() * 2.0);
|
||||
let ms = avail / mw().max(mh()) as f32;
|
||||
let (map_w, map_h) = (mw() as f32 * ms, mh() as f32 * ms);
|
||||
let mrx = mm_x + (mm_w - map_w) * 0.5;
|
||||
let mry = mm_y + CH() + (mm_h - CH() * 2.0 - map_h) * 0.5;
|
||||
self.minimap_rect = Rect::new(mrx, mry, map_w, map_h);
|
||||
draw_texture_ex(&self.minimap_tex, mrx, mry, WHITE, DrawTextureParams { dest_size: Some(vec2(map_w, map_h)), ..Default::default() });
|
||||
for e in &g.ents {
|
||||
if e.alive && !e.held {
|
||||
let c = if e.hero { Color::new(0.6, 0.85, 1.0, 1.0) } else if e.kind == EK::Worker { Color::new(1.0, 0.6, 0.3, 1.0) } else { Color::new(1.0, 0.25, 0.25, 1.0) };
|
||||
@@ -377,7 +386,7 @@ impl Ui {
|
||||
for k in 0..4 {
|
||||
let a = corners[k];
|
||||
let b = corners[(k + 1) % 4];
|
||||
let clampp = |p: Vec2| vec2(mrx + p.x.clamp(0.0, MW as f32) * ms, mry + p.y.clamp(0.0, MH as f32) * ms);
|
||||
let clampp = |p: Vec2| vec2(mrx + p.x.clamp(0.0, mw() as f32) * ms, mry + p.y.clamp(0.0, mh() as f32) * ms);
|
||||
let (pa, pb) = (clampp(a), clampp(b));
|
||||
draw_line(pa.x, pa.y, pb.x, pb.y, 1.5, WHITE);
|
||||
}
|
||||
@@ -623,7 +632,7 @@ pub fn hover_info(g: &Game, ent: Option<usize>, tile: Option<(i32, i32)>) -> Vec
|
||||
}
|
||||
Kind::Portal => {
|
||||
out.push((tr("tile.portal"), MANA));
|
||||
out.push((tr(if g.portal_owned() { "portal.claimed" } else { "portal.neutral" }), DIM));
|
||||
out.push((tr(if t.owner == Owner::Player { "portal.claimed" } else { "portal.neutral" }), DIM));
|
||||
}
|
||||
Kind::Gate => {
|
||||
out.push((tr("tile.gate"), BLUE));
|
||||
|
||||
Reference in new issue
Block a user