mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
force of mount in teleporting commands
This commit is contained in:
parent
e39790e9e4
commit
57551c479c
@ -461,6 +461,7 @@ impl ServerChatCommand {
|
|||||||
Float("x", 0.0, Required),
|
Float("x", 0.0, Required),
|
||||||
Float("y", 0.0, Required),
|
Float("y", 0.0, Required),
|
||||||
Float("z", 0.0, Required),
|
Float("z", 0.0, Required),
|
||||||
|
Boolean("Force from mount", "true".to_string(), Optional),
|
||||||
],
|
],
|
||||||
"Teleport to a position",
|
"Teleport to a position",
|
||||||
Some(Admin),
|
Some(Admin),
|
||||||
@ -505,6 +506,7 @@ impl ServerChatCommand {
|
|||||||
Float("x", 0.0, Required),
|
Float("x", 0.0, Required),
|
||||||
Float("y", 0.0, Required),
|
Float("y", 0.0, Required),
|
||||||
Float("z", 0.0, Required),
|
Float("z", 0.0, Required),
|
||||||
|
Boolean("Force from mount", "true".to_string(), Optional),
|
||||||
],
|
],
|
||||||
"Offset your current position",
|
"Offset your current position",
|
||||||
Some(Admin),
|
Some(Admin),
|
||||||
@ -637,7 +639,10 @@ impl ServerChatCommand {
|
|||||||
// Uses Message because site names can contain spaces,
|
// Uses Message because site names can contain spaces,
|
||||||
// which would be assumed to be separators otherwise
|
// which would be assumed to be separators otherwise
|
||||||
ServerChatCommand::Site => cmd(
|
ServerChatCommand::Site => cmd(
|
||||||
vec![SiteName(Required)],
|
vec![
|
||||||
|
SiteName(Required),
|
||||||
|
Boolean("Force from mount", "true".to_string(), Optional),
|
||||||
|
],
|
||||||
"Teleport to a site",
|
"Teleport to a site",
|
||||||
Some(Moderator),
|
Some(Moderator),
|
||||||
),
|
),
|
||||||
@ -681,12 +686,18 @@ impl ServerChatCommand {
|
|||||||
Some(Admin),
|
Some(Admin),
|
||||||
),
|
),
|
||||||
ServerChatCommand::Tp => cmd(
|
ServerChatCommand::Tp => cmd(
|
||||||
vec![PlayerName(Optional)],
|
vec![
|
||||||
|
PlayerName(Optional),
|
||||||
|
Boolean("Force from mount", "true".to_string(), Optional),
|
||||||
|
],
|
||||||
"Teleport to another player",
|
"Teleport to another player",
|
||||||
Some(Moderator),
|
Some(Moderator),
|
||||||
),
|
),
|
||||||
ServerChatCommand::RtsimTp => cmd(
|
ServerChatCommand::RtsimTp => cmd(
|
||||||
vec![Integer("npc index", 0, Required)],
|
vec![
|
||||||
|
Integer("npc index", 0, Required),
|
||||||
|
Boolean("Force from mount", "true".to_string(), Optional),
|
||||||
|
],
|
||||||
"Teleport to an rtsim npc",
|
"Teleport to an rtsim npc",
|
||||||
Some(Moderator),
|
Some(Moderator),
|
||||||
),
|
),
|
||||||
|
@ -40,7 +40,7 @@ use common::{
|
|||||||
event::{EventBus, ServerEvent},
|
event::{EventBus, ServerEvent},
|
||||||
generation::{EntityConfig, EntityInfo},
|
generation::{EntityConfig, EntityInfo},
|
||||||
link::Is,
|
link::Is,
|
||||||
mounting::Rider,
|
mounting::{Rider, VolumeRider},
|
||||||
npc::{self, get_npc_name},
|
npc::{self, get_npc_name},
|
||||||
outcome::Outcome,
|
outcome::Outcome,
|
||||||
parse_cmd_args,
|
parse_cmd_args,
|
||||||
@ -227,22 +227,52 @@ fn position_mut<T>(
|
|||||||
server: &mut Server,
|
server: &mut Server,
|
||||||
entity: EcsEntity,
|
entity: EcsEntity,
|
||||||
descriptor: &str,
|
descriptor: &str,
|
||||||
|
force_from_mount: Option<bool>,
|
||||||
f: impl for<'a> FnOnce(&'a mut comp::Pos) -> T,
|
f: impl for<'a> FnOnce(&'a mut comp::Pos) -> T,
|
||||||
) -> CmdResult<T> {
|
) -> CmdResult<T> {
|
||||||
// TODO: Handle volume mount
|
let entity = if force_from_mount.unwrap_or(false) {
|
||||||
let entity = server
|
server
|
||||||
.state
|
.state
|
||||||
.ecs()
|
.ecs()
|
||||||
.read_storage::<Is<Rider>>()
|
.write_storage::<Is<Rider>>()
|
||||||
.get(entity)
|
.remove(entity);
|
||||||
.and_then(|is_rider| {
|
server
|
||||||
server
|
.state
|
||||||
|
.ecs()
|
||||||
|
.write_storage::<Is<VolumeRider>>()
|
||||||
|
.remove(entity);
|
||||||
|
entity
|
||||||
|
} else {
|
||||||
|
server
|
||||||
|
.state
|
||||||
|
.read_storage::<Is<Rider>>()
|
||||||
|
.get(entity)
|
||||||
|
.and_then(|is_rider| {
|
||||||
|
server
|
||||||
|
.state
|
||||||
|
.ecs()
|
||||||
|
.read_resource::<UidAllocator>()
|
||||||
|
.retrieve_entity_internal(is_rider.mount.into())
|
||||||
|
})
|
||||||
|
.or(server
|
||||||
.state
|
.state
|
||||||
.ecs()
|
.read_storage::<Is<VolumeRider>>()
|
||||||
.read_resource::<UidAllocator>()
|
.get(entity)
|
||||||
.retrieve_entity_internal(is_rider.mount.into())
|
.and_then(|volume_rider| {
|
||||||
})
|
Some(match volume_rider.pos.kind {
|
||||||
.unwrap_or(entity);
|
common::mounting::Volume::Terrain => {
|
||||||
|
Err("Tried to move the world.".to_string())
|
||||||
|
},
|
||||||
|
common::mounting::Volume::Entity(uid) => Ok(server
|
||||||
|
.state
|
||||||
|
.ecs()
|
||||||
|
.read_resource::<UidAllocator>()
|
||||||
|
.retrieve_entity_internal(uid.into())?),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.transpose()?)
|
||||||
|
.unwrap_or(entity)
|
||||||
|
};
|
||||||
|
|
||||||
let mut maybe_pos = None;
|
let mut maybe_pos = None;
|
||||||
|
|
||||||
@ -830,8 +860,10 @@ fn handle_jump(
|
|||||||
args: Vec<String>,
|
args: Vec<String>,
|
||||||
action: &ServerChatCommand,
|
action: &ServerChatCommand,
|
||||||
) -> CmdResult<()> {
|
) -> CmdResult<()> {
|
||||||
if let (Some(x), Some(y), Some(z)) = parse_cmd_args!(args, f32, f32, f32) {
|
if let (Some(x), Some(y), Some(z), force_from_mount) =
|
||||||
position_mut(server, target, "target", |current_pos| {
|
parse_cmd_args!(args, f32, f32, f32, bool)
|
||||||
|
{
|
||||||
|
position_mut(server, target, "target", force_from_mount, |current_pos| {
|
||||||
current_pos.0 += Vec3::new(x, y, z)
|
current_pos.0 += Vec3::new(x, y, z)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -846,8 +878,10 @@ fn handle_goto(
|
|||||||
args: Vec<String>,
|
args: Vec<String>,
|
||||||
action: &ServerChatCommand,
|
action: &ServerChatCommand,
|
||||||
) -> CmdResult<()> {
|
) -> CmdResult<()> {
|
||||||
if let (Some(x), Some(y), Some(z)) = parse_cmd_args!(args, f32, f32, f32) {
|
if let (Some(x), Some(y), Some(z), force_from_mount) =
|
||||||
position_mut(server, target, "target", |current_pos| {
|
parse_cmd_args!(args, f32, f32, f32, bool)
|
||||||
|
{
|
||||||
|
position_mut(server, target, "target", force_from_mount, |current_pos| {
|
||||||
current_pos.0 = Vec3::new(x, y, z)
|
current_pos.0 = Vec3::new(x, y, z)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -865,7 +899,7 @@ fn handle_site(
|
|||||||
action: &ServerChatCommand,
|
action: &ServerChatCommand,
|
||||||
) -> CmdResult<()> {
|
) -> CmdResult<()> {
|
||||||
#[cfg(feature = "worldgen")]
|
#[cfg(feature = "worldgen")]
|
||||||
if let Some(dest_name) = parse_cmd_args!(args, String) {
|
if let (Some(dest_name), force_from_mount) = parse_cmd_args!(args, String, bool) {
|
||||||
let site = server
|
let site = server
|
||||||
.world
|
.world
|
||||||
.civs()
|
.civs()
|
||||||
@ -882,7 +916,7 @@ fn handle_site(
|
|||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
position_mut(server, target, "target", |current_pos| {
|
position_mut(server, target, "target", force_from_mount, |current_pos| {
|
||||||
current_pos.0 = site_pos
|
current_pos.0 = site_pos
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -907,7 +941,7 @@ fn handle_respawn(
|
|||||||
.ok_or("No waypoint set")?
|
.ok_or("No waypoint set")?
|
||||||
.get_pos();
|
.get_pos();
|
||||||
|
|
||||||
position_mut(server, target, "target", |current_pos| {
|
position_mut(server, target, "target", Some(true), |current_pos| {
|
||||||
current_pos.0 = waypoint;
|
current_pos.0 = waypoint;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -1206,7 +1240,8 @@ fn handle_tp(
|
|||||||
args: Vec<String>,
|
args: Vec<String>,
|
||||||
action: &ServerChatCommand,
|
action: &ServerChatCommand,
|
||||||
) -> CmdResult<()> {
|
) -> CmdResult<()> {
|
||||||
let player = if let Some(alias) = parse_cmd_args!(args, String) {
|
let (player, force_from_mount) = parse_cmd_args!(args, String, bool);
|
||||||
|
let player = if let Some(alias) = player {
|
||||||
find_alias(server.state.ecs(), &alias)?.0
|
find_alias(server.state.ecs(), &alias)?.0
|
||||||
} else if client != target {
|
} else if client != target {
|
||||||
client
|
client
|
||||||
@ -1214,7 +1249,7 @@ fn handle_tp(
|
|||||||
return Err(action.help_string());
|
return Err(action.help_string());
|
||||||
};
|
};
|
||||||
let player_pos = position(server, player, "player")?;
|
let player_pos = position(server, player, "player")?;
|
||||||
position_mut(server, target, "target", |target_pos| {
|
position_mut(server, target, "target", force_from_mount, |target_pos| {
|
||||||
*target_pos = player_pos
|
*target_pos = player_pos
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -1227,7 +1262,8 @@ fn handle_rtsim_tp(
|
|||||||
action: &ServerChatCommand,
|
action: &ServerChatCommand,
|
||||||
) -> CmdResult<()> {
|
) -> CmdResult<()> {
|
||||||
use crate::rtsim::RtSim;
|
use crate::rtsim::RtSim;
|
||||||
let pos = if let Some(id) = parse_cmd_args!(args, u32) {
|
let (npc_index, force_from_mount) = parse_cmd_args!(args, u32, bool);
|
||||||
|
let pos = if let Some(id) = npc_index {
|
||||||
// TODO: Take some other identifier than an integer to this command.
|
// TODO: Take some other identifier than an integer to this command.
|
||||||
server
|
server
|
||||||
.state
|
.state
|
||||||
@ -1243,7 +1279,7 @@ fn handle_rtsim_tp(
|
|||||||
} else {
|
} else {
|
||||||
return Err(action.help_string());
|
return Err(action.help_string());
|
||||||
};
|
};
|
||||||
position_mut(server, target, "target", |target_pos| {
|
position_mut(server, target, "target", force_from_mount, |target_pos| {
|
||||||
target_pos.0 = pos;
|
target_pos.0 = pos;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -3935,7 +3971,7 @@ fn handle_location(
|
|||||||
if let Some(name) = parse_cmd_args!(args, String) {
|
if let Some(name) = parse_cmd_args!(args, String) {
|
||||||
let loc = server.state.ecs().read_resource::<Locations>().get(&name);
|
let loc = server.state.ecs().read_resource::<Locations>().get(&name);
|
||||||
match loc {
|
match loc {
|
||||||
Ok(loc) => position_mut(server, target, "target", |target_pos| {
|
Ok(loc) => position_mut(server, target, "target", Some(true), |target_pos| {
|
||||||
target_pos.0 = loc;
|
target_pos.0 = loc;
|
||||||
}),
|
}),
|
||||||
Err(e) => Err(e.to_string()),
|
Err(e) => Err(e.to_string()),
|
||||||
|
@ -878,9 +878,7 @@ where
|
|||||||
pub fn get_sprites(
|
pub fn get_sprites(
|
||||||
&self,
|
&self,
|
||||||
body: Skel::Body,
|
body: Skel::Body,
|
||||||
) -> Option<
|
) -> Option<&[Instances<SpriteInstance>; SPRITE_LOD_LEVELS]> {
|
||||||
&[Instances<SpriteInstance>; SPRITE_LOD_LEVELS],
|
|
||||||
> {
|
|
||||||
let key = FigureKey {
|
let key = FigureKey {
|
||||||
body,
|
body,
|
||||||
item_key: None,
|
item_key: None,
|
||||||
|
@ -473,10 +473,15 @@ impl FigureMgrStates {
|
|||||||
.count()
|
.count()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_terrain_locals<'a, Q: ?Sized>(&'a self, body: &Body, entity: &Q) -> Option<&'a BoundTerrainLocals>
|
fn get_terrain_locals<'a, Q: ?Sized>(
|
||||||
|
&'a self,
|
||||||
|
body: &Body,
|
||||||
|
entity: &Q,
|
||||||
|
) -> Option<&'a BoundTerrainLocals>
|
||||||
where
|
where
|
||||||
EcsEntity: Borrow<Q>,
|
EcsEntity: Borrow<Q>,
|
||||||
Q: Hash + Eq, {
|
Q: Hash + Eq,
|
||||||
|
{
|
||||||
match body {
|
match body {
|
||||||
Body::Ship(body) => {
|
Body::Ship(body) => {
|
||||||
if matches!(body, ship::Body::Volume) {
|
if matches!(body, ship::Body::Volume) {
|
||||||
@ -486,7 +491,7 @@ impl FigureMgrStates {
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6345,8 +6350,9 @@ impl FigureMgr {
|
|||||||
// Don't render dead entities
|
// Don't render dead entities
|
||||||
.filter(|(_, _, _, _, health, _)| health.map_or(true, |h| !h.is_dead))
|
.filter(|(_, _, _, _, health, _)| health.map_or(true, |h| !h.is_dead))
|
||||||
{
|
{
|
||||||
if let Some((sprite_instances, data)) =
|
if let Some((sprite_instances, data)) = self
|
||||||
self.get_sprite_instances(entity, body, collider).zip(self.states.get_terrain_locals(body, &entity))
|
.get_sprite_instances(entity, body, collider)
|
||||||
|
.zip(self.states.get_terrain_locals(body, &entity))
|
||||||
{
|
{
|
||||||
let dist = collider
|
let dist = collider
|
||||||
.and_then(|collider| {
|
.and_then(|collider| {
|
||||||
@ -6973,8 +6979,7 @@ impl FigureMgr {
|
|||||||
entity: EcsEntity,
|
entity: EcsEntity,
|
||||||
body: &Body,
|
body: &Body,
|
||||||
collider: Option<&Collider>,
|
collider: Option<&Collider>,
|
||||||
) -> Option<
|
) -> Option<&'a [Instances<SpriteInstance>; SPRITE_LOD_LEVELS]> {
|
||||||
&'a [Instances<SpriteInstance>; SPRITE_LOD_LEVELS]> {
|
|
||||||
match body {
|
match body {
|
||||||
Body::Ship(body) => {
|
Body::Ship(body) => {
|
||||||
if let Some(Collider::Volume(vol)) = collider {
|
if let Some(Collider::Volume(vol)) = collider {
|
||||||
@ -7359,24 +7364,28 @@ pub trait FigureData: Sized {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FigureData for () {
|
impl FigureData for () {
|
||||||
fn new(_renderer: &mut Renderer) -> Self {
|
fn new(_renderer: &mut Renderer) {}
|
||||||
()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update(&mut self, _renderer: &mut Renderer, _parameters: &FigureUpdateCommonParameters) {
|
fn update(&mut self, _renderer: &mut Renderer, _parameters: &FigureUpdateCommonParameters) {}
|
||||||
()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FigureData for BoundTerrainLocals {
|
impl FigureData for BoundTerrainLocals {
|
||||||
fn new(renderer: &mut Renderer) -> Self {
|
fn new(renderer: &mut Renderer) -> Self {
|
||||||
renderer.create_terrain_bound_locals(&[TerrainLocals::new(Vec3::zero(), Quaternion::identity(), Vec2::zero(), 0.0)])
|
renderer.create_terrain_bound_locals(&[TerrainLocals::new(
|
||||||
|
Vec3::zero(),
|
||||||
|
Quaternion::identity(),
|
||||||
|
Vec2::zero(),
|
||||||
|
0.0,
|
||||||
|
)])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, renderer: &mut Renderer, parameters: &FigureUpdateCommonParameters) {
|
fn update(&mut self, renderer: &mut Renderer, parameters: &FigureUpdateCommonParameters) {
|
||||||
renderer.update_consts(self, &[
|
renderer.update_consts(self, &[TerrainLocals::new(
|
||||||
TerrainLocals::new(parameters.pos.into(), parameters.ori.into_vec4().into(), Vec2::zero(), 0.0),
|
parameters.pos.into(),
|
||||||
])
|
parameters.ori.into_vec4().into(),
|
||||||
|
Vec2::zero(),
|
||||||
|
0.0,
|
||||||
|
)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,10 +3,7 @@ use super::{
|
|||||||
load::{BodySpec, ShipBoneMeshes},
|
load::{BodySpec, ShipBoneMeshes},
|
||||||
EcsEntity,
|
EcsEntity,
|
||||||
};
|
};
|
||||||
use common::{
|
use common::{assets, comp::ship::figuredata::VoxelCollider};
|
||||||
assets,
|
|
||||||
comp::ship::figuredata::VoxelCollider,
|
|
||||||
};
|
|
||||||
use std::{convert::TryFrom, sync::Arc};
|
use std::{convert::TryFrom, sync::Arc};
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
|
Loading…
Reference in New Issue
Block a user