client shorthands

This commit is contained in:
Isse 2023-11-22 23:40:13 +01:00
parent 34edfdb7a2
commit 51c67d7394
2 changed files with 79 additions and 10 deletions

View File

@ -1,11 +1,23 @@
use std::str::FromStr; use std::str::FromStr;
use crate::{ use crate::{
render::ExperimentalShader, session::settings_change::change_render_mode, GlobalState, render::ExperimentalShader,
session::{settings_change::change_render_mode, SessionState},
GlobalState,
}; };
use client::Client; use client::Client;
use common::{cmd::*, comp::Admin, parse_cmd_args, uuid::Uuid}; use common::{
cmd::*,
comp::Admin,
link::Is,
mounting::{Mount, Rider, VolumeRider},
parse_cmd_args,
resources::PlayerEntity,
uuid::Uuid,
};
use common_net::sync::WorldSyncExt;
use levenshtein::levenshtein; use levenshtein::levenshtein;
use specs::WorldExt;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
// Please keep this sorted alphabetically, same as with server commands :-) // Please keep this sorted alphabetically, same as with server commands :-)
@ -148,12 +160,70 @@ type CommandResult = Result<Option<String>, String>;
// Note: it's not clear what data future commands will need access to, so the // Note: it's not clear what data future commands will need access to, so the
// signature of this function might change // signature of this function might change
pub fn run_command( pub fn run_command(
client: &mut Client, session_state: &mut SessionState,
global_state: &mut GlobalState, global_state: &mut GlobalState,
cmd: &str, cmd: &str,
args: Vec<String>, mut args: Vec<String>,
) -> CommandResult { ) -> CommandResult {
let command = ChatCommandKind::from_str(cmd); let command = ChatCommandKind::from_str(cmd);
let client = &mut session_state.client.borrow_mut();
let ecs = client.state().ecs();
let player = ecs.read_resource::<PlayerEntity>().0;
for arg in args.iter_mut() {
if arg.starts_with('@') {
let uid = match arg.trim_start_matches('@') {
"target" => session_state
.target_entity
.and_then(|e| ecs.uid_from_entity(e))
.ok_or("Not looking at a valid target".to_string())?,
"selected" => session_state
.selected_entity
.and_then(|(e, _)| ecs.uid_from_entity(e))
.ok_or("You don't have a valid target selected".to_string())?,
"viewpoint" => session_state
.viewpoint_entity
.and_then(|e| ecs.uid_from_entity(e))
.ok_or("Not viewing from a valid viewpoint entity".to_string())?,
"mount" => {
if let Some(player) = player {
ecs.read_storage::<Is<Rider>>()
.get(player)
.map(|is_rider| is_rider.mount)
.or(ecs.read_storage::<Is<VolumeRider>>().get(player).and_then(
|is_rider| match is_rider.pos.kind {
common::mounting::Volume::Terrain => None,
common::mounting::Volume::Entity(uid) => Some(uid),
},
))
.ok_or("Not riding a valid entity".to_string())?
} else {
return Err("No player entity".to_string());
}
},
"rider" => {
if let Some(player) = player {
ecs.read_storage::<Is<Mount>>()
.get(player)
.map(|is_mount| is_mount.rider)
.ok_or("No valid rider".to_string())?
} else {
return Err("No player entity".to_string());
}
},
"self" => player
.and_then(|e| ecs.uid_from_entity(e))
.ok_or("No player entity")?,
ident => {
return Err(format!(
"Expected target/selected/viewpoint/mount/rider found {ident}"
));
},
};
let uid = u64::from(uid);
*arg = format!("uid@{uid}");
}
}
match command { match command {
Ok(ChatCommandKind::Server(cmd)) => { Ok(ChatCommandKind::Server(cmd)) => {

View File

@ -90,7 +90,7 @@ enum TickAction {
pub struct SessionState { pub struct SessionState {
scene: Scene, scene: Scene,
client: Rc<RefCell<Client>>, pub(crate) client: Rc<RefCell<Client>>,
metadata: UpdateCharacterMetadata, metadata: UpdateCharacterMetadata,
hud: Hud, hud: Hud,
key_state: KeyState, key_state: KeyState,
@ -104,9 +104,9 @@ pub struct SessionState {
camera_clamp: bool, camera_clamp: bool,
zoom_lock: bool, zoom_lock: bool,
is_aiming: bool, is_aiming: bool,
target_entity: Option<specs::Entity>, pub(crate) target_entity: Option<specs::Entity>,
selected_entity: Option<(specs::Entity, std::time::Instant)>, pub(crate) selected_entity: Option<(specs::Entity, std::time::Instant)>,
viewpoint_entity: Option<specs::Entity>, pub(crate) viewpoint_entity: Option<specs::Entity>,
interactable: Option<Interactable>, interactable: Option<Interactable>,
#[cfg(not(target_os = "macos"))] #[cfg(not(target_os = "macos"))]
mumble_link: SharedLink, mumble_link: SharedLink,
@ -1530,8 +1530,7 @@ impl PlayState for SessionState {
self.client.borrow_mut().send_chat(msg); self.client.borrow_mut().send_chat(msg);
}, },
HudEvent::SendCommand(name, args) => { HudEvent::SendCommand(name, args) => {
match run_command(&mut self.client.borrow_mut(), global_state, &name, args) match run_command(self, global_state, &name, args) {
{
Ok(Some(info)) => { Ok(Some(info)) => {
// TODO: Localise // TODO: Localise
self.hud self.hud