mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fix rtsim airships
This commit is contained in:
parent
a386c68df5
commit
06d7548dc6
@ -387,5 +387,9 @@ impl<'a, E> Emitter<'a, E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E> Drop for Emitter<'a, E> {
|
impl<'a, E> Drop for Emitter<'a, E> {
|
||||||
fn drop(&mut self) { self.bus.queue.lock().unwrap().append(&mut self.events); }
|
fn drop(&mut self) {
|
||||||
|
if !self.events.is_empty() {
|
||||||
|
self.bus.queue.lock().unwrap().append(&mut self.events);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,7 +258,7 @@ impl Npc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct Riding {
|
pub struct Riding {
|
||||||
pub vehicle: VehicleId,
|
pub vehicle: VehicleId,
|
||||||
pub steering: bool,
|
pub steering: bool,
|
||||||
|
@ -183,7 +183,7 @@ fn on_tick(ctx: EventCtx<SimulateNpcs, OnTick>) {
|
|||||||
match npc.controller.activity {
|
match npc.controller.activity {
|
||||||
// If steering, the NPC controls the vehicle's motion
|
// If steering, the NPC controls the vehicle's motion
|
||||||
Some(NpcActivity::Goto(target, speed_factor)) if riding.steering => {
|
Some(NpcActivity::Goto(target, speed_factor)) if riding.steering => {
|
||||||
let diff = target.xy() - vehicle.wpos.xy();
|
let diff = target - vehicle.wpos;
|
||||||
let dist2 = diff.magnitude_squared();
|
let dist2 = diff.magnitude_squared();
|
||||||
|
|
||||||
if dist2 > 0.5f32.powi(2) {
|
if dist2 > 0.5f32.powi(2) {
|
||||||
@ -212,7 +212,7 @@ fn on_tick(ctx: EventCtx<SimulateNpcs, OnTick>) {
|
|||||||
}
|
}
|
||||||
vehicle.dir = (target.xy() - vehicle.wpos.xy())
|
vehicle.dir = (target.xy() - vehicle.wpos.xy())
|
||||||
.try_normalized()
|
.try_normalized()
|
||||||
.unwrap_or(Vec2::unit_y());
|
.unwrap_or(vehicle.dir);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// When riding, other actions are disabled
|
// When riding, other actions are disabled
|
||||||
@ -294,7 +294,7 @@ fn on_tick(ctx: EventCtx<SimulateNpcs, OnTick>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (_, vehicle) in data.npcs.vehicles.iter_mut() {
|
for (id, vehicle) in data.npcs.vehicles.iter_mut() {
|
||||||
// Try to keep ships above ground and within the map
|
// Try to keep ships above ground and within the map
|
||||||
if matches!(vehicle.mode, SimulationMode::Simulated) {
|
if matches!(vehicle.mode, SimulationMode::Simulated) {
|
||||||
vehicle.wpos = vehicle
|
vehicle.wpos = vehicle
|
||||||
@ -312,5 +312,12 @@ fn on_tick(ctx: EventCtx<SimulateNpcs, OnTick>) {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if let Some(Actor::Npc(driver)) = vehicle.driver
|
||||||
|
&& data.npcs.npcs.get(driver).and_then(|driver| {
|
||||||
|
Some(driver.riding.as_ref()?.vehicle != id)
|
||||||
|
}).unwrap_or(true)
|
||||||
|
{
|
||||||
|
vehicle.driver = None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -809,6 +809,8 @@ impl Server {
|
|||||||
self.state.delete_component::<Anchor>(entity);
|
self.state.delete_component::<Anchor>(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut rtsim = self.state.ecs().write_resource::<rtsim::RtSim>();
|
||||||
|
let rtsim_entities = self.state.ecs().read_storage::<RtSimEntity>();
|
||||||
// Remove NPCs that are outside the view distances of all players
|
// Remove NPCs that are outside the view distances of all players
|
||||||
// This is done by removing NPCs in unloaded chunks
|
// This is done by removing NPCs in unloaded chunks
|
||||||
let to_delete = {
|
let to_delete = {
|
||||||
@ -818,9 +820,15 @@ impl Server {
|
|||||||
&self.state.ecs().read_storage::<comp::Pos>(),
|
&self.state.ecs().read_storage::<comp::Pos>(),
|
||||||
!&self.state.ecs().read_storage::<comp::Presence>(),
|
!&self.state.ecs().read_storage::<comp::Presence>(),
|
||||||
self.state.ecs().read_storage::<Anchor>().maybe(),
|
self.state.ecs().read_storage::<Anchor>().maybe(),
|
||||||
|
rtsim_entities.maybe(),
|
||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
.filter(|(_, pos, _, anchor)| {
|
.filter(|(_, pos, _, anchor, rtsim_entity)| {
|
||||||
|
if rtsim_entity.map_or(false, |rtsim_entity| {
|
||||||
|
!rtsim.can_unload_entity(*rtsim_entity)
|
||||||
|
}) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
let chunk_key = terrain.pos_key(pos.0.map(|e| e.floor() as i32));
|
let chunk_key = terrain.pos_key(pos.0.map(|e| e.floor() as i32));
|
||||||
match anchor {
|
match anchor {
|
||||||
Some(Anchor::Chunk(hc)) => {
|
Some(Anchor::Chunk(hc)) => {
|
||||||
@ -835,13 +843,11 @@ impl Server {
|
|||||||
None => terrain.get_key_real(chunk_key).is_none(),
|
None => terrain.get_key_real(chunk_key).is_none(),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map(|(entity, _, _, _)| entity)
|
.map(|(entity, _, _, _, _)| entity)
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut rtsim = self.state.ecs().write_resource::<rtsim::RtSim>();
|
|
||||||
let rtsim_entities = self.state.ecs().read_storage::<RtSimEntity>();
|
|
||||||
let rtsim_vehicles = self.state.ecs().read_storage::<RtSimVehicle>();
|
let rtsim_vehicles = self.state.ecs().read_storage::<RtSimVehicle>();
|
||||||
|
|
||||||
// Assimilate entities that are part of the real-time world simulation
|
// Assimilate entities that are part of the real-time world simulation
|
||||||
@ -856,6 +862,8 @@ impl Server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
drop(rtsim_entities);
|
||||||
|
drop(rtsim);
|
||||||
|
|
||||||
// Actually perform entity deletion
|
// Actually perform entity deletion
|
||||||
for entity in to_delete {
|
for entity in to_delete {
|
||||||
|
@ -177,17 +177,23 @@ impl RtSim {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn hook_rtsim_entity_unload(&mut self, entity: RtSimEntity) {
|
pub fn hook_rtsim_entity_unload(&mut self, entity: RtSimEntity) {
|
||||||
if let Some(npc) = self
|
if let Some(npc) = self.state.get_data_mut().npcs.get_mut(entity.0) {
|
||||||
.state
|
|
||||||
.get_data_mut()
|
|
||||||
.npcs
|
|
||||||
.get_mut(entity.0)
|
|
||||||
.filter(|npc| npc.riding.is_none())
|
|
||||||
{
|
|
||||||
npc.mode = SimulationMode::Simulated;
|
npc.mode = SimulationMode::Simulated;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn can_unload_entity(&self, entity: RtSimEntity) -> bool {
|
||||||
|
let data = self.state.data();
|
||||||
|
data.npcs
|
||||||
|
.get(entity.0)
|
||||||
|
.and_then(|npc| {
|
||||||
|
let riding = npc.riding.as_ref()?;
|
||||||
|
let vehicle = data.npcs.vehicles.get(riding.vehicle)?;
|
||||||
|
Some(matches!(vehicle.mode, SimulationMode::Simulated))
|
||||||
|
})
|
||||||
|
.unwrap_or(true)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn hook_rtsim_vehicle_unload(&mut self, entity: RtSimVehicle) {
|
pub fn hook_rtsim_vehicle_unload(&mut self, entity: RtSimVehicle) {
|
||||||
let data = self.state.get_data_mut();
|
let data = self.state.get_data_mut();
|
||||||
if let Some(vehicle) = data.npcs.vehicles.get_mut(entity.0) {
|
if let Some(vehicle) = data.npcs.vehicles.get_mut(entity.0) {
|
||||||
|
@ -19,7 +19,7 @@ use rtsim::data::{
|
|||||||
npc::{Profession, SimulationMode},
|
npc::{Profession, SimulationMode},
|
||||||
Npc, Sites,
|
Npc, Sites,
|
||||||
};
|
};
|
||||||
use specs::{Join, Read, ReadExpect, ReadStorage, WriteExpect, WriteStorage};
|
use specs::{Entities, Join, Read, ReadExpect, ReadStorage, WriteExpect, WriteStorage};
|
||||||
use std::{sync::Arc, time::Duration};
|
use std::{sync::Arc, time::Duration};
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
use world::site::settlement::trader_loadout;
|
use world::site::settlement::trader_loadout;
|
||||||
@ -212,6 +212,7 @@ fn get_npc_entity_info(npc: &Npc, sites: &Sites, index: IndexRef) -> EntityInfo
|
|||||||
pub struct Sys;
|
pub struct Sys;
|
||||||
impl<'a> System<'a> for Sys {
|
impl<'a> System<'a> for Sys {
|
||||||
type SystemData = (
|
type SystemData = (
|
||||||
|
Entities<'a>,
|
||||||
Read<'a, DeltaTime>,
|
Read<'a, DeltaTime>,
|
||||||
Read<'a, Time>,
|
Read<'a, Time>,
|
||||||
Read<'a, TimeOfDay>,
|
Read<'a, TimeOfDay>,
|
||||||
@ -234,6 +235,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
fn run(
|
fn run(
|
||||||
_job: &mut Job<Self>,
|
_job: &mut Job<Self>,
|
||||||
(
|
(
|
||||||
|
entities,
|
||||||
dt,
|
dt,
|
||||||
time,
|
time,
|
||||||
time_of_day,
|
time_of_day,
|
||||||
@ -419,30 +421,40 @@ impl<'a> System<'a> for Sys {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut emitter = server_event_bus.emitter();
|
||||||
// Synchronise rtsim NPC with entity data
|
// Synchronise rtsim NPC with entity data
|
||||||
for (pos, rtsim_entity, agent) in
|
for (entity, pos, rtsim_entity, agent) in (
|
||||||
(&positions, &rtsim_entities, (&mut agents).maybe()).join()
|
&entities,
|
||||||
|
&positions,
|
||||||
|
&rtsim_entities,
|
||||||
|
(&mut agents).maybe(),
|
||||||
|
)
|
||||||
|
.join()
|
||||||
{
|
{
|
||||||
data.npcs
|
if let Some(npc) = data.npcs.get_mut(rtsim_entity.0) {
|
||||||
.get_mut(rtsim_entity.0)
|
match npc.mode {
|
||||||
.filter(|npc| matches!(npc.mode, SimulationMode::Loaded))
|
SimulationMode::Loaded => {
|
||||||
.map(|npc| {
|
// Update rtsim NPC state
|
||||||
// Update rtsim NPC state
|
npc.wpos = pos.0;
|
||||||
npc.wpos = pos.0;
|
|
||||||
|
|
||||||
// Update entity state
|
// Update entity state
|
||||||
if let Some(agent) = agent {
|
if let Some(agent) = agent {
|
||||||
agent.rtsim_controller.personality = npc.personality;
|
agent.rtsim_controller.personality = npc.personality;
|
||||||
agent.rtsim_controller.activity = npc.controller.activity;
|
agent.rtsim_controller.activity = npc.controller.activity;
|
||||||
agent
|
agent
|
||||||
.rtsim_controller
|
.rtsim_controller
|
||||||
.actions
|
.actions
|
||||||
.extend(std::mem::take(&mut npc.controller.actions));
|
.extend(std::mem::take(&mut npc.controller.actions));
|
||||||
if let Some(rtsim_outbox) = &mut agent.rtsim_outbox {
|
if let Some(rtsim_outbox) = &mut agent.rtsim_outbox {
|
||||||
npc.inbox.append(rtsim_outbox);
|
npc.inbox.append(rtsim_outbox);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
SimulationMode::Simulated => {
|
||||||
|
emitter.emit(ServerEvent::Delete(entity));
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user