From 50606a2dd2def4d49876eb5c3abf16b85ba06280 Mon Sep 17 00:00:00 2001 From: core Date: Thu, 10 Jul 2025 21:26:46 -0400 Subject: [PATCH] feat: part rotation during drag ghosting with Q/E --- crates/unified/src/attachment.rs | 8 +++++ crates/unified/src/client/parts.rs | 56 +++++++++++++++++++++++------ crates/unified/src/ecs.rs | 12 +++++-- crates/unified/src/server/player.rs | 22 ++++++++---- 4 files changed, 80 insertions(+), 18 deletions(-) diff --git a/crates/unified/src/attachment.rs b/crates/unified/src/attachment.rs index ba47d5999c1095fdc0254c6d421e54ed776b1dde..ab32e03fccbeb60a07f9b229e9f1022fa565aad6 100644 --- a/crates/unified/src/attachment.rs +++ b/crates/unified/src/attachment.rs @@ -1,3 +1,4 @@ +use std::ops::Deref; use bevy::ecs::entity::MapEntities; use bevy::prelude::*; use serde::{Deserialize, Serialize}; @@ -35,6 +36,13 @@ pub struct SnapOf(#[entities] pub Entity); #[derive(Component, Serialize, Deserialize, MapEntities)] #[relationship_target(relationship = SnapOf)] pub struct Snaps(#[entities] Vec); +impl Deref for Snaps { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} #[derive(Serialize, Deserialize)] pub struct JointId(pub String); diff --git a/crates/unified/src/client/parts.rs b/crates/unified/src/client/parts.rs index 669be3136e50954233b96ca80041eb019d58f271..904bc12dc3302fc45bbfa0351769b83505a47e62 100644 --- a/crates/unified/src/client/parts.rs +++ b/crates/unified/src/client/parts.rs @@ -1,4 +1,5 @@ use bevy::color::palettes::css::{ORANGE, RED}; +use bevy::color::palettes::tailwind::{CYAN_400, CYAN_800}; use crate::client::Me; use crate::ecs::{CursorWorldCoordinates, DragRequestEvent, Part}; use bevy::prelude::*; @@ -10,6 +11,7 @@ use crate::client::key_input::AttachmentDebugRes; pub fn parts_plugin(app: &mut App) { app.insert_resource(DragResource(None)); + app.insert_resource(SnapResource(None)); app.add_systems(Update, (handle_incoming_parts, handle_updated_parts, update_drag_ghosts)); app.add_observer(on_part_release); } @@ -59,6 +61,9 @@ fn handle_updated_parts( #[derive(Resource)] struct DragResource(Option); +#[derive(Resource)] +struct SnapResource(Option); + #[derive(Component)] struct DragGhost; @@ -91,35 +96,50 @@ fn on_part_release( mut events: EventWriter, cursor: Res, mut commands: Commands, - ghosts: Query>, + ghost: Single<(Entity, &Transform), With>, + snap: Res ) { if ev.button != PointerButton::Primary { return; } if let Some(e) = drag.0 { - for ghost in &ghosts { - commands.entity(ghost).despawn(); - } + let mut rotation = ghost.1.rotation; + commands.entity(ghost.0).despawn(); if let Some(c) = cursor.0 { debug!(?e, ?c, "sending drag request"); - events.write(DragRequestEvent(e, c)); + events.write(DragRequestEvent { + drag_target: e, + drag_to: c, + set_rotation: rotation, + snap_target: snap.0, + }); } } drag.0 = None; } + + +/// !IMPORTANT! +/// This function forms the bulk of the attachment system. +/// PLEASE DO NOT MODIFY OR MOVE +/// +/// This code is super cursed, and it will break at the lightest breeze fn update_drag_ghosts( mut ghost: Single<&mut Transform, (With, Without, Without, Without)>, cursor: Res, - snaps: Query<(&Transform, &SnapOfJoint, &SnapOf)>, - joints: Query<(&Transform, &JointOf), Without>, + snaps: Query<(&Transform, &SnapOfJoint, &SnapOf, Entity)>, + joints: Query<(&Transform, &JointOf, Entity), Without>, parts: Query<(&GlobalTransform, Option<&Me>, Option<&PartInShip>), With>, me: Single>, debug: Res, + mut rsnap: ResMut, drag: Res, mut gizmos: Gizmos, + keys: Res>, + time: Res