mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'sam/permanent-spawn-safezone' into 'master'
Safezone is now permanently in existence at spawn. See merge request veloren/veloren!2144
This commit is contained in:
commit
1892ec571d
@ -172,6 +172,10 @@ pub enum ServerEvent {
|
|||||||
target: Uid,
|
target: Uid,
|
||||||
max_range: Option<f32>,
|
max_range: Option<f32>,
|
||||||
},
|
},
|
||||||
|
CreateSafezone {
|
||||||
|
range: Option<f32>,
|
||||||
|
pos: Pos,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EventBus<E> {
|
pub struct EventBus<E> {
|
||||||
|
@ -1069,22 +1069,7 @@ fn handle_safezone(
|
|||||||
) -> CmdResult<()> {
|
) -> CmdResult<()> {
|
||||||
let range = scan_fmt_some!(&args, &action.arg_fmt(), f32);
|
let range = scan_fmt_some!(&args, &action.arg_fmt(), f32);
|
||||||
let pos = position(server, target, "target")?;
|
let pos = position(server, target, "target")?;
|
||||||
server
|
server.state.create_safezone(range, pos).build();
|
||||||
.state
|
|
||||||
.create_object(pos, comp::object::Body::BoltNature)
|
|
||||||
.with(comp::Mass(10_f32.powi(10)))
|
|
||||||
.with(comp::Auras::new(vec![Aura::new(
|
|
||||||
AuraKind::Buff {
|
|
||||||
kind: BuffKind::Invulnerability,
|
|
||||||
data: BuffData::new(1.0, Some(Duration::from_secs(1))),
|
|
||||||
category: BuffCategory::Natural,
|
|
||||||
source: BuffSource::World,
|
|
||||||
},
|
|
||||||
range.unwrap_or(100.0),
|
|
||||||
None,
|
|
||||||
AuraTarget::All,
|
|
||||||
)]))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
|
@ -19,7 +19,7 @@ use interaction::{
|
|||||||
use inventory_manip::handle_inventory;
|
use inventory_manip::handle_inventory;
|
||||||
use invite::{handle_invite, handle_invite_response};
|
use invite::{handle_invite, handle_invite_response};
|
||||||
use player::{handle_client_disconnect, handle_exit_ingame};
|
use player::{handle_client_disconnect, handle_exit_ingame};
|
||||||
use specs::{Entity as EcsEntity, WorldExt};
|
use specs::{Builder, Entity as EcsEntity, WorldExt};
|
||||||
use trade::{cancel_trade_for, handle_process_trade_action};
|
use trade::{cancel_trade_for, handle_process_trade_action};
|
||||||
|
|
||||||
mod entity_creation;
|
mod entity_creation;
|
||||||
@ -212,6 +212,9 @@ impl Server {
|
|||||||
target,
|
target,
|
||||||
max_range,
|
max_range,
|
||||||
} => handle_teleport_to(&self, entity, target, max_range),
|
} => handle_teleport_to(&self, entity, target, max_range),
|
||||||
|
ServerEvent::CreateSafezone { range, pos } => {
|
||||||
|
self.state.create_safezone(range, pos).build();
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,11 @@ use world::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
struct SpawnPoint(Vec3<f32>);
|
pub struct SpawnPoint(Vec3<f32>);
|
||||||
|
|
||||||
|
impl Default for SpawnPoint {
|
||||||
|
fn default() -> Self { Self(Vec3::new(0.0, 0.0, 256.0)) }
|
||||||
|
}
|
||||||
|
|
||||||
// Tick count used for throttling network updates
|
// Tick count used for throttling network updates
|
||||||
// Note this doesn't account for dt (so update rate changes with tick rate)
|
// Note this doesn't account for dt (so update rate changes with tick rate)
|
||||||
@ -299,7 +303,7 @@ impl Server {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "worldgen")]
|
#[cfg(feature = "worldgen")]
|
||||||
let spawn_point = {
|
let spawn_point = SpawnPoint({
|
||||||
let index = index.as_index_ref();
|
let index = index.as_index_ref();
|
||||||
// NOTE: all of these `.map(|e| e as [type])` calls should compile into no-ops,
|
// NOTE: all of these `.map(|e| e as [type])` calls should compile into no-ops,
|
||||||
// but are needed to be explicit about casting (and to make the compiler stop
|
// but are needed to be explicit about casting (and to make the compiler stop
|
||||||
@ -327,12 +331,12 @@ impl Server {
|
|||||||
};
|
};
|
||||||
|
|
||||||
world.find_lowest_accessible_pos(index, spawn_chunk)
|
world.find_lowest_accessible_pos(index, spawn_chunk)
|
||||||
};
|
});
|
||||||
#[cfg(not(feature = "worldgen"))]
|
#[cfg(not(feature = "worldgen"))]
|
||||||
let spawn_point = Vec3::new(0.0, 0.0, 256.0);
|
let spawn_point = SpawnPoint::default();
|
||||||
|
|
||||||
// Set the spawn point we calculated above
|
// Set the spawn point we calculated above
|
||||||
state.ecs_mut().insert(SpawnPoint(spawn_point));
|
state.ecs_mut().insert(spawn_point);
|
||||||
|
|
||||||
// Insert a default AABB for the world
|
// Insert a default AABB for the world
|
||||||
// TODO: prevent this from being deleted
|
// TODO: prevent this from being deleted
|
||||||
|
@ -43,6 +43,7 @@ pub struct Settings {
|
|||||||
pub max_player_group_size: u32,
|
pub max_player_group_size: u32,
|
||||||
pub client_timeout: Duration,
|
pub client_timeout: Duration,
|
||||||
pub spawn_town: Option<String>,
|
pub spawn_town: Option<String>,
|
||||||
|
pub safe_spawn: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Settings {
|
impl Default for Settings {
|
||||||
@ -61,6 +62,7 @@ impl Default for Settings {
|
|||||||
max_player_group_size: 6,
|
max_player_group_size: 6,
|
||||||
client_timeout: Duration::from_secs(40),
|
client_timeout: Duration::from_secs(40),
|
||||||
spawn_town: None,
|
spawn_town: None,
|
||||||
|
safe_spawn: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ use specs::{
|
|||||||
saveload::MarkerAllocator, Builder, Entity as EcsEntity, EntityBuilder as EcsEntityBuilder,
|
saveload::MarkerAllocator, Builder, Entity as EcsEntity, EntityBuilder as EcsEntityBuilder,
|
||||||
Join, WorldExt,
|
Join, WorldExt,
|
||||||
};
|
};
|
||||||
|
use std::time::Duration;
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
@ -72,6 +73,8 @@ pub trait StateExt {
|
|||||||
pos: comp::Pos,
|
pos: comp::Pos,
|
||||||
ori: comp::Ori,
|
ori: comp::Ori,
|
||||||
) -> EcsEntityBuilder;
|
) -> EcsEntityBuilder;
|
||||||
|
/// Creates a safezone
|
||||||
|
fn create_safezone(&mut self, range: Option<f32>, pos: comp::Pos) -> EcsEntityBuilder;
|
||||||
// NOTE: currently only used for testing
|
// NOTE: currently only used for testing
|
||||||
/// Queues chunk generation in the view distance of the persister, this
|
/// Queues chunk generation in the view distance of the persister, this
|
||||||
/// entity must be built before those chunks are received (the builder
|
/// entity must be built before those chunks are received (the builder
|
||||||
@ -318,6 +321,27 @@ impl StateExt for State {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_safezone(&mut self, range: Option<f32>, pos: comp::Pos) -> EcsEntityBuilder {
|
||||||
|
use comp::{
|
||||||
|
aura::{Aura, AuraKind, AuraTarget, Auras},
|
||||||
|
buff::{BuffCategory, BuffData, BuffKind, BuffSource},
|
||||||
|
};
|
||||||
|
self.ecs_mut()
|
||||||
|
.create_entity_synced()
|
||||||
|
.with(pos)
|
||||||
|
.with(Auras::new(vec![Aura::new(
|
||||||
|
AuraKind::Buff {
|
||||||
|
kind: BuffKind::Invulnerability,
|
||||||
|
data: BuffData::new(1.0, Some(Duration::from_secs(1))),
|
||||||
|
category: BuffCategory::Natural,
|
||||||
|
source: BuffSource::World,
|
||||||
|
},
|
||||||
|
range.unwrap_or(100.0),
|
||||||
|
None,
|
||||||
|
AuraTarget::All,
|
||||||
|
)]))
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: currently only used for testing
|
// NOTE: currently only used for testing
|
||||||
/// Queues chunk generation in the view distance of the persister, this
|
/// Queues chunk generation in the view distance of the persister, this
|
||||||
/// entity must be built before those chunks are received (the builder
|
/// entity must be built before those chunks are received (the builder
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
chunk_generator::ChunkGenerator, client::Client, presence::Presence, rtsim::RtSim, Tick,
|
chunk_generator::ChunkGenerator, client::Client, presence::Presence, rtsim::RtSim,
|
||||||
|
settings::Settings, SpawnPoint, Tick,
|
||||||
};
|
};
|
||||||
use common::{
|
use common::{
|
||||||
comp::{
|
comp::{
|
||||||
@ -33,6 +34,8 @@ impl<'a> System<'a> for Sys {
|
|||||||
type SystemData = (
|
type SystemData = (
|
||||||
Read<'a, EventBus<ServerEvent>>,
|
Read<'a, EventBus<ServerEvent>>,
|
||||||
Read<'a, Tick>,
|
Read<'a, Tick>,
|
||||||
|
Read<'a, SpawnPoint>,
|
||||||
|
Read<'a, Settings>,
|
||||||
WriteExpect<'a, ChunkGenerator>,
|
WriteExpect<'a, ChunkGenerator>,
|
||||||
WriteExpect<'a, TerrainGrid>,
|
WriteExpect<'a, TerrainGrid>,
|
||||||
Write<'a, TerrainChanges>,
|
Write<'a, TerrainChanges>,
|
||||||
@ -51,6 +54,8 @@ impl<'a> System<'a> for Sys {
|
|||||||
(
|
(
|
||||||
server_event_bus,
|
server_event_bus,
|
||||||
tick,
|
tick,
|
||||||
|
spawn_point,
|
||||||
|
server_settings,
|
||||||
mut chunk_generator,
|
mut chunk_generator,
|
||||||
mut terrain,
|
mut terrain,
|
||||||
mut terrain_changes,
|
mut terrain_changes,
|
||||||
@ -218,6 +223,14 @@ impl<'a> System<'a> for Sys {
|
|||||||
rtsim_entity: None,
|
rtsim_entity: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Insert a safezone if chunk contains the spawn position
|
||||||
|
if server_settings.safe_spawn && is_spawn_chunk(key, *spawn_point, &terrain) {
|
||||||
|
server_emitter.emit(ServerEvent::CreateSafezone {
|
||||||
|
range: Some(100.0),
|
||||||
|
pos: Pos(spawn_point.0),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove chunks that are too far from players.
|
// Remove chunks that are too far from players.
|
||||||
@ -271,3 +284,8 @@ pub fn chunk_in_vd(
|
|||||||
|
|
||||||
adjusted_dist_sqr <= vd.pow(2)
|
adjusted_dist_sqr <= vd.pow(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_spawn_chunk(chunk_pos: Vec2<i32>, spawn_pos: SpawnPoint, terrain: &TerrainGrid) -> bool {
|
||||||
|
let spawn_chunk_pos = terrain.pos_key(spawn_pos.0.map(|e| e as i32));
|
||||||
|
chunk_pos == spawn_chunk_pos
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user