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,
|
Safezone,
|
||||||
Say,
|
Say,
|
||||||
SetMotd,
|
SetMotd,
|
||||||
|
Site,
|
||||||
SkillPoint,
|
SkillPoint,
|
||||||
Spawn,
|
Spawn,
|
||||||
Sudo,
|
Sudo,
|
||||||
@ -140,6 +141,7 @@ pub static CHAT_COMMANDS: &[ChatCommand] = &[
|
|||||||
ChatCommand::Safezone,
|
ChatCommand::Safezone,
|
||||||
ChatCommand::Say,
|
ChatCommand::Say,
|
||||||
ChatCommand::SetMotd,
|
ChatCommand::SetMotd,
|
||||||
|
ChatCommand::Site,
|
||||||
ChatCommand::SkillPoint,
|
ChatCommand::SkillPoint,
|
||||||
ChatCommand::Spawn,
|
ChatCommand::Spawn,
|
||||||
ChatCommand::Sudo,
|
ChatCommand::Sudo,
|
||||||
@ -438,6 +440,9 @@ impl ChatCommand {
|
|||||||
ChatCommand::SetMotd => {
|
ChatCommand::SetMotd => {
|
||||||
cmd(vec![Message(Optional)], "Set the server description", Admin)
|
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(
|
ChatCommand::SkillPoint => cmd(
|
||||||
vec![
|
vec![
|
||||||
Enum("skill tree", SKILL_TREES.clone(), Required),
|
Enum("skill tree", SKILL_TREES.clone(), Required),
|
||||||
@ -546,6 +551,7 @@ impl ChatCommand {
|
|||||||
ChatCommand::Safezone => "safezone",
|
ChatCommand::Safezone => "safezone",
|
||||||
ChatCommand::Say => "say",
|
ChatCommand::Say => "say",
|
||||||
ChatCommand::SetMotd => "set_motd",
|
ChatCommand::SetMotd => "set_motd",
|
||||||
|
ChatCommand::Site => "site",
|
||||||
ChatCommand::SkillPoint => "skill_point",
|
ChatCommand::SkillPoint => "skill_point",
|
||||||
ChatCommand::Spawn => "spawn",
|
ChatCommand::Spawn => "spawn",
|
||||||
ChatCommand::Sudo => "sudo",
|
ChatCommand::Sudo => "sudo",
|
||||||
|
@ -127,6 +127,7 @@ fn get_handler(cmd: &ChatCommand) -> CommandHandler {
|
|||||||
ChatCommand::Safezone => handle_safezone,
|
ChatCommand::Safezone => handle_safezone,
|
||||||
ChatCommand::Say => handle_say,
|
ChatCommand::Say => handle_say,
|
||||||
ChatCommand::SetMotd => handle_set_motd,
|
ChatCommand::SetMotd => handle_set_motd,
|
||||||
|
ChatCommand::Site => handle_site,
|
||||||
ChatCommand::SkillPoint => handle_skill_point,
|
ChatCommand::SkillPoint => handle_skill_point,
|
||||||
ChatCommand::Spawn => handle_spawn,
|
ChatCommand::Spawn => handle_spawn,
|
||||||
ChatCommand::Sudo => handle_sudo,
|
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(
|
fn handle_home(
|
||||||
server: &mut Server,
|
server: &mut Server,
|
||||||
client: EcsEntity,
|
client: EcsEntity,
|
||||||
|
Loading…
Reference in New Issue
Block a user