addressed review comments

This commit is contained in:
Maxicarlos08 2023-07-24 09:58:32 +02:00
parent e5fe64ccf6
commit 8fe5f2e708
No known key found for this signature in database
7 changed files with 84 additions and 108 deletions

View File

@ -34,7 +34,7 @@ pub mod projectile;
pub mod shockwave;
pub mod skillset;
mod stats;
mod teleport;
pub mod teleport;
pub mod visual;
// Reexports

View File

@ -4,6 +4,11 @@ use vek::Vec3;
use crate::resources::{Secs, Time};
pub enum TeleporterEvent {
PortalTeleport { entity: Entity, target: Vec3<f32> },
SetPortalActive { portal: Entity, active: bool },
}
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Teleporter {
pub target: Vec3<f32>,

View File

@ -332,6 +332,7 @@ pub enum ServerEvent {
RemoveLightEmitter {
entity: EcsEntity,
},
PortalEvent(comp::teleport::TeleporterEvent),
}
pub struct EventBus<E> {

View File

@ -21,6 +21,8 @@ use common::{
inventory::item::{AbilityMap, MaterialStatManifest},
item::flatten_counted_items,
loot_owner::LootOwnerKind,
object,
teleport::TeleporterEvent,
Alignment, Auras, Body, CharacterState, Energy, Group, Health, HealthChange, Inventory,
Player, Poise, Pos, SkillSet, Stats,
},
@ -1656,3 +1658,31 @@ pub fn handle_remove_light_emitter(server: &mut Server, entity: EcsEntity) {
.write_storage::<comp::LightEmitter>()
.remove(entity);
}
pub fn handle_portal_event(server: &mut Server, event: TeleporterEvent) {
let ecs = server.state.ecs();
match event {
TeleporterEvent::PortalTeleport { entity, target } => {
ecs.write_storage::<comp::Pos>()
.get_mut(entity)
.map(|old_position| {
old_position.0 = target;
});
ecs.write_storage::<comp::ForceUpdate>()
.get_mut(entity)
.map(|forced_update| forced_update.update());
},
TeleporterEvent::SetPortalActive { portal, active } => {
ecs.write_storage::<comp::Body>()
.get_mut(portal)
.map(|mut body| {
*body = comp::body::Body::Object(if active {
object::Body::PortalActive
} else {
object::Body::Portal
});
});
},
}
}

View File

@ -1,6 +1,7 @@
use crate::{
events::{
entity_creation::handle_create_teleporter,
entity_manipulation::handle_portal_event,
interaction::{handle_mount_volume, handle_tame_pet},
},
persistence::PersistedComponents,
@ -299,6 +300,7 @@ impl Server {
ServerEvent::RemoveLightEmitter { entity } => {
handle_remove_light_emitter(self, entity)
},
ServerEvent::PortalEvent(event) => handle_portal_event(self, event),
}
}

View File

@ -1,15 +1,10 @@
use std::time::Duration;
use common::{
comp::{
ability::AbilityMeta, object, Agent, Body, CharacterState, ForceUpdate, Player, Pos,
Teleporter, Teleporting,
object, teleport::TeleporterEvent, Agent, Body, CharacterState, Player, Pos, Teleporter,
Teleporting,
},
event::{EventBus, ServerEvent},
resources::Time,
states::{
blink,
utils::{AbilityInfo, StageSection},
},
CachedSpatialGrid,
};
use common_ecs::{Origin, Phase, System};
@ -29,16 +24,16 @@ fn in_portal_range(player_pos: Vec3<f32>, portal_pos: Vec3<f32>) -> bool {
impl<'a> System<'a> for Sys {
type SystemData = (
Entities<'a>,
WriteStorage<'a, Pos>,
ReadStorage<'a, Pos>,
ReadStorage<'a, Player>,
ReadStorage<'a, Teleporter>,
ReadStorage<'a, Agent>,
WriteStorage<'a, ForceUpdate>,
WriteStorage<'a, Teleporting>,
WriteStorage<'a, Body>,
WriteStorage<'a, CharacterState>,
ReadStorage<'a, Body>,
ReadStorage<'a, CharacterState>,
Read<'a, CachedSpatialGrid>,
Read<'a, Time>,
Read<'a, EventBus<ServerEvent>>,
);
const NAME: &'static str = "teleporter";
@ -49,26 +44,23 @@ impl<'a> System<'a> for Sys {
_job: &mut common_ecs::Job<Self>,
(
entities,
mut positions,
positions,
players,
teleporters,
agent,
mut forced_update,
mut teleporting,
mut bodies,
mut character_states,
bodies,
character_states,
spatial_grid,
time,
event_bus,
): Self::SystemData,
) {
let mut attempt_teleport = vec![];
let mut cancel_teleport = vec![];
let mut player_data = (
&entities,
&positions,
&players,
&mut character_states,
&character_states,
teleporting.entries(),
)
.join();
@ -86,8 +78,8 @@ impl<'a> System<'a> for Sys {
})
};
for (portal_entity, teleporter_pos, mut body, teleporter) in
(&entities, &positions, &mut bodies, &teleporters).join()
for (portal_entity, teleporter_pos, body, teleporter) in
(&entities, &positions, &bodies, &teleporters).join()
{
let nearby_entities = spatial_grid
.0
@ -95,7 +87,7 @@ impl<'a> System<'a> for Sys {
let mut is_active = false;
for (entity, pos, _, mut character_state, teleporting) in
for (entity, pos, _, character_state, teleporting) in
nearby_entities.filter_map(|entity| {
player_data
.get(entity, &entities)
@ -104,7 +96,11 @@ impl<'a> System<'a> for Sys {
})
})
{
if 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 let StorageEntry::Occupied(entry) = teleporting {
entry.remove();
};
@ -118,81 +114,40 @@ impl<'a> System<'a> for Sys {
portal: portal_entity,
end_time: Time(time.0 + teleporter.buildup_time.0),
});
} else if let Some(remaining) = if let StorageEntry::Occupied(entry) = teleporting {
let teleporting = entry.get();
((time.0 - teleporting.teleport_start.0) >= teleporter.buildup_time.0 / 3.
&& !matches!(*character_state, CharacterState::Blink(_)))
.then_some(teleporter.buildup_time.0 - (time.0 - teleporting.teleport_start.0))
} else {
None
} {
// Move into blink character state at half buildup time
*character_state = CharacterState::Blink(blink::Data {
timer: Duration::default(),
stage_section: StageSection::Buildup,
static_data: blink::StaticData {
buildup_duration: Duration::from_secs_f64(remaining),
recover_duration: Duration::default(),
max_range: 0.,
ability_info: AbilityInfo {
tool: None,
hand: None,
input: common::comp::InputKind::Primary,
ability_meta: AbilityMeta::default(),
ability: None,
input_attr: None,
},
},
});
}
is_active = true;
}
if (*body == Body::Object(object::Body::PortalActive)) != is_active {
*body = Body::Object(if is_active {
object::Body::PortalActive
} else {
object::Body::Portal
});
event_bus.emit_now(ServerEvent::PortalEvent(TeleporterEvent::SetPortalActive {
portal: portal_entity,
active: is_active,
}));
}
}
for (entity, position, _, teleporting) in
(&entities, &positions, &players, &teleporting).join()
for (entity, position, _, teleporting_entry) in
(&entities, &positions, &players, teleporting.entries()).join()
{
let portal_pos = positions.get(teleporting.portal);
let Some(teleporter) = teleporters.get(teleporting.portal) else {
cancel_teleport.push(entity);
let StorageEntry::Occupied(teleporting) = teleporting_entry else { continue };
let portal_pos = positions.get(teleporting.get().portal);
let Some(teleporter) = teleporters.get(teleporting.get().portal) else {
teleporting.remove();
continue
};
if portal_pos.map_or(true, |portal_pos| {
!in_portal_range(position.0, portal_pos.0)
}) {
cancel_teleport.push(entity);
} else if teleporting.end_time.0 <= time.0 {
attempt_teleport.push((entity, *teleporter));
cancel_teleport.push(entity);
teleporting.remove();
} else if teleporting.get().end_time.0 <= time.0 {
teleporting.remove();
event_bus.emit_now(ServerEvent::PortalEvent(TeleporterEvent::PortalTeleport {
entity,
target: teleporter.target,
}));
}
}
for entity in cancel_teleport {
teleporting.remove(entity);
character_states.get_mut(entity).map(|mut state| {
if let CharacterState::Blink(data) = &mut *state {
data.stage_section = StageSection::Recover;
}
});
}
for (entity, teleporter) in attempt_teleport {
positions
.get_mut(entity)
.map(|position| position.0 = teleporter.target);
forced_update
.get_mut(entity)
.map(|forced_update| forced_update.update());
}
}
}

