use bevy::ecs::entity::MapEntities; use bevy::prelude::*; use serde::{Deserialize, Serialize}; #[derive(Component, Serialize, Deserialize)] /// The primary component for a ship structure pub struct Ship; #[derive(Component, Serialize, Deserialize, MapEntities)] #[relationship_target(relationship = PartInShip, linked_spawn)] pub struct Parts(#[entities] Vec); #[derive(Component, Serialize, Deserialize, MapEntities)] #[relationship(relationship_target = Parts)] pub struct PartInShip(#[entities] pub Entity); #[derive(Component, Serialize, Deserialize)] #[require(Transform)] pub struct Joint { pub id: JointId, pub transform: Transform, } #[derive(Component, Serialize, Deserialize, MapEntities)] pub struct Peer(#[entities] Entity); #[derive(Component, Serialize, Deserialize, MapEntities)] #[relationship(relationship_target = Joints)] pub struct JointOf(#[entities] pub Entity); #[derive(Component, Serialize, Deserialize, MapEntities)] #[relationship_target(relationship = JointOf)] pub struct Joints(#[entities] Vec); #[derive(Component, Serialize, Deserialize, MapEntities)] #[relationship(relationship_target = Snaps)] pub struct SnapOf(#[entities] pub Entity); #[derive(Component, Serialize, Deserialize, MapEntities)] #[relationship_target(relationship = SnapOf)] pub struct Snaps(#[entities] Vec); #[derive(Serialize, Deserialize)] pub struct JointId(pub String); impl JointId { #[must_use] pub fn from_part_and_joint_id(part: String, joint: String) -> Self { Self(format!("{part}:{joint}")) } } #[derive(Serialize, Deserialize, Component, MapEntities)] pub struct SnapOfJoint(#[entities] pub Entity);