mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added command to teleport to sites by name
This commit is contained in:
parent
f16c2b8b4c
commit
12cf8847c8
@ -80,6 +80,7 @@ pub enum ChatCommand {
|
||||
Safezone,
|
||||
Say,
|
||||
SetMotd,
|
||||
Site,
|
||||
SkillPoint,
|
||||
Spawn,
|
||||
Sudo,
|
||||
@ -140,6 +141,7 @@ pub static CHAT_COMMANDS: &[ChatCommand] = &[
|
||||
ChatCommand::Safezone,
|
||||
ChatCommand::Say,
|
||||
ChatCommand::SetMotd,
|
||||
ChatCommand::Site,
|
||||
ChatCommand::SkillPoint,
|
||||
ChatCommand::Spawn,
|
||||
ChatCommand::Sudo,
|
||||
@ -438,6 +440,9 @@ impl ChatCommand {
|
||||
ChatCommand::SetMotd => {
|
||||
cmd(vec![Message(Optional)], "Set the server description", Admin)
|
||||
},
|
||||
// Uses Message because site names can contain spaces, which would be assumed to be
|
||||
// separators otherwise
|
||||
ChatCommand::Site => cmd(vec![Message(Required)], "Teleport to a site", Admin),
|
||||
ChatCommand::SkillPoint => cmd(
|
||||
vec![
|
||||
Enum("skill tree", SKILL_TREES.clone(), Required),
|
||||
@ -546,6 +551,7 @@ impl ChatCommand {
|
||||
ChatCommand::Safezone => "safezone",
|
||||
ChatCommand::Say => "say",
|
||||
ChatCommand::SetMotd => "set_motd",
|
||||
ChatCommand::Site => "site",
|
||||
ChatCommand::SkillPoint => "skill_point",
|
||||
ChatCommand::Spawn => "spawn",
|
||||
ChatCommand::Sudo => "sudo",
|
||||
|
@ -127,6 +127,7 @@ fn get_handler(cmd: &ChatCommand) -> CommandHandler {
|
||||
ChatCommand::Safezone => handle_safezone,
|
||||
ChatCommand::Say => handle_say,
|
||||
ChatCommand::SetMotd => handle_set_motd,
|
||||
ChatCommand::Site => handle_site,
|
||||
ChatCommand::SkillPoint => handle_skill_point,
|
||||
ChatCommand::Spawn => handle_spawn,
|
||||
ChatCommand::Sudo => handle_sudo,
|
||||
@ -463,6 +464,91 @@ fn handle_goto(
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_site(
|
||||
server: &mut Server,
|
||||
client: EcsEntity,
|
||||
target: EcsEntity,
|
||||
args: String,
|
||||
action: &ChatCommand,
|
||||
) {
|
||||
if let Ok(dest_name) = scan_fmt!(&args, &action.arg_fmt(), String) {
|
||||
if server
|
||||
.state
|
||||
.read_component_copied::<comp::Pos>(target)
|
||||
.is_some()
|
||||
{
|
||||
match server.world.civs().sites().find(|site| {
|
||||
site.site_tmp
|
||||
.map_or(false, |id| server.index.sites[id].name() == dest_name)
|
||||
}) {
|
||||
Some(site) => {
|
||||
// The bulk of this code is to find the z coordinate to teleport to, searching
|
||||
// for the lowest available one. Copied nearly verbatim from server's lib.rs
|
||||
let dest_chunk = site.center;
|
||||
// Unwrapping because generate_chunk only returns err when should_continue evals
|
||||
// to true
|
||||
let (tc, _cs) = server
|
||||
.world
|
||||
.generate_chunk(server.index.as_index_ref(), dest_chunk, || false)
|
||||
.unwrap();
|
||||
let min_z = tc.get_min_z();
|
||||
let max_z = tc.get_max_z();
|
||||
|
||||
let pos = TerrainChunkSize::center_wpos(dest_chunk);
|
||||
let pos = Vec3::new(pos.x, pos.y, min_z);
|
||||
let pos = {
|
||||
use common::vol::ReadVol;
|
||||
(0..(max_z - min_z))
|
||||
.map(|z_diff| pos + Vec3::unit_z() * z_diff)
|
||||
.find(|test_pos| {
|
||||
let chunk_relative_xy =
|
||||
test_pos.xy().map2(TerrainChunkSize::RECT_SIZE, |e, sz| {
|
||||
e.rem_euclid(sz as i32)
|
||||
});
|
||||
tc.get(
|
||||
Vec3::new(chunk_relative_xy.x, chunk_relative_xy.y, test_pos.z)
|
||||
- Vec3::unit_z(),
|
||||
)
|
||||
.map_or(false, |b| b.is_filled())
|
||||
&& (0..3).all(|z| {
|
||||
tc.get(
|
||||
Vec3::new(
|
||||
chunk_relative_xy.x,
|
||||
chunk_relative_xy.y,
|
||||
test_pos.z,
|
||||
) + Vec3::unit_z() * z,
|
||||
)
|
||||
.map_or(true, |b| !b.is_solid())
|
||||
})
|
||||
})
|
||||
.unwrap_or(pos)
|
||||
.map(|e| e as f32)
|
||||
+ 0.5
|
||||
};
|
||||
server.state.write_component(target, comp::Pos(pos));
|
||||
server.state.write_component(target, comp::ForceUpdate);
|
||||
},
|
||||
None => {
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandError, "Site not found"),
|
||||
);
|
||||
},
|
||||
};
|
||||
} else {
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandError, "You have no position."),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandError, action.help_string()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_home(
|
||||
server: &mut Server,
|
||||
client: EcsEntity,
|
||||
|
Loading…
Reference in New Issue
Block a user