From 8ca7b418d6d315606fb4f425282ebabc865a105e Mon Sep 17 00:00:00 2001 From: Markus Moenig Date: Sat, 20 Jul 2024 16:40:46 +0700 Subject: [PATCH] Started with tool api --- creator/embedded/brush.png | Bin 0 -> 17361 bytes creator/embedded/pen.png | Bin 0 -> 17495 bytes creator/src/editor.rs | 56 ++++++++++-- creator/src/main.rs | 8 ++ creator/src/tileeditor.rs | 78 ++-------------- creator/src/toollist.rs | 153 ++++++++++++++++++++++++++++++++ creator/src/tools/mod.rs | 56 ++++++++++++ creator/src/tools/tiledrawer.rs | 117 ++++++++++++++++++++++++ shared/src/renderer.rs | 1 - shared/src/server/context.rs | 9 ++ 10 files changed, 399 insertions(+), 79 deletions(-) create mode 100644 creator/embedded/brush.png create mode 100644 creator/embedded/pen.png create mode 100644 creator/src/toollist.rs create mode 100644 creator/src/tools/mod.rs create mode 100644 creator/src/tools/tiledrawer.rs diff --git a/creator/embedded/brush.png b/creator/embedded/brush.png new file mode 100644 index 0000000000000000000000000000000000000000..f614867d9242030ec86592ac9eab077d3752dbff GIT binary patch literal 17361 zcmeI4e~cVe9l+8g0?=OHGhq>YLeL z@Ah{44i6v|c6S)CoujG*6j!S`cVqQ8%C zzvV^rv#K<_&tsU6_XXb`=D}nA46~)j8Xfb;a<^!@Q;Y(`$-`*1SVGziliFM@0sR2< z**qM#?19J|&;BUFTE;+RZ#*aDN<(nM8lHCH?&+PQ`t$)^H6okSy{W2(92B7s*lMw0 zds=lM68hDU95nM0HdOHs3`7Qlfb3Xq7dzy*kc~$ZoG!+atfEH6xSEvYn^;K@6TG1E zqRa`RCa9Vqvh`0S-HW7@Yna+dW?MZR`fngI;rk_x=PQ*;v=WOt?l>>1s>%xzFG(EI z;Jhi@2UX7YuCF<1_{l&|cde3dIW`;k1$k%EABaSPK+R8mT*Xo|knPpkA&Ptzlz1^J z@SThdy=haLbPM6789EOOun2A6Lv~_EyV8W?JKluTC1kU^YhW}dxm+`L$LlQ?JBIfB zt!0FujvbN^~TZh?9 z8Z|^M%g|Io$wN_6xjaw}PBG*-msCuHGtHPR2tZX7BN0N(<#6*wt}~848EiY`x|X2~ zM@Q~kmt~qzh)Y1>bXAhkTtS6P3UQr-KrvMTU4hsNggILj=vLQ42^17ConR~m3KkQL zSOUm-GyaSkNpLX$Ov#i5J)V~vL;UZS97^P}Cd3=r_`_RrtsSdR0DBx7X}&SCM#D#G z=FEIvg@y_^Q%*=+UXo=lDeDRcVLon}hMG|0DEBWXS+t#_bmr=be%bkjkWzxI(@a5) zDg1EqiveBh{bU&ID)j~?Hq5CXoiQ&vr!K83qdT)%5e1n!tOpiWW{t{qaU~brL7*}) zQ(K+ef-^fPC(!C66mF>YLU&Rcc9Jzp>7}OAHuD81M%_Cqo=MfTE&(GZ1=Y0FwVJM7 zD(0+HEN8g|buCHS zC@!1^QKq9&u;$IT^IMQ*s=cQbGHp{y5i;2 z_D@#6bj3ffo?!EKrL$^M{ZhG?Y?7i$PyYb<}ef@eg_WIms zHm{ib%8SSNap_3^&08P)_U!2F_fD}Fl7EhGC=Sof-0`_TzBh5^t@%T1_g{H_)ni}$ z^p3CnX2rL9`lilq**3%Pf8nk2%ngtH;dJ@(tDpYnP1?C@U&`KdkvIC^VfI|(Tvr|b zYv0`Oe|z6q=Ji8Ae5HJJPj=(PC*S$gGxLStMN1DId48n?`>yNRD~_%I!JAWOo|}0v z*Z->%$@8yP&Og2G_QaV}2k-dHQ_+Ki2Up$xi(|(hIKDo6dU|~BwN)ptd1Li2A6?UP zL-`*2vc4bRc;>|6HJ^X}!h5~X-T%~`U;qBvv!7u8K0i0V(%}62ANt03zC8NtCyt*u zKA8RY+_?>Bv)Yk=^iSV)^zDZqU2)Z#cdupcetTrMIJx8J!Am!?TX$xj+_Hc6KfDPN A>i_@% literal 0 HcmV?d00001 diff --git a/creator/embedded/pen.png b/creator/embedded/pen.png new file mode 100644 index 0000000000000000000000000000000000000000..1070bd3dd1dcc9a1e82e67a1414ec504d9ea569a GIT binary patch literal 17495 zcmeI4eQXrR6~NcEq1eQtO-V`}D4QdsMCp1zZtr}%IbURac5TX0V+@#55%2BJ*^BRP zkK46%{k zw|)ZtlqZ_DnH077bN07{I`H^1idtKux3ydCq4lzA#Htm|2!rZWECIDC%71?oDj>Ire7L_O%zn+B3#)4+x{b)Z|7G}rxs3V%w54r0Jk=u|8k zH|12VEA3Z?vfa$O=(LK}UF)i|2c+9WEp)w+1hl8x%c#8DN7qQzyhrj0;+JWG#Oc_R~yMrmX{=n!NM#!1dk5SVIGPguGUr)|GV*yyopT`qed^vTXEmOul=%`7`ekxeNH zmapd6Vn&*ZY!W@mX!_DLl?71{198iQc6?F0M3-S1W|uL~kf?j!fniKSAvAW;>y5>V z4sBWuy%0ebX;DkFtv>v_tZH5sIWR`17E*5lsy}dkZ=rvpQxMuX3_xRaDll;QT zdjmnm0s-5S;dzD^+jv2Cdt}jfFDJ+x=WvqIEbtLBG(FNk$A?=M1eq6|J{+2bKHx^w z6idPK;?#Bc(NsBNBx8yd&|^v`U=#69KbvoKXrkpQ*BenI2`>u-+j-@=_XvQ{f<=( z*K#^VZUVbzx8^#cdOFo5l%xslja=)>?PQc2QR=g8(g{IUR69uqRC{{>&Ckwi&0iL> z%$n(Q!-^?+qYS)GmcJ=-oP;Ocvy!VT75@FXQWsOL&)+;m!CKI@K=^$v^Y z8&}h6xW)_9vuIb-%DmNd=29Kbij8I5Y(bqFrHGsSXt_8za68I2zkSe@VMPwB!*rDt zfCa;xHix%#U%OpdM|;whbB(~k56jzsv!>4OLep(GHg$Fvn&vGx$8{?J?~mz=DQI?B z*{9*mQEd}^0t5nHkH_utvxUut7A<-TMB9TpJX4wW*+77YqqI$7M^VFV^BFoivWA&$ z<9Jq+4os#MJ_&*kp;+`3$`Lbk7WwFf{ER+&-^e2w1fjqY2re8-NQdA;C~yRV3x^WY zA-E6<9D(4%p@eh@E`$O{Ah>WSAsvDXp}-LcE*wfohu}gea0G%2hZ52uxDW~)f#AZS zgmeflgaSt(xNs;T9fAv?z!3;897;%s;6f;H1cD2P64D{K5DFZD;KHGVbO>2D-#t=!AXwhey!CrcJ6rbte$9^;Uh8=7g_UQ_mp8J@FRYx|_V&|bmtL5dX!DkC zzi`*Drn{CT?znJi|IypO)qC{pe;PMm>w1Nq)}A?e^$$mm{cK=HV;;WTIXuahe0p$f z|2HOIzpZ0CckxH>Y#w@W{GVHPich}S_SE6A=SI(*JaB~%9NV#F=7>3cR6D)&mZ#dc z?7Px4d3^WAGn0>2rdId-bkDQy{uOVwo{!OE{Cj^tHd>h~yM;O~l_g95xbWi8smt_R zx4wKrzU|z<)-qS$82#>jKiPfnKu71~I`QD}?~=8bU)*$dc=;P|_uMzMVtn|nk#BP= zhR=WM{Lq=|~$AZ+Y*G7hZc_{Rc-A^9qo<1%=zy9AxzPR(} zzy11Wdma*NsnI>`pPPMPN<6Xh*X7^ry1j+zf1qqf>8YWLgzxE@#lP7{ec>-lA1k}` zmi~P`c&%>HNXy~F<7-}9vVX8o7#1?dTdfESz^EXqq$*2aCB|Qcm4}e C{#axH literal 0 HcmV?d00001 diff --git a/creator/src/editor.rs b/creator/src/editor.rs index ca248019..573364d2 100644 --- a/creator/src/editor.rs +++ b/creator/src/editor.rs @@ -27,11 +27,12 @@ lazy_static! { // pub static ref VOXELTHREAD: Mutex = Mutex::new(VoxelThread::default()); pub static ref PRERENDERTHREAD: Mutex = Mutex::new(PreRenderThread::default()); pub static ref UNDOMANAGER: Mutex = Mutex::new(UndoManager::default()); + pub static ref TOOLLIST: Mutex = Mutex::new(ToolList::default()); } #[derive(PartialEq, Clone, Copy, Debug)] -enum ActiveEditor { - TileEditor, +pub enum ActiveEditor { + GameEditor, ScreenEditor, } @@ -74,7 +75,7 @@ impl TheTrait for Editor { project: Project::new(), project_path: None, - active_editor: ActiveEditor::TileEditor, + active_editor: ActiveEditor::GameEditor, sidebar: Sidebar::new(), panels: Panels::new(), @@ -324,6 +325,36 @@ impl TheTrait for Editor { let mut shared_canvas = TheCanvas::new(); shared_canvas.set_layout(vsplitlayout); + // Tool List + let mut tool_list_canvas: TheCanvas = TheCanvas::new(); + + let mut tool_list_bar_canvas = TheCanvas::new(); + tool_list_bar_canvas.set_widget(TheToolListBar::new(TheId::empty())); + tool_list_canvas.set_top(tool_list_bar_canvas); + + let mut v_tool_list_layout = TheVLayout::new(TheId::named("Tool List Layout")); + v_tool_list_layout.limiter_mut().set_max_width(51); + v_tool_list_layout.set_margin(vec4i(2, 2, 2, 2)); + v_tool_list_layout.set_padding(1); + + TOOLLIST.lock().unwrap().set_active_editor( + ActiveEditor::GameEditor, + &mut v_tool_list_layout, + ctx, + ); + + tool_list_canvas.set_layout(v_tool_list_layout); + + let mut tool_list_border_canvas = TheCanvas::new(); + let mut border_widget = TheIconView::new(TheId::empty()); + border_widget.set_border_color(Some([82, 82, 82, 255])); + border_widget.limiter_mut().set_max_width(1); + border_widget.limiter_mut().set_max_height(i32::MAX); + tool_list_border_canvas.set_widget(border_widget); + + tool_list_canvas.set_right(tool_list_border_canvas); + shared_canvas.set_left(tool_list_canvas); + ui.canvas.set_center(shared_canvas); let mut status_canvas = TheCanvas::new(); @@ -394,7 +425,7 @@ impl TheTrait for Editor { if self.server.state == ServerState::Running { // Ticks self.client - .tick(self.active_editor == ActiveEditor::TileEditor); + .tick(self.active_editor == ActiveEditor::GameEditor); let debug = self.server.tick(); if !debug.is_empty() { self.sidebar.add_debug_messages(debug, ui, ctx); @@ -523,7 +554,7 @@ impl TheTrait for Editor { } } - if self.active_editor == ActiveEditor::TileEditor + if self.active_editor == ActiveEditor::GameEditor && redraw_update && !self.project.regions.is_empty() { @@ -565,6 +596,17 @@ impl TheTrait for Editor { &mut self.client, &mut self.server_ctx, ); + if TOOLLIST.lock().unwrap().handle_event( + &event, + ui, + ctx, + &mut self.project, + &mut self.server, + &mut self.client, + &mut self.server_ctx, + ) { + redraw = true; + } if self.panels.handle_event( &event, ui, @@ -671,7 +713,7 @@ impl TheTrait for Editor { TheEvent::IndexChanged(id, index) => { if id.name == "Editor Tab Tabbar" { if index == 0 { - self.active_editor = ActiveEditor::TileEditor; + self.active_editor = ActiveEditor::GameEditor; } else if index == 1 { self.active_editor = ActiveEditor::ScreenEditor; } @@ -1369,7 +1411,7 @@ impl TheTrait for Editor { update_server_icons = true; } else if self.server.state == ServerState::Paused { self.client - .tick(self.active_editor == ActiveEditor::TileEditor); + .tick(self.active_editor == ActiveEditor::GameEditor); let debug = self.server.tick(); if !debug.is_empty() { self.sidebar.add_debug_messages(debug, ui, ctx); diff --git a/creator/src/main.rs b/creator/src/main.rs index e4e23e76..c7daf681 100644 --- a/creator/src/main.rs +++ b/creator/src/main.rs @@ -15,6 +15,8 @@ pub mod tileeditor; pub mod tilefxeditor; pub mod tilemapeditor; pub mod tilepicker; +pub mod toollist; +pub mod tools; pub mod undo; use rust_embed::RustEmbed; @@ -30,6 +32,8 @@ pub mod prelude { pub use shared::prelude::*; pub use theframework::prelude::*; + pub use crate::editor::ActiveEditor; + pub use crate::externals::*; pub use crate::misc::*; pub use crate::modelfxeditor::*; @@ -41,9 +45,13 @@ pub mod prelude { pub use crate::tilefxeditor::*; pub use crate::tilemapeditor::*; pub use crate::tilepicker::*; + pub use crate::toollist::*; pub use crate::undo::materialfx_undo::*; pub use crate::undo::region_undo::*; pub use crate::undo::*; + + pub use crate::tools::tiledrawer::TileDrawerTool; + pub use crate::tools::*; } use crate::editor::Editor; diff --git a/creator/src/tileeditor.rs b/creator/src/tileeditor.rs index dc786385..290bab3b 100644 --- a/creator/src/tileeditor.rs +++ b/creator/src/tileeditor.rs @@ -818,6 +818,7 @@ impl TileEditor { // An item in the tile list was selected else if id.name == "Tilemap Tile" { self.curr_tile_uuid = Some(id.uuid); + server_ctx.curr_tile_id = Some(id.uuid); if let Some(t) = TILEDRAWER.lock().unwrap().tiles.get(&id.uuid) { if let Some(icon_view) = ui.get_icon_view("Icon Preview") { @@ -831,6 +832,8 @@ impl TileEditor { server.update_tiles(project.extract_tiles()); } else if id.name == "Ground Icon" { self.curr_layer_role = Layer2DRole::Ground; + server_ctx.curr_layer_role = Layer2DRole::Ground; + self.set_icon_colors(ui); server_ctx.show_fx_marker = false; redraw = true; @@ -850,6 +853,8 @@ impl TileEditor { ); } else if id.name == "Wall Icon" { self.curr_layer_role = Layer2DRole::Wall; + server_ctx.curr_layer_role = Layer2DRole::Wall; + self.set_icon_colors(ui); server_ctx.show_fx_marker = false; redraw = true; @@ -869,6 +874,8 @@ impl TileEditor { ); } else if id.name == "Ceiling Icon" { self.curr_layer_role = Layer2DRole::Ceiling; + server_ctx.curr_layer_role = Layer2DRole::Ceiling; + self.set_icon_colors(ui); server_ctx.show_fx_marker = false; redraw = true; @@ -1834,77 +1841,6 @@ impl TileEditor { self.set_editor_group_index(EditorMode::Draw, ui, ctx); } } else if self.editor_mode == EditorMode::Draw { - if let Some(curr_tile_uuid) = self.curr_tile_uuid { - if TILEDRAWER - .lock() - .unwrap() - .tiles - .contains_key(&curr_tile_uuid) - { - if self.curr_layer_role == Layer2DRole::FX { - // Set the tile preview. - if let Some(widget) = ui.get_widget("TileFX RGBA") { - if let Some(tile_rgba) = widget.as_rgba_view() { - if let Some(tile) = project - .extract_region_tile(server_ctx.curr_region, (coord.x, coord.y)) - { - let preview_size = TILEFXEDITOR.lock().unwrap().preview_size; - tile_rgba - .set_grid(Some(preview_size / tile.buffer[0].dim().width)); - tile_rgba.set_buffer( - tile.buffer[0].scaled(preview_size, preview_size), - ); - } - } - } - } - - let palette = project.palette.clone(); - if let Some(region) = project.get_region_mut(&server_ctx.curr_region) { - if self.curr_layer_role == Layer2DRole::FX { - if !TILEFXEDITOR.lock().unwrap().curr_timeline.is_empty() { - region.set_tilefx( - (coord.x, coord.y), - TILEFXEDITOR.lock().unwrap().curr_timeline.clone(), - ) - } else if let Some(tile) = region.tiles.get_mut(&(coord.x, coord.y)) { - tile.tilefx = None; - } - } else { - let mut prev = None; - if let Some(tile) = region.tiles.get(&(coord.x, coord.y)) { - prev = Some(tile.clone()); - } - - region.set_tile( - (coord.x, coord.y), - self.curr_layer_role, - self.curr_tile_uuid, - ); - - if let Some(tile) = region.tiles.get(&(coord.x, coord.y)) { - if prev != Some(tile.clone()) { - let undo = RegionUndoAtom::RegionTileEdit( - vec2i(coord.x, coord.y), - prev, - Some(tile.clone()), - ); - - UNDOMANAGER - .lock() - .unwrap() - .add_region_undo(®ion.id, undo, ctx); - } - } - } - self.set_icon_previews(region, &palette, coord, ui); - - server.update_region(region); - RENDERER.lock().unwrap().set_region(region); - } - } - //self.redraw_region(ui, server, ctx, server_ctx); - } } redraw } diff --git a/creator/src/toollist.rs b/creator/src/toollist.rs new file mode 100644 index 00000000..e875c3c3 --- /dev/null +++ b/creator/src/toollist.rs @@ -0,0 +1,153 @@ +use std::any::Any; + +use crate::editor::{PRERENDERTHREAD, TILEDRAWER, UNDOMANAGER}; +use crate::prelude::*; + +pub use ActiveEditor::*; + +pub struct ToolList { + pub active_editor: ActiveEditor, + + pub game_tools: Vec>, + pub curr_game_tool: usize, + + pub screen_tools: Vec>, + pub curr_screen_tool: usize, +} + +impl Default for ToolList { + fn default() -> Self { + Self::new() + } +} + +impl ToolList { + pub fn new() -> Self { + let game_tools: Vec> = vec![Box::new(TileDrawerTool::new())]; + let screen_tools: Vec> = vec![Box::new(TileDrawerTool::new())]; + + Self { + active_editor: ActiveEditor::GameEditor, + + game_tools, + curr_game_tool: 0, + + screen_tools, + curr_screen_tool: 0, + } + } + + /// Build the UI + pub fn set_active_editor( + &mut self, + active_editor: ActiveEditor, + list: &mut TheVLayout, + _ctx: &mut TheContext, + ) { + self.active_editor = active_editor; + + match active_editor { + GameEditor => { + for (index, tool) in self.game_tools.iter().enumerate() { + let mut b = TheToolListButton::new(tool.id()); + + b.set_icon_name(tool.icon_name()); + b.set_status_text(&tool.info()); + if index == self.curr_game_tool { + b.set_state(TheWidgetState::Selected); + } + list.add_widget(Box::new(b)); + } + } + ScreenEditor => {} + } + } + + #[allow(clippy::too_many_arguments)] + pub fn handle_event( + &mut self, + event: &TheEvent, + ui: &mut TheUI, + ctx: &mut TheContext, + project: &mut Project, + server: &mut Server, + client: &mut Client, + server_ctx: &mut ServerContext, + ) -> bool { + let mut redraw = false; + match event { + TheEvent::TileEditorClicked(id, coord) => { + if id.name == "Region Editor View" { + match &self.active_editor { + GameEditor => { + redraw = self.game_tools[self.curr_game_tool].tool_event( + ToolEvent::TileDown(*coord), + ToolContext::TwoD, + ui, + ctx, + project, + server, + client, + server_ctx, + ); + } + ScreenEditor => { + redraw = self.screen_tools[self.curr_screen_tool].tool_event( + ToolEvent::TileDown(*coord), + ToolContext::TwoD, + ui, + ctx, + project, + server, + client, + server_ctx, + ); + } + } + } + } + TheEvent::TileEditorDragged(id, coord) => { + if id.name == "Region Editor View" { + match &self.active_editor { + GameEditor => { + redraw = self.game_tools[self.curr_game_tool].tool_event( + ToolEvent::TileDrag(*coord), + ToolContext::TwoD, + ui, + ctx, + project, + server, + client, + server_ctx, + ); + } + ScreenEditor => { + redraw = self.screen_tools[self.curr_screen_tool].tool_event( + ToolEvent::TileDown(*coord), + ToolContext::TwoD, + ui, + ctx, + project, + server, + client, + server_ctx, + ); + } + } + } + } + _ => {} + } + + if !redraw { + redraw = match &self.active_editor { + GameEditor => self.game_tools[self.curr_game_tool] + .handle_event(event, ui, ctx, project, server, client, server_ctx), + ScreenEditor => self.screen_tools[self.curr_screen_tool] + .handle_event(event, ui, ctx, project, server, client, server_ctx), + }; + } + + redraw + } +} diff --git a/creator/src/tools/mod.rs b/creator/src/tools/mod.rs new file mode 100644 index 00000000..605323ad --- /dev/null +++ b/creator/src/tools/mod.rs @@ -0,0 +1,56 @@ +pub use crate::prelude::*; + +pub mod tiledrawer; + +#[derive(PartialEq, Clone, Debug, Copy)] +pub enum ToolEvent { + TileDown(Vec2i), + TileDrag(Vec2i), + TileUp(Vec2i), +} + +#[derive(PartialEq, Clone, Debug, Copy)] +pub enum ToolContext { + TwoD, + ThreeD, +} + +#[allow(unused)] +pub trait Tool: Send { + fn new() -> Self + where + Self: Sized; + + fn id(&self) -> TheId; + fn info(&self) -> String; + fn icon_name(&self) -> String; + + #[allow(clippy::too_many_arguments)] + fn tool_event( + &mut self, + tool_event: ToolEvent, + tool_context: ToolContext, + ui: &mut TheUI, + ctx: &mut TheContext, + project: &mut Project, + server: &mut Server, + client: &mut Client, + server_ctx: &mut ServerContext, + ) -> bool { + false + } + + #[allow(clippy::too_many_arguments)] + fn handle_event( + &mut self, + event: &TheEvent, + ui: &mut TheUI, + ctx: &mut TheContext, + project: &mut Project, + server: &mut Server, + client: &mut Client, + server_ctx: &mut ServerContext, + ) -> bool { + false + } +} diff --git a/creator/src/tools/tiledrawer.rs b/creator/src/tools/tiledrawer.rs new file mode 100644 index 00000000..11f9e4d7 --- /dev/null +++ b/creator/src/tools/tiledrawer.rs @@ -0,0 +1,117 @@ +use crate::prelude::*; +use ToolEvent::*; + +use crate::editor::{ + CODEEDITOR, MODELFXEDITOR, PRERENDERTHREAD, RENDERER, RENDERMODE, SIDEBARMODE, TILEDRAWER, + TILEFXEDITOR, UNDOMANAGER, +}; + +pub struct TileDrawerTool { + id: TheId, +} + +impl Tool for TileDrawerTool { + fn new() -> Self + where + Self: Sized, + { + Self { + id: TheId::named("Tile Drawer Tool"), + } + } + + fn id(&self) -> TheId { + self.id.clone() + } + fn info(&self) -> String { + str!("I draw tiles") + } + fn icon_name(&self) -> String { + str!("pen") + } + + fn tool_event( + &mut self, + tool_event: ToolEvent, + _tool_context: ToolContext, + ui: &mut TheUI, + ctx: &mut TheContext, + project: &mut Project, + server: &mut Server, + _client: &mut Client, + server_ctx: &mut ServerContext, + ) -> bool { + let coord = match tool_event { + TileDown(c) => c, + TileDrag(c) => c, + _ => { + return false; + } + }; + + if let Some(curr_tile_id) = server_ctx.curr_tile_id { + if TILEDRAWER.lock().unwrap().tiles.contains_key(&curr_tile_id) { + if server_ctx.curr_layer_role == Layer2DRole::FX { + // Set the tile preview. + if let Some(widget) = ui.get_widget("TileFX RGBA") { + if let Some(tile_rgba) = widget.as_rgba_view() { + if let Some(tile) = project + .extract_region_tile(server_ctx.curr_region, (coord.x, coord.y)) + { + let preview_size = TILEFXEDITOR.lock().unwrap().preview_size; + tile_rgba.set_grid(Some(preview_size / tile.buffer[0].dim().width)); + tile_rgba + .set_buffer(tile.buffer[0].scaled(preview_size, preview_size)); + } + } + } + } + + if let Some(region) = project.get_region_mut(&server_ctx.curr_region) { + if server_ctx.curr_layer_role == Layer2DRole::FX { + if !TILEFXEDITOR.lock().unwrap().curr_timeline.is_empty() { + region.set_tilefx( + (coord.x, coord.y), + TILEFXEDITOR.lock().unwrap().curr_timeline.clone(), + ) + } else if let Some(tile) = region.tiles.get_mut(&(coord.x, coord.y)) { + tile.tilefx = None; + } + } else { + let mut prev = None; + if let Some(tile) = region.tiles.get(&(coord.x, coord.y)) { + prev = Some(tile.clone()); + } + + region.set_tile( + (coord.x, coord.y), + server_ctx.curr_layer_role, + server_ctx.curr_tile_id, + ); + + if let Some(tile) = region.tiles.get(&(coord.x, coord.y)) { + if prev != Some(tile.clone()) { + let undo = RegionUndoAtom::RegionTileEdit( + vec2i(coord.x, coord.y), + prev, + Some(tile.clone()), + ); + + UNDOMANAGER + .lock() + .unwrap() + .add_region_undo(®ion.id, undo, ctx); + } + } + } + //self.set_icon_previews(region, &palette, coord, ui); + + server.update_region(region); + RENDERER.lock().unwrap().set_region(region); + } + } + //self.redraw_region(ui, server, ctx, server_ctx); + } + false + } +} diff --git a/shared/src/renderer.rs b/shared/src/renderer.rs index 48282d70..8ae2b2b2 100644 --- a/shared/src/renderer.rs +++ b/shared/src/renderer.rs @@ -584,7 +584,6 @@ impl Renderer { hit.normal = region .heightmap .calculate_normal(terrain_hit.x, terrain_hit.z, 0.001); - // let terrain_normal = hit.normal; hit.hit_point = terrain_hit; //hit.distance = terrain_dist; diff --git a/shared/src/server/context.rs b/shared/src/server/context.rs index 7f2d39c1..f72474e6 100644 --- a/shared/src/server/context.rs +++ b/shared/src/server/context.rs @@ -39,6 +39,12 @@ pub struct ServerContext { /// The logged interactions of the characters. pub interactions: FxHashMap>, + /// The currently selected tile + pub curr_tile_id: Option, + + /// The currently selected layer role + pub curr_layer_role: Layer2DRole, + /// The conceptual display range [0..1] of the 2D preview. /// Only relevent in Model view. 0 is full conceptual display. 1 is full detail. pub conceptual_display: Option, @@ -79,6 +85,9 @@ impl ServerContext { interactions: FxHashMap::default(), + curr_tile_id: None, + curr_layer_role: Layer2DRole::Wall, + conceptual_display: None, curr_geo_object: None,