mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
refactor teleporter system and include nearby pets
This commit is contained in:
parent
92ab8dab9a
commit
0c9a942027
@ -693,7 +693,6 @@ void main() {
|
|||||||
spin_in_axis(vec3(rand6, rand7, rand8), rand9 * 3 + lifetime * 5)
|
spin_in_axis(vec3(rand6, rand7, rand8), rand9 * 3 + lifetime * 5)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
<<<<<<< HEAD
|
|
||||||
case INK:
|
case INK:
|
||||||
f_reflect = 0.0; // Magic water doesn't reflect light, it emits it
|
f_reflect = 0.0; // Magic water doesn't reflect light, it emits it
|
||||||
float black_color = 0.3 + 0.2 * rand3 + 0.3 * max(floor(rand4 + 0.3), 0.0);
|
float black_color = 0.3 + 0.2 * rand3 + 0.3 * max(floor(rand4 + 0.3), 0.0);
|
||||||
@ -703,7 +702,8 @@ void main() {
|
|||||||
vec3(ink_size),
|
vec3(ink_size),
|
||||||
vec4(0.5 * black_color, 0.75 * black_color, black_color, 1),
|
vec4(0.5 * black_color, 0.75 * black_color, black_color, 1),
|
||||||
spin_in_axis(vec3(rand6, rand7, rand8), percent() * 10 + 3 * rand9)
|
spin_in_axis(vec3(rand6, rand7, rand8), percent() * 10 + 3 * rand9)
|
||||||
=======
|
);
|
||||||
|
break;
|
||||||
case UPWARD_PORTAL_FIZZ:
|
case UPWARD_PORTAL_FIZZ:
|
||||||
f_reflect = 0.0;
|
f_reflect = 0.0;
|
||||||
attr = Attr(
|
attr = Attr(
|
||||||
@ -711,7 +711,6 @@ void main() {
|
|||||||
vec3(max(1.0, 0.05 * length(start_pos + inst_dir * percent()))),
|
vec3(max(1.0, 0.05 * length(start_pos + inst_dir * percent()))),
|
||||||
vec4(vec3(1.23, 1.41, 1.44), 1.0),// * (1.0 - length(inst_dir) * 0.1),
|
vec4(vec3(1.23, 1.41, 1.44), 1.0),// * (1.0 - length(inst_dir) * 0.1),
|
||||||
identity()//spin_in_axis(perp_axis, asin(inst_dir.z / length(inst_dir)) + PI / 2.0)
|
identity()//spin_in_axis(perp_axis, asin(inst_dir.z / length(inst_dir)) + PI / 2.0)
|
||||||
>>>>>>> 70e6945e87 (portal particles)
|
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -331,7 +331,7 @@ impl Body {
|
|||||||
Body::LightningBolt => "lightning_bolt",
|
Body::LightningBolt => "lightning_bolt",
|
||||||
Body::SpearIcicle => "spear_icicle",
|
Body::SpearIcicle => "spear_icicle",
|
||||||
Body::Portal => "portal",
|
Body::Portal => "portal",
|
||||||
Self::PortalActive => "portal_active",
|
Body::PortalActive => "portal_active",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,7 +339,7 @@ pub enum ServerEvent {
|
|||||||
StartTeleporting {
|
StartTeleporting {
|
||||||
entity: EcsEntity,
|
entity: EcsEntity,
|
||||||
portal: EcsEntity,
|
portal: EcsEntity,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EventBus<E> {
|
pub struct EventBus<E> {
|
||||||
|
@ -140,12 +140,9 @@ impl<'a> System<'a> for Sys {
|
|||||||
},
|
},
|
||||||
ControlEvent::ActivatePortal(portal_uid) => {
|
ControlEvent::ActivatePortal(portal_uid) => {
|
||||||
if let Some(portal) = read_data.id_maps.uid_entity(portal_uid) {
|
if let Some(portal) = read_data.id_maps.uid_entity(portal_uid) {
|
||||||
server_emitter.emit(ServerEvent::StartTeleporting {
|
server_emitter.emit(ServerEvent::StartTeleporting { entity, portal });
|
||||||
entity,
|
|
||||||
portal,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1693,10 +1693,9 @@ pub fn handle_start_teleporting(server: &mut Server, entity: EcsEntity, portal:
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
let _ = teleportings
|
let _ = teleportings.insert(entity, comp::Teleporting {
|
||||||
.insert(entity, comp::Teleporting {
|
portal,
|
||||||
portal,
|
end_time: Time(end_time),
|
||||||
end_time: Time(end_time),
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
use common::{
|
use common::{
|
||||||
comp::{object, Agent, Body, CharacterState, Pos, Teleporter, Teleporting},
|
comp::{object, Agent, Alignment, Body, CharacterState, Pos, Teleporter, Teleporting},
|
||||||
event::{EventBus, ServerEvent},
|
event::{EventBus, ServerEvent},
|
||||||
resources::Time,
|
resources::Time,
|
||||||
|
uid::Uid,
|
||||||
CachedSpatialGrid,
|
CachedSpatialGrid,
|
||||||
};
|
};
|
||||||
use common_ecs::{Origin, Phase, System};
|
use common_ecs::{Origin, Phase, System};
|
||||||
use specs::{Entities, Entity, Join, Read, ReadStorage, WriteStorage};
|
use specs::{Entities, Join, Read, ReadStorage, WriteStorage};
|
||||||
use vek::Vec3;
|
use vek::Vec3;
|
||||||
|
|
||||||
pub 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
|
const MAX_AGGRO_DIST: f32 = 200.; // If an entity further than this is aggroed at a player, the portal will still work
|
||||||
|
const PET_TELEPORT_RADIUS: f32 = 20.;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Sys;
|
pub struct Sys;
|
||||||
@ -22,7 +24,9 @@ impl<'a> System<'a> for Sys {
|
|||||||
type SystemData = (
|
type SystemData = (
|
||||||
Entities<'a>,
|
Entities<'a>,
|
||||||
ReadStorage<'a, Pos>,
|
ReadStorage<'a, Pos>,
|
||||||
|
ReadStorage<'a, Uid>,
|
||||||
ReadStorage<'a, Teleporter>,
|
ReadStorage<'a, Teleporter>,
|
||||||
|
ReadStorage<'a, Alignment>,
|
||||||
ReadStorage<'a, Agent>,
|
ReadStorage<'a, Agent>,
|
||||||
WriteStorage<'a, Teleporting>,
|
WriteStorage<'a, Teleporting>,
|
||||||
ReadStorage<'a, Body>,
|
ReadStorage<'a, Body>,
|
||||||
@ -41,7 +45,9 @@ impl<'a> System<'a> for Sys {
|
|||||||
(
|
(
|
||||||
entities,
|
entities,
|
||||||
positions,
|
positions,
|
||||||
|
uids,
|
||||||
teleporters,
|
teleporters,
|
||||||
|
alignments,
|
||||||
agent,
|
agent,
|
||||||
mut teleporting,
|
mut teleporting,
|
||||||
bodies,
|
bodies,
|
||||||
@ -64,44 +70,20 @@ impl<'a> System<'a> for Sys {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut teleporting_updates = Vec::new();
|
let mut cancel_teleporting = Vec::new();
|
||||||
|
|
||||||
for (portal_entity, teleporter_pos, body, teleporter) in
|
for (portal_entity, teleporter_pos, body, _) in
|
||||||
(&entities, &positions, &bodies, &teleporters).join()
|
(&entities, &positions, &bodies, &teleporters).join()
|
||||||
{
|
{
|
||||||
let nearby_entities = spatial_grid
|
let is_active = spatial_grid
|
||||||
.0
|
.0
|
||||||
.in_circle_aabr(teleporter_pos.0.xy(), TELEPORT_RADIUS);
|
.in_circle_aabr(teleporter_pos.0.xy(), TELEPORT_RADIUS)
|
||||||
|
.any(|entity| {
|
||||||
let mut is_active = false;
|
(&positions, &teleporting)
|
||||||
|
|
||||||
for (entity, pos, character_state, teleporting) in
|
|
||||||
nearby_entities.filter_map(|entity| {
|
|
||||||
(
|
|
||||||
&entities,
|
|
||||||
&positions,
|
|
||||||
&character_states,
|
|
||||||
teleporting.maybe(),
|
|
||||||
)
|
|
||||||
.join()
|
.join()
|
||||||
.get(entity, &entities)
|
.get(entity, &entities)
|
||||||
.filter(|(_, pos, _, _)| in_portal_range(pos.0, teleporter_pos.0))
|
.map_or(false, |(pos, _)| in_portal_range(pos.0, teleporter_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));
|
|
||||||
};
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
is_active |= teleporting.is_some();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*body == Body::Object(object::Body::PortalActive)) != is_active {
|
if (*body == Body::Object(object::Body::PortalActive)) != is_active {
|
||||||
event_bus.emit_now(ServerEvent::ChangeBody {
|
event_bus.emit_now(ServerEvent::ChangeBody {
|
||||||
@ -115,41 +97,58 @@ impl<'a> System<'a> for Sys {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update_teleporting(&mut teleporting_updates, &mut teleporting);
|
for (entity, uid, position, teleporting, character_state) in (
|
||||||
|
&entities,
|
||||||
for (entity, position, teleporting) in (&entities, &positions, &teleporting).join() {
|
&uids,
|
||||||
let mut remove = || teleporting_updates.push((entity, None));
|
&positions,
|
||||||
|
&teleporting,
|
||||||
|
&character_states,
|
||||||
|
)
|
||||||
|
.join()
|
||||||
|
{
|
||||||
let portal_pos = positions.get(teleporting.portal);
|
let portal_pos = positions.get(teleporting.portal);
|
||||||
let Some(teleporter) = teleporters.get(teleporting.portal) else {
|
let Some(teleporter) = teleporters.get(teleporting.portal) else {
|
||||||
remove();
|
cancel_teleporting.push(entity);
|
||||||
continue
|
continue
|
||||||
};
|
};
|
||||||
|
|
||||||
if portal_pos.map_or(true, |portal_pos| {
|
if portal_pos.map_or(true, |portal_pos| {
|
||||||
!in_portal_range(position.0, portal_pos.0)
|
!in_portal_range(position.0, portal_pos.0)
|
||||||
}) {
|
}) || (teleporter.requires_no_aggro && check_aggro(entity, position.0))
|
||||||
remove();
|
|| !matches!(
|
||||||
|
character_state,
|
||||||
|
CharacterState::Idle(_) | CharacterState::Wielding(_)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
cancel_teleporting.push(entity);
|
||||||
} else if teleporting.end_time.0 <= time.0 {
|
} else if teleporting.end_time.0 <= time.0 {
|
||||||
remove();
|
// Send teleport events for all nearby pets and the owner
|
||||||
event_bus.emit_now(ServerEvent::TeleportToPosition {
|
let nearby = spatial_grid
|
||||||
entity,
|
.0
|
||||||
position: teleporter.target,
|
.in_circle_aabr(position.0.xy(), PET_TELEPORT_RADIUS)
|
||||||
});
|
.filter_map(|entity| {
|
||||||
|
(&entities, &positions, &alignments)
|
||||||
|
.join()
|
||||||
|
.get(entity, &entities)
|
||||||
|
})
|
||||||
|
.filter_map(|(entity, entity_position, alignment)| {
|
||||||
|
(matches!(alignment, Alignment::Owned(entity_uid) if entity_uid == uid)
|
||||||
|
&& entity_position.0.distance_squared(position.0)
|
||||||
|
<= PET_TELEPORT_RADIUS.powi(2))
|
||||||
|
.then_some(entity)
|
||||||
|
});
|
||||||
|
|
||||||
|
for entity in nearby {
|
||||||
|
cancel_teleporting.push(entity);
|
||||||
|
event_bus.emit_now(ServerEvent::TeleportToPosition {
|
||||||
|
entity,
|
||||||
|
position: teleporter.target,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update_teleporting(&mut teleporting_updates, &mut teleporting);
|
for entity in cancel_teleporting {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_teleporting(
|
|
||||||
updates: &mut Vec<(Entity, Option<Teleporting>)>,
|
|
||||||
teleporting: &mut WriteStorage<'_, Teleporting>,
|
|
||||||
) {
|
|
||||||
for (entity, update) in updates.drain(..) {
|
|
||||||
if let Some(add) = update {
|
|
||||||
let _ = teleporting.insert(entity, add);
|
|
||||||
} else {
|
|
||||||
let _ = teleporting.remove(entity);
|
let _ = teleporting.remove(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1029,10 +1029,7 @@ impl PlayState for SessionState {
|
|||||||
Interactable::Entity(entity) => {
|
Interactable::Entity(entity) => {
|
||||||
let body = client
|
let body = client
|
||||||
.state()
|
.state()
|
||||||
.ecs()
|
.read_component_cloned::<comp::Body>(*entity);
|
||||||
.read_storage::<comp::Body>()
|
|
||||||
.get(*entity)
|
|
||||||
.map(ToOwned::to_owned);
|
|
||||||
|
|
||||||
if client
|
if client
|
||||||
.state()
|
.state()
|
||||||
|
Loading…
Reference in New Issue
Block a user