diff --git a/rust/src/chat.rs b/rust/src/chat.rs index b74b004..20f9430 100644 --- a/rust/src/chat.rs +++ b/rust/src/chat.rs @@ -61,6 +61,10 @@ impl ChatMessage { add_player(&mut label, &player); label.append_text(&kind.as_kill_text()); } + DamageSource::God => { + add_player(&mut label, &player); + label.append_text(" was removed from the world by godly forces"); + } } } } diff --git a/rust/src/game_manager.rs b/rust/src/game_manager.rs index 216a144..0f0e1af 100644 --- a/rust/src/game_manager.rs +++ b/rust/src/game_manager.rs @@ -29,7 +29,7 @@ use crate::{ }, replay::{ReplayEvent, ReplayPlayback, ReplayRecorder}, team_resource::TeamResource, - ui::cli::{Command, CommandLinePanel}, + ui::cli::{CliColor, Command, CommandLinePanel}, }; pub const GAME_MANAGER_GLOBAL: &str = "GameManagerGlobal"; @@ -248,6 +248,45 @@ impl Command for RespawnBallCommand { } } +pub struct ListPlayersCommand; +impl Command for ListPlayersCommand { + fn execute(&self, cli: &mut CommandLinePanel, _: &[&str]) { + if let Some(game) = &mut Game::singleton() { + for player in &game.bind().players { + cli.publish_message( + format!(" - {} ({})", player.data.name, player.id()), + CliColor::Info, + ); + } + } + } + + fn help(&self) -> &str { + "lists all players" + } +} + +pub struct KillCommand; +impl Command for KillCommand { + fn execute(&self, cli: &mut CommandLinePanel, args: &[&str]) { + if let Some(player_str) = args.first() { + if let Ok(player_id) = player_str.parse() { + if let Some(game) = &mut Game::singleton() { + game.bind_mut().kill_player(player_id); + } + } else { + cli.publish_message("Invalid player id".to_string(), CliColor::Error); + } + } else { + cli.publish_message("Usage: kill [player_id]".to_string(), CliColor::Error); + } + } + + fn help(&self) -> &str { + "kills given player" + } +} + #[derive(GodotClass)] #[class(base=Node, init)] pub struct Game { @@ -483,6 +522,10 @@ impl Game { let mut cli = CommandLinePanel::singleton(); cli.bind_mut() .register_command("respawn_ball".to_string(), Box::new(RespawnBallCommand)); + cli.bind_mut() + .register_command("players".to_string(), Box::new(ListPlayersCommand)); + cli.bind_mut() + .register_command("kill".to_string(), Box::new(KillCommand)); } } }); @@ -553,6 +596,8 @@ impl Game { let mut cli = CommandLinePanel::singleton(); cli.bind_mut() .unregister_command("respawn_ball".to_string()); + cli.bind_mut().unregister_command("players".to_string()); + cli.bind_mut().unregister_command("kill".to_string()); } pub fn change_option(&mut self, opt: GameOption, value: GameOptionValue) { @@ -1287,6 +1332,17 @@ impl Game { } } + // Used to kill the player from the serverside via a command + pub fn kill_player(&mut self, target_player_id: u16) { + if let Some(player) = self.find_player_mut(target_player_id) + && let Some(character) = &mut player.character + { + character + .dyn_bind_mut() + .take_damage(DamageSource::God, 1000, true); + } + } + pub fn recorder(&mut self) -> &mut Option> { &mut self.replay_recorder } diff --git a/rust/src/player/mod.rs b/rust/src/player/mod.rs index 6bd1b70..4092142 100644 --- a/rust/src/player/mod.rs +++ b/rust/src/player/mod.rs @@ -316,6 +316,7 @@ impl PlayerCommon for T { pub enum DamageSource { Player(u16), Killbox(KillboxKind), + God, } impl DamageSource { @@ -323,6 +324,7 @@ impl DamageSource { match self { DamageSource::Player(id) => (DamageSourceSignal::Player, *id, KillboxKind::default()), DamageSource::Killbox(kind) => (DamageSourceSignal::Killbox, 0, *kind), + DamageSource::God => (DamageSourceSignal::God, 0, KillboxKind::default()), } } @@ -330,6 +332,7 @@ impl DamageSource { match signal { DamageSourceSignal::Player => DamageSource::Player(player), DamageSourceSignal::Killbox => DamageSource::Killbox(kind), + DamageSourceSignal::God => DamageSource::God, } } } @@ -339,4 +342,5 @@ impl DamageSource { pub enum DamageSourceSignal { Player, Killbox, + God, }