Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed asteroids being duplicate loaded + generated in wrong sectors #205

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cosmos_client/src/inventory/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,7 @@ fn handle_interactions(
fn create_item_stack_slot_data(item_stack: &ItemStack, ecmds: &mut EntityCommands, text_style: TextStyle, quantity: u16) {
ecmds
.insert((
Name::new("Render Item"),
NodeBundle {
style: Style {
width: Val::Px(64.0),
Expand Down
1 change: 1 addition & 0 deletions cosmos_client/src/netty/gameplay/receiver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ pub(crate) fn client_sync_players(
},
Collider::capsule_y(0.5, 0.25),
LockedAxes::ROTATION_LOCKED,
Name::new(format!("Player ({name})")),
RigidBody::Dynamic,
body.create_velocity(),
Player::new(name, id),
Expand Down
25 changes: 14 additions & 11 deletions cosmos_client/src/ui/crosshair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,22 @@ use crate::state::game_state::GameState;

fn add_crosshair(mut commands: Commands, asset_server: Res<AssetServer>) {
commands
.spawn(NodeBundle {
style: Style {
position_type: PositionType::Absolute,
display: Display::Flex,
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
width: Val::Percent(100.0),
height: Val::Percent(100.0),
.spawn((
NodeBundle {
style: Style {
position_type: PositionType::Absolute,
display: Display::Flex,
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
width: Val::Percent(100.0),
height: Val::Percent(100.0),
..default()
},
// color: Color::NONE.into(),
..default()
},
// color: Color::NONE.into(),
..default()
})
Name::new("Crosshair"),
))
.with_children(|parent| {
parent
.spawn(ImageBundle {
Expand Down
1 change: 1 addition & 0 deletions cosmos_client/src/ui/item_renderer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ struct UICamera;

fn create_ui_camera(mut commands: Commands) {
commands.spawn((
Name::new("UI Camera"),
Camera3dBundle {
projection: Projection::Orthographic(OrthographicProjection {
scaling_mode: ScalingMode::WindowSize(40.0),
Expand Down
87 changes: 55 additions & 32 deletions cosmos_core/src/structure/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use std::fmt::Display;

use bevy::prelude::{App, Event, IntoSystemConfigs, PreUpdate};
use bevy::prelude::{App, Event, IntoSystemConfigs, Name, PreUpdate};
use bevy::reflect::Reflect;
use bevy::utils::{HashMap, HashSet};
use bevy_rapier3d::prelude::PhysicsWorld;
Expand Down Expand Up @@ -509,6 +509,43 @@ fn remove_empty_chunks(
}
}

fn spawn_chunk_entity(
commands: &mut Commands,
structure: &mut Structure,
chunk_coordinate: ChunkCoordinate,
structure_entity: Entity,
body_world: Option<&PhysicsWorld>,
chunk_set_events: &mut HashSet<ChunkSetEvent>,
) {
let mut entity_cmds = commands.spawn((
PbrBundle {
transform: Transform::from_translation(structure.chunk_relative_position(chunk_coordinate)),
..Default::default()
},
Name::new("Chunk Entity"),
NoSendEntity,
ChunkEntity {
structure_entity,
chunk_location: chunk_coordinate,
},
));

if let Some(bw) = body_world {
entity_cmds.insert(*bw);
}

let entity = entity_cmds.id();

commands.entity(structure_entity).add_child(entity);

structure.set_chunk_entity(chunk_coordinate, entity);

chunk_set_events.insert(ChunkSetEvent {
structure_entity,
coords: chunk_coordinate,
});
}

fn add_chunks_system(
mut chunk_init_reader: EventReader<ChunkInitEvent>,
mut block_reader: EventReader<BlockChangedEvent>,
Expand All @@ -532,37 +569,23 @@ fn add_chunks_system(
}

for (structure_entity, chunk_coordinate) in s_chunks {
if let Ok((mut structure, body_world)) = structure_query.get_mut(structure_entity) {
if let Some(chunk) = structure.chunk_from_chunk_coordinates(chunk_coordinate) {
if !chunk.is_empty() && structure.chunk_entity(chunk_coordinate).is_none() {
let mut entity_cmds = commands.spawn((
PbrBundle {
transform: Transform::from_translation(structure.chunk_relative_position(chunk_coordinate)),
..Default::default()
},
NoSendEntity,
ChunkEntity {
structure_entity,
chunk_location: chunk_coordinate,
},
));

if let Some(bw) = body_world {
entity_cmds.insert(*bw);
}

let entity = entity_cmds.id();

commands.entity(structure_entity).add_child(entity);

structure.set_chunk_entity(chunk_coordinate, entity);

chunk_set_events.insert(ChunkSetEvent {
structure_entity,
coords: chunk_coordinate,
});
}
}
let Ok((mut structure, body_world)) = structure_query.get_mut(structure_entity) else {
continue;
};

let Some(chunk) = structure.chunk_from_chunk_coordinates(chunk_coordinate) else {
continue;
};

if !chunk.is_empty() && structure.chunk_entity(chunk_coordinate).is_none() {
spawn_chunk_entity(
&mut commands,
&mut structure,
chunk_coordinate,
structure_entity,
body_world,
&mut chunk_set_events,
);
}
}

Expand Down
1 change: 1 addition & 0 deletions cosmos_server/src/events/netty/netty_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ fn handle_events_system(
PlayerLooking { rotation: Quat::IDENTITY },
LoadingDistance::new(2, 9999),
ActiveEvents::COLLISION_EVENTS,
Name::new(format!("Player ({name})")),
));

let entity = player_commands.id();
Expand Down
2 changes: 1 addition & 1 deletion cosmos_server/src/persistence/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ impl SerializedData {
}

/// Returns true if a sector has at some point been generated at this location
pub fn is_sector_loaded(sector: Sector) -> bool {
pub fn is_sector_generated(sector: Sector) -> bool {
fs::try_exists(SaveFileIdentifier::get_sector_path(sector)).unwrap_or(false)
}

Expand Down
4 changes: 2 additions & 2 deletions cosmos_server/src/persistence/player_loading.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use std::{ffi::OsStr, fs, time::Duration};

use bevy::{
prelude::{warn, App, Commands, Component, DespawnRecursiveExt, Entity, IntoSystemConfigs, Query, ResMut, Update, With, Without},
prelude::{warn, App, Commands, Component, DespawnRecursiveExt, Entity, IntoSystemConfigs, Name, Query, ResMut, Update, With, Without},
tasks::{AsyncComputeTaskPool, Task},
time::common_conditions::on_timer,
};
Expand Down Expand Up @@ -62,7 +62,7 @@ fn monitor_loading_task(
.entity_id()
.expect("A non-base SaveFileIdentifier was attempted to be loaded in load_near")
}) {
commands.spawn((sfi, NeedsLoaded));
commands.spawn((sfi, NeedsLoaded, Name::new("Needs Loaded Entity")));
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions cosmos_server/src/structure/asteroid/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
use bevy::prelude::App;

mod generator;
mod persistence;
pub mod server_asteroid_builder;
mod sync;

pub(super) fn register(app: &mut App) {
sync::register(app);
generator::register(app);
persistence::register(app);
}
103 changes: 103 additions & 0 deletions cosmos_server/src/structure/asteroid/persistence.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use bevy::prelude::*;
use cosmos_core::structure::{
asteroid::{asteroid_builder::TAsteroidBuilder, Asteroid},
events::StructureLoadedEvent,
structure_iterator::ChunkIteratorResult,
ChunkInitEvent, Structure,
};

use crate::persistence::{
loading::{begin_loading, done_loading, NeedsLoaded},
saving::{begin_saving, done_saving, NeedsSaved},
SerializedData,
};

use super::server_asteroid_builder::ServerAsteroidBuilder;

fn on_save_structure(mut query: Query<(&mut SerializedData, &Structure), (With<NeedsSaved>, With<Asteroid>)>) {
for (mut s_data, structure) in query.iter_mut() {
s_data.serialize_data("cosmos:structure", structure);
s_data.serialize_data("cosmos:is_asteroid", &true);
}
}

fn on_load_structure(
query: Query<(Entity, &SerializedData), With<NeedsLoaded>>,
mut event_writer: EventWriter<DelayedStructureLoadEvent>,
mut commands: Commands,
) {
for (entity, s_data) in query.iter() {
if s_data.deserialize_data::<bool>("cosmos:is_asteroid").unwrap_or(false) {
if let Some(mut structure) = s_data.deserialize_data::<Structure>("cosmos:structure") {
let loc = s_data
.deserialize_data("cosmos:location")
.expect("Every asteroid should have a location when saved!");

let mut entity_cmd = commands.entity(entity);

let builder = ServerAsteroidBuilder::default();

builder.insert_asteroid(&mut entity_cmd, loc, &mut structure);

let entity = entity_cmd.id();

event_writer.send(DelayedStructureLoadEvent(entity));

commands.entity(entity).insert(structure);
}
}
}
}

/// I hate this, but the only way to prevent issues with events is to delay the sending of the chunk init events
/// by 2 frames, so two events are needed to do this. This is really horrible, but the only way I can think of
/// to get this to work ;(
#[derive(Debug, Event)]
struct DelayedStructureLoadEvent(pub Entity);
#[derive(Debug, Event)]
struct EvenMoreDelayedStructureLoadEvent(Entity);

fn delayed_structure_event(
mut event_reader: EventReader<DelayedStructureLoadEvent>,
mut event_writer: EventWriter<EvenMoreDelayedStructureLoadEvent>,
) {
for ev in event_reader.iter() {
event_writer.send(EvenMoreDelayedStructureLoadEvent(ev.0));
}
}

fn even_more_delayed_structure_event(
mut event_reader: EventReader<EvenMoreDelayedStructureLoadEvent>,
mut chunk_set_event_writer: EventWriter<ChunkInitEvent>,
mut structure_loaded_event_writer: EventWriter<StructureLoadedEvent>,
query: Query<&Structure>,
) {
for ev in event_reader.iter() {
if let Ok(structure) = query.get(ev.0) {
for res in structure.all_chunks_iter(false) {
// This will always be true because include_empty is false
if let ChunkIteratorResult::FilledChunk {
position: coords,
chunk: _,
} = res
{
chunk_set_event_writer.send(ChunkInitEvent {
structure_entity: ev.0,
coords,
});
}
}
}

structure_loaded_event_writer.send(StructureLoadedEvent { structure_entity: ev.0 });
}
}

pub(super) fn register(app: &mut App) {
app.add_systems(PreUpdate, even_more_delayed_structure_event)
.add_systems(Update, delayed_structure_event)
.add_event::<DelayedStructureLoadEvent>()
.add_event::<EvenMoreDelayedStructureLoadEvent>()
.add_systems(First, on_save_structure.after(begin_saving).before(done_saving))
.add_systems(Update, on_load_structure.after(begin_loading).before(done_loading));
}
21 changes: 13 additions & 8 deletions cosmos_server/src/structure/planet/persistence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ fn populate_chunks(
.insert((
serialized_data,
NeedsLoaded,
Name::new("Needs Loaded Chunk"),
NoSendEntity,
ChunkEntity {
structure_entity: needs.structure_entity,
Expand All @@ -137,10 +138,13 @@ fn populate_chunks(
} else {
commands
.entity(entity)
.insert(ChunkNeedsGenerated {
coords: needs.chunk_coords,
structure_entity: needs.structure_entity,
})
.insert((
ChunkNeedsGenerated {
coords: needs.chunk_coords,
structure_entity: needs.structure_entity,
},
Name::new("Needs Generated Chunk"),
))
.remove::<ChunkNeedsPopulated>();
}
}
Expand All @@ -157,10 +161,11 @@ fn load_chunk(
if let Ok(mut structure) = structure_query.get_mut(ce.structure_entity) {
let coords = chunk.chunk_coordinates();

commands.entity(entity).insert(PbrBundle {
transform: Transform::from_translation(structure.chunk_relative_position(coords)),
..Default::default()
});
commands
.entity(entity)
.insert(TransformBundle::from_transform(Transform::from_translation(
structure.chunk_relative_position(coords),
)));

structure.set_chunk_entity(coords, entity);

Expand Down
2 changes: 0 additions & 2 deletions cosmos_server/src/structure/ship/persistence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,6 @@ fn even_more_delayed_structure_event(

pub(super) fn register(app: &mut App) {
app.add_systems(PreUpdate, even_more_delayed_structure_event)
// After to ensure 1 frame delay
// Used to have `.after(even_more_delayed_structure_event)`
.add_systems(Update, delayed_structure_event)
.add_event::<DelayedStructureLoadEvent>()
.add_event::<EvenMoreDelayedStructureLoadEvent>()
Expand Down
Loading
Loading