2022-09-03 21:40:18 +02:00
|
|
|
#![warn(absolute_paths_not_starting_with_crate)]
|
|
|
|
// #![warn(box_pointers)]
|
|
|
|
#![warn(elided_lifetimes_in_paths)]
|
|
|
|
#![warn(explicit_outlives_requirements)]
|
|
|
|
#![warn(keyword_idents)]
|
|
|
|
#![warn(macro_use_extern_crate)]
|
|
|
|
#![warn(meta_variable_misuse)]
|
|
|
|
#![warn(missing_abi)]
|
2022-09-06 12:08:05 +02:00
|
|
|
// #![warn(missing_copy_implementations)]
|
2022-09-03 21:40:18 +02:00
|
|
|
#![warn(missing_debug_implementations)]
|
|
|
|
// #![warn(missing_docs)]
|
|
|
|
#![warn(non_ascii_idents)]
|
|
|
|
#![warn(noop_method_call)]
|
|
|
|
#![warn(pointer_structural_match)]
|
|
|
|
#![warn(rust_2021_incompatible_closure_captures)]
|
|
|
|
#![warn(rust_2021_incompatible_or_patterns)]
|
|
|
|
#![warn(rust_2021_prefixes_incompatible_syntax)]
|
|
|
|
#![warn(rust_2021_prelude_collisions)]
|
|
|
|
#![warn(single_use_lifetimes)]
|
|
|
|
#![warn(trivial_casts)]
|
|
|
|
#![warn(trivial_numeric_casts)]
|
|
|
|
#![warn(unreachable_pub)]
|
|
|
|
#![warn(unsafe_code)]
|
|
|
|
#![warn(unsafe_op_in_unsafe_fn)]
|
|
|
|
#![warn(unstable_features)]
|
|
|
|
#![warn(unused_crate_dependencies)]
|
|
|
|
#![warn(unused_extern_crates)]
|
|
|
|
#![warn(unused_import_braces)]
|
|
|
|
#![warn(unused_lifetimes)]
|
|
|
|
#![warn(unused_macro_rules)]
|
|
|
|
#![warn(unused_qualifications)]
|
|
|
|
#![warn(unused_results)]
|
|
|
|
#![warn(variant_size_differences)]
|
2022-08-25 15:45:45 +02:00
|
|
|
|
2022-09-06 20:40:27 +02:00
|
|
|
mod components;
|
2022-09-06 15:40:09 +02:00
|
|
|
mod plugins;
|
2022-09-06 20:40:27 +02:00
|
|
|
mod resources;
|
|
|
|
mod ui_helpers;
|
2022-09-05 11:43:50 +02:00
|
|
|
|
2022-09-06 11:07:13 +02:00
|
|
|
use bevy::{
|
|
|
|
app::App,
|
2022-09-06 20:40:27 +02:00
|
|
|
log::LogSettings,
|
|
|
|
utils::{default, tracing::Level},
|
2022-09-06 11:07:13 +02:00
|
|
|
};
|
2022-09-06 22:09:53 +02:00
|
|
|
#[cfg(all(feature = "render", feature = "planet_view"))]
|
|
|
|
use bevy::{
|
|
|
|
asset::Handle,
|
|
|
|
core_pipeline::core_3d::Camera3dBundle,
|
|
|
|
pbr::{PbrBundle, PointLight, PointLightBundle, StandardMaterial},
|
|
|
|
prelude::Vec3,
|
|
|
|
render::camera::OrthographicProjection,
|
|
|
|
render::mesh::{shape::Icosphere, Mesh},
|
|
|
|
transform::components::Transform,
|
|
|
|
};
|
2022-09-05 11:43:50 +02:00
|
|
|
#[cfg(feature = "render")]
|
2022-09-03 21:40:18 +02:00
|
|
|
use bevy::{
|
2022-09-06 22:09:53 +02:00
|
|
|
asset::{AssetServer, Assets},
|
|
|
|
core_pipeline::core_2d::{Camera2d, Camera2dBundle},
|
2022-09-03 21:40:18 +02:00
|
|
|
ecs::{
|
|
|
|
change_detection::ResMut,
|
2022-09-06 11:07:13 +02:00
|
|
|
query::{Changed, With},
|
|
|
|
system::{Commands, Query, Res},
|
2022-09-03 21:40:18 +02:00
|
|
|
},
|
2022-09-06 11:07:13 +02:00
|
|
|
hierarchy::BuildChildren,
|
2022-09-06 22:09:53 +02:00
|
|
|
prelude::Vec2,
|
2022-09-03 21:40:18 +02:00
|
|
|
render::{
|
2022-09-06 22:09:53 +02:00
|
|
|
camera::{Camera, RenderTarget},
|
2022-09-06 11:07:13 +02:00
|
|
|
color::Color,
|
2022-09-03 21:40:18 +02:00
|
|
|
render_resource::{
|
|
|
|
Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages,
|
|
|
|
},
|
|
|
|
texture::{Image, ImageSettings},
|
2022-09-06 11:07:13 +02:00
|
|
|
},
|
2022-09-06 15:40:09 +02:00
|
|
|
sprite::{Sprite, SpriteBundle},
|
|
|
|
text::Text,
|
2022-09-06 22:09:53 +02:00
|
|
|
transform::components::GlobalTransform,
|
2022-09-06 11:07:13 +02:00
|
|
|
ui::{
|
2022-09-06 20:40:27 +02:00
|
|
|
entity::{NodeBundle, TextBundle},
|
|
|
|
AlignSelf, FocusPolicy, Interaction, JustifyContent, PositionType, Size, Style, UiColor,
|
|
|
|
UiRect, Val,
|
2022-09-03 21:40:18 +02:00
|
|
|
},
|
2022-09-06 11:07:13 +02:00
|
|
|
window::{CursorIcon, WindowDescriptor, Windows},
|
2022-09-03 21:40:18 +02:00
|
|
|
winit::WinitSettings,
|
|
|
|
};
|
2022-09-06 22:09:53 +02:00
|
|
|
|
2022-09-06 20:40:27 +02:00
|
|
|
#[cfg(all(feature = "debug", feature = "render"))]
|
|
|
|
use bevy::{
|
|
|
|
diagnostic::{Diagnostics, FrameTimeDiagnosticsPlugin},
|
|
|
|
log::debug,
|
|
|
|
};
|
2022-09-06 15:40:09 +02:00
|
|
|
#[cfg(feature = "render")]
|
2022-09-06 20:40:27 +02:00
|
|
|
use components::{
|
|
|
|
markers::{InfoPanel, ToolbarButton},
|
|
|
|
third_party::PanCam,
|
|
|
|
};
|
2022-09-06 15:40:09 +02:00
|
|
|
use plugins::WorldPlugins;
|
2022-09-06 20:40:27 +02:00
|
|
|
#[cfg(feature = "render")]
|
|
|
|
use resources::CursorMapPosition;
|
2022-09-03 21:40:18 +02:00
|
|
|
use save::*;
|
2022-09-06 20:40:27 +02:00
|
|
|
#[cfg(feature = "render")]
|
|
|
|
use ui_helpers::{toolbar_button, toolbar_button_text};
|
2022-08-25 15:45:45 +02:00
|
|
|
|
2022-09-05 11:43:50 +02:00
|
|
|
#[cfg(feature = "render")]
|
2022-09-06 11:07:13 +02:00
|
|
|
fn refresh_world_texture(images: &mut Assets<Image>, world_manager: &WorldManager) {
|
2022-09-06 20:40:27 +02:00
|
|
|
#[cfg(feature = "debug")]
|
2022-09-06 11:07:13 +02:00
|
|
|
debug!("refreshing world texture");
|
|
|
|
let image_handle = images.get_handle(world_manager.image_handle_id);
|
|
|
|
images.get_mut(&image_handle).unwrap().data = world_manager.world_color_bytes();
|
2022-09-06 16:49:41 +02:00
|
|
|
|
|
|
|
// TODO: Update Icosphere material... try to find out why it doesn't automatically=
|
2022-09-06 11:07:13 +02:00
|
|
|
}
|
|
|
|
|
2022-09-06 12:08:05 +02:00
|
|
|
#[cfg(feature = "render")]
|
2022-09-06 11:07:13 +02:00
|
|
|
const NORMAL_BUTTON: Color = Color::rgb(0.15, 0.15, 0.15);
|
|
|
|
#[cfg(feature = "render")]
|
2022-09-06 20:40:27 +02:00
|
|
|
const HOVERED_BUTTON: Color = Color::rgb(0.25, 0.25, 0.25);
|
2022-09-06 12:08:05 +02:00
|
|
|
#[cfg(feature = "render")]
|
2022-09-06 20:40:27 +02:00
|
|
|
const PRESSED_BUTTON: Color = Color::rgb(0.35, 0.60, 0.35);
|
2022-09-06 12:29:13 +02:00
|
|
|
#[cfg(feature = "render")]
|
2022-09-06 20:40:27 +02:00
|
|
|
fn handle_toolbar_button(
|
2022-09-06 12:29:13 +02:00
|
|
|
mut interaction_query: Query<
|
|
|
|
'_,
|
|
|
|
'_,
|
2022-09-06 20:40:27 +02:00
|
|
|
(&Interaction, &mut UiColor, &ToolbarButton),
|
|
|
|
Changed<Interaction>,
|
2022-09-06 12:29:13 +02:00
|
|
|
>,
|
|
|
|
mut windows: ResMut<'_, Windows>,
|
|
|
|
mut images: ResMut<'_, Assets<Image>>,
|
|
|
|
mut world_manager: ResMut<'_, WorldManager>,
|
|
|
|
) {
|
2022-09-06 20:40:27 +02:00
|
|
|
for (interaction, mut color, toolbar_button) in &mut interaction_query {
|
2022-09-06 12:29:13 +02:00
|
|
|
match *interaction {
|
|
|
|
Interaction::Clicked => {
|
|
|
|
windows.primary_mut().set_cursor_icon(CursorIcon::Default);
|
|
|
|
*color = PRESSED_BUTTON.into();
|
2022-09-06 20:40:27 +02:00
|
|
|
match toolbar_button {
|
|
|
|
ToolbarButton::Rainfall => {
|
|
|
|
#[cfg(feature = "debug")]
|
|
|
|
debug!("Toggling rainfall");
|
|
|
|
world_manager.toggle_rainfall();
|
|
|
|
}
|
|
|
|
ToolbarButton::Temperature => {
|
|
|
|
#[cfg(feature = "debug")]
|
|
|
|
debug!("Toggling temperature");
|
|
|
|
world_manager.toggle_temperature();
|
|
|
|
}
|
|
|
|
ToolbarButton::Contours => {
|
|
|
|
#[cfg(feature = "debug")]
|
|
|
|
debug!("Toggling contours");
|
|
|
|
world_manager.toggle_contours();
|
|
|
|
}
|
2022-09-07 00:44:41 +02:00
|
|
|
ToolbarButton::GenerateWorld => {
|
|
|
|
#[cfg(feature = "debug")]
|
|
|
|
debug!("Generating new world");
|
|
|
|
_ = world_manager
|
|
|
|
.new_world()
|
|
|
|
.expect("Failed to generate new world");
|
|
|
|
}
|
|
|
|
ToolbarButton::SaveWorld => {
|
|
|
|
#[cfg(feature = "debug")]
|
|
|
|
debug!("Saving world");
|
|
|
|
_ = world_manager.save_world("planet.ron");
|
|
|
|
}
|
|
|
|
ToolbarButton::LoadWorld => {
|
|
|
|
#[cfg(feature = "debug")]
|
|
|
|
debug!("Loading world");
|
|
|
|
_ = world_manager.load_world("planet.ron");
|
|
|
|
}
|
2022-09-06 20:40:27 +02:00
|
|
|
}
|
2022-09-06 12:29:13 +02:00
|
|
|
refresh_world_texture(&mut images, &world_manager)
|
|
|
|
}
|
|
|
|
Interaction::Hovered => {
|
|
|
|
windows.primary_mut().set_cursor_icon(CursorIcon::Hand);
|
|
|
|
*color = HOVERED_BUTTON.into();
|
|
|
|
}
|
|
|
|
Interaction::None => {
|
|
|
|
windows.primary_mut().set_cursor_icon(CursorIcon::Default);
|
|
|
|
*color = NORMAL_BUTTON.into();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-06 15:40:09 +02:00
|
|
|
#[cfg(feature = "render")]
|
|
|
|
fn update_cursor_map_position(
|
|
|
|
mut cursor_map_position: ResMut<'_, CursorMapPosition>,
|
|
|
|
transform: Query<'_, '_, (&Camera, &GlobalTransform), With<Camera2d>>,
|
|
|
|
windows: Res<'_, Windows>,
|
|
|
|
world_manager: Res<'_, WorldManager>,
|
|
|
|
) {
|
|
|
|
let (camera, transform) = transform.single();
|
|
|
|
|
|
|
|
let window = match camera.target {
|
|
|
|
RenderTarget::Window(window_id) => windows.get(window_id).unwrap(),
|
|
|
|
RenderTarget::Image(_) => windows.primary(),
|
|
|
|
};
|
|
|
|
|
|
|
|
if let Some(screen_position) = window.cursor_position() {
|
|
|
|
let window_size = Vec2::new(window.width(), window.height());
|
|
|
|
|
|
|
|
// GPU coordinates [-1..1]
|
2022-09-06 23:16:47 +02:00
|
|
|
let ndc = (screen_position / window_size) * 2.0 - Vec2::ONE;
|
2022-09-06 15:40:09 +02:00
|
|
|
|
|
|
|
// Matrix to reverse camera transform
|
|
|
|
let ndc_to_world = transform.compute_matrix() * camera.projection_matrix().inverse();
|
|
|
|
|
|
|
|
let world_position =
|
|
|
|
ndc_to_world.project_point3(ndc.extend(-1.0)).truncate() / WORLD_SCALE as f32;
|
|
|
|
|
2022-09-06 23:16:47 +02:00
|
|
|
let world = world_manager.world();
|
|
|
|
cursor_map_position.x = world_position.x as i32 + world.width / 2 - 1;
|
|
|
|
cursor_map_position.y = world.height / 2 - world_position.y as i32 - 1;
|
2022-09-06 15:40:09 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-06 22:09:53 +02:00
|
|
|
#[cfg(all(feature = "render", feature = "planet_view"))]
|
2022-09-06 16:49:41 +02:00
|
|
|
const ROTATION_SPEED: f32 = 0.002;
|
2022-09-06 22:09:53 +02:00
|
|
|
#[cfg(all(feature = "render", feature = "planet_view"))]
|
2022-09-06 16:49:41 +02:00
|
|
|
fn rotate_planet(mut planet_transform: Query<'_, '_, &mut Transform, With<Handle<Mesh>>>) {
|
|
|
|
planet_transform.single_mut().rotate_y(ROTATION_SPEED);
|
|
|
|
}
|
|
|
|
|
2022-09-06 15:40:09 +02:00
|
|
|
#[cfg(feature = "render")]
|
|
|
|
fn update_info_panel(
|
2022-09-06 20:40:27 +02:00
|
|
|
#[cfg(feature = "debug")] diagnostics: Res<'_, Diagnostics>,
|
2022-09-06 15:40:09 +02:00
|
|
|
cursor_position: Res<'_, CursorMapPosition>,
|
|
|
|
world_manager: Res<'_, WorldManager>,
|
|
|
|
mut text: Query<'_, '_, &mut Text, With<InfoPanel>>,
|
|
|
|
) {
|
|
|
|
let world = world_manager.world();
|
|
|
|
text.single_mut().sections[0].value = if cursor_position.x >= 0
|
|
|
|
&& cursor_position.x < world.width
|
|
|
|
&& cursor_position.y >= 0
|
|
|
|
&& cursor_position.y < world.height
|
|
|
|
{
|
|
|
|
let cell = &world.terrain[cursor_position.y as usize][cursor_position.x as usize];
|
2022-09-06 20:40:27 +02:00
|
|
|
#[cfg(feature = "debug")]
|
|
|
|
{
|
|
|
|
format!(
|
2022-09-06 23:16:47 +02:00
|
|
|
"FPS: ~{}\nMouse position: {}\nAltitude: {}\nRainfall: {}\nTemperature: {}",
|
2022-09-06 20:40:27 +02:00
|
|
|
match diagnostics.get_measurement(FrameTimeDiagnosticsPlugin::FPS) {
|
|
|
|
None => f64::NAN,
|
2022-09-06 23:16:47 +02:00
|
|
|
Some(fps) => fps.value.round(),
|
2022-09-06 20:40:27 +02:00
|
|
|
},
|
|
|
|
*cursor_position,
|
|
|
|
cell.altitude,
|
|
|
|
cell.rainfall,
|
|
|
|
cell.temperature
|
|
|
|
)
|
|
|
|
}
|
|
|
|
#[cfg(not(feature = "debug"))]
|
|
|
|
{
|
|
|
|
format!(
|
|
|
|
"Mouse position: {}\nAltitude: {}\nRainfall: {}\nTemperature: {}",
|
|
|
|
*cursor_position, cell.altitude, cell.rainfall, cell.temperature
|
|
|
|
)
|
|
|
|
}
|
2022-09-06 15:40:09 +02:00
|
|
|
} else {
|
2022-09-06 23:16:47 +02:00
|
|
|
format!(
|
|
|
|
"FPS: ~{}\nMouse position: {}\nOut of bounds",
|
|
|
|
match diagnostics.get_measurement(FrameTimeDiagnosticsPlugin::FPS) {
|
|
|
|
None => f64::NAN,
|
|
|
|
Some(fps) => fps.value.round(),
|
|
|
|
},
|
|
|
|
*cursor_position
|
|
|
|
)
|
2022-09-06 15:40:09 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-09-06 11:07:13 +02:00
|
|
|
#[cfg(feature = "render")]
|
|
|
|
fn generate_graphics(
|
2022-09-03 21:40:18 +02:00
|
|
|
mut commands: Commands<'_, '_>,
|
|
|
|
mut images: ResMut<'_, Assets<Image>>,
|
2022-09-06 22:09:53 +02:00
|
|
|
#[cfg(feature = "planet_view")] mut materials: ResMut<'_, Assets<StandardMaterial>>,
|
|
|
|
#[cfg(feature = "planet_view")] mut meshes: ResMut<'_, Assets<Mesh>>,
|
2022-09-06 11:07:13 +02:00
|
|
|
mut world_manager: ResMut<'_, WorldManager>,
|
|
|
|
asset_server: Res<'_, AssetServer>,
|
2022-09-03 21:40:18 +02:00
|
|
|
) {
|
2022-09-06 15:40:09 +02:00
|
|
|
let world = world_manager.world();
|
|
|
|
let custom_sprite_size = Vec2 {
|
|
|
|
x: (WORLD_SCALE * world.width) as f32,
|
|
|
|
y: (WORLD_SCALE * world.height) as f32,
|
|
|
|
};
|
2022-09-03 21:40:18 +02:00
|
|
|
|
|
|
|
let image_handle = images.add(Image {
|
2022-09-04 12:41:11 +02:00
|
|
|
data: world_manager.world_color_bytes(),
|
2022-09-03 21:40:18 +02:00
|
|
|
texture_descriptor: TextureDescriptor {
|
|
|
|
label: None,
|
|
|
|
size: Extent3d {
|
|
|
|
width: world.width as u32,
|
|
|
|
height: world.height as u32,
|
|
|
|
..default()
|
|
|
|
},
|
|
|
|
dimension: TextureDimension::D2,
|
|
|
|
format: TextureFormat::Rgba32Float,
|
|
|
|
mip_level_count: 1,
|
|
|
|
sample_count: 1,
|
|
|
|
usage: TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING,
|
|
|
|
},
|
|
|
|
..default()
|
|
|
|
});
|
2022-09-06 11:07:13 +02:00
|
|
|
world_manager.image_handle_id = image_handle.id;
|
2022-09-03 21:40:18 +02:00
|
|
|
|
2022-09-06 22:09:53 +02:00
|
|
|
#[cfg(feature = "planet_view")]
|
|
|
|
{
|
|
|
|
_ = commands.spawn_bundle(Camera3dBundle {
|
2022-09-06 16:49:41 +02:00
|
|
|
camera: Camera {
|
|
|
|
is_active: false,
|
|
|
|
..default()
|
|
|
|
},
|
2022-09-06 22:09:53 +02:00
|
|
|
transform: Transform::from_xyz(0.0, 0.0, 8.0).looking_at(default(), Vec3::Y),
|
|
|
|
projection: OrthographicProjection {
|
|
|
|
scale: 0.01,
|
|
|
|
..default()
|
|
|
|
}
|
|
|
|
.into(),
|
2022-09-06 16:49:41 +02:00
|
|
|
..default()
|
2022-09-06 22:09:53 +02:00
|
|
|
});
|
|
|
|
_ = commands.spawn_bundle(PbrBundle {
|
|
|
|
mesh: meshes.add(Mesh::from(Icosphere {
|
|
|
|
radius: 2.0,
|
|
|
|
subdivisions: 9,
|
|
|
|
})),
|
|
|
|
material: materials.add(images.get_handle(world_manager.image_handle_id).into()),
|
|
|
|
transform: Transform::from_translation(default()),
|
|
|
|
..default()
|
|
|
|
});
|
|
|
|
_ = commands.spawn_bundle(PointLightBundle {
|
|
|
|
transform: Transform::from_xyz(-20.0, 20.0, 50.0),
|
|
|
|
point_light: PointLight {
|
|
|
|
intensity: 600000.,
|
|
|
|
range: 100.,
|
|
|
|
..default()
|
|
|
|
},
|
|
|
|
..default()
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
_ = commands
|
|
|
|
.spawn_bundle(Camera2dBundle { ..default() })
|
2022-09-06 15:40:09 +02:00
|
|
|
.insert(PanCam::default());
|
|
|
|
_ = commands.spawn_bundle(SpriteBundle {
|
|
|
|
texture: images.get_handle(world_manager.image_handle_id),
|
|
|
|
sprite: Sprite {
|
|
|
|
custom_size: Some(custom_sprite_size),
|
|
|
|
..default()
|
|
|
|
},
|
|
|
|
..default()
|
|
|
|
});
|
2022-09-06 11:07:13 +02:00
|
|
|
_ = commands
|
2022-09-06 12:35:05 +02:00
|
|
|
.spawn_bundle(NodeBundle {
|
2022-09-06 11:07:13 +02:00
|
|
|
style: Style {
|
2022-09-06 12:35:05 +02:00
|
|
|
size: Size::new(Val::Percent(100.0), Val::Percent(100.0)),
|
2022-09-06 11:07:13 +02:00
|
|
|
..default()
|
|
|
|
},
|
2022-09-06 12:35:05 +02:00
|
|
|
color: Color::NONE.into(),
|
2022-09-03 21:40:18 +02:00
|
|
|
..default()
|
2022-09-06 11:07:13 +02:00
|
|
|
})
|
2022-09-06 12:35:05 +02:00
|
|
|
.with_children(|root_node| {
|
2022-09-06 15:40:09 +02:00
|
|
|
_ = root_node
|
|
|
|
.spawn_bundle(NodeBundle {
|
|
|
|
style: Style {
|
|
|
|
align_self: AlignSelf::FlexEnd,
|
|
|
|
padding: UiRect::all(Val::Px(2.0)),
|
|
|
|
..default()
|
|
|
|
},
|
|
|
|
color: Color::rgba(1.0, 1.0, 1.0, 0.05).into(),
|
|
|
|
focus_policy: FocusPolicy::Pass,
|
2022-09-06 12:35:05 +02:00
|
|
|
..default()
|
2022-09-06 15:40:09 +02:00
|
|
|
})
|
|
|
|
.with_children(|info_panel| {
|
|
|
|
_ = info_panel
|
|
|
|
.spawn_bundle(TextBundle {
|
|
|
|
text: Text::from_section(
|
|
|
|
"Info Panel",
|
|
|
|
bevy::text::TextStyle {
|
|
|
|
font: asset_server.load("JuliaMono.ttf"),
|
|
|
|
font_size: 15.0,
|
|
|
|
color: Color::WHITE,
|
|
|
|
},
|
|
|
|
),
|
|
|
|
..default()
|
|
|
|
})
|
|
|
|
.insert(InfoPanel);
|
|
|
|
});
|
2022-09-06 12:35:05 +02:00
|
|
|
_ = root_node
|
2022-09-06 12:08:05 +02:00
|
|
|
.spawn_bundle(NodeBundle {
|
2022-09-06 11:07:13 +02:00
|
|
|
style: Style {
|
2022-09-06 12:08:05 +02:00
|
|
|
size: Size::new(Val::Percent(100.0), Val::Undefined),
|
|
|
|
padding: UiRect::all(Val::Px(3.0)),
|
|
|
|
justify_content: JustifyContent::SpaceAround,
|
2022-09-06 12:35:05 +02:00
|
|
|
position_type: PositionType::Absolute,
|
2022-09-06 11:07:13 +02:00
|
|
|
..default()
|
|
|
|
},
|
2022-09-06 12:08:05 +02:00
|
|
|
color: Color::NONE.into(),
|
|
|
|
focus_policy: FocusPolicy::Pass,
|
2022-09-06 11:07:13 +02:00
|
|
|
..default()
|
|
|
|
})
|
2022-09-06 12:08:05 +02:00
|
|
|
.with_children(|button_box| {
|
2022-09-07 00:08:33 +02:00
|
|
|
ToolbarButton::ITEMS.iter().for_each(|&button_type| {
|
|
|
|
_ = button_box
|
|
|
|
.spawn_bundle(toolbar_button())
|
|
|
|
.with_children(|button| {
|
|
|
|
_ = button
|
|
|
|
.spawn_bundle(toolbar_button_text(&asset_server, button_type));
|
|
|
|
})
|
|
|
|
.insert(button_type)
|
|
|
|
});
|
2022-09-06 11:07:13 +02:00
|
|
|
});
|
|
|
|
});
|
2022-09-03 21:40:18 +02:00
|
|
|
}
|
|
|
|
|
2022-09-06 20:40:27 +02:00
|
|
|
#[cfg(feature = "render")]
|
2022-09-06 23:16:47 +02:00
|
|
|
const WORLD_SCALE: i32 = 4;
|
2022-09-03 21:40:18 +02:00
|
|
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
2022-09-05 11:43:50 +02:00
|
|
|
let mut app = App::new();
|
2022-09-03 21:40:18 +02:00
|
|
|
let mut manager = WorldManager::new();
|
2022-09-05 11:43:50 +02:00
|
|
|
#[cfg(feature = "render")]
|
|
|
|
{
|
|
|
|
let world = manager.new_world()?;
|
|
|
|
_ = app
|
2022-09-06 16:49:41 +02:00
|
|
|
.insert_resource(WinitSettings::game())
|
2022-09-05 11:43:50 +02:00
|
|
|
// Use nearest-neighbor rendering for cripsier pixels
|
|
|
|
.insert_resource(ImageSettings::default_nearest())
|
|
|
|
.insert_resource(WindowDescriptor {
|
2022-09-06 15:40:09 +02:00
|
|
|
width: (WORLD_SCALE * world.width) as f32,
|
|
|
|
height: (WORLD_SCALE * world.height) as f32,
|
2022-09-05 11:43:50 +02:00
|
|
|
title: String::from("World-RS"),
|
|
|
|
resizable: true,
|
|
|
|
..default()
|
|
|
|
})
|
2022-09-06 15:40:09 +02:00
|
|
|
.insert_resource(CursorMapPosition::default())
|
2022-09-06 11:07:13 +02:00
|
|
|
.add_startup_system(generate_graphics)
|
2022-09-06 20:40:27 +02:00
|
|
|
.add_system(handle_toolbar_button)
|
2022-09-06 15:40:09 +02:00
|
|
|
.add_system(update_cursor_map_position)
|
2022-09-06 22:09:53 +02:00
|
|
|
.add_system(update_info_panel);
|
|
|
|
#[cfg(all(feature = "render", feature = "planet_view"))]
|
|
|
|
{
|
|
|
|
_ = app.add_system(rotate_planet);
|
|
|
|
}
|
2022-09-05 11:43:50 +02:00
|
|
|
}
|
|
|
|
#[cfg(not(feature = "render"))]
|
|
|
|
{
|
|
|
|
_ = manager.new_world()?
|
|
|
|
}
|
2022-09-06 11:07:13 +02:00
|
|
|
|
2022-09-07 00:08:33 +02:00
|
|
|
_ = app.insert_resource(LogSettings {
|
|
|
|
#[cfg(feature = "debug")]
|
|
|
|
level: Level::DEBUG,
|
|
|
|
#[cfg(not(feature = "debug"))]
|
|
|
|
level: Level::WARN,
|
|
|
|
..default()
|
|
|
|
});
|
2022-09-06 11:07:13 +02:00
|
|
|
|
2022-09-06 15:40:09 +02:00
|
|
|
app.add_plugins(WorldPlugins).insert_resource(manager).run();
|
2022-09-03 21:40:18 +02:00
|
|
|
|
|
|
|
Ok(())
|
2022-08-25 15:45:45 +02:00
|
|
|
}
|