mirror of
https://github.com/Noratrieb/game-wip-dontplay.git
synced 2026-01-14 19:55:02 +01:00
Add torches
This commit is contained in:
parent
704819a988
commit
77099ab8a6
13 changed files with 427 additions and 133 deletions
146
Cargo.lock
generated
146
Cargo.lock
generated
|
|
@ -29,6 +29,15 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.70"
|
||||
|
|
@ -106,6 +115,12 @@ version = "3.12.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cairo-sys-rs"
|
||||
version = "0.16.3"
|
||||
|
|
@ -163,7 +178,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -205,7 +220,7 @@ source = "git+https://github.com/crumblingstatue/egui-inspect.git#5cf1f05c0f4f66
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -225,6 +240,19 @@ version = "0.21.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8ecd80612937e0267909d5351770fe150004e24dab93954f69ca62eecd3f77e"
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
|
||||
dependencies = [
|
||||
"humantime",
|
||||
"is-terminal",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "epaint"
|
||||
version = "0.21.0"
|
||||
|
|
@ -474,6 +502,12 @@ version = "0.3.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.3"
|
||||
|
|
@ -504,6 +538,18 @@ dependencies = [
|
|||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"io-lifetimes",
|
||||
"rustix",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.61"
|
||||
|
|
@ -571,13 +617,17 @@ dependencies = [
|
|||
"egui",
|
||||
"egui-inspect",
|
||||
"egui-sfml",
|
||||
"env_logger",
|
||||
"fnv",
|
||||
"gamedebug_core",
|
||||
"hecs",
|
||||
"log",
|
||||
"num-traits",
|
||||
"rand",
|
||||
"rfd",
|
||||
"rmp-serde",
|
||||
"s2dc",
|
||||
"serde",
|
||||
"sfml",
|
||||
"sfml-xt",
|
||||
"worldgen",
|
||||
|
|
@ -689,6 +739,12 @@ dependencies = [
|
|||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.9"
|
||||
|
|
@ -792,6 +848,23 @@ dependencies = [
|
|||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||
|
||||
[[package]]
|
||||
name = "rfd"
|
||||
version = "0.11.3"
|
||||
|
|
@ -817,6 +890,28 @@ dependencies = [
|
|||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rmp"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44519172358fd6d58656c86ab8e7fbc9e1490c3e8f14d35ed78ca0dd07403c9f"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"num-traits",
|
||||
"paste",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rmp-serde"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c5b13be192e0220b8afb7222aa5813cb62cc269ebb5cac346ca6487681d2913e"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"rmp",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.37.8"
|
||||
|
|
@ -850,6 +945,20 @@ name = "serde"
|
|||
version = "1.0.159"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.159"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.13",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
|
|
@ -924,6 +1033,17 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-deps"
|
||||
version = "6.0.4"
|
||||
|
|
@ -937,6 +1057,15 @@ dependencies = [
|
|||
"version-compare",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.7.3"
|
||||
|
|
@ -1028,7 +1157,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
|
@ -1062,7 +1191,7 @@ checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
|
@ -1105,6 +1234,15 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@ rand = "0.8.5"
|
|||
rfd = "0.11.3"
|
||||
sfml = "0.20.0"
|
||||
worldgen = "0.5.3"
|
||||
rmp-serde = "1.1.1"
|
||||
serde = { version = "1.0.159", features = ["derive"] }
|
||||
log = "0.4.17"
|
||||
env_logger = "0.10.0"
|
||||
|
||||
[dependencies.s2dc]
|
||||
git = "https://github.com/crumblingstatue/s2dc.git"
|
||||
|
|
|
|||
BIN
res/tiles.png
BIN
res/tiles.png
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 10 KiB |
132
src/app.rs
132
src/app.rs
|
|
@ -1,8 +1,5 @@
|
|||
use std::fmt::{self};
|
||||
|
||||
use anyhow::Context;
|
||||
use egui_inspect::inspect;
|
||||
use egui_sfml::{egui, SfEgui};
|
||||
use egui_sfml::SfEgui;
|
||||
use gamedebug_core::{imm, imm_dbg};
|
||||
use sfml::{
|
||||
audio::SoundSource,
|
||||
|
|
@ -15,13 +12,13 @@ use sfml::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
debug::DebugState,
|
||||
game::{for_each_tile_on_screen, Biome, GameState, LightSource},
|
||||
debug::{self, DebugState},
|
||||
game::{for_each_tile_on_screen, Biome, GameState},
|
||||
graphics::{self, ScreenPos, ScreenPosScalar},
|
||||
input::Input,
|
||||
math::{center_offset, px_per_frame_to_km_h, WorldPos, M_PER_PX, TILE_SIZE},
|
||||
math::{center_offset, TILE_SIZE},
|
||||
res::Res,
|
||||
world::{Tile, TilePosScalar, CHUNK_EXTENT},
|
||||
world::{TilePosScalar, CHUNK_EXTENT},
|
||||
};
|
||||
|
||||
/// Application level state (includes game and ui state, etc.)
|
||||
|
|
@ -76,6 +73,7 @@ impl App {
|
|||
self.input.clear_pressed();
|
||||
gamedebug_core::inc_frame();
|
||||
}
|
||||
self.game.tile_db.try_save();
|
||||
}
|
||||
|
||||
fn do_event_handling(&mut self) {
|
||||
|
|
@ -132,7 +130,7 @@ impl App {
|
|||
let mut on_screen_tile_ents = Vec::new();
|
||||
for_each_tile_on_screen(self.game.camera_offset, self.rt.size(), |tp, _sp| {
|
||||
let tid = self.game.world.tile_at_mut(tp, &self.game.worldgen).mid;
|
||||
if tid == Tile::EMPTY {
|
||||
if !self.game.tile_db[tid].solid {
|
||||
return;
|
||||
}
|
||||
let tsize = TILE_SIZE as i32;
|
||||
|
|
@ -186,7 +184,12 @@ impl App {
|
|||
wpos.x = wpos.x.saturating_add_signed(loc.x.into());
|
||||
wpos.y = wpos.y.saturating_add_signed(loc.y.into());
|
||||
let mouse_tpos = wpos.tile_pos();
|
||||
imm!("Mouse @ tile {}, {}", mouse_tpos.x, mouse_tpos.y);
|
||||
imm!(
|
||||
"Mouse @ tile {}, {} ({:?})",
|
||||
mouse_tpos.x,
|
||||
mouse_tpos.y,
|
||||
self.game.world.tile_at_mut(mouse_tpos, &self.game.worldgen)
|
||||
);
|
||||
imm!(
|
||||
"@ chunk {}, {}",
|
||||
mouse_tpos.x / CHUNK_EXTENT as TilePosScalar,
|
||||
|
|
@ -207,8 +210,6 @@ impl App {
|
|||
} else {
|
||||
t.bg = self.game.tile_to_place;
|
||||
}
|
||||
} else if self.input.mid_pressed {
|
||||
self.game.light_sources.push(LightSource { pos: wpos });
|
||||
}
|
||||
if self.game.camera_offset.y > 643_000 {
|
||||
self.game.current_biome = Biome::Underground;
|
||||
|
|
@ -274,15 +275,13 @@ impl App {
|
|||
self.rw.draw_with_renderstates(&spr, &rst);
|
||||
self.sf_egui
|
||||
.do_frame(|ctx| {
|
||||
if self.debug.panel {
|
||||
debug_panel_ui(
|
||||
&mut self.debug,
|
||||
&mut self.game,
|
||||
ctx,
|
||||
&mut self.res,
|
||||
&mut self.scale,
|
||||
);
|
||||
}
|
||||
debug::do_debug_ui(
|
||||
ctx,
|
||||
&mut self.debug,
|
||||
&mut self.game,
|
||||
&mut self.res,
|
||||
&mut self.scale,
|
||||
);
|
||||
})
|
||||
.unwrap();
|
||||
self.sf_egui.draw(&mut self.rw, None);
|
||||
|
|
@ -300,94 +299,3 @@ fn viewport_center_offset(rw_size: Vector2u, rt_size: Vector2u, scale: u8) -> Sc
|
|||
y: y as ScreenPosScalar,
|
||||
}
|
||||
}
|
||||
|
||||
fn debug_panel_ui(
|
||||
debug: &mut DebugState,
|
||||
mut game: &mut GameState,
|
||||
ctx: &egui::Context,
|
||||
res: &mut Res,
|
||||
mut scale: &mut u8,
|
||||
) {
|
||||
egui::Window::new("Debug (F12)").show(ctx, |ui| {
|
||||
if debug.freecam {
|
||||
ui.label("Cam x");
|
||||
ui.add(egui::DragValue::new(&mut game.camera_offset.x));
|
||||
ui.label("Cam y");
|
||||
ui.add(egui::DragValue::new(&mut game.camera_offset.y));
|
||||
let co = game.camera_offset;
|
||||
ui.label(format!(
|
||||
"Cam Depth: {}",
|
||||
LengthDisp(co.y as f32 - WorldPos::SURFACE as f32)
|
||||
));
|
||||
ui.label(format!(
|
||||
"Cam offset from center: {}",
|
||||
LengthDisp(co.x as f32 - WorldPos::CENTER as f32)
|
||||
));
|
||||
} else {
|
||||
let tp = game.player.center_tp();
|
||||
imm_dbg!(tp);
|
||||
ui.label(format!(
|
||||
"Player Depth: {}",
|
||||
LengthDisp(game.player.feet_y() as f32 - WorldPos::SURFACE as f32)
|
||||
));
|
||||
ui.label(format!(
|
||||
"Player offset from center: {}",
|
||||
LengthDisp(game.player.col_en.en.pos.x as f32 - WorldPos::CENTER as f32)
|
||||
));
|
||||
ui.label(format!(
|
||||
"Hspeed: {} ({} km/h)",
|
||||
game.player.hspeed,
|
||||
px_per_frame_to_km_h(game.player.hspeed)
|
||||
));
|
||||
ui.label(format!(
|
||||
"Vspeed: {} ({} km/h)",
|
||||
game.player.vspeed,
|
||||
px_per_frame_to_km_h(game.player.vspeed)
|
||||
));
|
||||
}
|
||||
ui.label("Music volume");
|
||||
let mut vol = res.surf_music.volume();
|
||||
ui.add(egui::DragValue::new(&mut vol));
|
||||
res.surf_music.set_volume(vol);
|
||||
ui.separator();
|
||||
egui::ScrollArea::both()
|
||||
.id_source("insp_scroll")
|
||||
.max_height(240.)
|
||||
.max_width(340.0)
|
||||
.show(ui, |ui| {
|
||||
inspect! {
|
||||
ui,
|
||||
scale, game
|
||||
}
|
||||
});
|
||||
ui.separator();
|
||||
egui::ScrollArea::vertical().show(ui, |ui| {
|
||||
gamedebug_core::for_each_imm(|info| match info {
|
||||
gamedebug_core::Info::Msg(msg) => {
|
||||
ui.label(msg);
|
||||
}
|
||||
gamedebug_core::Info::Rect(_, _, _, _, _) => todo!(),
|
||||
});
|
||||
});
|
||||
gamedebug_core::clear_immediates();
|
||||
});
|
||||
}
|
||||
|
||||
struct LengthDisp(f32);
|
||||
|
||||
impl fmt::Display for LengthDisp {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let meters = self.0 * M_PER_PX;
|
||||
if meters.abs() > 1000. {
|
||||
let km = if meters.is_sign_negative() {
|
||||
(meters / 1000.).ceil()
|
||||
} else {
|
||||
(meters / 1000.).floor()
|
||||
};
|
||||
let m = meters % 1000.;
|
||||
write!(f, "{km} km, {m} m")
|
||||
} else {
|
||||
write!(f, "{meters} m")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
102
src/debug.rs
102
src/debug.rs
|
|
@ -1,11 +1,20 @@
|
|||
use sfml::window::Key;
|
||||
use egui_inspect::inspect;
|
||||
use sfml::{audio::SoundSource, window::Key};
|
||||
|
||||
use crate::input::Input;
|
||||
use crate::{
|
||||
game::GameState,
|
||||
input::Input,
|
||||
math::{px_per_frame_to_km_h, WorldPos},
|
||||
res::Res,
|
||||
stringfmt::LengthDisp,
|
||||
tiles::tiledb_edit_ui::tiledb_edit_ui,
|
||||
};
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct DebugState {
|
||||
pub panel: bool,
|
||||
panel: bool,
|
||||
pub freecam: bool,
|
||||
tiledb_edit: bool,
|
||||
}
|
||||
|
||||
impl DebugState {
|
||||
|
|
@ -18,3 +27,90 @@ impl DebugState {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn debug_panel_ui(
|
||||
debug: &mut DebugState,
|
||||
mut game: &mut GameState,
|
||||
ctx: &egui::Context,
|
||||
res: &mut Res,
|
||||
mut scale: &mut u8,
|
||||
) {
|
||||
egui::Window::new("Debug (F12)").show(ctx, |ui| {
|
||||
if debug.freecam {
|
||||
ui.label("Cam x");
|
||||
ui.add(egui::DragValue::new(&mut game.camera_offset.x));
|
||||
ui.label("Cam y");
|
||||
ui.add(egui::DragValue::new(&mut game.camera_offset.y));
|
||||
let co = game.camera_offset;
|
||||
ui.label(format!(
|
||||
"Cam Depth: {}",
|
||||
LengthDisp(co.y as f32 - WorldPos::SURFACE as f32)
|
||||
));
|
||||
ui.label(format!(
|
||||
"Cam offset from center: {}",
|
||||
LengthDisp(co.x as f32 - WorldPos::CENTER as f32)
|
||||
));
|
||||
} else {
|
||||
ui.label(format!(
|
||||
"Player Depth: {}",
|
||||
LengthDisp(game.player.feet_y() as f32 - WorldPos::SURFACE as f32)
|
||||
));
|
||||
ui.label(format!(
|
||||
"Player offset from center: {}",
|
||||
LengthDisp(game.player.col_en.en.pos.x as f32 - WorldPos::CENTER as f32)
|
||||
));
|
||||
ui.label(format!(
|
||||
"Hspeed: {} ({} km/h)",
|
||||
game.player.hspeed,
|
||||
px_per_frame_to_km_h(game.player.hspeed)
|
||||
));
|
||||
ui.label(format!(
|
||||
"Vspeed: {} ({} km/h)",
|
||||
game.player.vspeed,
|
||||
px_per_frame_to_km_h(game.player.vspeed)
|
||||
));
|
||||
}
|
||||
ui.label("Music volume");
|
||||
let mut vol = res.surf_music.volume();
|
||||
ui.add(egui::DragValue::new(&mut vol));
|
||||
res.surf_music.set_volume(vol);
|
||||
ui.separator();
|
||||
egui::ScrollArea::both()
|
||||
.id_source("insp_scroll")
|
||||
.max_height(240.)
|
||||
.max_width(340.0)
|
||||
.show(ui, |ui| {
|
||||
inspect! {
|
||||
ui,
|
||||
scale,
|
||||
game,
|
||||
debug.tiledb_edit
|
||||
}
|
||||
});
|
||||
ui.separator();
|
||||
egui::ScrollArea::vertical().show(ui, |ui| {
|
||||
gamedebug_core::for_each_imm(|info| match info {
|
||||
gamedebug_core::Info::Msg(msg) => {
|
||||
ui.label(msg);
|
||||
}
|
||||
gamedebug_core::Info::Rect(_, _, _, _, _) => todo!(),
|
||||
});
|
||||
});
|
||||
gamedebug_core::clear_immediates();
|
||||
});
|
||||
}
|
||||
|
||||
pub(crate) fn do_debug_ui(
|
||||
ctx: &egui::Context,
|
||||
debug: &mut DebugState,
|
||||
game: &mut GameState,
|
||||
res: &mut Res,
|
||||
scale: &mut u8,
|
||||
) {
|
||||
if debug.panel {
|
||||
debug_panel_ui(debug, game, ctx, res, scale);
|
||||
}
|
||||
if debug.tiledb_edit {
|
||||
tiledb_edit_ui(ctx, &mut game.tile_db);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
30
src/game.rs
30
src/game.rs
|
|
@ -3,17 +3,16 @@ mod player;
|
|||
use derivative::Derivative;
|
||||
use egui_inspect::derive::Inspect;
|
||||
use sfml::{
|
||||
graphics::{
|
||||
Color, Rect, RectangleShape, RenderTarget, RenderTexture, Shape, Sprite, Transformable,
|
||||
},
|
||||
graphics::{Color, RectangleShape, RenderTarget, RenderTexture, Shape, Sprite, Transformable},
|
||||
system::{Clock, Vector2u},
|
||||
SfBox,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
graphics::{ScreenPos, ScreenPosScalar},
|
||||
math::{wp_to_tp, WorldPos},
|
||||
math::{wp_to_tp, WorldPos, TILE_SIZE},
|
||||
res::Res,
|
||||
tiles::TileDb,
|
||||
world::{Tile, TileId, TilePos, World},
|
||||
worldgen::Worldgen,
|
||||
};
|
||||
|
|
@ -37,11 +36,12 @@ pub struct GameState {
|
|||
#[opaque]
|
||||
pub clock: SfBox<Clock>,
|
||||
pub light_sources: Vec<LightSource>,
|
||||
pub tile_db: TileDb,
|
||||
}
|
||||
|
||||
#[derive(Debug, Inspect)]
|
||||
pub struct LightSource {
|
||||
pub pos: WorldPos,
|
||||
pub pos: ScreenPos,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug, Inspect)]
|
||||
|
|
@ -52,20 +52,27 @@ pub enum Biome {
|
|||
|
||||
impl GameState {
|
||||
pub(crate) fn draw_world(&mut self, rt: &mut RenderTexture, res: &mut Res) {
|
||||
self.light_sources.clear();
|
||||
let mut s = Sprite::with_texture(&res.tile_atlas);
|
||||
for_each_tile_on_screen(self.camera_offset, rt.size(), |tp, sp| {
|
||||
let tile = self.world.tile_at_mut(tp, &self.worldgen);
|
||||
s.set_position(sp.to_sf_vec());
|
||||
if tile.bg != Tile::EMPTY {
|
||||
s.set_texture_rect(Rect::new((tile.bg - 1) as i32 * 32, 0, 32, 32));
|
||||
s.set_texture_rect(self.tile_db[tile.bg].atlas_offset.to_sf_rect());
|
||||
rt.draw(&s);
|
||||
}
|
||||
if tile.mid != Tile::EMPTY {
|
||||
s.set_texture_rect(Rect::new((tile.mid - 1) as i32 * 32, 0, 32, 32));
|
||||
s.set_texture_rect(self.tile_db[tile.mid].atlas_offset.to_sf_rect());
|
||||
if self.tile_db[tile.mid].emits_light {
|
||||
let mut pos = sp;
|
||||
pos.x += (TILE_SIZE / 2) as i16;
|
||||
pos.y += (TILE_SIZE / 2) as i16;
|
||||
self.light_sources.push(LightSource { pos: sp });
|
||||
}
|
||||
rt.draw(&s);
|
||||
}
|
||||
if tile.fg != Tile::EMPTY {
|
||||
s.set_texture_rect(Rect::new((tile.fg - 1) as i32 * 32, 0, 32, 32));
|
||||
s.set_texture_rect(self.tile_db[tile.fg].atlas_offset.to_sf_rect());
|
||||
rt.draw(&s);
|
||||
}
|
||||
});
|
||||
|
|
@ -102,14 +109,10 @@ impl GameState {
|
|||
255,
|
||||
));
|
||||
for ls in &self.light_sources {
|
||||
let (x, y) = (
|
||||
ls.pos.x as i32 - self.camera_offset.x as i32,
|
||||
ls.pos.y as i32 - self.camera_offset.y as i32,
|
||||
);
|
||||
let mut s = Sprite::with_texture(&res.light_texture);
|
||||
s.set_scale((4., 4.));
|
||||
s.set_origin((128., 128.));
|
||||
s.set_position((x as f32, y as f32));
|
||||
s.set_position((ls.pos.x.into(), ls.pos.y.into()));
|
||||
lightmap.draw(&s);
|
||||
}
|
||||
}
|
||||
|
|
@ -152,6 +155,7 @@ impl Default for GameState {
|
|||
ambient_light: 0,
|
||||
clock: Clock::start(),
|
||||
light_sources: Vec::new(),
|
||||
tile_db: TileDb::load_or_default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ impl Player {
|
|||
jumps_left: 0,
|
||||
}
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
pub fn center_tp(&self) -> TilePos {
|
||||
TilePos {
|
||||
x: (self.col_en.en.pos.x / TILE_SIZE as i32) as TilePosScalar,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use egui_inspect::derive::Inspect;
|
||||
use sfml::{
|
||||
graphics::RenderWindow,
|
||||
system::Vector2f,
|
||||
|
|
@ -23,7 +24,7 @@ impl ScreenRes {
|
|||
}
|
||||
|
||||
// We assume this game won't be played above 32767*32767 resolution
|
||||
#[derive(Default, Clone, Copy, Debug)]
|
||||
#[derive(Default, Clone, Copy, Debug, Inspect)]
|
||||
pub struct ScreenPos {
|
||||
pub x: ScreenPosScalar,
|
||||
pub y: ScreenPosScalar,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ mod graphics;
|
|||
mod input;
|
||||
mod math;
|
||||
mod res;
|
||||
mod stringfmt;
|
||||
mod tiles;
|
||||
mod world;
|
||||
mod worldgen;
|
||||
|
||||
|
|
@ -18,6 +20,9 @@ fn try_main() -> anyhow::Result<()> {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
env_logger::builder()
|
||||
.filter_level(log::LevelFilter::Info)
|
||||
.init();
|
||||
if let Err(e) = try_main() {
|
||||
rfd::MessageDialog::new()
|
||||
.set_title("Fatal error")
|
||||
|
|
|
|||
22
src/stringfmt.rs
Normal file
22
src/stringfmt.rs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
use std::fmt;
|
||||
|
||||
use crate::math::M_PER_PX;
|
||||
|
||||
pub struct LengthDisp(pub f32);
|
||||
|
||||
impl fmt::Display for LengthDisp {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let meters = self.0 * M_PER_PX;
|
||||
if meters.abs() > 1000. {
|
||||
let km = if meters.is_sign_negative() {
|
||||
(meters / 1000.).ceil()
|
||||
} else {
|
||||
(meters / 1000.).floor()
|
||||
};
|
||||
let m = meters % 1000.;
|
||||
write!(f, "{km} km, {m} m")
|
||||
} else {
|
||||
write!(f, "{meters} m")
|
||||
}
|
||||
}
|
||||
}
|
||||
106
src/tiles.rs
Normal file
106
src/tiles.rs
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
pub mod tiledb_edit_ui;
|
||||
|
||||
use std::ops::Index;
|
||||
|
||||
use egui_inspect::derive::Inspect;
|
||||
use log::warn;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sfml::graphics::IntRect;
|
||||
|
||||
use crate::{math::TILE_SIZE, world::TileId};
|
||||
|
||||
#[derive(Serialize, Deserialize, Default, Debug, Inspect)]
|
||||
pub struct TileDef {
|
||||
pub solid: bool,
|
||||
pub emits_light: bool,
|
||||
pub atlas_offset: AtlasOffset,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Inspect)]
|
||||
pub struct TileDb {
|
||||
db: Vec<TileDef>,
|
||||
}
|
||||
|
||||
impl Default for TileDb {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
// Add empty/air tile
|
||||
db: vec![EMPTY],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const EMPTY: TileDef = TileDef {
|
||||
solid: false,
|
||||
emits_light: false,
|
||||
// Rendering empty tile is actually special cased, and no rendering is done.
|
||||
// But just in case, put the offset to UNKNOWN
|
||||
atlas_offset: UNKNOWN_ATLAS_OFF,
|
||||
};
|
||||
|
||||
impl Index<TileId> for TileDb {
|
||||
type Output = TileDef;
|
||||
|
||||
fn index(&self, index: TileId) -> &Self::Output {
|
||||
self.db.get(index as usize).unwrap_or(&UNKNOWN_TILE)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Inspect, Serialize, Deserialize)]
|
||||
pub struct AtlasOffset {
|
||||
pub x: u16,
|
||||
pub y: u16,
|
||||
}
|
||||
impl AtlasOffset {
|
||||
pub(crate) fn to_sf_rect(&self) -> IntRect {
|
||||
IntRect {
|
||||
left: self.x as i32,
|
||||
top: self.y as i32,
|
||||
width: TILE_SIZE as i32,
|
||||
height: TILE_SIZE as i32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for AtlasOffset {
|
||||
fn default() -> Self {
|
||||
UNKNOWN_ATLAS_OFF
|
||||
}
|
||||
}
|
||||
|
||||
const UNKNOWN_ATLAS_OFF: AtlasOffset = AtlasOffset { x: 320, y: 0 };
|
||||
|
||||
static UNKNOWN_TILE: TileDef = TileDef {
|
||||
solid: true,
|
||||
emits_light: true,
|
||||
atlas_offset: UNKNOWN_ATLAS_OFF,
|
||||
};
|
||||
|
||||
const PATH: &str = "tiles.dat";
|
||||
|
||||
impl TileDb {
|
||||
pub fn load_or_default() -> Self {
|
||||
match std::fs::read(PATH) {
|
||||
Ok(data) => match rmp_serde::from_slice(&data) {
|
||||
Ok(db) => db,
|
||||
Err(e) => {
|
||||
warn!("Failed to load tile database: {e}\nCreating default.");
|
||||
Default::default()
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
warn!("Failed to load tile database: {e}\nCreating default.");
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn try_save(&self) {
|
||||
match rmp_serde::to_vec(self) {
|
||||
Ok(vec) => match std::fs::write(PATH, vec) {
|
||||
Ok(()) => {}
|
||||
Err(e) => warn!("Failed to save tile db: {e}"),
|
||||
},
|
||||
Err(e) => warn!("Failed to save tile db: {e}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
9
src/tiles/tiledb_edit_ui.rs
Normal file
9
src/tiles/tiledb_edit_ui.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
use super::TileDb;
|
||||
|
||||
pub fn tiledb_edit_ui(ctx: &egui::Context, tile_db: &mut TileDb) {
|
||||
egui::Window::new("Tiledb editor").show(ctx, |ui| {
|
||||
if ui.button("Add new default").clicked() {
|
||||
tile_db.db.push(super::TileDef::default());
|
||||
}
|
||||
});
|
||||
}
|
||||
BIN
tiles.dat
Normal file
BIN
tiles.dat
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue