mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
bug fixes and airships land at airship stations
This commit is contained in:
parent
1f195fd848
commit
7fd255ec6c
@ -168,6 +168,19 @@ impl Body {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Max speed in block/s
|
||||
pub fn get_speed(&self) -> f32 {
|
||||
match self {
|
||||
Body::DefaultAirship => 7.0,
|
||||
Body::AirBalloon => 8.0,
|
||||
Body::SailBoat => 5.0,
|
||||
Body::Galleon => 6.0,
|
||||
Body::Skiff => 6.0,
|
||||
Body::Submarine => 4.0,
|
||||
_ => 10.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Terrain is 11.0 scale relative to small-scale voxels,
|
||||
|
@ -184,7 +184,10 @@ impl Body {
|
||||
// => 1 / (1 - drag).powi(2) - 1 = (dv / 30) / v
|
||||
// => 1 / (1 / (1 - drag).powi(2) - 1) = v / (dv / 30)
|
||||
// => (dv / 30) / (1 / (1 - drag).powi(2) - 1) = v
|
||||
let v = (-self.base_accel() / 30.0) / ((1.0 - FRIC_GROUND).powi(2) - 1.0);
|
||||
let v = match self {
|
||||
Body::Ship(ship) => ship.get_speed(),
|
||||
_ => (-self.base_accel() / 30.0) / ((1.0 - FRIC_GROUND).powi(2) - 1.0),
|
||||
};
|
||||
debug_assert!(v >= 0.0, "Speed must be positive!");
|
||||
v
|
||||
}
|
||||
|
@ -179,8 +179,14 @@ impl Data {
|
||||
}
|
||||
}
|
||||
|
||||
if rng.gen_bool(0.4) {
|
||||
let wpos = rand_wpos(&mut rng, matches_plazas) + Vec3::unit_z() * 50.0;
|
||||
for plot in site2
|
||||
.plots
|
||||
.values()
|
||||
.filter(|plot| matches!(plot.kind(), PlotKind::AirshipDock(_)))
|
||||
{
|
||||
let wpos = site2.tile_center_wpos(plot.root_tile());
|
||||
let wpos = wpos.as_().with_z(world.sim().get_surface_alt_approx(wpos))
|
||||
+ Vec3::unit_z() * 70.0;
|
||||
let vehicle_id = this.npcs.create_npc(Npc::new(
|
||||
rng.gen(),
|
||||
wpos,
|
||||
|
@ -25,7 +25,7 @@ use common::{
|
||||
rtsim::{Actor, ChunkResource, NpcInput, Profession, Role, SiteId},
|
||||
spiral::Spiral2d,
|
||||
store::Id,
|
||||
terrain::{CoordinateConversions, SiteKindMeta, TerrainChunkSize},
|
||||
terrain::{CoordinateConversions, TerrainChunkSize},
|
||||
time::DayPeriod,
|
||||
util::Dir,
|
||||
};
|
||||
@ -1012,27 +1012,35 @@ fn pilot<S: State>(ship: common::comp::ship::Body) -> impl Action<S> {
|
||||
// Travel between different towns in a straight line
|
||||
now(move |ctx, _| {
|
||||
let data = &*ctx.state.data();
|
||||
let site = data
|
||||
let station_wpos = data
|
||||
.sites
|
||||
.iter()
|
||||
.filter(|(id, _)| Some(*id) != ctx.npc.current_site)
|
||||
.filter(|(_, site)| {
|
||||
site.world_site
|
||||
.and_then(|site| ctx.index.sites.get(site).kind.convert_to_meta())
|
||||
.map_or(false, |meta| matches!(meta, SiteKindMeta::Settlement(_)))
|
||||
.filter_map(|(_, site)| ctx.index.sites.get(site.world_site?).site2())
|
||||
.flat_map(|site| {
|
||||
site.plots()
|
||||
.filter(|plot| matches!(plot.kind(), PlotKind::AirshipDock(_)))
|
||||
.map(|plot| site.tile_center_wpos(plot.root_tile()))
|
||||
})
|
||||
.choose(&mut ctx.rng);
|
||||
if let Some((_id, site)) = site {
|
||||
if let Some(station_wpos) = station_wpos {
|
||||
Either::Right(
|
||||
goto_2d_flying(
|
||||
site.wpos.as_(),
|
||||
station_wpos.as_(),
|
||||
1.0,
|
||||
50.0,
|
||||
150.0,
|
||||
110.0,
|
||||
ship.flying_height(),
|
||||
)
|
||||
.then(goto_2d_flying(site.wpos.as_(), 1.0, 10.0, 32.0, 16.0, 10.0)),
|
||||
.then(goto_2d_flying(
|
||||
station_wpos.as_(),
|
||||
1.0,
|
||||
10.0,
|
||||
32.0,
|
||||
16.0,
|
||||
30.0,
|
||||
)),
|
||||
)
|
||||
} else {
|
||||
Either::Left(finish())
|
||||
|
@ -242,16 +242,15 @@ fn on_tick(ctx: EventCtx<SimulateNpcs, OnTick>) {
|
||||
match activity {
|
||||
// Move NPCs if they have a target destination
|
||||
Some(NpcActivity::Goto(target, speed_factor)) => {
|
||||
let diff = target.xy() - npc.wpos.xy();
|
||||
let diff = target - npc.wpos;
|
||||
let dist2 = diff.magnitude_squared();
|
||||
|
||||
if dist2 > 0.5f32.powi(2) {
|
||||
let new_wpos = npc.wpos
|
||||
+ (diff
|
||||
* (npc.body.max_speed_approx() * speed_factor * ctx.event.dt
|
||||
/ dist2.sqrt())
|
||||
.min(1.0))
|
||||
.with_z(0.0);
|
||||
let offset = diff
|
||||
* (npc.body.max_speed_approx() * speed_factor * ctx.event.dt
|
||||
/ dist2.sqrt())
|
||||
.min(1.0);
|
||||
let new_wpos = npc.wpos + offset;
|
||||
|
||||
let is_valid = match npc.body {
|
||||
// Don't move water bound bodies outside of water.
|
||||
|
@ -854,11 +854,12 @@ 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(),
|
||||
)
|
||||
.join()
|
||||
.filter(|(_, pos, _, anchor)| {
|
||||
.filter(|(_, pos, _, anchor, rtsim_entity)| {
|
||||
let chunk_key = terrain.pos_key(pos.0.map(|e| e.floor() as i32));
|
||||
match anchor {
|
||||
let unload = 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
|
||||
@ -869,22 +870,27 @@ 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)
|
||||
.map(|(entity, _, _, _, _)| entity)
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
|
||||
#[cfg(feature = "worldgen")]
|
||||
{
|
||||
let rtsim_entities = self.state.ecs().read_storage::<RtSimEntity>();
|
||||
// Assimilate entities that are part of the real-time world simulation
|
||||
for entity in &to_delete {
|
||||
if let Some(rtsim_entity) = rtsim_entities.get(*entity) {
|
||||
rtsim.hook_rtsim_entity_unload(*rtsim_entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
drop(rtsim);
|
||||
|
||||
// Actually perform entity deletion
|
||||
|
@ -176,15 +176,25 @@ impl RtSim {
|
||||
.emit(event::OnBlockChange { changes }, world, index);
|
||||
}
|
||||
|
||||
pub fn hook_rtsim_entity_unload(&mut self, entity: RtSimEntity) {
|
||||
pub fn hook_rtsim_entity_unload(&mut self, entity: RtSimEntity) -> bool {
|
||||
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 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
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user