require interaction to start teleportation

This commit is contained in:
Maxicarlos08 2023-08-01 20:56:55 +02:00
parent 0929a3c76c
commit 92ab8dab9a
No known key found for this signature in database
11 changed files with 87 additions and 44 deletions

View File

@ -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

View File

@ -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

View File

@ -158,6 +158,7 @@ pub enum ControlEvent {
auxiliary_key: ability::AuxiliaryKey,
new_ability: ability::AuxiliaryAbility,
},
ActivatePortal(Uid),
}
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]

View File

@ -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,
}

View File

@ -336,6 +336,10 @@ pub enum ServerEvent {
entity: EcsEntity,
position: Vec3<f32>,
},
StartTeleporting {
entity: EcsEntity,
portal: EcsEntity,
}
}
pub struct EventBus<E> {

View File

@ -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,
});
}
}
}
}
}

View File

@ -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),
});
}
}

View File

@ -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)
},
}
}

View File

@ -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 {

View File

@ -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)

View File

@ -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);
}