mirror of
https://codeberg.org/schrottkatze/mgd2-tram-championships.git
synced 2025-07-04 02:57:39 +00:00
Compare commits
8 commits
cf05050c95
...
d43b5b64e1
Author | SHA1 | Date | |
---|---|---|---|
d43b5b64e1 | |||
3a3c238cd8 | |||
3b0bd65078 | |||
4c24f67cd5 | |||
|
d79475ae2a | ||
1e6a2ec8d7 | |||
4b71994b6b | |||
3157af2c2b |
14 changed files with 225 additions and 95 deletions
BIN
blender/10X5Hallway.blend
Normal file
BIN
blender/10X5Hallway.blend
Normal file
Binary file not shown.
118
src/debug.rs
Normal file
118
src/debug.rs
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
//! Seperate out debugging uis/plugins in it's own module for cleanliness.
|
||||||
|
use std::{fs, path::PathBuf};
|
||||||
|
|
||||||
|
use bevy::prelude::*;
|
||||||
|
use bevy_inspector_egui::bevy_egui::EguiPlugin;
|
||||||
|
use clap::Subcommand;
|
||||||
|
use console::{ConsoleLog, exec_script};
|
||||||
|
|
||||||
|
use crate::AppState;
|
||||||
|
|
||||||
|
mod console;
|
||||||
|
|
||||||
|
/// Debug system set.
|
||||||
|
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub struct DebugSet;
|
||||||
|
|
||||||
|
pub fn plugin(app: &mut App) {
|
||||||
|
app.add_plugins(EguiPlugin {
|
||||||
|
enable_multipass_for_primary_context: true,
|
||||||
|
})
|
||||||
|
.add_event::<DebugEvent>()
|
||||||
|
.add_systems(
|
||||||
|
Update,
|
||||||
|
(handle_debug_logs, start_game, run_file.pipe(exec_script)).in_set(DebugSet),
|
||||||
|
)
|
||||||
|
.add_systems(Startup, startup_file.pipe(exec_script))
|
||||||
|
.add_plugins(console::plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Event, Debug, Subcommand, PartialEq, Eq)]
|
||||||
|
enum DebugEvent {
|
||||||
|
/// Close the debug console.
|
||||||
|
#[command(name = "close", aliases = ["close-console"])]
|
||||||
|
CloseDebugConsole,
|
||||||
|
|
||||||
|
/// Output a string to the console.
|
||||||
|
///
|
||||||
|
/// Needed for logging in startup scripts, since the console isn't initialized yet.
|
||||||
|
#[command(name = "echo", aliases = ["print", "print-to-console"])]
|
||||||
|
PrintToConsole {
|
||||||
|
/// Print as error.
|
||||||
|
#[arg(short, long)]
|
||||||
|
error: bool,
|
||||||
|
/// The text to be printed in the console.
|
||||||
|
text: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Log as INFO or ERROR to stdout.
|
||||||
|
Log {
|
||||||
|
/// Log as error.
|
||||||
|
#[arg(short, long)]
|
||||||
|
error: bool,
|
||||||
|
/// The text to be logged.
|
||||||
|
text: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Start the game
|
||||||
|
StartGame,
|
||||||
|
|
||||||
|
/// Run a tx file (the games debug scripting lang :3)
|
||||||
|
#[command(name = "run")]
|
||||||
|
RunFile { file: PathBuf },
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_game(
|
||||||
|
mut dbg_reader: EventReader<DebugEvent>,
|
||||||
|
mut log: ResMut<ConsoleLog>,
|
||||||
|
cur_state: Res<State<AppState>>,
|
||||||
|
mut next_state: ResMut<NextState<AppState>>,
|
||||||
|
) {
|
||||||
|
for ev in dbg_reader.read() {
|
||||||
|
if *ev == DebugEvent::StartGame {
|
||||||
|
if *cur_state == AppState::Ingame {
|
||||||
|
log.err("Can't start game since it's already started.");
|
||||||
|
} else {
|
||||||
|
log.write("Starting game...");
|
||||||
|
next_state.set(AppState::Ingame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_debug_logs(mut dbg_reader: EventReader<DebugEvent>) {
|
||||||
|
for ev in dbg_reader.read() {
|
||||||
|
if let DebugEvent::Log { error, text } = ev {
|
||||||
|
if *error {
|
||||||
|
error!("{text}")
|
||||||
|
} else {
|
||||||
|
info!("{text}")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_file(mut dbg_reader: EventReader<DebugEvent>) -> Option<(String, String)> {
|
||||||
|
for ev in dbg_reader.read() {
|
||||||
|
if let DebugEvent::RunFile { file } = ev {
|
||||||
|
let f = std::fs::read_to_string(file);
|
||||||
|
|
||||||
|
if let Ok(f) = f {
|
||||||
|
return Some((f, String::from(file.file_name().unwrap().to_string_lossy())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn startup_file() -> Option<(String, String)> {
|
||||||
|
let path: PathBuf = "./startup.tx".into();
|
||||||
|
|
||||||
|
fs::exists(&path).unwrap_or(false).then(|| {
|
||||||
|
Some((
|
||||||
|
fs::read_to_string(&path).unwrap(),
|
||||||
|
path.file_name().unwrap().to_string_lossy().to_string(),
|
||||||
|
))
|
||||||
|
})?
|
||||||
|
}
|
|
@ -1,12 +1,15 @@
|
||||||
|
use std::panic::Location;
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
use cli::respond;
|
||||||
use ui::{
|
use ui::{
|
||||||
DebugConsole, autofocus, autoscroll, handle_open_console, process_prompt, update_content,
|
DebugConsole, autofocus, autoscroll, handle_open_console, process_prompt, update_content,
|
||||||
update_scroll_position,
|
update_scroll_position,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{AppState, cleanup::despawn, game::GameplaySet};
|
use crate::{AppState, cleanup::despawn};
|
||||||
|
|
||||||
use super::DebugEvent;
|
use super::{DebugEvent, DebugSet};
|
||||||
|
|
||||||
mod cli;
|
mod cli;
|
||||||
mod ui;
|
mod ui;
|
||||||
|
@ -15,14 +18,12 @@ pub(super) fn plugin(app: &mut App) {
|
||||||
app.init_state::<ConsoleState>()
|
app.init_state::<ConsoleState>()
|
||||||
.add_systems(
|
.add_systems(
|
||||||
OnEnter(ConsoleState::Open),
|
OnEnter(ConsoleState::Open),
|
||||||
(open_console, (autofocus, autoscroll).after(open_console)),
|
(open_console, (autofocus, autoscroll).after(open_console)).in_set(DebugSet),
|
||||||
)
|
)
|
||||||
.add_systems(
|
.add_systems(
|
||||||
Update,
|
Update,
|
||||||
(
|
(
|
||||||
handle_open_console
|
handle_open_console.run_if(in_state(ConsoleState::Closed)),
|
||||||
.in_set(GameplaySet)
|
|
||||||
.run_if(in_state(ConsoleState::Closed).and(in_state(AppState::Ingame))),
|
|
||||||
update_content.run_if(resource_changed::<ConsoleLog>),
|
update_content.run_if(resource_changed::<ConsoleLog>),
|
||||||
(
|
(
|
||||||
update_scroll_position,
|
update_scroll_position,
|
||||||
|
@ -30,21 +31,27 @@ pub(super) fn plugin(app: &mut App) {
|
||||||
execute_console_events,
|
execute_console_events,
|
||||||
)
|
)
|
||||||
.run_if(in_state(ConsoleState::Open)),
|
.run_if(in_state(ConsoleState::Open)),
|
||||||
),
|
)
|
||||||
|
.in_set(DebugSet),
|
||||||
|
)
|
||||||
|
.add_systems(
|
||||||
|
OnExit(ConsoleState::Open),
|
||||||
|
despawn::<DebugConsole>.in_set(DebugSet),
|
||||||
)
|
)
|
||||||
.add_systems(OnExit(ConsoleState::Open), despawn::<DebugConsole>)
|
|
||||||
.insert_resource::<ConsoleLog>(ConsoleLog::new());
|
.insert_resource::<ConsoleLog>(ConsoleLog::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// the usize is a read index
|
/// the usize is a read index
|
||||||
#[derive(Resource, Clone)]
|
#[derive(Resource, Clone)]
|
||||||
struct ConsoleLog(Vec<ConsoleEvent>, usize);
|
pub struct ConsoleLog(Vec<ConsoleEvent>, usize);
|
||||||
|
|
||||||
impl ConsoleLog {
|
impl ConsoleLog {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self(
|
Self(
|
||||||
vec![ConsoleEvent::Output(String::from(
|
vec![ConsoleEvent::Output(format!(
|
||||||
"Welcome to the dev console :3\n (i should probably put some proper info into this some time)",
|
"Running {} ({})\nMeow!! :3",
|
||||||
|
env!("CARGO_PKG_NAME"),
|
||||||
|
env!("CARGO_PKG_VERSION")
|
||||||
))],
|
))],
|
||||||
1,
|
1,
|
||||||
)
|
)
|
||||||
|
@ -56,15 +63,15 @@ impl ConsoleLog {
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn input(&mut self, content: &str) {
|
fn input(&mut self, content: &str) {
|
||||||
self.0.push(ConsoleEvent::Input(content.to_string()))
|
self.0.push(ConsoleEvent::Input(content.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn output(&mut self, content: &str) {
|
pub fn write(&mut self, content: &str) {
|
||||||
self.0.push(ConsoleEvent::Output(content.to_string()))
|
self.0.push(ConsoleEvent::Output(content.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn error(&mut self, content: &str) {
|
pub fn err(&mut self, content: &str) {
|
||||||
self.0.push(ConsoleEvent::Error(content.to_string()))
|
self.0.push(ConsoleEvent::Error(content.to_string()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,8 +105,30 @@ fn execute_console_events(
|
||||||
for ev in ev_reader.read() {
|
for ev in ev_reader.read() {
|
||||||
match ev {
|
match ev {
|
||||||
DebugEvent::CloseDebugConsole => next_state.set(ConsoleState::Closed),
|
DebugEvent::CloseDebugConsole => next_state.set(ConsoleState::Closed),
|
||||||
DebugEvent::PrintToConsole(s) => log.output(s),
|
DebugEvent::PrintToConsole { text, error: false } => log.write(text),
|
||||||
_ => todo!(),
|
DebugEvent::PrintToConsole { text, error: true } => log.err(text),
|
||||||
|
_ => {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn exec_script(
|
||||||
|
file: In<Option<(String, String)>>,
|
||||||
|
mut dbg_writer: EventWriter<DebugEvent>,
|
||||||
|
mut logger: ResMut<ConsoleLog>,
|
||||||
|
) {
|
||||||
|
let Some((file, file_name)) = &*file else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (line_nr, line) in file.lines().enumerate() {
|
||||||
|
if !line.trim().is_empty() && !line.trim().starts_with("//") {
|
||||||
|
match respond(line) {
|
||||||
|
Ok(ev) => {
|
||||||
|
dbg_writer.write(ev);
|
||||||
|
}
|
||||||
|
Err(err) => logger.err(&format!("{err}\n\n({file_name}:{line_nr})")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
31
src/debug/console/cli.rs
Normal file
31
src/debug/console/cli.rs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
use bevy::prelude::*;
|
||||||
|
use clap::{Parser, Subcommand};
|
||||||
|
|
||||||
|
use crate::debug::DebugEvent;
|
||||||
|
|
||||||
|
use super::ConsoleLog;
|
||||||
|
|
||||||
|
pub(super) fn respond(line: &str) -> Result<DebugEvent, String> {
|
||||||
|
let args = shlex::split(line).ok_or("Invalid Quoting")?;
|
||||||
|
let cli = Cli::try_parse_from(args).map_err(|e| e.to_string());
|
||||||
|
|
||||||
|
// help detection
|
||||||
|
let command_contains_help = line.contains("help") || line.contains("-h");
|
||||||
|
let some_line_starts_with_usage = cli
|
||||||
|
.as_ref()
|
||||||
|
.is_err_and(|item| item.lines().any(|line| line.starts_with("Usage: ")));
|
||||||
|
|
||||||
|
if command_contains_help && some_line_starts_with_usage {
|
||||||
|
let Err(text) = cli else { unreachable!() };
|
||||||
|
return Ok(DebugEvent::PrintToConsole { text, error: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(cli?.cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Parser)]
|
||||||
|
#[command(multicall = true)]
|
||||||
|
struct Cli {
|
||||||
|
#[command(subcommand)]
|
||||||
|
cmd: DebugEvent,
|
||||||
|
}
|
|
@ -16,7 +16,7 @@ use bevy_ui_text_input::TextSubmitEvent;
|
||||||
pub(super) use components::console;
|
pub(super) use components::console;
|
||||||
use components::{Content, Prompt};
|
use components::{Content, Prompt};
|
||||||
|
|
||||||
use crate::game::debug::DebugEvent;
|
use crate::debug::DebugEvent;
|
||||||
|
|
||||||
use super::{ConsoleEvent, ConsoleLog, ConsoleState, OPEN_CONSOLE_DEFAULT, cli::respond};
|
use super::{ConsoleEvent, ConsoleLog, ConsoleState, OPEN_CONSOLE_DEFAULT, cli::respond};
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ pub fn process_prompt(
|
||||||
Ok(debug_ev) => {
|
Ok(debug_ev) => {
|
||||||
debug_event_writer.write(debug_ev);
|
debug_event_writer.write(debug_ev);
|
||||||
}
|
}
|
||||||
Err(e) => log.error(&e),
|
Err(e) => log.err(&e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ pub fn update_content(
|
||||||
) {
|
) {
|
||||||
c.entity(*content).with_children(|parent| {
|
c.entity(*content).with_children(|parent| {
|
||||||
for item in log.unread() {
|
for item in log.unread() {
|
||||||
match dbg!(item) {
|
match item {
|
||||||
ConsoleEvent::Input(s) => {
|
ConsoleEvent::Input(s) => {
|
||||||
parent.spawn(components::input(s.to_string(), &asset_server));
|
parent.spawn(components::input(s.to_string(), &asset_server));
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
use bevy::{ecs::spawn::SpawnWith, prelude::*};
|
use bevy::{ecs::spawn::SpawnWith, prelude::*};
|
||||||
use bevy_ui_text_input::{TextInputMode, TextInputNode, TextInputPrompt};
|
use bevy_ui_text_input::{TextInputMode, TextInputNode, TextInputPrompt};
|
||||||
|
|
||||||
use crate::game::debug::console::{ConsoleEvent, ConsoleLog};
|
use crate::debug::console::{ConsoleEvent, ConsoleLog};
|
||||||
|
|
||||||
use super::DebugConsole;
|
use super::DebugConsole;
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ pub fn console(data: ConsoleLog, asset_server: AssetServer) -> impl Bundle {
|
||||||
},
|
},
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
BorderRadius::bottom(Val::Px(10.)),
|
||||||
BorderColor(Color::BLACK),
|
BorderColor(Color::BLACK),
|
||||||
ZIndex(i32::MAX),
|
ZIndex(i32::MAX),
|
||||||
BackgroundColor(Color::Srgba(Srgba::BLACK.with_alpha(0.2))),
|
BackgroundColor(Color::Srgba(Srgba::BLACK.with_alpha(0.2))),
|
|
@ -1,14 +0,0 @@
|
||||||
//! Seperate out debugging uis/plugins in it's own module for cleanliness.
|
|
||||||
use bevy::prelude::*;
|
|
||||||
use bevy_inspector_egui::bevy_egui::EguiPlugin;
|
|
||||||
|
|
||||||
pub fn plugin(app: &mut App) {
|
|
||||||
app.add_plugins(EguiPlugin {
|
|
||||||
enable_multipass_for_primary_context: true,
|
|
||||||
})
|
|
||||||
.add_plugins((
|
|
||||||
// WorldInspectorPlugin::new(),
|
|
||||||
// StateInspectorPlugin::<AppState>::new(),
|
|
||||||
// StateInspectorPlugin::<menus::CurrentMenu>::new(),
|
|
||||||
));
|
|
||||||
}
|
|
13
src/game.rs
13
src/game.rs
|
@ -6,18 +6,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
mod camera;
|
mod camera;
|
||||||
mod debug;
|
|
||||||
mod scene;
|
mod scene;
|
||||||
mod tram {
|
|
||||||
use bevy::prelude::*;
|
|
||||||
|
|
||||||
fn spawn_tram(
|
|
||||||
mut c: Commands,
|
|
||||||
mut meshes: ResMut<Assets<Mesh>>,
|
|
||||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gameplay system set. All functions in this control the gameplay (duh).
|
/// Gameplay system set. All functions in this control the gameplay (duh).
|
||||||
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
@ -29,6 +18,6 @@ pub fn plugin(app: &mut App) {
|
||||||
OnExit(AppState::Ingame),
|
OnExit(AppState::Ingame),
|
||||||
despawn::<cleanup::Scene>.in_set(GameplaySet),
|
despawn::<cleanup::Scene>.in_set(GameplaySet),
|
||||||
)
|
)
|
||||||
.add_plugins((debug::plugin, camera::plugin));
|
.add_plugins(camera::plugin);
|
||||||
app.configure_sets(Update, GameplaySet.run_if(in_state(AppState::Ingame)));
|
app.configure_sets(Update, GameplaySet.run_if(in_state(AppState::Ingame)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
use bevy::prelude::*;
|
|
||||||
|
|
||||||
mod console;
|
|
||||||
|
|
||||||
#[derive(Event)]
|
|
||||||
enum DebugEvent {
|
|
||||||
CloseDebugConsole,
|
|
||||||
PrintToConsole(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn plugin(app: &mut App) {
|
|
||||||
app.add_plugins(console::plugin).add_event::<DebugEvent>();
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
use clap::{Parser, Subcommand};
|
|
||||||
|
|
||||||
use crate::game::debug::DebugEvent;
|
|
||||||
|
|
||||||
pub(super) fn respond(line: &str) -> Result<DebugEvent, String> {
|
|
||||||
let might_be_help_call = line.contains("help") || line.contains("-h");
|
|
||||||
let args = shlex::split(line).ok_or("Invalid Quoting")?;
|
|
||||||
let cli = Cli::try_parse_from(args).map_err(|e| e.to_string());
|
|
||||||
|
|
||||||
if might_be_help_call && cli.as_ref().is_err_and(|item| item.starts_with("Usage: ")) {
|
|
||||||
let Err(s) = cli else { unreachable!() };
|
|
||||||
return Ok(DebugEvent::PrintToConsole(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(match cli?.cmd {
|
|
||||||
Commands::Close => DebugEvent::CloseDebugConsole,
|
|
||||||
Commands::Echo { text } => DebugEvent::PrintToConsole(text),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
|
||||||
#[command(multicall = true)]
|
|
||||||
struct Cli {
|
|
||||||
#[command(subcommand)]
|
|
||||||
cmd: Commands,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Subcommand)]
|
|
||||||
enum Commands {
|
|
||||||
Close,
|
|
||||||
Echo { text: String },
|
|
||||||
}
|
|
|
@ -2,14 +2,15 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_skein::SkeinPlugin;
|
use bevy_skein::SkeinPlugin;
|
||||||
use bevy_ui_text_input::TextInputPlugin;
|
use bevy_ui_text_input::TextInputPlugin;
|
||||||
|
use clap::ValueEnum;
|
||||||
|
|
||||||
mod camera;
|
mod camera;
|
||||||
mod cleanup;
|
mod cleanup;
|
||||||
mod debugging;
|
mod debug;
|
||||||
mod game;
|
mod game;
|
||||||
mod menus;
|
mod menus;
|
||||||
|
|
||||||
#[derive(States, Default, Debug, Clone, PartialEq, Eq, Hash, Reflect)]
|
#[derive(States, Default, Debug, Clone, PartialEq, Eq, Hash, Reflect, ValueEnum)]
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
enum AppState {
|
enum AppState {
|
||||||
#[default]
|
#[default]
|
||||||
|
@ -23,7 +24,7 @@ fn main() {
|
||||||
.register_type::<TPCTarget>()
|
.register_type::<TPCTarget>()
|
||||||
.add_systems(Startup, camera::setup)
|
.add_systems(Startup, camera::setup)
|
||||||
.add_plugins((DefaultPlugins, TextInputPlugin))
|
.add_plugins((DefaultPlugins, TextInputPlugin))
|
||||||
.add_plugins((game::plugin, menus::plugin, debugging::plugin))
|
.add_plugins((game::plugin, menus::plugin, debug::plugin))
|
||||||
.add_plugins(SkeinPlugin::default())
|
.add_plugins(SkeinPlugin::default())
|
||||||
.init_state::<AppState>()
|
.init_state::<AppState>()
|
||||||
.register_type::<AppState>()
|
.register_type::<AppState>()
|
||||||
|
|
|
@ -5,6 +5,8 @@ use bevy::{
|
||||||
state::state::FreelyMutableState,
|
state::state::FreelyMutableState,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::cleanup::despawn;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
ItemPosition, MenuItemInternal, MenuItemType, OnPressAction,
|
ItemPosition, MenuItemInternal, MenuItemType, OnPressAction,
|
||||||
menus::{Menu, Menus},
|
menus::{Menu, Menus},
|
||||||
|
@ -30,7 +32,8 @@ where
|
||||||
update_ui_trigger::<NavState>,
|
update_ui_trigger::<NavState>,
|
||||||
handle_press_actions::<NavState>.run_if(in_state(self.trigger.clone())),
|
handle_press_actions::<NavState>.run_if(in_state(self.trigger.clone())),
|
||||||
),
|
),
|
||||||
);
|
)
|
||||||
|
.add_systems(OnExit(self.trigger.clone()), close_menu::<NavState>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +56,15 @@ impl<T: States, S: States> Menus<T, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn close_menu<S: States + FreelyMutableState>(
|
||||||
|
mut c: Commands,
|
||||||
|
mut nav_state: ResMut<NextState<S>>,
|
||||||
|
closed_when: Res<MenusClosedWhen<S>>,
|
||||||
|
) {
|
||||||
|
c.run_system_cached(despawn::<UiParent<S>>);
|
||||||
|
nav_state.set(closed_when.0.clone());
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
struct MenusStore<S: States>(HashMap<S, Menu<S>>);
|
struct MenusStore<S: States>(HashMap<S, Menu<S>>);
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
|
|
2
startup.tx
Normal file
2
startup.tx
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
log "hello from startup script!!"
|
||||||
|
start-game
|
6
test.tx
Normal file
6
test.tx
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
// test comment
|
||||||
|
echo hii
|
||||||
|
echo "meow"
|
||||||
|
|
||||||
|
echo 42
|
||||||
|
start-game
|
Loading…
Add table
Add a link
Reference in a new issue