From 79e2ba7b831dee6d3025c2869832eae3d27a074a Mon Sep 17 00:00:00 2001 From: crumblingstatue Date: Sat, 8 Apr 2023 16:14:59 +0200 Subject: [PATCH] Make light offset of tiles variable --- src/app.rs | 14 +++++++------- src/game.rs | 25 +++++++++++++------------ src/graphics.rs | 16 +++++++++------- src/input.rs | 6 +++--- src/tiles.rs | 16 ++++++++++++---- src/tiles/tiledb_edit_ui.rs | 27 +++++++++++++++++++++++++++ tiles.dat | Bin 76 -> 78 bytes 7 files changed, 71 insertions(+), 33 deletions(-) diff --git a/src/app.rs b/src/app.rs index 63053ae..2806e05 100644 --- a/src/app.rs +++ b/src/app.rs @@ -14,7 +14,7 @@ use sfml::{ use crate::{ debug::{self, DebugState}, game::{for_each_tile_on_screen, Biome, GameState}, - graphics::{self, ScreenPos, ScreenPosScalar}, + graphics::{self, ScreenSc, ScreenVec}, input::Input, math::{center_offset, TILE_SIZE}, res::Res, @@ -178,8 +178,8 @@ impl App { let vco = viewport_center_offset(self.rw.size(), rt_size, self.scale); loc.x -= vco.x; loc.y -= vco.y; - loc.x /= self.scale as ScreenPosScalar; - loc.y /= self.scale as ScreenPosScalar; + loc.x /= self.scale as ScreenSc; + loc.y /= self.scale as ScreenSc; let mut wpos = self.game.camera_offset; wpos.x = wpos.x.saturating_add_signed(loc.x.into()); wpos.y = wpos.y.saturating_add_signed(loc.y.into()); @@ -289,13 +289,13 @@ impl App { } } -fn viewport_center_offset(rw_size: Vector2u, rt_size: Vector2u, scale: u8) -> ScreenPos { +fn viewport_center_offset(rw_size: Vector2u, rt_size: Vector2u, scale: u8) -> ScreenVec { let rw_size = rw_size; let rt_size = rt_size * scale as u32; let x = center_offset(rt_size.x as i32, rw_size.x as i32); let y = center_offset(rt_size.y as i32, rw_size.y as i32); - ScreenPos { - x: x as ScreenPosScalar, - y: y as ScreenPosScalar, + ScreenVec { + x: x as ScreenSc, + y: y as ScreenSc, } } diff --git a/src/game.rs b/src/game.rs index 1abf5c3..55683b8 100644 --- a/src/game.rs +++ b/src/game.rs @@ -9,8 +9,8 @@ use sfml::{ }; use crate::{ - graphics::{ScreenPos, ScreenPosScalar}, - math::{wp_to_tp, WorldPos, TILE_SIZE}, + graphics::{ScreenSc, ScreenVec}, + math::{wp_to_tp, WorldPos}, res::Res, tiles::TileDb, world::{Tile, TileId, TilePos, World}, @@ -41,7 +41,7 @@ pub struct GameState { #[derive(Debug, Inspect)] pub struct LightSource { - pub pos: ScreenPos, + pub pos: ScreenVec, } #[derive(PartialEq, Eq, Clone, Copy, Debug, Inspect)] @@ -63,11 +63,12 @@ impl GameState { } if tile.mid != Tile::EMPTY { 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 }); + if let Some(light) = self.tile_db[tile.mid].light { + let pos = ScreenVec { + x: sp.x + light.x, + y: sp.y + light.y, + }; + self.light_sources.push(LightSource { pos }); } rt.draw(&s); } @@ -121,7 +122,7 @@ impl GameState { pub fn for_each_tile_on_screen( camera_offset: WorldPos, rt_size: Vector2u, - mut f: impl FnMut(TilePos, ScreenPos), + mut f: impl FnMut(TilePos, ScreenVec), ) { for y in (-32..(rt_size.y as i16) + 32).step_by(32) { for x in (-32..(rt_size.x as i16) + 32).step_by(32) { @@ -130,9 +131,9 @@ pub fn for_each_tile_on_screen( x: wp_to_tp(camera_offset.x.saturating_add(x.try_into().unwrap_or(0))), y: wp_to_tp(camera_offset.y.saturating_add(y.try_into().unwrap_or(0))), }, - ScreenPos { - x: ((x as i64) - ((camera_offset.x as i64) % 32)) as ScreenPosScalar, - y: ((y as i64) - ((camera_offset.y as i64) % 32)) as ScreenPosScalar, + ScreenVec { + x: ((x as i64) - ((camera_offset.x as i64) % 32)) as ScreenSc, + y: ((y as i64) - ((camera_offset.y as i64) % 32)) as ScreenSc, }, ) } diff --git a/src/graphics.rs b/src/graphics.rs index 78dc868..331b962 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -1,4 +1,5 @@ use egui_inspect::derive::Inspect; +use serde::{Deserialize, Serialize}; use sfml::{ graphics::RenderWindow, system::Vector2f, @@ -23,16 +24,17 @@ impl ScreenRes { } } -// We assume this game won't be played above 32767*32767 resolution -#[derive(Default, Clone, Copy, Debug, Inspect)] -pub struct ScreenPos { - pub x: ScreenPosScalar, - pub y: ScreenPosScalar, +#[derive(Default, Clone, Copy, Debug, Inspect, Serialize, Deserialize)] +pub struct ScreenVec { + pub x: ScreenSc, + pub y: ScreenSc, } -pub type ScreenPosScalar = i16; +/// Screen position/offset scalar +/// We assume this game won't be played above 32767*32767 resolution +pub type ScreenSc = i16; -impl ScreenPos { +impl ScreenVec { pub fn to_sf_vec(self) -> Vector2f { Vector2f::new(self.x.into(), self.y.into()) } diff --git a/src/input.rs b/src/input.rs index cb22515..4f65191 100644 --- a/src/input.rs +++ b/src/input.rs @@ -1,7 +1,7 @@ use fnv::FnvHashSet; use sfml::window::{mouse, Event, Key}; -use crate::graphics::ScreenPos; +use crate::graphics::ScreenVec; #[derive(Default, Debug)] pub struct Input { @@ -9,7 +9,7 @@ pub struct Input { pressed: FnvHashSet, pub lmb_down: bool, pub rmb_down: bool, - pub mouse_down_loc: ScreenPos, + pub mouse_down_loc: ScreenVec, pub mid_pressed: bool, } @@ -24,7 +24,7 @@ impl Input { self.down.remove(code); } &Event::MouseButtonPressed { button, x, y } => { - self.mouse_down_loc = ScreenPos { + self.mouse_down_loc = ScreenVec { x: x as i16, y: y as i16, }; diff --git a/src/tiles.rs b/src/tiles.rs index eaeefbd..e90a324 100644 --- a/src/tiles.rs +++ b/src/tiles.rs @@ -7,12 +7,17 @@ use log::warn; use serde::{Deserialize, Serialize}; use sfml::graphics::IntRect; -use crate::{math::TILE_SIZE, world::TileId}; +use crate::{ + graphics::{ScreenSc, ScreenVec}, + math::TILE_SIZE, + world::TileId, +}; #[derive(Serialize, Deserialize, Default, Debug, Inspect)] pub struct TileDef { pub solid: bool, - pub emits_light: bool, + /// Whether the tile emits light, and the light source offset + pub light: Option, pub atlas_offset: AtlasOffset, } @@ -32,7 +37,7 @@ impl Default for TileDb { const EMPTY: TileDef = TileDef { solid: false, - emits_light: false, + light: None, // 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, @@ -72,7 +77,10 @@ const UNKNOWN_ATLAS_OFF: AtlasOffset = AtlasOffset { x: 320, y: 0 }; static UNKNOWN_TILE: TileDef = TileDef { solid: true, - emits_light: true, + light: Some(ScreenVec { + x: TILE_SIZE as ScreenSc / 2, + y: TILE_SIZE as ScreenSc / 2, + }), atlas_offset: UNKNOWN_ATLAS_OFF, }; diff --git a/src/tiles/tiledb_edit_ui.rs b/src/tiles/tiledb_edit_ui.rs index 8ced76b..2048f13 100644 --- a/src/tiles/tiledb_edit_ui.rs +++ b/src/tiles/tiledb_edit_ui.rs @@ -1,7 +1,34 @@ +use crate::{ + graphics::{ScreenSc, ScreenVec}, + math::TILE_SIZE, +}; + use super::TileDb; pub fn tiledb_edit_ui(ctx: &egui::Context, tile_db: &mut TileDb) { egui::Window::new("Tiledb editor").show(ctx, |ui| { + ui.label(format!("Number of tile defs: {}", tile_db.db.len())); + ui.separator(); + for (i, def) in tile_db.db.iter_mut().enumerate() { + ui.label(i.to_string()); + match &mut def.light { + Some(light) => { + ui.label("x"); + ui.add(egui::DragValue::new(&mut light.x)); + ui.label("y"); + ui.add(egui::DragValue::new(&mut light.y)); + } + None => { + if ui.button("Insert light emit").clicked() { + def.light = Some(ScreenVec { + x: TILE_SIZE as ScreenSc / 2, + y: TILE_SIZE as ScreenSc / 2, + }); + } + } + } + } + ui.separator(); if ui.button("Add new default").clicked() { tile_db.db.push(super::TileDef::default()); } diff --git a/tiles.dat b/tiles.dat index e0697deaf36de9f46a25666e6d6987a51d9acaa2..7d181d738b690c7db80d89192e33cac979426dd2 100644 GIT binary patch literal 78 zcmbO@Yx1E3lg=_aFibvtU=jnERA88VXc8~$q_d157E~6d>d=8nXBIGkG@UsBroei^ HvJ4CWuOTF) literal 76 zcmbO@Yx1E(lg=_aFibvtXc7aMRA88V=