View File

@ -1047,16 +1047,6 @@ impl Floor {
let tiles = Arc::clone(&tiles);
make_wall_contours(tiles, floor_corner, floor_z, wall_thickness, tunnel_height)
}));
let walls_fat = painter.prim(Primitive::sampling(floor_prim, {
let tiles = Arc::clone(&tiles);
make_wall_contours(
tiles,
floor_corner,
floor_z,
wall_thickness - 1.,
tunnel_height + 1.,
)
}));
// The surface 1 unit thicker than the walls is used to place the torches onto
let wall_contour_surface = painter.prim(Primitive::sampling(floor_prim, {
@ -1123,13 +1113,10 @@ impl Floor {
.without(lighting_mask_x.intersect(lighting_mask_y))
};
let walls_only = painter.prim(Primitive::without(wall_contours, walls_fat));
// Declare collections of various disjoint primitives that need postprocessing
// after handling all the local information per-tile
let mut stairs_bb = Vec::new();
let mut stairs = Vec::new();
let mut stair_walls = Vec::new();
let mut pillars = Vec::new();
let mut boss_room_center = None;
let mut sprites = Vec::new();
@ -1159,10 +1146,9 @@ impl Floor {
outer_tile_aabr(0),
floor_z - 2..(floor_z + tunnel_height as i32) + 2,
)));
let walls_in_tile = painter.prim(Primitive::intersect(outer_tile_aabb, walls_only));
// Fill Walls
painter.fill(walls_in_tile, Fill::Block(stone_wall));
painter.fill(outer_tile_aabb, Fill::Block(stone_wall));
let tile_floor_fill = painter.prim(Primitive::Aabb(aabr_with_z(
tile_aabr,
@ -1203,10 +1189,12 @@ impl Floor {
StairsKind::Spiral => Primitive::Cylinder(aabb),
StairsKind::WallSpiral => Primitive::Aabb(aabb),
});
let outer_bb = painter.prim(match kind {
painter.fill(painter.prim(match kind {
StairsKind::WallSpiral => Primitive::Aabb(outer_aabb),
StairsKind::Spiral => Primitive::Cylinder(outer_aabb),
});
}), Fill::Block(stone_wall));
let stair = painter.prim(Primitive::sampling(bb, match kind {
StairsKind::Spiral => spiral_staircase(center, radius, 0.5, 9.0),
StairsKind::WallSpiral => wall_staircase(center, radius, 27.0),
@ -1231,7 +1219,6 @@ impl Floor {
}
lights = painter.prim(Primitive::intersect(lights, lighting_mask));
stairs_bb.push(bb);
stair_walls.push(outer_bb);
stairs.push((stair, lights));
}
@ -1395,14 +1382,10 @@ impl Floor {
}
// Carve out space for the stairs
for (stair_bb, outer_stairs_bb) in stairs_bb.iter().zip(stair_walls.iter()) {
painter.fill(
painter.prim(Primitive::without(*outer_stairs_bb, *stair_bb)),
Fill::Block(stone_wall),
);
painter.fill(*stair_bb, Fill::Block(vacant));
for stair_bb in stairs_bb {
painter.fill(stair_bb, Fill::Block(vacant));
// Prevent sprites from floating above the stairs
let stair_bb_up = painter.prim(Primitive::translate(*stair_bb, Vec3::unit_z()));
let stair_bb_up = painter.prim(Primitive::translate(stair_bb, Vec3::unit_z()));
for (sprite, _) in sprites.iter_mut() {
*sprite = painter.prim(Primitive::without(*sprite, stair_bb_up));
}