single-build structure view on-load.
TODO: swapping between grid view and structure view. multiple of each being loaded, selecting bringing it to view. creating new structure and grid assets from UI.
This commit is contained in:
parent
0e19a10325
commit
63b49c70c7
|
@ -3,7 +3,7 @@
|
||||||
use bevy::{diagnostic::FrameTimeDiagnosticsPlugin, prelude::*, window::WindowResolution};
|
use bevy::{diagnostic::FrameTimeDiagnosticsPlugin, prelude::*, window::WindowResolution};
|
||||||
|
|
||||||
use crate::vvlib::{
|
use crate::vvlib::{
|
||||||
s_oct_asset::{self, OctAssetMarker, OctTreeAsset},
|
s_oct_asset::{self},
|
||||||
s_structure_asset::StructureAssetPlugin,
|
s_structure_asset::StructureAssetPlugin,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ pub fn setup(app: &mut App) -> &mut App {
|
||||||
app.add_plugins(DefaultPlugins.set(WindowPlugin {
|
app.add_plugins(DefaultPlugins.set(WindowPlugin {
|
||||||
primary_window: Some(Window {
|
primary_window: Some(Window {
|
||||||
resolution: WindowResolution::new(1152., 864.).with_scale_factor_override(1.0),
|
resolution: WindowResolution::new(1152., 864.).with_scale_factor_override(1.0),
|
||||||
title: "testbed".to_string(),
|
title: "VixeVoxe".to_string(),
|
||||||
..default()
|
..default()
|
||||||
}),
|
}),
|
||||||
..default()
|
..default()
|
||||||
|
@ -37,44 +37,4 @@ pub fn setup(app: &mut App) -> &mut App {
|
||||||
s_editor_ui::register_edit_ui(app)
|
s_editor_ui::register_edit_ui(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn startup(
|
pub fn startup() {}
|
||||||
mut pairs: ResMut<s_oct_asset::MeshingOctTreePairs>,
|
|
||||||
asset_server: Res<AssetServer>,
|
|
||||||
mesh_assets: ResMut<Assets<Mesh>>,
|
|
||||||
mut oct_assets: ResMut<Assets<OctTreeAsset>>,
|
|
||||||
mut commands: Commands,
|
|
||||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
|
||||||
) {
|
|
||||||
let id = OctTreeAsset::load(&mut pairs, asset_server, mesh_assets, "test.vvg".into());
|
|
||||||
let parent = commands
|
|
||||||
.spawn(TransformBundle {
|
|
||||||
local: Transform::from_scale(Vec3::splat(0.25)),
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
.id();
|
|
||||||
let child = commands
|
|
||||||
.spawn((
|
|
||||||
PbrBundle {
|
|
||||||
mesh: id.clone(),
|
|
||||||
material: materials.add(Color::rgb(1., 1., 1.)),
|
|
||||||
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
OctAssetMarker {
|
|
||||||
oct_handle: pairs.oct_handle_for(id, &mut oct_assets),
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.id();
|
|
||||||
commands.entity(parent).add_child(child);
|
|
||||||
let light_transform = Transform::from_xyz(1.8, 1.8, 1.8).looking_at(Vec3::ZERO, Vec3::Y);
|
|
||||||
|
|
||||||
commands.spawn(PointLightBundle {
|
|
||||||
point_light: PointLight {
|
|
||||||
intensity: 100000.0,
|
|
||||||
range: 1000.0,
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
transform: light_transform,
|
|
||||||
..default()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,16 +1,7 @@
|
||||||
use bevy::{
|
use bevy::{
|
||||||
app::{Startup, Update},
|
app::{Startup, Update}, asset::{AssetServer, Assets, Handle}, ecs::{
|
||||||
asset::{AssetServer, Assets, Handle},
|
entity::Entity, event::EventWriter, query::With, system::{Commands, Query, Res, ResMut, Resource}
|
||||||
ecs::{
|
}, hierarchy::BuildChildren, math::Vec3, pbr::{PointLight, PointLightBundle}, prelude::{default, SpatialBundle}, render::{camera::Camera, color::Color}, transform::{components::{GlobalTransform, Transform}, TransformBundle}, window::{PrimaryWindow, Window, WindowResolution}
|
||||||
entity::Entity,
|
|
||||||
query::With,
|
|
||||||
system::{Commands, Query, Res, ResMut, Resource},
|
|
||||||
},
|
|
||||||
math::Vec3,
|
|
||||||
prelude::default,
|
|
||||||
render::{camera::Camera, color::Color},
|
|
||||||
transform::components::{GlobalTransform, Transform},
|
|
||||||
window::{PrimaryWindow, Window, WindowResolution},
|
|
||||||
};
|
};
|
||||||
use bevy_egui::{
|
use bevy_egui::{
|
||||||
egui::{self, color_picker, epaint::Hsva, Id, Pos2, Rect, ScrollArea},
|
egui::{self, color_picker, epaint::Hsva, Id, Pos2, Rect, ScrollArea},
|
||||||
|
@ -21,7 +12,7 @@ use crate::{
|
||||||
vvedit::s_editor_bevy_input_shim::keybind_codes::REMOVE_VOXEL,
|
vvedit::s_editor_bevy_input_shim::keybind_codes::REMOVE_VOXEL,
|
||||||
vvlib::{
|
vvlib::{
|
||||||
s_inputs::InputRegister, s_intersections::octtree_ray_overlap, s_obb::OBB,
|
s_inputs::InputRegister, s_intersections::octtree_ray_overlap, s_obb::OBB,
|
||||||
s_oct_asset::OctAssetMarker, s_structure_asset::StructureAsset,
|
s_oct_asset::OctAssetMarker, s_structure_asset::{StructureAsset, StructureComponent, StructureUpdateMessage, StructureUpdateType},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -59,6 +50,7 @@ pub struct EditWindowUIState {
|
||||||
pub selected_structure_element: String,
|
pub selected_structure_element: String,
|
||||||
pub selected_structure: String,
|
pub selected_structure: String,
|
||||||
pub selected_grid: String,
|
pub selected_grid: String,
|
||||||
|
pub display_state: DisplayState,
|
||||||
}
|
}
|
||||||
impl Default for EditWindowUIState {
|
impl Default for EditWindowUIState {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
@ -71,6 +63,7 @@ impl Default for EditWindowUIState {
|
||||||
selected_structure_element: "".into(),
|
selected_structure_element: "".into(),
|
||||||
selected_structure: "".into(),
|
selected_structure: "".into(),
|
||||||
selected_grid: "".into(),
|
selected_grid: "".into(),
|
||||||
|
display_state: Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,6 +84,14 @@ impl PopupWindowMode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Clone)]
|
||||||
|
pub enum DisplayState {
|
||||||
|
#[default]
|
||||||
|
None, //nothing loaded yet
|
||||||
|
GridView(String),
|
||||||
|
StructureView(String),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct EditWindowEguiState {
|
pub struct EditWindowEguiState {
|
||||||
pub popup_identifier: Option<Id>,
|
pub popup_identifier: Option<Id>,
|
||||||
|
@ -184,7 +185,6 @@ pub fn register_edit_ui(
|
||||||
) -> &mut bevy::prelude::App {
|
) -> &mut bevy::prelude::App {
|
||||||
app.insert_resource(EditWindowUIState {
|
app.insert_resource(EditWindowUIState {
|
||||||
brush_color: egui_color_from(Color::RED),
|
brush_color: egui_color_from(Color::RED),
|
||||||
grids: Vec::new(),
|
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
app.add_plugins(EguiPlugin);
|
app.add_plugins(EguiPlugin);
|
||||||
|
@ -199,19 +199,64 @@ pub fn register_edit_ui(
|
||||||
|
|
||||||
pub fn startup_system_edit_ui(
|
pub fn startup_system_edit_ui(
|
||||||
// formatting comment
|
// formatting comment
|
||||||
commands: Commands,
|
mut commands: Commands,
|
||||||
mut shared_ui_state: ResMut<EditWindowUIState>,
|
mut shared_ui_state: ResMut<EditWindowUIState>,
|
||||||
asset_server: ResMut<AssetServer>,
|
asset_server: ResMut<AssetServer>,
|
||||||
|
//mut pairs: ResMut<MeshingOctTreePairs>,
|
||||||
|
//mesh_assets: ResMut<Assets<Mesh>>,
|
||||||
|
mut event_writer: EventWriter<StructureUpdateMessage>,
|
||||||
) {
|
) {
|
||||||
spawn_camera(commands);
|
spawn_camera(&mut commands);
|
||||||
let str = "test.vvs";
|
let str = "test.vvs";
|
||||||
let handle = asset_server.load::<StructureAsset>(str);
|
let handle = asset_server.load::<StructureAsset>(str);
|
||||||
let data = StructureEditData {
|
let data = StructureEditData {
|
||||||
path: str.into(),
|
path: str.into(),
|
||||||
id: handle,
|
id: handle.clone(),
|
||||||
has_changed_since_last_save: false,
|
has_changed_since_last_save: false,
|
||||||
};
|
};
|
||||||
shared_ui_state.structures.push(data);
|
shared_ui_state.structures.push(data);
|
||||||
|
|
||||||
|
//let id = OctTreeAsset::load(&mut pairs, asset_server.into(), mesh_assets, "test.vvg".into());
|
||||||
|
let parent = commands
|
||||||
|
.spawn(TransformBundle {
|
||||||
|
local: Transform::from_scale(Vec3::splat(1f32)),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.id();
|
||||||
|
/*let child = commands
|
||||||
|
.spawn((
|
||||||
|
PbrBundle {
|
||||||
|
mesh: id.clone(),
|
||||||
|
material: materials.add(Color::rgb(1., 1., 1.)),
|
||||||
|
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
OctAssetMarker {
|
||||||
|
oct_handle: pairs.oct_handle_for(id, &mut oct_assets),
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.id();
|
||||||
|
commands.entity(parent).add_child(child);*/
|
||||||
|
let id = commands.spawn((SpatialBundle::INHERITED_IDENTITY, StructureComponent {
|
||||||
|
asset: handle,
|
||||||
|
nodes: Default::default(),
|
||||||
|
})).id();
|
||||||
|
commands.entity(parent).add_child(id.clone());
|
||||||
|
event_writer.send(StructureUpdateMessage {
|
||||||
|
update_type: StructureUpdateType::Build,
|
||||||
|
entity: id,
|
||||||
|
});
|
||||||
|
let light_transform = Transform::from_xyz(7f32, 7f32, 7f32).looking_at(Vec3::ZERO, Vec3::Y);
|
||||||
|
|
||||||
|
commands.spawn(PointLightBundle {
|
||||||
|
point_light: PointLight {
|
||||||
|
intensity: 100000.0,
|
||||||
|
range: 10000.0,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
transform: light_transform,
|
||||||
|
..default()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
fn update_ui_scale_factor(
|
fn update_ui_scale_factor(
|
||||||
mut egui_settings: ResMut<EguiSettings>,
|
mut egui_settings: ResMut<EguiSettings>,
|
||||||
|
|
|
@ -127,8 +127,8 @@ pub mod orbit_camera {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Spawn a camera like this
|
/// Spawn a camera like this
|
||||||
pub fn spawn_camera(mut commands: Commands) {
|
pub fn spawn_camera(commands: &mut Commands) {
|
||||||
let translation = Vec3::new(-2.0, 2.5, 5.0);
|
let translation = Vec3::new(-5.0, 5f32, 10.0);
|
||||||
let radius = translation.length();
|
let radius = translation.length();
|
||||||
|
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
|
|
|
@ -1,7 +1,20 @@
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
use bevy::{
|
use bevy::{
|
||||||
app::{App, Plugin},
|
app::{App, Plugin, Update},
|
||||||
asset::{Asset, AssetApp, AssetLoader, AssetServer, AsyncReadExt, Handle},
|
asset::{Asset, AssetApp, AssetLoader, AssetServer, Assets, AsyncReadExt, Handle},
|
||||||
|
ecs::{
|
||||||
|
component::Component,
|
||||||
|
entity::Entity,
|
||||||
|
event::{Event, EventReader},
|
||||||
|
system::{Commands, Query, ResMut},
|
||||||
|
world::Mut,
|
||||||
|
},
|
||||||
|
hierarchy::{BuildChildren, DespawnRecursiveExt},
|
||||||
|
pbr::{PbrBundle, StandardMaterial},
|
||||||
|
prelude::{default, SpatialBundle},
|
||||||
reflect::TypePath,
|
reflect::TypePath,
|
||||||
|
render::{color::Color, mesh::Mesh, view::Visibility},
|
||||||
transform::components::Transform,
|
transform::components::Transform,
|
||||||
utils::{hashbrown::HashMap, thiserror},
|
utils::{hashbrown::HashMap, thiserror},
|
||||||
};
|
};
|
||||||
|
@ -10,7 +23,7 @@ use s_string_tree::StringTree;
|
||||||
use crate::vvedit::s_string_tree;
|
use crate::vvedit::s_string_tree;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use super::s_oct_asset::OctTreeAsset;
|
use super::s_oct_asset::{MeshingOctTreePairs, OctAssetMarker, OctTreeAsset};
|
||||||
|
|
||||||
#[derive(Asset, TypePath)]
|
#[derive(Asset, TypePath)]
|
||||||
pub struct StructureAsset {
|
pub struct StructureAsset {
|
||||||
|
@ -18,6 +31,169 @@ pub struct StructureAsset {
|
||||||
pub default_pose_positions: HashMap<String, Transform>,
|
pub default_pose_positions: HashMap<String, Transform>,
|
||||||
pub element_data: HashMap<String, ElementData>,
|
pub element_data: HashMap<String, ElementData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct StructureComponent {
|
||||||
|
pub asset: Handle<StructureAsset>,
|
||||||
|
pub nodes: HashMap<String, Entity>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Event)]
|
||||||
|
pub struct StructureUpdateMessage {
|
||||||
|
pub update_type: StructureUpdateType,
|
||||||
|
pub entity: Entity,
|
||||||
|
}
|
||||||
|
pub enum StructureUpdateType {
|
||||||
|
Build, // just builds.
|
||||||
|
Rebuild, // deletes old nodes and rebuilds
|
||||||
|
Reshape, //moves transforms and that's it
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build_tree(
|
||||||
|
root_entity: &Entity,
|
||||||
|
asset: &StructureAsset,
|
||||||
|
structure_component: Mut<StructureComponent>,
|
||||||
|
materials: &mut ResMut<Assets<StandardMaterial>>,
|
||||||
|
meshes: &mut ResMut<Assets<Mesh>>,
|
||||||
|
pairs: &mut ResMut<MeshingOctTreePairs>,
|
||||||
|
commands: &mut Commands,
|
||||||
|
) {
|
||||||
|
let mut sorted_construction_order = asset.layout.list_of_elements();
|
||||||
|
sorted_construction_order.sort_by(|left, right| {
|
||||||
|
if let Some(left) = asset.layout.depth_of(left) {
|
||||||
|
if let Some(right) = asset.layout.depth_of(right) {
|
||||||
|
return left.cmp(&right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Ordering::Equal;
|
||||||
|
});
|
||||||
|
for each in sorted_construction_order {
|
||||||
|
if let Some(element_data) = asset.element_data.get(&each) {
|
||||||
|
let trans = {
|
||||||
|
if let Some(transform) = asset.default_pose_positions.get(&each) {
|
||||||
|
transform
|
||||||
|
} else {
|
||||||
|
&Transform::IDENTITY
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let p_entity = {
|
||||||
|
if let Some(parent) = asset.layout.parent_of(&each) {
|
||||||
|
if let Some(result) = structure_component.nodes.get(parent) {
|
||||||
|
result
|
||||||
|
} else {
|
||||||
|
&root_entity
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
&root_entity
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let child = {
|
||||||
|
match element_data {
|
||||||
|
ElementData::None => {
|
||||||
|
let mut spat_bundle = SpatialBundle::from_transform(trans.clone());
|
||||||
|
spat_bundle.visibility = Visibility::Inherited;
|
||||||
|
commands.spawn(spat_bundle).id()
|
||||||
|
}
|
||||||
|
ElementData::Unprocessed(_) => {
|
||||||
|
println!("somehow not processed in build");
|
||||||
|
let mut spat_bundle = SpatialBundle::from_transform(trans.clone());
|
||||||
|
spat_bundle.visibility = Visibility::Inherited;
|
||||||
|
commands.spawn(spat_bundle).id()
|
||||||
|
}
|
||||||
|
ElementData::MeshAsset(handle, _) => {
|
||||||
|
let mut spat_bundle = SpatialBundle::from_transform(trans.clone());
|
||||||
|
spat_bundle.visibility = Visibility::Inherited;
|
||||||
|
commands
|
||||||
|
.spawn(spat_bundle)
|
||||||
|
.with_children(|parent| {
|
||||||
|
parent.spawn((
|
||||||
|
PbrBundle {
|
||||||
|
mesh: pairs.mesh_handle_for(handle.clone(), meshes),
|
||||||
|
material: materials.add(Color::rgb(1., 1., 1.)),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
OctAssetMarker {
|
||||||
|
oct_handle: handle.clone(),
|
||||||
|
},
|
||||||
|
));
|
||||||
|
})
|
||||||
|
.id()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
commands.entity(p_entity.clone()).add_child(child.clone());
|
||||||
|
println!("{}", child.clone().to_bits());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn structure_update(
|
||||||
|
mut events: EventReader<StructureUpdateMessage>,
|
||||||
|
mut tracker: Query<(Entity, &mut StructureComponent)>,
|
||||||
|
mut shaper: Query<(Entity, &mut Transform)>,
|
||||||
|
mut structure_assets: ResMut<Assets<StructureAsset>>,
|
||||||
|
mut asset_server: ResMut<AssetServer>,
|
||||||
|
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||||
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
|
mut pairs: ResMut<MeshingOctTreePairs>,
|
||||||
|
mut commands: Commands,
|
||||||
|
) {
|
||||||
|
for event in events.read() {
|
||||||
|
if let Ok((root_entity, mut structure_component)) = tracker.get_mut(event.entity) {
|
||||||
|
let handle = structure_component.asset.clone();
|
||||||
|
if let Some(asset) = structure_assets.get_mut(handle.clone()) {
|
||||||
|
for (_, element) in &mut asset.element_data {
|
||||||
|
if element.needs_processing() {
|
||||||
|
if let Some(processed_value) =
|
||||||
|
element.process_from_save_format(&mut asset_server)
|
||||||
|
{
|
||||||
|
*element = processed_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(asset) = structure_assets.get_mut(handle.clone()) {
|
||||||
|
match event.update_type {
|
||||||
|
StructureUpdateType::Build => build_tree(
|
||||||
|
&root_entity,
|
||||||
|
asset,
|
||||||
|
structure_component,
|
||||||
|
&mut materials,
|
||||||
|
&mut meshes,
|
||||||
|
&mut pairs,
|
||||||
|
&mut commands,
|
||||||
|
),
|
||||||
|
StructureUpdateType::Rebuild => {
|
||||||
|
for (_, each) in &structure_component.nodes {
|
||||||
|
commands.entity(each.clone()).despawn_recursive();
|
||||||
|
}
|
||||||
|
structure_component.nodes.clear();
|
||||||
|
build_tree(
|
||||||
|
&root_entity,
|
||||||
|
asset,
|
||||||
|
structure_component,
|
||||||
|
&mut materials,
|
||||||
|
&mut meshes,
|
||||||
|
&mut pairs,
|
||||||
|
&mut commands,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
StructureUpdateType::Reshape => {
|
||||||
|
for (name, ent) in &structure_component.nodes {
|
||||||
|
if let Ok((_, mut trans)) = shaper.get_mut(ent.clone()) {
|
||||||
|
if let Some(value) = asset.default_pose_positions.get(name) {
|
||||||
|
trans.clone_from(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum ElementData {
|
pub enum ElementData {
|
||||||
None,
|
None,
|
||||||
|
@ -25,6 +201,12 @@ pub enum ElementData {
|
||||||
MeshAsset(Handle<OctTreeAsset>, String), //store path
|
MeshAsset(Handle<OctTreeAsset>, String), //store path
|
||||||
}
|
}
|
||||||
impl ElementData {
|
impl ElementData {
|
||||||
|
pub fn needs_processing(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Self::Unprocessed(_) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
pub fn is_none(&self) -> bool {
|
pub fn is_none(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
ElementData::None => true,
|
ElementData::None => true,
|
||||||
|
@ -38,11 +220,13 @@ impl ElementData {
|
||||||
ElementData::MeshAsset(_, path) => Some(format!("grid|{path}")),
|
ElementData::MeshAsset(_, path) => Some(format!("grid|{path}")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn process_from_save_format(&mut self, server: &mut AssetServer) -> Option<Self> {
|
pub fn process_from_save_format(&mut self, server: &mut ResMut<AssetServer>) -> Option<Self> {
|
||||||
let mut result_change = ElementData::None;
|
let mut result_change = ElementData::None;
|
||||||
match self {
|
match self {
|
||||||
ElementData::Unprocessed(contents) => {
|
ElementData::Unprocessed(contents) => {
|
||||||
|
println!("{}", contents.clone());
|
||||||
let mut sides = contents.split("|");
|
let mut sides = contents.split("|");
|
||||||
|
sides.next();
|
||||||
let left = sides.next();
|
let left = sides.next();
|
||||||
if left.is_none() {
|
if left.is_none() {
|
||||||
return None;
|
return None;
|
||||||
|
@ -82,6 +266,8 @@ impl Plugin for StructureAssetPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.init_asset_loader::<StructureLoader>();
|
app.init_asset_loader::<StructureLoader>();
|
||||||
app.init_asset::<StructureAsset>();
|
app.init_asset::<StructureAsset>();
|
||||||
|
app.add_systems(Update, structure_update);
|
||||||
|
app.add_event::<StructureUpdateMessage>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -494,11 +680,6 @@ pub mod serialization {
|
||||||
} else {
|
} else {
|
||||||
return None;
|
return None;
|
||||||
}*/
|
}*/
|
||||||
if let Some(children) = each.children() {
|
|
||||||
for each in children {
|
|
||||||
to_process.push(each);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// v HELPER FUNCTION
|
// v HELPER FUNCTION
|
||||||
fn save_child(element: &String, tree: &StringTree, data: &mut String) {
|
fn save_child(element: &String, tree: &StringTree, data: &mut String) {
|
||||||
|
@ -556,14 +737,18 @@ pub mod serialization {
|
||||||
data += "||";
|
data += "||";
|
||||||
// v NODE DATA SUCH AS RELIANT GRIDS
|
// v NODE DATA SUCH AS RELIANT GRIDS
|
||||||
for (name, element_data) in &asset.element_data {
|
for (name, element_data) in &asset.element_data {
|
||||||
data += NEWLINE;
|
|
||||||
data += name.as_str();
|
|
||||||
data += "|";
|
|
||||||
let save_formatted = element_data.to_save_format();
|
let save_formatted = element_data.to_save_format();
|
||||||
if save_formatted.is_none() {
|
if save_formatted.is_none() {
|
||||||
|
println!("Couldn't save element data to save format");
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
data += save_formatted.unwrap().as_str();
|
let formatted = save_formatted.unwrap();
|
||||||
|
if formatted.trim() != "" {
|
||||||
|
data += NEWLINE;
|
||||||
|
data += name.as_str();
|
||||||
|
data += "|";
|
||||||
|
data += formatted.as_str();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// ^ NODE DATA SUCH AS RELIANT GRIDS
|
// ^ NODE DATA SUCH AS RELIANT GRIDS
|
||||||
Some(data.as_bytes().to_vec())
|
Some(data.as_bytes().to_vec())
|
||||||
|
|
Loading…
Reference in a new issue