mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Various tweaks: moved radius determination to function on , comments, simplified server Destroy event code, debug assert modified components aren't removed in change tracking, etc
This commit is contained in:
parent
b2752d2419
commit
934c5d6846
@ -33,6 +33,23 @@ impl Body {
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
// Note: this might need to be refined to something more complex for realistic
|
||||
// behavior with less cylindrical bodies (e.g. wolfs)
|
||||
pub fn radius(&self) -> f32 {
|
||||
// TODO: Improve these values (some might be reliant on more info in inner type)
|
||||
match self {
|
||||
Body::Humanoid(_) => 0.5,
|
||||
Body::QuadrupedSmall(_) => 0.6,
|
||||
Body::QuadrupedMedium(_) => 0.9,
|
||||
Body::BirdMedium(_) => 0.5,
|
||||
Body::FishMedium(_) => 0.5,
|
||||
Body::Dragon(_) => 2.5,
|
||||
Body::BirdSmall(_) => 0.2,
|
||||
Body::FishSmall(_) => 0.2,
|
||||
Body::BipedLarge(_) => 1.0,
|
||||
Body::Object(_) => 0.3,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for Body {
|
||||
|
@ -8,6 +8,9 @@ use std::{
|
||||
marker::PhantomData,
|
||||
};
|
||||
|
||||
/// Implemented by type that carries component data for insertion and modification
|
||||
/// The assocatied `Phantom` type only carries information about which component type is of
|
||||
/// interest and is used to transmit deletion events
|
||||
pub trait CompPacket: Clone + Debug + Send + 'static {
|
||||
type Phantom: Clone + Debug + Serialize + DeserializeOwned;
|
||||
|
||||
|
@ -51,10 +51,9 @@ where
|
||||
self.inserted.add(*id);
|
||||
}
|
||||
specs::storage::ComponentEvent::Modified(id) => {
|
||||
// We don't care about modification if the component was just added or was
|
||||
// removed
|
||||
// Could potentially remove since this should theoretically never occur...
|
||||
if !self.removed.contains(*id) && !self.inserted.contains(*id) {
|
||||
// We don't care about modification if the component was just added
|
||||
if !self.inserted.contains(*id) {
|
||||
debug_assert!(!self.removed.contains(*id)); // Theoretically impossible
|
||||
self.modified.add(*id);
|
||||
}
|
||||
}
|
||||
|
@ -147,8 +147,11 @@ impl<'a> System<'a> for Sys {
|
||||
if target_stats.is_dead {
|
||||
choose_new = true;
|
||||
} else if dist < 0.001 {
|
||||
// TODO: move back? (probably can only happen when entities are at a
|
||||
// different z-level due to repulsion)
|
||||
// Probably can only happen when entities are at a different z-level
|
||||
// since at the same level repulsion would keep them apart.
|
||||
// Distinct from the first if block since we may want to change the
|
||||
// behavior for this case.
|
||||
choose_new = true;
|
||||
} else if dist < MIN_ATTACK_DIST {
|
||||
// Fight (and slowly move closer)
|
||||
inputs.move_dir =
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
comp::{
|
||||
ActionState::*, CharacterState, Controller, HealthChange, HealthSource, Item, ItemKind,
|
||||
Ori, Pos, Scale, Stats,
|
||||
ActionState::*, Body, CharacterState, Controller, HealthChange, HealthSource, Item,
|
||||
ItemKind, Ori, Pos, Scale, Stats,
|
||||
},
|
||||
event::{EventBus, LocalEvent, ServerEvent},
|
||||
state::DeltaTime,
|
||||
@ -30,8 +30,9 @@ impl<'a> System<'a> for Sys {
|
||||
ReadStorage<'a, Ori>,
|
||||
ReadStorage<'a, Scale>,
|
||||
ReadStorage<'a, Controller>,
|
||||
ReadStorage<'a, Body>,
|
||||
ReadStorage<'a, Stats>,
|
||||
WriteStorage<'a, CharacterState>,
|
||||
WriteStorage<'a, Stats>,
|
||||
);
|
||||
|
||||
fn run(
|
||||
@ -46,15 +47,16 @@ impl<'a> System<'a> for Sys {
|
||||
orientations,
|
||||
scales,
|
||||
controllers,
|
||||
mut character_states,
|
||||
bodies,
|
||||
stats,
|
||||
mut character_states,
|
||||
): Self::SystemData,
|
||||
) {
|
||||
let mut server_emitter = server_bus.emitter();
|
||||
let mut _local_emitter = local_bus.emitter();
|
||||
|
||||
// Attacks
|
||||
for (entity, uid, pos, ori, scale_maybe, _, stat) in (
|
||||
for (entity, uid, pos, ori, scale_maybe, _, attacker_stats) in (
|
||||
&entities,
|
||||
&uids,
|
||||
&positions,
|
||||
@ -68,7 +70,7 @@ impl<'a> System<'a> for Sys {
|
||||
let recover_duration = if let Some(Item {
|
||||
kind: ItemKind::Tool { kind, .. },
|
||||
..
|
||||
}) = stat.equipment.main
|
||||
}) = attacker_stats.equipment.main
|
||||
{
|
||||
kind.attack_recover_duration()
|
||||
} else {
|
||||
@ -96,7 +98,7 @@ impl<'a> System<'a> for Sys {
|
||||
if deal_damage {
|
||||
if let Some(Attack { .. }) = &character_states.get(entity).map(|c| c.action) {
|
||||
// Go through all other entities
|
||||
for (b, uid_b, pos_b, ori_b, scale_b_maybe, character_b, stat_b) in (
|
||||
for (b, uid_b, pos_b, ori_b, scale_b_maybe, character_b, stats_b, body_b) in (
|
||||
&entities,
|
||||
&uids,
|
||||
&positions,
|
||||
@ -104,6 +106,7 @@ impl<'a> System<'a> for Sys {
|
||||
scales.maybe(),
|
||||
&character_states,
|
||||
&stats,
|
||||
&bodies,
|
||||
)
|
||||
.join()
|
||||
{
|
||||
@ -115,19 +118,18 @@ impl<'a> System<'a> for Sys {
|
||||
// Scales
|
||||
let scale = scale_maybe.map_or(1.0, |s| s.0);
|
||||
let scale_b = scale_b_maybe.map_or(1.0, |s| s.0);
|
||||
// TODO: don't do this here
|
||||
let rad_b = 0.5 * scale_b;
|
||||
let rad_b = body_b.radius() * scale_b;
|
||||
|
||||
// Check if it is a hit
|
||||
if entity != b
|
||||
&& !stat_b.is_dead
|
||||
&& !stats_b.is_dead
|
||||
// Spherical wedge shaped attack field
|
||||
&& pos.0.distance_squared(pos_b.0) < (rad_b + scale * ATTACK_RANGE).powi(2)
|
||||
&& ori2.angle_between(pos_b2 - pos2) < ATTACK_ANGLE.to_radians() / 2.0 + (rad_b / pos2.distance(pos_b2)).atan()
|
||||
{
|
||||
// Weapon gives base damage
|
||||
let mut dmg = if let Some(ItemKind::Tool { power, .. }) =
|
||||
stat.equipment.main.as_ref().map(|i| &i.kind)
|
||||
attacker_stats.equipment.main.as_ref().map(|i| &i.kind)
|
||||
{
|
||||
*power as i32
|
||||
} else {
|
||||
|
@ -413,21 +413,25 @@ impl Server {
|
||||
}
|
||||
}
|
||||
|
||||
// This sucks
|
||||
let mut remove = false;
|
||||
let mut remove = true;
|
||||
|
||||
if let Some(client) = state.ecs().write_storage::<Client>().get_mut(entity) {
|
||||
let _ = state
|
||||
remove = false;
|
||||
state
|
||||
.ecs()
|
||||
.write_storage()
|
||||
.insert(entity, comp::Vel(Vec3::zero()));
|
||||
let _ = state
|
||||
.insert(entity, comp::Vel(Vec3::zero()))
|
||||
.err()
|
||||
.map(|err| error!("Failed to set zero vel on dead client: {:?}", err));
|
||||
state
|
||||
.ecs()
|
||||
.write_storage()
|
||||
.insert(entity, comp::ForceUpdate);
|
||||
.insert(entity, comp::ForceUpdate)
|
||||
.err()
|
||||
.map(|err| {
|
||||
error!("Failed to insert ForceUpdate on dead client: {:?}", err)
|
||||
});
|
||||
client.force_state(ClientState::Dead);
|
||||
} else {
|
||||
remove = true;
|
||||
}
|
||||
|
||||
if remove {
|
||||
|
@ -756,10 +756,7 @@ impl Ui {
|
||||
}
|
||||
|
||||
fn default_scissor(renderer: &Renderer) -> Aabr<u16> {
|
||||
let (screen_w, screen_h) = renderer
|
||||
.get_resolution()
|
||||
.map(|e| (e as u16).max(1))
|
||||
.into_tuple();
|
||||
let (screen_w, screen_h) = renderer.get_resolution().into_tuple();
|
||||
Aabr {
|
||||
min: Vec2 { x: 0, y: 0 },
|
||||
max: Vec2 {
|
||||
|
Loading…
Reference in New Issue
Block a user