mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'zesterer/damage-fixes' into 'master'
Make items vanish after 5 minutes See merge request veloren/veloren!3963
This commit is contained in:
commit
e71eee0cd2
@ -69,6 +69,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Creatures flee less quickly when low on health
|
||||
- All `/build_area_*` commands have been renamed to `/area_*`, and you will have to pass an additional area type
|
||||
- Collision damage can now be applied in horizontal axes, in addition to the vertical axis
|
||||
- Items will vanish after 5 minutes to minimise performance problems
|
||||
|
||||
### Removed
|
||||
|
||||
|
@ -64,6 +64,7 @@ macro_rules! synced_components {
|
||||
combo: Combo,
|
||||
active_abilities: ActiveAbilities,
|
||||
can_build: CanBuild,
|
||||
object: Object,
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -253,3 +254,7 @@ impl NetSync for ActiveAbilities {
|
||||
impl NetSync for CanBuild {
|
||||
const SYNC_FROM: SyncFrom = SyncFrom::ClientEntity;
|
||||
}
|
||||
|
||||
impl NetSync for Object {
|
||||
const SYNC_FROM: SyncFrom = SyncFrom::AnyEntity;
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
use super::item::Reagent;
|
||||
use crate::uid::Uid;
|
||||
use crate::{resources::Time, uid::Uid};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specs::Component;
|
||||
use specs::{Component, DerefFlaggedStorage};
|
||||
use std::time::Duration;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum Object {
|
||||
Bomb {
|
||||
owner: Option<Uid>,
|
||||
@ -12,8 +13,12 @@ pub enum Object {
|
||||
owner: Option<Uid>,
|
||||
reagent: Reagent,
|
||||
},
|
||||
DeleteAfter {
|
||||
spawned_at: Time,
|
||||
timeout: Duration,
|
||||
},
|
||||
}
|
||||
|
||||
impl Component for Object {
|
||||
type Storage = specs::VecStorage<Self>;
|
||||
type Storage = DerefFlaggedStorage<Self, specs::VecStorage<Self>>;
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ use common::{
|
||||
self,
|
||||
item::{ItemKind, MaterialStatManifest},
|
||||
skills::{GeneralSkill, Skill},
|
||||
ChatType, Group, Inventory, Item, LootOwner, Player, Poise, Presence, PresenceKind,
|
||||
ChatType, Group, Inventory, Item, LootOwner, Object, Player, Poise, Presence, PresenceKind,
|
||||
},
|
||||
effect::Effect,
|
||||
link::{Link, LinkHandle},
|
||||
@ -40,7 +40,7 @@ use specs::{
|
||||
saveload::MarkerAllocator, Builder, Entity as EcsEntity, EntityBuilder as EcsEntityBuilder,
|
||||
Join, WorldExt,
|
||||
};
|
||||
use std::time::Instant;
|
||||
use std::time::{Duration, Instant};
|
||||
use tracing::{trace, warn};
|
||||
use vek::*;
|
||||
|
||||
@ -366,6 +366,8 @@ impl StateExt for State {
|
||||
// Only if merging items fails do we give up and create a new item
|
||||
}
|
||||
|
||||
let spawned_at = *self.ecs().read_resource::<Time>();
|
||||
|
||||
let item_drop = comp::item_drop::Body::from(&item);
|
||||
let body = comp::Body::ItemDrop(item_drop);
|
||||
let light_emitter = match &*item.kind() {
|
||||
@ -388,6 +390,11 @@ impl StateExt for State {
|
||||
.with(item_drop.density())
|
||||
.with(body.collider())
|
||||
.with(body)
|
||||
.with(Object::DeleteAfter {
|
||||
spawned_at,
|
||||
// Delete the item drop after 5 minutes
|
||||
timeout: Duration::from_secs(300),
|
||||
})
|
||||
.maybe_with(loot_owner)
|
||||
.maybe_with(light_emitter)
|
||||
.build(),
|
||||
|
@ -2,11 +2,11 @@ use common::{
|
||||
comp::{Object, PhysicsState, Pos, Vel},
|
||||
effect::Effect,
|
||||
event::{EventBus, ServerEvent},
|
||||
resources::DeltaTime,
|
||||
resources::{DeltaTime, Time},
|
||||
Damage, DamageKind, DamageSource, Explosion, RadiusEffect,
|
||||
};
|
||||
use common_ecs::{Job, Origin, Phase, System};
|
||||
use specs::{Entities, Join, Read, ReadStorage, WriteStorage};
|
||||
use specs::{Entities, Join, Read, ReadStorage};
|
||||
use vek::Rgb;
|
||||
|
||||
/// This system is responsible for handling misc object behaviours
|
||||
@ -16,11 +16,12 @@ impl<'a> System<'a> for Sys {
|
||||
type SystemData = (
|
||||
Entities<'a>,
|
||||
Read<'a, DeltaTime>,
|
||||
Read<'a, Time>,
|
||||
Read<'a, EventBus<ServerEvent>>,
|
||||
ReadStorage<'a, Pos>,
|
||||
ReadStorage<'a, Vel>,
|
||||
ReadStorage<'a, PhysicsState>,
|
||||
WriteStorage<'a, Object>,
|
||||
ReadStorage<'a, Object>,
|
||||
);
|
||||
|
||||
const NAME: &'static str = "object";
|
||||
@ -29,7 +30,7 @@ impl<'a> System<'a> for Sys {
|
||||
|
||||
fn run(
|
||||
_job: &mut Job<Self>,
|
||||
(entities, _dt, server_bus, positions, velocities, physics_states, mut objects): Self::SystemData,
|
||||
(entities, _dt, time, server_bus, positions, velocities, physics_states, objects): Self::SystemData,
|
||||
) {
|
||||
let mut server_emitter = server_bus.emitter();
|
||||
|
||||
@ -39,7 +40,7 @@ impl<'a> System<'a> for Sys {
|
||||
&positions,
|
||||
&velocities,
|
||||
&physics_states,
|
||||
&mut objects,
|
||||
&objects,
|
||||
)
|
||||
.join()
|
||||
{
|
||||
@ -160,6 +161,14 @@ impl<'a> System<'a> for Sys {
|
||||
});
|
||||
}
|
||||
},
|
||||
Object::DeleteAfter {
|
||||
spawned_at,
|
||||
timeout,
|
||||
} => {
|
||||
if (time.0 - spawned_at.0).max(0.0) > timeout.as_secs_f64() {
|
||||
server_emitter.emit(ServerEvent::Delete(entity));
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,8 +40,8 @@ use common::{
|
||||
item::{tool::AbilityContext, Hands, ItemKind, ToolKind},
|
||||
ship::{self, figuredata::VOXEL_COLLIDER_MANIFEST},
|
||||
Body, CharacterActivity, CharacterState, Collider, Controller, Health, Inventory, Item,
|
||||
ItemKey, Last, LightAnimation, LightEmitter, Ori, PhysicsState, PoiseState, Pos, Scale,
|
||||
SkillSet, Stance, Vel,
|
||||
ItemKey, Last, LightAnimation, LightEmitter, Object, Ori, PhysicsState, PoiseState, Pos,
|
||||
Scale, SkillSet, Stance, Vel,
|
||||
},
|
||||
link::Is,
|
||||
mounting::{Rider, VolumeRider},
|
||||
@ -6394,6 +6394,7 @@ impl FigureMgr {
|
||||
filter_state: impl Fn(&FigureStateMeta) -> bool,
|
||||
) {
|
||||
let ecs = state.ecs();
|
||||
let time = ecs.read_resource::<Time>();
|
||||
let items = ecs.read_storage::<Item>();
|
||||
(
|
||||
&ecs.entities(),
|
||||
@ -6404,11 +6405,13 @@ impl FigureMgr {
|
||||
ecs.read_storage::<Inventory>().maybe(),
|
||||
ecs.read_storage::<Scale>().maybe(),
|
||||
ecs.read_storage::<Collider>().maybe(),
|
||||
ecs.read_storage::<Object>().maybe(),
|
||||
)
|
||||
.join()
|
||||
// Don't render dead entities
|
||||
.filter(|(_, _, _, _, health, _, _, _)| health.map_or(true, |h| !h.is_dead))
|
||||
.for_each(|(entity, pos, _, body, _, inventory, scale, collider)| {
|
||||
.filter(|(_, _, _, _, health, _, _, _, _)| health.map_or(true, |h| !h.is_dead))
|
||||
.filter(|(_, _, _, _, _, _, _, _, obj)| !self.should_flicker(*time, *obj))
|
||||
.for_each(|(entity, pos, _, body, _, inventory, scale, collider, _)| {
|
||||
if let Some((bound, model, _)) = self.get_model_for_render(
|
||||
tick,
|
||||
camera,
|
||||
@ -6541,6 +6544,19 @@ impl FigureMgr {
|
||||
}
|
||||
}
|
||||
|
||||
// Returns `true` if an object should flicker because it's about to vanish
|
||||
fn should_flicker(&self, time: Time, obj: Option<&Object>) -> bool {
|
||||
if let Some(Object::DeleteAfter {
|
||||
spawned_at,
|
||||
timeout,
|
||||
}) = obj
|
||||
{
|
||||
time.0 > spawned_at.0 + timeout.as_secs_f64() - 10.0 && (time.0 * 8.0).fract() < 0.5
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render<'a>(
|
||||
&'a self,
|
||||
drawer: &mut FigureDrawer<'_, 'a>,
|
||||
@ -6552,10 +6568,11 @@ impl FigureMgr {
|
||||
span!(_guard, "render", "FigureManager::render");
|
||||
let ecs = state.ecs();
|
||||
|
||||
let time = ecs.read_resource::<Time>();
|
||||
let character_state_storage = state.read_storage::<CharacterState>();
|
||||
let character_state = character_state_storage.get(viewpoint_entity);
|
||||
let items = ecs.read_storage::<Item>();
|
||||
for (entity, pos, body, _, inventory, scale, collider) in (
|
||||
for (entity, pos, body, _, inventory, scale, collider, _) in (
|
||||
&ecs.entities(),
|
||||
&ecs.read_storage::<Pos>(),
|
||||
&ecs.read_storage::<Body>(),
|
||||
@ -6563,12 +6580,14 @@ impl FigureMgr {
|
||||
ecs.read_storage::<Inventory>().maybe(),
|
||||
ecs.read_storage::<Scale>().maybe(),
|
||||
ecs.read_storage::<Collider>().maybe(),
|
||||
ecs.read_storage::<Object>().maybe(),
|
||||
)
|
||||
.join()
|
||||
// Don't render dead entities
|
||||
.filter(|(_, _, _, health, _, _, _)| health.map_or(true, |h| !h.is_dead))
|
||||
.filter(|(_, _, _, health, _, _, _, _)| health.map_or(true, |h| !h.is_dead))
|
||||
// Don't render player
|
||||
.filter(|(entity, _, _, _, _, _, _)| *entity != viewpoint_entity)
|
||||
.filter(|(entity, _, _, _, _, _, _, _)| *entity != viewpoint_entity)
|
||||
.filter(|(_, _, _, _, _, _, _, obj)| !self.should_flicker(*time, *obj))
|
||||
{
|
||||
if let Some((bound, model, atlas)) = self.get_model_for_render(
|
||||
tick,
|
||||
|
Loading…
Reference in New Issue
Block a user