mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
despawn with volume mount
This commit is contained in:
parent
7856aac713
commit
e0e7fe499d
@ -72,6 +72,8 @@ use common::{
|
||||
cmd::ServerChatCommand,
|
||||
comp,
|
||||
event::{EventBus, ServerEvent},
|
||||
link::Is,
|
||||
mounting::{Volume, VolumeRider},
|
||||
region::RegionMap,
|
||||
resources::{BattleMode, GameMode, Time, TimeOfDay},
|
||||
rtsim::RtSimEntity,
|
||||
@ -844,7 +846,6 @@ impl Server {
|
||||
self.state.delete_component::<Anchor>(entity);
|
||||
}
|
||||
|
||||
let mut rtsim = self.state.ecs().write_resource::<rtsim::RtSim>();
|
||||
// Remove NPCs that are outside the view distances of all players
|
||||
// This is done by removing NPCs in unloaded chunks
|
||||
let to_delete = {
|
||||
@ -854,12 +855,28 @@ impl Server {
|
||||
&self.state.ecs().read_storage::<comp::Pos>(),
|
||||
!&self.state.ecs().read_storage::<comp::Presence>(),
|
||||
self.state.ecs().read_storage::<Anchor>().maybe(),
|
||||
self.state.ecs().read_storage::<RtSimEntity>().maybe(),
|
||||
self.state.ecs().read_storage::<Is<VolumeRider>>().maybe(),
|
||||
)
|
||||
.join()
|
||||
.filter(|(_, pos, _, anchor, rtsim_entity)| {
|
||||
let chunk_key = terrain.pos_key(pos.0.map(|e| e.floor() as i32));
|
||||
let unload = match anchor {
|
||||
.filter(|(_, pos, _, anchor, is_volume_rider)| {
|
||||
let pos = is_volume_rider
|
||||
.and_then(|is_volume_rider| match is_volume_rider.pos.kind {
|
||||
Volume::Terrain => None,
|
||||
Volume::Entity(e) => {
|
||||
let e = self.state.ecs().entity_from_uid(e)?;
|
||||
let pos = self
|
||||
.state
|
||||
.ecs()
|
||||
.read_storage::<comp::Pos>()
|
||||
.get(e)
|
||||
.copied()?;
|
||||
|
||||
Some(pos.0)
|
||||
},
|
||||
})
|
||||
.unwrap_or(pos.0);
|
||||
let chunk_key = terrain.pos_key(pos.map(|e| e.floor() as i32));
|
||||
match anchor {
|
||||
Some(Anchor::Chunk(hc)) => {
|
||||
// Check if both this chunk and the NPCs `home_chunk` is unloaded. If
|
||||
// so, we delete them. We check for
|
||||
@ -870,28 +887,22 @@ impl Server {
|
||||
},
|
||||
Some(Anchor::Entity(entity)) => !self.state.ecs().is_alive(*entity),
|
||||
None => terrain.get_key_real(chunk_key).is_none(),
|
||||
};
|
||||
|
||||
if unload {
|
||||
// For rtsim entities we only want to unload if assimilation succeeds
|
||||
if let Some(rtsim_entity) = rtsim_entity {
|
||||
#[cfg(feature = "worldgen")]
|
||||
let res = rtsim.hook_rtsim_entity_unload(**rtsim_entity);
|
||||
#[cfg(not(feature = "worldgen"))]
|
||||
let res = true;
|
||||
res
|
||||
} else {
|
||||
true
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.map(|(entity, _, _, _, _)| entity)
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
|
||||
drop(rtsim);
|
||||
#[cfg(feature = "worldgen")]
|
||||
{
|
||||
let mut rtsim = self.state.ecs().write_resource::<rtsim::RtSim>();
|
||||
let rtsim_entities = self.state.ecs().read_storage();
|
||||
for entity in &to_delete {
|
||||
if let Some(rtsim_entity) = rtsim_entities.get(*entity) {
|
||||
rtsim.hook_rtsim_entity_unload(*rtsim_entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Actually perform entity deletion
|
||||
for entity in to_delete {
|
||||
|
@ -176,26 +176,15 @@ impl RtSim {
|
||||
.emit(event::OnBlockChange { changes }, world, index);
|
||||
}
|
||||
|
||||
pub fn hook_rtsim_entity_unload(&mut self, entity: RtSimEntity) -> bool {
|
||||
pub fn hook_rtsim_entity_unload(&mut self, entity: RtSimEntity) {
|
||||
let data = self.state.get_data_mut();
|
||||
if data.npcs.mounts.get_mount_link(entity.0).is_none() {
|
||||
|
||||
if let Some(npc) = data.npcs.get_mut(entity.0) {
|
||||
if matches!(npc.mode, SimulationMode::Simulated) {
|
||||
error!("Unloaded already unloaded entity");
|
||||
}
|
||||
npc.mode = SimulationMode::Simulated;
|
||||
}
|
||||
if let Some(steerer) = data.npcs.mounts.get_steerer_link(entity.0) && let Actor::Npc(npc) = steerer.rider
|
||||
&& let Some(npc) = data.npcs.get_mut(npc) {
|
||||
if matches!(npc.mode, SimulationMode::Simulated) {
|
||||
error!("Unloaded already unloaded steerer entity");
|
||||
}
|
||||
npc.mode = SimulationMode::Simulated;
|
||||
}
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hook_rtsim_actor_death(
|
||||
|
Loading…
Reference in New Issue
Block a user