mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Add basis for projectiles
But we have no controller action to spawn them yet
This commit is contained in:
@ -22,6 +22,7 @@ pub enum ServerEvent {
|
|||||||
cause: comp::HealthSource,
|
cause: comp::HealthSource,
|
||||||
},
|
},
|
||||||
Respawn(EcsEntity),
|
Respawn(EcsEntity),
|
||||||
|
Shoot(EcsEntity),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EventBus<E> {
|
pub struct EventBus<E> {
|
||||||
|
@ -87,7 +87,9 @@ impl Server {
|
|||||||
state
|
state
|
||||||
.ecs_mut()
|
.ecs_mut()
|
||||||
.add_resource(SpawnPoint(Vec3::new(16_384.0, 16_384.0, 512.0)));
|
.add_resource(SpawnPoint(Vec3::new(16_384.0, 16_384.0, 512.0)));
|
||||||
state.ecs_mut().add_resource(EventBus::<ServerEvent>::default());
|
state
|
||||||
|
.ecs_mut()
|
||||||
|
.add_resource(EventBus::<ServerEvent>::default());
|
||||||
|
|
||||||
// Set starting time for the server.
|
// Set starting time for the server.
|
||||||
state.ecs_mut().write_resource::<TimeOfDay>().0 = settings.start_time;
|
state.ecs_mut().write_resource::<TimeOfDay>().0 = settings.start_time;
|
||||||
@ -176,6 +178,22 @@ impl Server {
|
|||||||
//.with(comp::LightEmitter::default())
|
//.with(comp::LightEmitter::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Build a projectile
|
||||||
|
pub fn create_projectile(
|
||||||
|
state: &mut State,
|
||||||
|
pos: comp::Pos,
|
||||||
|
vel: comp::Vel,
|
||||||
|
body: comp::Body,
|
||||||
|
) -> EcsEntityBuilder {
|
||||||
|
state
|
||||||
|
.ecs_mut()
|
||||||
|
.create_entity_synced()
|
||||||
|
.with(pos)
|
||||||
|
.with(vel)
|
||||||
|
.with(comp::Ori(Vec3::unit_y()))
|
||||||
|
.with(body)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_player_character(
|
pub fn create_player_character(
|
||||||
state: &mut State,
|
state: &mut State,
|
||||||
entity: EcsEntity,
|
entity: EcsEntity,
|
||||||
@ -215,29 +233,29 @@ impl Server {
|
|||||||
|
|
||||||
/// Handle events coming through via the event bus
|
/// Handle events coming through via the event bus
|
||||||
fn handle_events(&mut self) {
|
fn handle_events(&mut self) {
|
||||||
let clients = &mut self.clients;
|
let events = self
|
||||||
|
.state
|
||||||
let events = self.state.ecs().read_resource::<EventBus<ServerEvent>>().recv_all();
|
.ecs()
|
||||||
|
.read_resource::<EventBus<ServerEvent>>()
|
||||||
|
.recv_all();
|
||||||
for event in events {
|
for event in events {
|
||||||
let ecs = self.state.ecs_mut();
|
let state = &mut self.state;
|
||||||
let mut todo_remove = None;
|
let clients = &mut self.clients;
|
||||||
{
|
|
||||||
let terrain = ecs.read_resource::<TerrainMap>();
|
|
||||||
let mut block_change = ecs.write_resource::<BlockChange>();
|
|
||||||
let mut stats = ecs.write_storage::<comp::Stats>();
|
|
||||||
let mut positions = ecs.write_storage::<comp::Pos>();
|
|
||||||
let mut velocities = ecs.write_storage::<comp::Vel>();
|
|
||||||
let mut force_updates = ecs.write_storage::<comp::ForceUpdate>();
|
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
ServerEvent::LandOnGround { entity, vel } => {
|
ServerEvent::LandOnGround { entity, vel } => {
|
||||||
if let Some(stats) = stats.get_mut(entity) {
|
if let Some(stats) = state
|
||||||
|
.ecs_mut()
|
||||||
|
.write_storage::<comp::Stats>()
|
||||||
|
.get_mut(entity)
|
||||||
|
{
|
||||||
let falldmg = (vel.z / 1.5 + 10.0) as i32;
|
let falldmg = (vel.z / 1.5 + 10.0) as i32;
|
||||||
if falldmg < 0 {
|
if falldmg < 0 {
|
||||||
stats.health.change_by(falldmg, comp::HealthSource::World);
|
stats.health.change_by(falldmg, comp::HealthSource::World);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerEvent::Explosion { pos, radius } => {
|
ServerEvent::Explosion { pos, radius } => {
|
||||||
const RAYS: usize = 500;
|
const RAYS: usize = 500;
|
||||||
|
|
||||||
@ -249,14 +267,36 @@ impl Server {
|
|||||||
)
|
)
|
||||||
.normalized();
|
.normalized();
|
||||||
|
|
||||||
let _ = terrain
|
let ecs = state.ecs_mut();
|
||||||
|
let mut block_change = ecs.write_resource::<BlockChange>();
|
||||||
|
|
||||||
|
let _ = ecs
|
||||||
|
.read_resource::<TerrainMap>()
|
||||||
.ray(pos, pos + dir * radius)
|
.ray(pos, pos + dir * radius)
|
||||||
.until(|_| rand::random::<f32>() < 0.05)
|
.until(|_| rand::random::<f32>() < 0.05)
|
||||||
.for_each(|pos| block_change.set(pos, Block::empty()))
|
.for_each(|pos| block_change.set(pos, Block::empty()))
|
||||||
.cast();
|
.cast();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServerEvent::Shoot(entity) => {
|
||||||
|
let pos = state
|
||||||
|
.ecs()
|
||||||
|
.read_storage::<comp::Pos>()
|
||||||
|
.get(entity)
|
||||||
|
.unwrap()
|
||||||
|
.0;
|
||||||
|
Self::create_projectile(
|
||||||
|
state,
|
||||||
|
comp::Pos(pos),
|
||||||
|
comp::Vel(Vec3::new(0.0, 100.0, 3.0)),
|
||||||
|
comp::Body::Object(comp::object::Body::Bomb),
|
||||||
|
)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
ServerEvent::Die { entity, cause } => {
|
ServerEvent::Die { entity, cause } => {
|
||||||
|
let ecs = state.ecs_mut();
|
||||||
// Chat message
|
// Chat message
|
||||||
if let Some(player) = ecs.read_storage::<comp::Player>().get(entity) {
|
if let Some(player) = ecs.read_storage::<comp::Player>().get(entity) {
|
||||||
let msg = if let comp::HealthSource::Attack { by } = cause {
|
let msg = if let comp::HealthSource::Attack { by } = cause {
|
||||||
@ -278,7 +318,10 @@ impl Server {
|
|||||||
clients.notify_registered(ServerMsg::kill(msg));
|
clients.notify_registered(ServerMsg::kill(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
// Give EXP to the client
|
// Give EXP to the client
|
||||||
|
let mut stats = ecs.write_storage::<comp::Stats>();
|
||||||
|
|
||||||
if let Some(entity_stats) = stats.get(entity).cloned() {
|
if let Some(entity_stats) = stats.get(entity).cloned() {
|
||||||
if let comp::HealthSource::Attack { by } = cause {
|
if let comp::HealthSource::Attack { by } = cause {
|
||||||
ecs.entity_from_uid(by.into()).map(|attacker| {
|
ecs.entity_from_uid(by.into()).map(|attacker| {
|
||||||
@ -292,31 +335,39 @@ impl Server {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(client) = clients.get_mut(&entity) {
|
if let Some(client) = clients.get_mut(&entity) {
|
||||||
let _ = velocities.insert(entity, comp::Vel(Vec3::zero()));
|
let _ = ecs.write_storage().insert(entity, comp::Vel(Vec3::zero()));
|
||||||
let _ = force_updates.insert(entity, comp::ForceUpdate);
|
let _ = ecs.write_storage().insert(entity, comp::ForceUpdate);
|
||||||
client.force_state(ClientState::Dead);
|
client.force_state(ClientState::Dead);
|
||||||
} else {
|
} else {
|
||||||
todo_remove = Some(entity.clone());
|
let _ = state.ecs_mut().delete_entity_synced(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerEvent::Respawn(entity) => {
|
ServerEvent::Respawn(entity) => {
|
||||||
// Only clients can respawn
|
// Only clients can respawn
|
||||||
if let Some(client) = clients.get_mut(&entity) {
|
if let Some(client) = clients.get_mut(&entity) {
|
||||||
client.allow_state(ClientState::Character);
|
client.allow_state(ClientState::Character);
|
||||||
stats.get_mut(entity).map(|stats| stats.revive());
|
state
|
||||||
positions.get_mut(entity).map(|pos| pos.0.z += 20.0);
|
.ecs_mut()
|
||||||
let _ = force_updates.insert(entity, comp::ForceUpdate);
|
.write_storage::<comp::Stats>()
|
||||||
|
.get_mut(entity)
|
||||||
|
.map(|stats| stats.revive());
|
||||||
|
state
|
||||||
|
.ecs_mut()
|
||||||
|
.write_storage::<comp::Pos>()
|
||||||
|
.get_mut(entity)
|
||||||
|
.map(|pos| pos.0.z += 20.0);
|
||||||
|
let _ = state
|
||||||
|
.ecs_mut()
|
||||||
|
.write_storage()
|
||||||
|
.insert(entity, comp::ForceUpdate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(entity) = todo_remove {
|
|
||||||
let _ = ecs.delete_entity_synced(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Execute a single server tick, handle input and update the game state by the given duration.
|
/// Execute a single server tick, handle input and update the game state by the given duration.
|
||||||
|
Reference in New Issue
Block a user