mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'synis/beam-aura-spatial-grid' into 'master'
Use SpatialGrid for Beam and Aura See merge request veloren/veloren!2214
This commit is contained in:
commit
27fb8a9f6c
@ -22,6 +22,7 @@ pub struct ReadData<'a> {
|
||||
dt: Read<'a, DeltaTime>,
|
||||
server_bus: Read<'a, EventBus<ServerEvent>>,
|
||||
uid_allocator: Read<'a, UidAllocator>,
|
||||
cached_spatial_grid: Read<'a, common::CachedSpatialGrid>,
|
||||
positions: ReadStorage<'a, Pos>,
|
||||
char_states: ReadStorage<'a, CharacterState>,
|
||||
healths: ReadStorage<'a, Health>,
|
||||
@ -81,15 +82,25 @@ impl<'a> System<'a> for Sys {
|
||||
expired_auras.push(key);
|
||||
}
|
||||
}
|
||||
for (target, target_pos, mut target_buffs, health, target_uid) in (
|
||||
&read_data.entities,
|
||||
&read_data.positions,
|
||||
&mut buffs,
|
||||
&read_data.healths,
|
||||
&read_data.uids,
|
||||
)
|
||||
.join()
|
||||
{
|
||||
let target_iter = read_data
|
||||
.cached_spatial_grid
|
||||
.0
|
||||
.in_circle_aabr(pos.0.xy(), aura.radius)
|
||||
.filter_map(|target| {
|
||||
read_data
|
||||
.positions
|
||||
.get(target)
|
||||
.and_then(|l| read_data.healths.get(target).map(|r| (l, r)))
|
||||
.and_then(|l| read_data.uids.get(target).map(|r| (l, r)))
|
||||
.map(|((target_pos, health), target_uid)| {
|
||||
(target, target_pos, health, target_uid)
|
||||
})
|
||||
});
|
||||
target_iter.for_each(|(target, target_pos, health, target_uid)| {
|
||||
let mut target_buffs = match buffs.get_mut(target) {
|
||||
Some(buff) => buff,
|
||||
None => return,
|
||||
};
|
||||
// Ensure entity is within the aura radius
|
||||
if target_pos.0.distance_squared(pos.0) < aura.radius.powi(2) {
|
||||
if let AuraTarget::GroupOf(uid) = aura.target {
|
||||
@ -103,7 +114,7 @@ impl<'a> System<'a> for Sys {
|
||||
|| *target_uid == uid;
|
||||
|
||||
if !same_group {
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,8 +138,9 @@ impl<'a> System<'a> for Sys {
|
||||
_ => true,
|
||||
};
|
||||
if apply_buff {
|
||||
// Checks that target is not already receiving a buff from an
|
||||
// aura, where the buff is of the same kind, and is of at least
|
||||
// Checks that target is not already receiving a buff from
|
||||
// an aura, where
|
||||
// the buff is of the same kind, and is of at least
|
||||
// the same strength and of at least the same duration
|
||||
// If no such buff is present, adds the buff
|
||||
let emit_buff = !target_buffs.buffs.iter().any(|(_, buff)| {
|
||||
@ -152,7 +164,8 @@ impl<'a> System<'a> for Sys {
|
||||
)),
|
||||
});
|
||||
}
|
||||
// Finds all buffs on target that are from an aura, are of the
|
||||
// Finds all buffs on target that are from an aura, are of
|
||||
// the
|
||||
// same buff kind, and are of at most the same strength
|
||||
// For any such buffs, marks it as recently applied
|
||||
for (_, buff) in
|
||||
@ -175,7 +188,7 @@ impl<'a> System<'a> for Sys {
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if !expired_auras.is_empty() {
|
||||
server_emitter.emit(ServerEvent::Aura {
|
||||
|
@ -29,6 +29,7 @@ pub struct ReadData<'a> {
|
||||
dt: Read<'a, DeltaTime>,
|
||||
terrain: ReadExpect<'a, TerrainGrid>,
|
||||
uid_allocator: Read<'a, UidAllocator>,
|
||||
cached_spatial_grid: Read<'a, common::CachedSpatialGrid>,
|
||||
uids: ReadStorage<'a, Uid>,
|
||||
positions: ReadStorage<'a, Pos>,
|
||||
orientations: ReadStorage<'a, Ori>,
|
||||
@ -122,19 +123,26 @@ impl<'a> System<'a> for Sys {
|
||||
return (server_events, add_hit_entities, outcomes);
|
||||
};
|
||||
|
||||
// Go through all other effectable entities
|
||||
for (target, uid_b, pos_b, health_b, body_b) in (
|
||||
&read_data.entities,
|
||||
&read_data.uids,
|
||||
&read_data.positions,
|
||||
&read_data.healths,
|
||||
&read_data.bodies,
|
||||
)
|
||||
.join()
|
||||
{
|
||||
// Go through all affectable entities by querying the spatial grid
|
||||
let target_iter = read_data
|
||||
.cached_spatial_grid
|
||||
.0
|
||||
.in_circle_aabr(pos.0.xy(), frame_end_dist - frame_start_dist)
|
||||
.filter_map(|target|{
|
||||
read_data
|
||||
.positions
|
||||
.get(target)
|
||||
.and_then(|l| read_data.healths.get(target).map(|r| (l,r)))
|
||||
.and_then(|l| read_data.uids.get(target).map(|r| (l,r)))
|
||||
.and_then(|l| read_data.bodies.get(target).map(|r| (l,r)))
|
||||
.map(|(((pos_b, health_b), uid_b), body_b)| {
|
||||
(target, uid_b, pos_b, health_b, body_b)
|
||||
})
|
||||
});
|
||||
target_iter.for_each(|(target, uid_b, pos_b, health_b, body_b)| {
|
||||
// Check to see if entity has already been hit recently
|
||||
if hit_entities.iter().any(|&uid| uid == *uid_b) {
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
// Scales
|
||||
@ -170,7 +178,7 @@ impl<'a> System<'a> for Sys {
|
||||
|
||||
// If owner, shouldn't heal or damage
|
||||
if Some(*uid_b) == beam_segment.owner {
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
let attacker_info =
|
||||
@ -208,7 +216,7 @@ impl<'a> System<'a> for Sys {
|
||||
|
||||
add_hit_entities.push((beam_owner, *uid_b));
|
||||
}
|
||||
}
|
||||
});
|
||||
(server_events, add_hit_entities, outcomes)
|
||||
}).reduce(|| (Vec::new(), Vec::new(), Vec::new()),
|
||||
|(mut events_a, mut hit_entities_a, mut outcomes_a),
|
||||
|
Loading…
Reference in New Issue
Block a user