mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
require interaction to start teleportation
This commit is contained in:
parent
0929a3c76c
commit
92ab8dab9a
@ -39,6 +39,7 @@ hud-auto_walk_indicator = Auto walk/swim active
|
||||
hud-zoom_lock_indicator-remind = Zoom locked
|
||||
hud-zoom_lock_indicator-enable = Camera zoom locked
|
||||
hud-zoom_lock_indicator-disable = Camera zoom unlocked
|
||||
hud-activate = Activate
|
||||
hud-collect = Collect
|
||||
hud-pick_up = Pick up
|
||||
hud-open = Open
|
||||
|
@ -1625,6 +1625,12 @@ impl Client {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn activate_portal(&mut self, portal: Uid) {
|
||||
self.send_msg(ClientGeneral::ControlEvent(ControlEvent::ActivatePortal(
|
||||
portal,
|
||||
)));
|
||||
}
|
||||
|
||||
fn control_action(&mut self, control_action: ControlAction) {
|
||||
if let Some(controller) = self
|
||||
.state
|
||||
|
@ -158,6 +158,7 @@ pub enum ControlEvent {
|
||||
auxiliary_key: ability::AuxiliaryKey,
|
||||
new_ability: ability::AuxiliaryAbility,
|
||||
},
|
||||
ActivatePortal(Uid),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
|
@ -17,7 +17,6 @@ impl Component for Teleporter {
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct Teleporting {
|
||||
pub teleport_start: Time,
|
||||
pub portal: Entity,
|
||||
pub end_time: Time,
|
||||
}
|
||||
|
@ -336,6 +336,10 @@ pub enum ServerEvent {
|
||||
entity: EcsEntity,
|
||||
position: Vec3<f32>,
|
||||
},
|
||||
StartTeleporting {
|
||||
entity: EcsEntity,
|
||||
portal: EcsEntity,
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EventBus<E> {
|
||||
|
@ -138,6 +138,14 @@ impl<'a> System<'a> for Sys {
|
||||
stance: Stance::None,
|
||||
});
|
||||
},
|
||||
ControlEvent::ActivatePortal(portal_uid) => {
|
||||
if let Some(portal) = read_data.id_maps.uid_entity(portal_uid) {
|
||||
server_emitter.emit(ServerEvent::StartTeleporting {
|
||||
entity,
|
||||
portal,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use crate::{
|
||||
BuffKind, BuffSource, PhysicsState,
|
||||
},
|
||||
rtsim,
|
||||
sys::terrain::SAFE_ZONE_RADIUS,
|
||||
sys::{teleporter::TELEPORT_RADIUS, terrain::SAFE_ZONE_RADIUS},
|
||||
Server, SpawnPoint, StateExt,
|
||||
};
|
||||
use authc::Uuid;
|
||||
@ -1657,11 +1657,7 @@ pub fn handle_remove_light_emitter(server: &mut Server, entity: EcsEntity) {
|
||||
.remove(entity);
|
||||
}
|
||||
|
||||
pub fn handle_teleport_to_position_event(
|
||||
server: &mut Server,
|
||||
entity: EcsEntity,
|
||||
position: Vec3<f32>,
|
||||
) {
|
||||
pub fn handle_teleport_to_position(server: &mut Server, entity: EcsEntity, position: Vec3<f32>) {
|
||||
let ecs = server.state.ecs();
|
||||
|
||||
ecs.write_storage::<comp::Pos>()
|
||||
@ -1673,3 +1669,34 @@ pub fn handle_teleport_to_position_event(
|
||||
.get_mut(entity)
|
||||
.map(|forced_update| forced_update.update());
|
||||
}
|
||||
|
||||
pub fn handle_start_teleporting(server: &mut Server, entity: EcsEntity, portal: EcsEntity) {
|
||||
let ecs = server.state.ecs();
|
||||
let positions = ecs.read_storage::<comp::Pos>();
|
||||
let mut teleportings = ecs.write_storage::<comp::Teleporting>();
|
||||
let now = ecs.read_resource::<Time>().0;
|
||||
|
||||
if let Some(end_time) = (!teleportings.contains(entity))
|
||||
.then(|| positions.get(entity))
|
||||
.flatten()
|
||||
.zip(positions.get(portal))
|
||||
.filter(|(entity_pos, portal_pos)| {
|
||||
entity_pos.0.distance_squared(portal_pos.0) <= TELEPORT_RADIUS.powi(2)
|
||||
})
|
||||
.and_then(|(_, _)| {
|
||||
Some(
|
||||
now + ecs
|
||||
.read_storage::<comp::Teleporter>()
|
||||
.get(portal)?
|
||||
.buildup_time
|
||||
.0,
|
||||
)
|
||||
})
|
||||
{
|
||||
let _ = teleportings
|
||||
.insert(entity, comp::Teleporting {
|
||||
portal,
|
||||
end_time: Time(end_time),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
events::{
|
||||
entity_creation::handle_create_teleporter,
|
||||
entity_manipulation::handle_teleport_to_position_event,
|
||||
entity_manipulation::{handle_start_teleporting, handle_teleport_to_position},
|
||||
interaction::{handle_mount_volume, handle_tame_pet},
|
||||
},
|
||||
persistence::PersistedComponents,
|
||||
@ -301,7 +301,10 @@ impl Server {
|
||||
handle_remove_light_emitter(self, entity)
|
||||
},
|
||||
ServerEvent::TeleportToPosition { entity, position } => {
|
||||
handle_teleport_to_position_event(self, entity, position)
|
||||
handle_teleport_to_position(self, entity, position)
|
||||
},
|
||||
ServerEvent::StartTeleporting { entity, portal } => {
|
||||
handle_start_teleporting(self, entity, portal)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use common_ecs::{Origin, Phase, System};
|
||||
use specs::{Entities, Entity, Join, Read, ReadStorage, WriteStorage};
|
||||
use vek::Vec3;
|
||||
|
||||
const TELEPORT_RADIUS: f32 = 3.;
|
||||
pub const TELEPORT_RADIUS: f32 = 3.;
|
||||
const MAX_AGGRO_DIST: f32 = 200.; // If an entity further than this is aggroed at a player, the portal will still work
|
||||
|
||||
#[derive(Default)]
|
||||
@ -88,8 +88,10 @@ impl<'a> System<'a> for Sys {
|
||||
.filter(|(_, pos, _, _)| in_portal_range(pos.0, teleporter_pos.0))
|
||||
})
|
||||
{
|
||||
if !matches!(character_state, CharacterState::Dance)
|
||||
|| (teleporter.requires_no_aggro && check_aggro(entity, pos.0))
|
||||
if !matches!(
|
||||
character_state,
|
||||
CharacterState::Idle(_) | CharacterState::Wielding(_)
|
||||
) || (teleporter.requires_no_aggro && check_aggro(entity, pos.0))
|
||||
{
|
||||
if teleporting.is_some() {
|
||||
teleporting_updates.push((entity, None));
|
||||
@ -98,18 +100,7 @@ impl<'a> System<'a> for Sys {
|
||||
continue;
|
||||
}
|
||||
|
||||
if teleporting.is_none() {
|
||||
teleporting_updates.push((
|
||||
entity,
|
||||
Some(Teleporting {
|
||||
teleport_start: *time,
|
||||
portal: portal_entity,
|
||||
end_time: Time(time.0 + teleporter.buildup_time.0),
|
||||
}),
|
||||
));
|
||||
}
|
||||
|
||||
is_active = true;
|
||||
is_active |= teleporting.is_some();
|
||||
}
|
||||
|
||||
if (*body == Body::Object(object::Body::PortalActive)) != is_active {
|
||||
|
@ -2250,7 +2250,7 @@ impl Hud {
|
||||
&global_state.window.key_layout,
|
||||
vec![(
|
||||
Some(GameInput::Interact),
|
||||
i18n.get_msg(if is_campfire { "hud-sit" } else { "gameinput-dance" }).to_string(),
|
||||
i18n.get_msg(if is_campfire { "hud-sit" } else { "hud-activate" }).to_string(),
|
||||
)],
|
||||
)
|
||||
.x_y(0.0, 100.0)
|
||||
|
@ -1027,6 +1027,13 @@ impl PlayState for SessionState {
|
||||
}
|
||||
},
|
||||
Interactable::Entity(entity) => {
|
||||
let body = client
|
||||
.state()
|
||||
.ecs()
|
||||
.read_storage::<comp::Body>()
|
||||
.get(*entity)
|
||||
.map(ToOwned::to_owned);
|
||||
|
||||
if client
|
||||
.state()
|
||||
.ecs()
|
||||
@ -1035,25 +1042,21 @@ impl PlayState for SessionState {
|
||||
.is_some()
|
||||
{
|
||||
client.pick_up(*entity);
|
||||
} else if let Some(is_campfire) = {
|
||||
let bodies = client
|
||||
.state()
|
||||
.ecs()
|
||||
.read_storage::<comp::Body>();
|
||||
|
||||
bodies
|
||||
.get(*entity)
|
||||
.filter(|body| {
|
||||
body.is_campfire() || body.is_portal()
|
||||
})
|
||||
.map(|body| body.is_campfire())
|
||||
} {
|
||||
if is_campfire {
|
||||
// TODO: maybe start crafting instead?
|
||||
client.toggle_sit();
|
||||
} else {
|
||||
client.toggle_dance();
|
||||
}
|
||||
} else if body
|
||||
.map_or(false, |body| body.is_campfire())
|
||||
{
|
||||
client.toggle_sit();
|
||||
} else if let Some(portal_uid) = body
|
||||
.map_or(false, |body| body.is_portal())
|
||||
.then(|| {
|
||||
client
|
||||
.state()
|
||||
.ecs()
|
||||
.uid_from_entity(*entity)
|
||||
})
|
||||
.flatten()
|
||||
{
|
||||
client.activate_portal(portal_uid);
|
||||
} else {
|
||||
client.npc_interact(*entity, Subject::Regular);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user