mirror of
https://github.com/Noratrieb/game-wip-dontplay.git
synced 2026-01-14 19:55:02 +01:00
Store worlds in user data dir
This commit is contained in:
parent
d2da1b39ed
commit
d7f57a2176
8 changed files with 98 additions and 30 deletions
52
Cargo.lock
generated
52
Cargo.lock
generated
|
|
@ -281,6 +281,26 @@ dependencies = [
|
|||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "directories"
|
||||
version = "5.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74be3be809c18e089de43bdc504652bb2bc473fca8756131f8689db8cf079ba9"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04414300db88f70d74c5ff54e50f9e1d1737d9a5b90f53fcf2e95ca2a9ab554b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dispatch"
|
||||
version = "0.2.0"
|
||||
|
|
@ -724,6 +744,7 @@ dependencies = [
|
|||
"anyhow",
|
||||
"clap",
|
||||
"derivative",
|
||||
"directories",
|
||||
"egui",
|
||||
"egui-inspect",
|
||||
"egui-sfml",
|
||||
|
|
@ -959,6 +980,17 @@ dependencies = [
|
|||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"redox_syscall",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.7.3"
|
||||
|
|
@ -1183,6 +1215,26 @@ dependencies = [
|
|||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.7.3"
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ log = "0.4.17"
|
|||
env_logger = "0.10.0"
|
||||
zstd = "0.12.3"
|
||||
clap = { version = "4.2.2", features = ["derive"] }
|
||||
directories = "5.0.0"
|
||||
|
||||
[dependencies.s2dc]
|
||||
#git = "https://github.com/crumblingstatue/s2dc.git"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use anyhow::Context;
|
||||
use directories::ProjectDirs;
|
||||
use egui_sfml::SfEgui;
|
||||
use gamedebug_core::{imm, imm_dbg};
|
||||
use sfml::{
|
||||
|
|
@ -36,6 +37,7 @@ pub struct App {
|
|||
pub rt: RenderTexture,
|
||||
/// Light map overlay, blended together with the non-lighted version of the scene
|
||||
pub light_map: RenderTexture,
|
||||
pub project_dirs: ProjectDirs,
|
||||
}
|
||||
|
||||
impl App {
|
||||
|
|
@ -51,10 +53,13 @@ impl App {
|
|||
RenderTexture::new(rw_size.x, rw_size.y).context("Failed to create render texture")?;
|
||||
let light_map = RenderTexture::new(rw_size.x, rw_size.y)
|
||||
.context("Failed to create lightmap texture")?;
|
||||
let project_dirs = ProjectDirs::from("", "", "mantle-diver").unwrap();
|
||||
let worlds_dir = project_dirs.data_dir().join("worlds");
|
||||
let path = worlds_dir.join(&args.world_name);
|
||||
Ok(Self {
|
||||
rw,
|
||||
should_quit: false,
|
||||
game: GameState::new(args.world_name),
|
||||
game: GameState::new(args.world_name, path),
|
||||
res,
|
||||
sf_egui,
|
||||
input: Input::default(),
|
||||
|
|
@ -62,6 +67,7 @@ impl App {
|
|||
scale: 1,
|
||||
rt,
|
||||
light_map,
|
||||
project_dirs,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use derivative::Derivative;
|
||||
use egui_inspect::derive::Inspect;
|
||||
use sfml::{
|
||||
|
|
@ -114,12 +116,12 @@ impl GameState {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn new(world_name: String) -> GameState {
|
||||
pub(crate) fn new(world_name: String, path: PathBuf) -> GameState {
|
||||
let mut spawn_point = WorldPos::SURFACE_CENTER;
|
||||
spawn_point.y -= 1104;
|
||||
Self {
|
||||
camera_offset: spawn_point,
|
||||
world: World::new(spawn_point, &world_name),
|
||||
world: World::new(spawn_point, &world_name, path),
|
||||
gravity: 0.55,
|
||||
tile_to_place: 1,
|
||||
current_biome: Biome::Surface,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use std::path::Path;
|
||||
|
||||
use egui_inspect::{derive::Inspect, inspect};
|
||||
use s2dc::{vec2, MobileEntity};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
|
@ -52,8 +54,8 @@ impl Player {
|
|||
self.col_en.en.pos.y + self.col_en.en.bb.y
|
||||
}
|
||||
|
||||
pub(crate) fn save(&self) {
|
||||
let result = std::fs::write("player.dat", rmp_serde::to_vec(self).unwrap());
|
||||
pub(crate) fn save(&self, path: &Path) {
|
||||
let result = std::fs::write(path.join("player.dat"), rmp_serde::to_vec(self).unwrap());
|
||||
log::info!("{result:?}");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
41
src/world.rs
41
src/world.rs
|
|
@ -1,7 +1,12 @@
|
|||
mod reg_chunk_existence;
|
||||
mod serialization;
|
||||
|
||||
use std::{fmt::Debug, fs::File, io::Seek, path::Path};
|
||||
use std::{
|
||||
fmt::Debug,
|
||||
fs::File,
|
||||
io::Seek,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use egui_inspect::derive::Inspect;
|
||||
use fnv::FnvHashMap;
|
||||
|
|
@ -47,15 +52,18 @@ pub struct World {
|
|||
pub ticks: u64,
|
||||
pub player: Player,
|
||||
pub name: String,
|
||||
#[opaque]
|
||||
pub path: PathBuf,
|
||||
}
|
||||
|
||||
impl World {
|
||||
pub fn new(spawn_point: WorldPos, name: &str) -> Self {
|
||||
pub fn new(spawn_point: WorldPos, name: &str, path: PathBuf) -> Self {
|
||||
Self {
|
||||
chunks: Default::default(),
|
||||
ticks: Default::default(),
|
||||
player: Player::new_at(spawn_point),
|
||||
name: name.to_string(),
|
||||
path,
|
||||
}
|
||||
}
|
||||
/// Get mutable access to the tile at `pos`.
|
||||
|
|
@ -66,15 +74,14 @@ impl World {
|
|||
let chk = self
|
||||
.chunks
|
||||
.entry(chk)
|
||||
.or_insert_with(|| Chunk::load_or_gen(chk, worldgen, &self.name));
|
||||
.or_insert_with(|| Chunk::load_or_gen(chk, worldgen, &self.path));
|
||||
chk.at_mut(local)
|
||||
}
|
||||
pub fn save(&self) {
|
||||
let result = std::fs::create_dir(&self.name);
|
||||
let result = std::fs::create_dir(&self.path);
|
||||
log::info!("{result:?}");
|
||||
std::env::set_current_dir(&self.name).unwrap();
|
||||
self.save_meta();
|
||||
self.player.save();
|
||||
self.player.save(&self.path);
|
||||
self.save_chunks();
|
||||
}
|
||||
pub fn save_meta(&self) {
|
||||
|
|
@ -82,12 +89,15 @@ impl World {
|
|||
name: self.name.clone(),
|
||||
ticks: self.ticks,
|
||||
};
|
||||
let result = std::fs::write("world.dat", rmp_serde::to_vec(&meta).unwrap());
|
||||
let result = std::fs::write(
|
||||
self.path.join("world.dat"),
|
||||
rmp_serde::to_vec(&meta).unwrap(),
|
||||
);
|
||||
log::info!("{result:?}");
|
||||
}
|
||||
pub fn save_chunks(&self) {
|
||||
for (pos, chk) in self.chunks.iter() {
|
||||
save_chunk(pos, chk);
|
||||
save_chunk(pos, chk, &self.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -225,12 +235,9 @@ impl Chunk {
|
|||
Self { tiles }
|
||||
}
|
||||
|
||||
pub fn load_or_gen(chk: ChunkPos, worldgen: &Worldgen, world_name: &str) -> Chunk {
|
||||
pub fn load_or_gen(chk: ChunkPos, worldgen: &Worldgen, world_path: &Path) -> Chunk {
|
||||
log::info!("Loading chunk {chk:?} (reg: {:?})", chk.region());
|
||||
let prev_dir = std::env::current_dir().unwrap();
|
||||
let result = std::env::set_current_dir(world_name);
|
||||
log::info!("{result:?}");
|
||||
let reg_filename = format_reg_file_name(chk.region());
|
||||
let reg_filename = world_path.join(format_reg_file_name(chk.region()));
|
||||
let chunk = if chunk_exists(®_filename, chk) {
|
||||
log::info!("Chunk exists, loading");
|
||||
let mut f = File::open(®_filename).unwrap();
|
||||
|
|
@ -245,8 +252,6 @@ impl Chunk {
|
|||
log::warn!("Chunk at {:?} doesn't exist, generating.", chk);
|
||||
Chunk::gen(chk, worldgen)
|
||||
};
|
||||
let result = std::env::set_current_dir(prev_dir);
|
||||
log::info!("{result:?}");
|
||||
chunk
|
||||
}
|
||||
|
||||
|
|
@ -255,11 +260,11 @@ impl Chunk {
|
|||
}
|
||||
}
|
||||
|
||||
fn chunk_exists(reg_filename: &str, pos: ChunkPos) -> bool {
|
||||
if !Path::new(®_filename).exists() {
|
||||
fn chunk_exists(reg_path: &Path, pos: ChunkPos) -> bool {
|
||||
if !Path::new(®_path).exists() {
|
||||
return false;
|
||||
}
|
||||
let bitset = ExistenceBitset::read_from_fs(reg_filename);
|
||||
let bitset = ExistenceBitset::read_from_fs(reg_path);
|
||||
let local = pos.local();
|
||||
let idx = loc_idx(local.1, local.0);
|
||||
crate::bitmanip::nth_bit_set(bitset.0, idx as usize)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::{fs::File, io::Read};
|
||||
use std::{fs::File, io::Read, path::Path};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct ExistenceBitset(pub u64);
|
||||
|
|
@ -12,8 +12,8 @@ impl ExistenceBitset {
|
|||
ExistenceBitset(u64::from_le_bytes(buf))
|
||||
}
|
||||
|
||||
pub fn read_from_fs(reg_filename: &str) -> ExistenceBitset {
|
||||
let mut f = File::open(reg_filename).unwrap();
|
||||
pub fn read_from_fs(path: &Path) -> ExistenceBitset {
|
||||
let mut f = File::open(path).unwrap();
|
||||
Self::read_from_file(&mut f)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ use crate::world::{
|
|||
|
||||
use super::{default_chunk_tiles, loc_byte_idx_xy, Chunk, ChunkPos};
|
||||
|
||||
pub(super) fn save_chunk(pos: &ChunkPos, chk: &Chunk) {
|
||||
let reg_file_name = format_reg_file_name(pos.region());
|
||||
pub(super) fn save_chunk(pos: &ChunkPos, chk: &Chunk, world_dir: &Path) {
|
||||
let reg_file_name = world_dir.join(format_reg_file_name(pos.region()));
|
||||
let reg_file_exists = Path::new(®_file_name).exists();
|
||||
if !reg_file_exists {
|
||||
log::warn!("Region file doesn't exist. Going to create one.");
|
||||
|
|
@ -86,8 +86,8 @@ fn test_chunk_seri() {
|
|||
for t in &mut chk.tiles {
|
||||
t.bg = 1;
|
||||
}
|
||||
save_chunk(&ChunkPos { x: 2, y: 0 }, &chk);
|
||||
save_chunk(&ChunkPos { x: 3, y: 0 }, &chk);
|
||||
save_chunk(&ChunkPos { x: 2, y: 0 }, &chk, "testworld".as_ref());
|
||||
save_chunk(&ChunkPos { x: 3, y: 0 }, &chk, "testworld".as_ref());
|
||||
let raw = std::fs::read("0.0.rgn").unwrap();
|
||||
zstd::decode_all(&raw[8..]).unwrap();
|
||||
std::fs::remove_file("0.0.rgn").unwrap();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue