mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Spawn players aboveground when using /site
or when their waypoint is underground.
This commit is contained in:
parent
eb08b6a153
commit
7555be0e25
@ -49,6 +49,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Significantly improved the performance of playing sound effects
|
- Significantly improved the performance of playing sound effects
|
||||||
- Dismantle and Material crafting tabs don't have duplicated recipes
|
- Dismantle and Material crafting tabs don't have duplicated recipes
|
||||||
- Campfires now despawn when underwater
|
- Campfires now despawn when underwater
|
||||||
|
- Players no longer spawn underground if their waypoint is underground
|
||||||
|
|
||||||
## [0.10.0] - 2021-06-12
|
## [0.10.0] - 2021-06-12
|
||||||
|
|
||||||
|
@ -676,9 +676,11 @@ fn handle_site(
|
|||||||
})
|
})
|
||||||
.ok_or_else(|| "Site not found".to_string())?;
|
.ok_or_else(|| "Site not found".to_string())?;
|
||||||
|
|
||||||
let site_pos = server
|
let site_pos = server.world.find_accessible_pos(
|
||||||
.world
|
server.index.as_index_ref(),
|
||||||
.find_lowest_accessible_pos(server.index.as_index_ref(), site.center);
|
TerrainChunkSize::center_wpos(site.center),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
position_mut(server, target, "target", |current_pos| {
|
position_mut(server, target, "target", |current_pos| {
|
||||||
current_pos.0 = site_pos
|
current_pos.0 = site_pos
|
||||||
|
@ -41,9 +41,12 @@ pub fn handle_loaded_character_data(
|
|||||||
Option<comp::Waypoint>,
|
Option<comp::Waypoint>,
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
server
|
server.state.update_character_data(
|
||||||
.state
|
entity,
|
||||||
.update_character_data(entity, loaded_components);
|
loaded_components,
|
||||||
|
&*server.world,
|
||||||
|
&server.index.as_index_ref(),
|
||||||
|
);
|
||||||
sys::subscription::initialize_region_subscription(server.state.ecs(), entity);
|
sys::subscription::initialize_region_subscription(server.state.ecs(), entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,7 +343,7 @@ impl Server {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
world.find_lowest_accessible_pos(index, spawn_chunk)
|
world.find_accessible_pos(index, TerrainChunkSize::center_wpos(spawn_chunk), false)
|
||||||
});
|
});
|
||||||
#[cfg(not(feature = "worldgen"))]
|
#[cfg(not(feature = "worldgen"))]
|
||||||
let spawn_point = SpawnPoint::default();
|
let spawn_point = SpawnPoint::default();
|
||||||
|
@ -97,7 +97,13 @@ pub trait StateExt {
|
|||||||
fn initialize_character_data(&mut self, entity: EcsEntity, character_id: CharacterId);
|
fn initialize_character_data(&mut self, entity: EcsEntity, character_id: CharacterId);
|
||||||
/// Update the components associated with the entity's current character.
|
/// Update the components associated with the entity's current character.
|
||||||
/// Performed after loading component data from the database
|
/// Performed after loading component data from the database
|
||||||
fn update_character_data(&mut self, entity: EcsEntity, components: PersistedComponents);
|
fn update_character_data(
|
||||||
|
&mut self,
|
||||||
|
entity: EcsEntity,
|
||||||
|
components: PersistedComponents,
|
||||||
|
world: &world::World,
|
||||||
|
index: &world::IndexRef,
|
||||||
|
);
|
||||||
/// Iterates over registered clients and send each `ServerMsg`
|
/// Iterates over registered clients and send each `ServerMsg`
|
||||||
fn send_chat(&self, msg: comp::UnresolvedChatMsg);
|
fn send_chat(&self, msg: comp::UnresolvedChatMsg);
|
||||||
fn notify_players(&self, msg: ServerGeneral);
|
fn notify_players(&self, msg: ServerGeneral);
|
||||||
@ -480,7 +486,13 @@ impl StateExt for State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_character_data(&mut self, entity: EcsEntity, components: PersistedComponents) {
|
fn update_character_data(
|
||||||
|
&mut self,
|
||||||
|
entity: EcsEntity,
|
||||||
|
components: PersistedComponents,
|
||||||
|
world: &world::World,
|
||||||
|
index: &world::IndexRef,
|
||||||
|
) {
|
||||||
let (body, stats, skill_set, inventory, waypoint) = components;
|
let (body, stats, skill_set, inventory, waypoint) = components;
|
||||||
|
|
||||||
if let Some(player_uid) = self.read_component_copied::<Uid>(entity) {
|
if let Some(player_uid) = self.read_component_copied::<Uid>(entity) {
|
||||||
@ -525,8 +537,13 @@ impl StateExt for State {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if let Some(waypoint) = waypoint {
|
if let Some(waypoint) = waypoint {
|
||||||
|
// Avoid spawning the player in terrain by finding the highest solid point in
|
||||||
|
// their waypoint's column to spawn them at
|
||||||
|
let spawn_pos =
|
||||||
|
world.find_accessible_pos(*index, waypoint.get_pos().xy().as_::<i32>(), false);
|
||||||
|
|
||||||
self.write_component_ignore_entity_dead(entity, waypoint);
|
self.write_component_ignore_entity_dead(entity, waypoint);
|
||||||
self.write_component_ignore_entity_dead(entity, comp::Pos(waypoint.get_pos()));
|
self.write_component_ignore_entity_dead(entity, comp::Pos(spawn_pos));
|
||||||
self.write_component_ignore_entity_dead(entity, comp::Vel(Vec3::zero()));
|
self.write_component_ignore_entity_dead(entity, comp::Vel(Vec3::zero()));
|
||||||
self.write_component_ignore_entity_dead(entity, comp::ForceUpdate);
|
self.write_component_ignore_entity_dead(entity, comp::ForceUpdate);
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,9 @@ use common::{
|
|||||||
assets,
|
assets,
|
||||||
generation::{ChunkSupplement, EntityInfo},
|
generation::{ChunkSupplement, EntityInfo},
|
||||||
resources::TimeOfDay,
|
resources::TimeOfDay,
|
||||||
terrain::{Block, BlockKind, SpriteKind, TerrainChunk, TerrainChunkMeta, TerrainChunkSize},
|
terrain::{
|
||||||
|
Block, BlockKind, SpriteKind, TerrainChunk, TerrainChunkMeta, TerrainChunkSize, TerrainGrid,
|
||||||
|
},
|
||||||
vol::{ReadVol, RectVolSize, WriteVol},
|
vol::{ReadVol, RectVolSize, WriteVol},
|
||||||
};
|
};
|
||||||
use common_net::msg::{world_msg, WorldMapMsg};
|
use common_net::msg::{world_msg, WorldMapMsg};
|
||||||
@ -187,9 +189,13 @@ impl World {
|
|||||||
|
|
||||||
pub fn sample_blocks(&self) -> BlockGen { BlockGen::new(ColumnGen::new(&self.sim)) }
|
pub fn sample_blocks(&self) -> BlockGen { BlockGen::new(ColumnGen::new(&self.sim)) }
|
||||||
|
|
||||||
pub fn find_lowest_accessible_pos(&self, index: IndexRef, chunk_pos: Vec2<i32>) -> Vec3<f32> {
|
pub fn find_accessible_pos(
|
||||||
// Calculate the middle of the chunk in the world
|
&self,
|
||||||
let spawn_wpos = TerrainChunkSize::center_wpos(chunk_pos);
|
index: IndexRef,
|
||||||
|
spawn_wpos: Vec2<i32>,
|
||||||
|
ascending: bool,
|
||||||
|
) -> Vec3<f32> {
|
||||||
|
let chunk_pos = TerrainGrid::chunk_key(spawn_wpos);
|
||||||
|
|
||||||
// Unwrapping because generate_chunk only returns err when should_continue evals
|
// Unwrapping because generate_chunk only returns err when should_continue evals
|
||||||
// to true
|
// to true
|
||||||
@ -199,9 +205,19 @@ impl World {
|
|||||||
let min_z = tc.get_min_z();
|
let min_z = tc.get_min_z();
|
||||||
let max_z = tc.get_max_z();
|
let max_z = tc.get_max_z();
|
||||||
|
|
||||||
let pos = Vec3::new(spawn_wpos.x, spawn_wpos.y, min_z);
|
let pos = Vec3::new(
|
||||||
|
spawn_wpos.x,
|
||||||
|
spawn_wpos.y,
|
||||||
|
if ascending { min_z } else { max_z },
|
||||||
|
);
|
||||||
(0..(max_z - min_z))
|
(0..(max_z - min_z))
|
||||||
.map(|z_diff| pos + Vec3::unit_z() * z_diff)
|
.map(|z_diff| {
|
||||||
|
if ascending {
|
||||||
|
pos + Vec3::unit_z() * z_diff
|
||||||
|
} else {
|
||||||
|
pos - Vec3::unit_z() * z_diff
|
||||||
|
}
|
||||||
|
})
|
||||||
.find(|test_pos| {
|
.find(|test_pos| {
|
||||||
let chunk_relative_xy = test_pos
|
let chunk_relative_xy = test_pos
|
||||||
.xy()
|
.xy()
|
||||||
|
Loading…
Reference in New Issue
Block a user