diff --git a/design/v0.txt b/design/v0.txt index 5f59a6e..b4e7e8d 100644 --- a/design/v0.txt +++ b/design/v0.txt @@ -40,3 +40,10 @@ Single-char ⎕ Music ⎕ something +was wäre mit +- seitwärts gehen +- mehr räume anzeigen +- aktuellen raum live updaten +- beep boops/animation wenn irgendwas im aktuellen raum passiert +- position beim hochgehen merken +- hintergrund rendern diff --git a/src/game.rs b/src/game.rs index 09985bf..4580946 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,19 +1,11 @@ use std::{ - error::Error, - fmt::{self}, - fs, - path::PathBuf, + error::Error, ffi::{OsString}, fmt::{self}, fs, path::PathBuf, process::Command }; use color_eyre::eyre::Result; use crossterm::event::{Event, KeyCode}; use ratatui::{ - Frame, - buffer::{Buffer, Cell}, - layout::{Constraint, Layout, Rect}, - style::Color, - text::{Line, Text}, - widgets::{Block, Widget}, + buffer::{Buffer, Cell}, layout::{Constraint, Layout, Rect}, prelude::Backend, style::Color, text::{Line, Text}, widgets::{Block, Widget}, Frame, Terminal }; use crate::geometry::{Grid, P2, V2}; @@ -24,7 +16,7 @@ pub struct GameModel { room: Room, } -#[derive(Clone)] +#[derive(Clone, Debug)] pub enum GameEvent { Quit, Nop, @@ -32,9 +24,10 @@ pub enum GameEvent { PlayerDash(V2), Interact, Navigate(NavigationTarget), + Run(OsString, Vec), } -#[derive(Clone)] +#[derive(Clone, Debug)] pub enum NavigationTarget { Path(PathBuf), Parent, @@ -68,7 +61,7 @@ struct Room { tiles: Grid, } -#[derive(Clone)] +#[derive(Clone, Debug)] struct Tile { style: TileStyle, action: Option, @@ -173,7 +166,9 @@ impl GameModel { } else { tiles .get_mut(P2::new(10, 2 + i as isize)) - .map(|tile| *tile = Tile::new(TileStyle::Box)); + .map(|tile| *tile = Tile::new(TileStyle::Box).with_action(GameEvent::Run("vim".into(), vec![ + entry.into() + ]))); } for (j, c) in entry @@ -197,11 +192,11 @@ impl GameModel { }) } - pub fn update(self, event: Event) -> Result { - self.update_game(GameEvent::from_crossterm(event)) + pub fn update(self, event: Event, terminal: &mut Terminal) -> Result { + self.update_game(GameEvent::from_crossterm(event), terminal) } - fn update_game(self, event: GameEvent) -> Result { + fn update_game(self, event: GameEvent, terminal: &mut Terminal) -> Result { use UpdateResult::*; Ok(match event { GameEvent::Quit => ShouldExit(self.path), @@ -242,7 +237,7 @@ impl GameModel { .and_then(|tile| tile.action.clone()); if let Some(action) = opt_action { - self.update_game(action)? + self.update_game(action, terminal)? } else { NewModel(self) } @@ -257,15 +252,21 @@ impl GameModel { NewModel(Self::new(path)?) } + GameEvent::Run(cmd, args) => { + Command::new(&cmd).args(args).spawn().unwrap().wait().unwrap(); + // TODO: Figure out why terminal isn't cleared on exit. + terminal.clear().unwrap(); + NewModel(self) + } }) } pub fn render(&self, frame: &mut Frame) { let layout = - Layout::vertical([Constraint::Fill(1), Constraint::Length(3)]).split(frame.area()); + Layout::vertical([Constraint::Fill(1), Constraint::Length(4)]).split(frame.area()); let camera_block_area = layout[0]; - let info_block_area = layout[1]; + let bottom_bar_area = layout[1]; let camera_block = Block::bordered() .title("camera") @@ -273,15 +274,30 @@ impl GameModel { let camera_area = camera_block.inner(camera_block_area); let camera = CameraWidget::new(self); + let bottom_bar_layout = Layout::horizontal([ + Constraint::Fill(1), + Constraint::Fill(1), + ]).split(bottom_bar_area); + + let info_block_area = bottom_bar_layout[0]; + let debug_block_area = bottom_bar_layout[1]; + let info_block = Block::bordered().title("cwd"); let info_area = info_block.inner(info_block_area); let info = Text::raw(self.path.to_string_lossy()); + let debug_block = Block::bordered().title("debug"); + let debug_area = info_block.inner(debug_block_area); + let debug = Text::raw(self.room.tiles.get(self.player_pos).map(|tile| format!("{:?}\n{:?}", tile.style, tile.action)).unwrap_or("".to_string())); + frame.render_widget(camera_block, camera_block_area); frame.render_widget(camera, camera_area); frame.render_widget(info_block, info_block_area); frame.render_widget(info, info_area); + + frame.render_widget(debug_block, debug_block_area); + frame.render_widget(debug, debug_area); } fn render_tiles(&self) -> Grid { @@ -302,7 +318,7 @@ impl GameModel { } } -#[derive(Clone)] +#[derive(Clone, Debug)] enum TileStyle { Floor, Player, @@ -312,12 +328,12 @@ enum TileStyle { Box, } -#[derive(Clone)] +#[derive(Clone, Debug)] struct Portal { kind: PortalKind, } -#[derive(Clone)] +#[derive(Clone, Debug)] enum PortalKind { Ladder, Portal, diff --git a/src/main.rs b/src/main.rs index 7bdd68b..cbcb110 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,7 +43,7 @@ fn main_loop(terminal: &mut Terminal) -> Result { terminal.draw(|frame| model.render(frame))?; let term_event = event::read()?; - match model.update(term_event)? { + match model.update(term_event, terminal)? { UpdateResult::NewModel(new_model) => model = new_model, UpdateResult::ShouldExit(path) => break Ok(path), }