From 9ce02084695c7c69b074a1fdc33bd27ad4095bbf Mon Sep 17 00:00:00 2001 From: Martin Indra Date: Mon, 20 Jun 2022 22:27:06 +0200 Subject: [PATCH] Implement object drafting Relates to #23. --- Cargo.lock | 1 + crates/objects/Cargo.toml | 1 + crates/objects/src/draft.rs | 106 ++++++++++++++++++++++++++++++++++++ crates/objects/src/lib.rs | 4 +- 4 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 crates/objects/src/draft.rs diff --git a/Cargo.lock b/Cargo.lock index 07495b1ce..0363ec7f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1673,6 +1673,7 @@ dependencies = [ "de_core", "de_map", "enum-map", + "glam", "iyes_loopless", "iyes_progress", "parry2d", diff --git a/crates/objects/Cargo.toml b/crates/objects/Cargo.toml index 465152f37..468e62b50 100644 --- a/crates/objects/Cargo.toml +++ b/crates/objects/Cargo.toml @@ -14,6 +14,7 @@ de_map = { path = "../map", version = "0.1.0-dev" } bevy = "0.7.0" iyes_loopless = "0.5.1" iyes_progress = { version = "0.3.0", features = [ "iyes_loopless" ] } +glam = "^0.20.2" parry2d = { git = "https://github.com/Indy2222/parry", branch = "feature/dilation" } parry3d = "0.9.0" enum-map = "2.3.0" diff --git a/crates/objects/src/draft.rs b/crates/objects/src/draft.rs new file mode 100644 index 000000000..18a71d09f --- /dev/null +++ b/crates/objects/src/draft.rs @@ -0,0 +1,106 @@ +//! This module implements a Bevy plugin for drafting new objects on the map. +//! This serves mostly as a visual guide for the user to correctly place new +//! structures on the map. + +use std::f32::consts::TAU; + +use bevy::prelude::*; +use de_core::{objects::ObjectType, projection::ToMsl, state::GameState}; +use glam::Vec2; +use iyes_loopless::prelude::*; + +use crate::ObjectCache; + +pub(crate) struct DraftPlugin; + +impl Plugin for DraftPlugin { + fn build(&self, app: &mut App) { + app.add_event::() + .add_event::() + .add_event::() + .add_event::() + .add_system(new_draft.run_in_state(GameState::Playing)); + } +} + +/// Places a new draft on the map and removes all other drafts. +pub struct NewDraftEvent { + object_type: ObjectType, + position: Vec2, +} + +impl NewDraftEvent { + pub fn new(object_type: ObjectType, position: Vec2) -> Self { + Self { + object_type, + position, + } + } + + fn object_type(&self) -> ObjectType { + self.object_type + } + + fn position(&self) -> Vec2 { + self.position + } +} + +pub struct MoveDraftEvent { + position: Vec2, +} + +impl MoveDraftEvent { + pub fn new(position: Vec2) -> Self { + Self { position } + } +} + +pub struct RotateDraftEvent { + angle: f32, +} + +impl RotateDraftEvent { + /// # Panics + /// + /// Might panic if `angle` is not between zero (inclusive) and 2π + /// (exclusive). + pub fn new(angle: f32) -> Self { + debug_assert!(angle >= 0.); + debug_assert!(angle < TAU); + Self { angle } + } +} + +pub struct ClearDraftsEvent; + +#[derive(Component)] +struct Draft; + +fn new_draft( + mut commands: Commands, + drafts: Query>, + cache: Res, + mut events: EventReader, +) { + let event = match events.iter().last() { + Some(event) => event, + None => return, + }; + + for draft in drafts.iter() { + commands.entity(draft).despawn(); + } + + let transform = Transform { + translation: event.position().to_msl(), + ..Default::default() + }; + let global_transform = GlobalTransform::from(transform); + let mut entity_commands = commands.spawn_bundle((global_transform, transform)); + entity_commands.with_children(|parent| { + parent.spawn_scene(cache.get(event.object_type()).scene()); + }); +} + +// TODO handle other events diff --git a/crates/objects/src/lib.rs b/crates/objects/src/lib.rs index 5a86eb512..e767767fb 100644 --- a/crates/objects/src/lib.rs +++ b/crates/objects/src/lib.rs @@ -5,12 +5,14 @@ use bevy::{app::PluginGroupBuilder, prelude::PluginGroup}; use cache::CachePlugin; pub use cache::ObjectCache; pub use collider::{ColliderCache, ObjectCollider}; +use draft::DraftPlugin; pub use ichnography::{Ichnography, IchnographyCache}; pub use spawner::SpawnEvent; use spawner::SpawnerPlugin; mod cache; mod collider; +mod draft; mod ichnography; mod loader; mod spawner; @@ -19,6 +21,6 @@ pub struct ObjectsPluginGroup; impl PluginGroup for ObjectsPluginGroup { fn build(&mut self, group: &mut PluginGroupBuilder) { - group.add(CachePlugin).add(SpawnerPlugin); + group.add(CachePlugin).add(SpawnerPlugin).add(DraftPlugin); } }