From 93b31a0e0c99e046e1da3997a9d9dad2973d960f Mon Sep 17 00:00:00 2001 From: core Date: Sat, 6 Jan 2024 23:44:15 -0500 Subject: [PATCH] module lights --- server/src/component.rs | 7 +++ server/src/main.rs | 72 +++++++++++++++++++++------- server/src/packet.rs | 15 ++++++ starkingdoms-client/src/globals.ts | 1 + starkingdoms-client/src/hub.ts | 5 ++ starkingdoms-client/src/protocol.ts | 4 ++ starkingdoms-client/src/rendering.ts | 9 +++- starkingdoms-client/src/textures.ts | 13 +++-- 8 files changed, 102 insertions(+), 24 deletions(-) diff --git a/server/src/component.rs b/server/src/component.rs index 592d83c812267abafe112ffb26aaadbb89ef3922..90cf50f19d27ce291aab764e4e2c311b5a074894 100644 --- a/server/src/component.rs +++ b/server/src/component.rs @@ -72,10 +72,17 @@ pub struct PlanetBundle { pub transform: TransformBundle, } +#[derive(Component, Copy, Clone)] +pub struct PartFlags { + pub attached: bool +} + + #[derive(Bundle)] pub struct PartBundle { pub transform: TransformBundle, pub part_type: PartType, + pub flags: PartFlags } #[derive(Bundle)] diff --git a/server/src/main.rs b/server/src/main.rs index 1bd82a8966e3bc5a25094572340df2650875d2c6..d1ec4f97eaf5e40dba6108d1eb94eb0ab2a93c2d 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -169,9 +169,11 @@ fn module_spawn( ); transform.rotate_z(angle); if part_query.iter().count() < FREE_MODULE_CAP { + let flags = PartFlags { attached: false }; let mut entity = commands.spawn(PartBundle { part_type: PartType::Cargo, transform: TransformBundle::from(transform), + flags }); entity .insert(RigidBody::Dynamic) @@ -199,6 +201,7 @@ fn module_spawn( part: Part { part_type: PartType::Cargo, transform: proto_transform!(transform), + flags: proto_part_flags!(flags) }, }; let buf = serde_json::to_vec(&packet).unwrap(); @@ -218,6 +221,7 @@ fn on_message( &mut Transform, &mut Velocity, Option<&LooseAttach>, + &mut PartFlags, ), (Without, Without, Without), >, @@ -230,6 +234,7 @@ fn on_message( &Velocity, Option<&CanAttach>, Option<&LooseAttach>, + &mut PartFlags ), (Without, Without), >, @@ -282,6 +287,7 @@ fn on_message( part: PartBundle { part_type: PartType::Hearty, transform: TransformBundle::from(transform), + flags: PartFlags { attached: false } }, player: Player { addr: *addr, @@ -365,7 +371,7 @@ fn on_message( // tell the player where parts are let mut parts = Vec::new(); - for (entity, part_type, transform, _, _) in &part_query { + for (entity, part_type, transform, _, _, flags) in &part_query { parts.push(( entity.index(), Part { @@ -373,10 +379,11 @@ fn on_message( transform: proto_transform!(Transform::from_translation( transform.translation * SCALE )), + flags: proto_part_flags!(flags) }, )); } - for (entity, part_type, transform, _, _, _, _) in &attached_query { + for (entity, part_type, transform, _, _, _, _, flags) in &attached_query { parts.push(( entity.index(), Part { @@ -384,6 +391,7 @@ fn on_message( transform: proto_transform!(Transform::from_translation( transform.translation * SCALE )), + flags: proto_part_flags!(flags) }, )); } @@ -395,6 +403,7 @@ fn on_message( transform.translation * SCALE ) .with_rotation(transform.rotation)), + flags: ProtoPartFlags { attached: false } }, )); let packet = Packet::PartPositions { parts }; @@ -506,6 +515,7 @@ fn on_message( module.2.rotation = Quat::from_euler(EulerRot::ZYX, angle, 0., 0.); module.3.linvel = velocity.linvel; + module.5.attached = true; let joint = FixedJointBuilder::new() .local_anchor1(vec2(0. / SCALE, -53. / SCALE)); let mut children = [None, None, None, None]; @@ -559,6 +569,7 @@ fn on_message( module.2.rotation = Quat::from_euler(EulerRot::ZYX, angle + PI, 0., 0.); module.3.linvel = velocity.linvel; + module.5.attached = true; let joint = FixedJointBuilder::new() .local_anchor1(vec2(0. / SCALE, 53. / SCALE)); let mut children = [None, None, None, None]; @@ -616,6 +627,7 @@ fn on_message( 0., ); module.3.linvel = velocity.linvel; + module.5.attached = true; let joint = FixedJointBuilder::new() .local_anchor1(vec2(53. / SCALE, 0. / SCALE)) .local_basis2(std::f32::consts::PI / 2.); @@ -678,6 +690,7 @@ fn on_message( 0., ); module.3.linvel = velocity.linvel; + module.5.attached = true; let joint = FixedJointBuilder::new() .local_anchor1(vec2(-53. / SCALE, 0. / SCALE)) .local_basis2(-std::f32::consts::PI / 2.); @@ -724,12 +737,13 @@ fn on_message( break; } } else if attached_query.contains(select) { - let module = attached_query.get(select).unwrap(); + let mut module = attached_query.get_mut(select).unwrap(); let parent = module.3.parent.unwrap(); commands.entity(select).remove::(); commands.entity(select).remove::(); let children_attach = module.3.clone(); if *module.1 == PartType::LandingThruster { + module.7.attached = false; commands.entity(select).insert(LooseAttach { children: module.3.children, }); @@ -737,6 +751,7 @@ fn on_message( .entity(module.3.children[2].unwrap()) .remove::(); } else { + module.7.attached = false; detach_recursive( &mut commands, module.3.clone(), @@ -792,6 +807,8 @@ fn on_message( &mut attached_query, &mut part_query, ) { + let mut part = part_query.get_mut(select).unwrap(); + part.5.attached = true; // all of this code is cursed. what the hell is it actually doing break; } // move module to cursor since no attach @@ -806,7 +823,7 @@ fn on_message( } break; } - for (entity, part_type, transform, _m_attach, _velocity, _, _) in + for (entity, part_type, transform, _m_attach, _velocity, _, _, _) in &attached_query { if *part_type == PartType::LandingThrusterSuspension { @@ -836,7 +853,7 @@ fn on_message( } } } - for (entity, part_type, transform, _, _) in &part_query { + for (entity, part_type, transform, _, _, _) in &part_query { if *part_type == PartType::LandingThrusterSuspension { continue; } @@ -899,6 +916,7 @@ fn detach_recursive( &Velocity, Option<&CanAttach>, Option<&LooseAttach>, + &mut PartFlags ), (Without, Without), >, @@ -906,8 +924,8 @@ fn detach_recursive( for child in attach.children { if let Some(child) = child { { - let (entity, part_type, _transform, attach, _velocity, _, _) = - attached_query.get(child).unwrap(); + let (entity, part_type, _transform, attach, _velocity, _, _, mut flags) = + attached_query.get_mut(child).unwrap(); commands.entity(entity).remove::(); if *part_type == PartType::LandingThruster { commands.entity(entity).insert(LooseAttach { @@ -916,21 +934,26 @@ fn detach_recursive( commands .entity(attach.children[2].unwrap()) .remove::(); + flags.attached = false; continue; } else if *part_type == PartType::LandingThrusterSuspension { + flags.attached = false; let parent = attach.parent.unwrap(); let parent_attach = attached_query.get(parent).unwrap().3; println!("suspension {:?} {:?}", parent_attach.children, entity); commands.entity(parent).insert(LooseAttach { children: parent_attach.children, }); + } else { + flags.attached = false; commands.entity(entity).remove::(); detach_recursive(commands, attach.clone(), attached_query); } } - let (entity, _part_type, _transform, attach, _velocity, _, _) = + let (entity, _part_type, _transform, attach, _velocity, _, _, mut flags) = attached_query.get_mut(child).unwrap(); + flags.attached = false; let parent = attach.parent.unwrap(); if attached_query.contains(parent) { let mut parent_attach = attached_query.get_mut(parent).unwrap().3; @@ -962,6 +985,7 @@ fn attach_on_module_tree( &Velocity, Option<&CanAttach>, Option<&LooseAttach>, + &mut PartFlags ), (Without, Without), >, @@ -972,6 +996,7 @@ fn attach_on_module_tree( &mut Transform, &mut Velocity, Option<&LooseAttach>, + &mut PartFlags ), (Without, Without, Without), >, @@ -979,7 +1004,7 @@ fn attach_on_module_tree( let mut ret = false; for child in attach.children { if let Some(child) = child { - let (entity, _part_type, transform, mut attach, velocity, can_attach, loose_attach) = + let (entity, _part_type, transform, mut attach, velocity, can_attach, loose_attach, _) = attached_query.get_mut(child).unwrap(); let p_pos = transform.translation; @@ -1028,6 +1053,7 @@ fn attach_on_module_tree( children, }); attach.children[2] = Some(module.0); + module.5.attached = true; return true; } else if attach.children[1] == None && attachable @@ -1069,6 +1095,7 @@ fn attach_on_module_tree( children, }); attach.children[1] = Some(module.0); + module.5.attached = true; return true; } else if attach.children[3] == None && attachable @@ -1110,6 +1137,7 @@ fn attach_on_module_tree( children, }); attach.children[3] = Some(module.0); + module.5.attached = true; return true; } ret = ret @@ -1137,7 +1165,7 @@ fn convert_modules( planet_query: Query<(Entity, &PlanetType, &Children)>, player_query: Query<&Attach, With>, mut attached_query: Query< - (Entity, &mut PartType, &mut Attach, &Children, &Transform), + (Entity, &mut PartType, &mut Attach, &Children, &Transform, &PartFlags), Without, >, mut collider_query: Query< @@ -1199,7 +1227,7 @@ fn convert_modules_recursive( planet_type: PlanetType, attach: Attach, attached_query: &mut Query< - (Entity, &mut PartType, &mut Attach, &Children, &Transform), + (Entity, &mut PartType, &mut Attach, &Children, &Transform, &PartFlags), Without, >, collider_query: &mut Query< @@ -1210,7 +1238,7 @@ fn convert_modules_recursive( ) { for child in attach.children { if let Some(child) = child { - let (module_entity, mut part_type, mut attach, children, module_transform) = + let (module_entity, mut part_type, mut attach, children, module_transform, part_flags) = attached_query.get_mut(child).unwrap(); if *part_type == PartType::Cargo { match planet_type { @@ -1238,6 +1266,7 @@ fn convert_modules_recursive( part: Part { part_type: PartType::Hub, transform: proto_transform!(transform), + flags: proto_part_flags!(part_flags) }, }; let buf = serde_json::to_vec(&packet).unwrap(); @@ -1260,6 +1289,7 @@ fn convert_modules_recursive( let mut suspension = commands.spawn(PartBundle { transform: TransformBundle::from(*module_transform), part_type: PartType::LandingThrusterSuspension, + flags: PartFlags { attached: false } }); suspension .insert(RigidBody::Dynamic) @@ -1298,6 +1328,7 @@ fn convert_modules_recursive( part: Part { part_type: PartType::LandingThruster, transform: proto_transform!(transform), + flags: proto_part_flags!(part_flags) }, }; let buf = serde_json::to_vec(&packet).unwrap(); @@ -1309,6 +1340,7 @@ fn convert_modules_recursive( part: Part { part_type: PartType::LandingThrusterSuspension, transform: proto_transform!(transform), + flags: proto_part_flags!(part_flags) }, }; let buf = serde_json::to_vec(&packet).unwrap(); @@ -1343,6 +1375,7 @@ fn break_modules( &Velocity, Option<&CanAttach>, Option<&LooseAttach>, + &mut PartFlags ), (Without, Without), >, @@ -1350,13 +1383,14 @@ fn break_modules( ) { let joints = rapier_context.entity2impulse_joint(); let mut detach_list = Vec::new(); - for (entity, part_type, _, attach, _, _, _) in &mut attached_query { + for (entity, part_type, _, attach, _, _, _, mut flags) in &mut attached_query { if *part_type == PartType::LandingThrusterSuspension { continue; } let handle = joints.get(&entity).unwrap(); let joint = rapier_context.impulse_joints.get(*handle).unwrap(); - if joint.impulses.magnitude() > 0.00005 { + if joint.impulses.magnitude() > 0.0001 { + flags.attached = false; detach_list.push((entity, *part_type, attach.clone())); } } @@ -1367,9 +1401,12 @@ fn break_modules( commands.entity(entity).insert(LooseAttach { children: attach.children, }); - commands + if (attach.children[2].is_some()) { + commands .entity(attach.children[2].unwrap()) .remove::(); + } + } else { detach_recursive(&mut commands, attach.clone(), &mut attached_query); } @@ -1516,12 +1553,12 @@ fn despawn_module_tree( fn on_position_change( mut commands: Commands, - part_query: Query<(Entity, &PartType, &Transform), Changed>, + part_query: Query<(Entity, &PartType, &Transform, &PartFlags), Changed>, planet_query: Query<(Entity, &PlanetType, &Transform), Changed>, mut packet_send: EventWriter, ) { let mut updated_parts = Vec::new(); - for (entity, part_type, transform) in part_query.iter() { + for (entity, part_type, transform, flags) in part_query.iter() { let id = commands.entity(entity).id().index(); updated_parts.push(( id, @@ -1531,6 +1568,7 @@ fn on_position_change( transform.translation * SCALE ) .with_rotation(transform.rotation)), + flags: proto_part_flags!(flags) }, )); } diff --git a/server/src/packet.rs b/server/src/packet.rs index 534fe15880a685950d742def2f3af59c8dfebda3..b3c832b15edabfd9c16305ee18b868ec0ae4c93b 100644 --- a/server/src/packet.rs +++ b/server/src/packet.rs @@ -43,6 +43,21 @@ pub struct Planet { pub struct Part { pub part_type: PartType, pub transform: ProtoTransform, + pub flags: ProtoPartFlags +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct ProtoPartFlags { + pub attached: bool +} + +#[macro_export] +macro_rules! proto_part_flags { + ($e:expr) => { + $crate::packet::ProtoPartFlags { + attached: $e.attached + } + } } #[derive(Debug, Serialize, Deserialize)] diff --git a/starkingdoms-client/src/globals.ts b/starkingdoms-client/src/globals.ts index 78308ea57cbcff0a67579e2d47cc8341ff44ac75..041c2b169ccd89d63a56eead3f62158009384941 100644 --- a/starkingdoms-client/src/globals.ts +++ b/starkingdoms-client/src/globals.ts @@ -28,6 +28,7 @@ export interface GlobalRendering { player_text_map: Map; planet_sprite_map: Map; part_sprite_map: Map; + part_sprites_need_texture_change: number[]; } export interface GlobalMe { diff --git a/starkingdoms-client/src/hub.ts b/starkingdoms-client/src/hub.ts index a5adbcd3c37ce0556bfb7503387ee08b66579dbf..866869066cc25a76b80e4e6c5f7dd69b55af0964 100644 --- a/starkingdoms-client/src/hub.ts +++ b/starkingdoms-client/src/hub.ts @@ -203,6 +203,11 @@ export async function hub_connect( let id = p.parts[i][0]; let new_part = p.parts[i][1]; + let old_part = global.parts_map.get(id); + if (old_part !== undefined && (old_part.part_type !== new_part.part_type || old_part.flags !== new_part.flags)) { + global.rendering?.part_sprites_need_texture_change.push(id); + } + global.parts_map.set(id, new_part); if (id === global.me?.part_id) { document.getElementById("pos-val-x")!.innerText = Math.round( diff --git a/starkingdoms-client/src/protocol.ts b/starkingdoms-client/src/protocol.ts index 66a79b3d4d1630675f87bd6e1724537368ce872b..16768e735c455666306705db1e780f29f0570621 100644 --- a/starkingdoms-client/src/protocol.ts +++ b/starkingdoms-client/src/protocol.ts @@ -28,6 +28,10 @@ export interface Planet { export interface Part { part_type: PartType; transform: ProtoTransform; + flags: PartFlags; +} +export interface PartFlags { + attached: boolean; } export interface ClientLoginPacket { username: string; diff --git a/starkingdoms-client/src/rendering.ts b/starkingdoms-client/src/rendering.ts index b4fafd20dbb9696c45921fb5429eca25086f99fc..5f77a7832d815b5395291b095c1eea348bb6045d 100644 --- a/starkingdoms-client/src/rendering.ts +++ b/starkingdoms-client/src/rendering.ts @@ -25,6 +25,7 @@ export function startRender() { player_text_map: new Map(), planet_sprite_map: new Map(), part_sprite_map: new Map(), + part_sprites_need_texture_change: [] }; app.ticker.add(() => { @@ -34,12 +35,16 @@ export function startRender() { -player()?.transform.y! + window.innerHeight / 2; for (let [id, part] of global.parts_map) { - let part_sprite; + let part_sprite if (global.rendering!.part_sprite_map.has(id)) { part_sprite = global.rendering!.part_sprite_map.get(id)!; + if (global.rendering!.part_sprites_need_texture_change.includes(id)) { + // slow :( + part_sprite.texture = PIXI.Texture.from(part_texture_url(part.part_type, part.flags.attached)); + } } else { - part_sprite = PIXI.Sprite.from(part_texture_url(part.part_type)); + part_sprite = PIXI.Sprite.from(part_texture_url(part.part_type, part.flags.attached)); global.rendering!.part_sprite_map.set(id, part_sprite); global.rendering!.app.stage.addChild(part_sprite); } diff --git a/starkingdoms-client/src/textures.ts b/starkingdoms-client/src/textures.ts index 9938e55c7f55c145e12b248289804ae68c796159..4ed86aebd5916ad30584417bce8c62f8896cc20e 100644 --- a/starkingdoms-client/src/textures.ts +++ b/starkingdoms-client/src/textures.ts @@ -4,8 +4,11 @@ import tex_moon from "./assets/moon.svg"; import tex_mars from "./assets/mars.svg"; import tex_hearty from "./assets/hearty.svg"; import tex_cargo_off from "./assets/cargo_off.svg"; +import tex_cargo_on from "./assets/cargo_on.svg"; import tex_hub_off from "./assets/hub_off.svg"; -import tex_landing_thruster from "./assets/landingthruster_off.svg"; +import tex_hub_on from "./assets/hub_on.svg"; +import tex_landing_thruster_off from "./assets/landingthruster_off.svg"; +import tex_landing_thruster_on from "./assets/landingthruster_on.svg"; import tex_landing_thruster_suspension from "./assets/landingleg.svg"; import tex_missing from "./assets/missing.svg"; @@ -20,15 +23,15 @@ export function planet_texture_url(type: PlanetType): string { return tex_missing; } -export function part_texture_url(type: PartType): string { +export function part_texture_url(type: PartType, attached: boolean): string { if (type == PartType.Hearty) { return tex_hearty; } else if (type == PartType.Cargo) { - return tex_cargo_off; + return attached ? tex_cargo_on : tex_cargo_off; } else if (type == PartType.Hub) { - return tex_hub_off; + return attached ? tex_hub_on : tex_hub_off; } else if (type == PartType.LandingThruster) { - return tex_landing_thruster; + return attached ? tex_landing_thruster_on : tex_landing_thruster_off; } else if (type == PartType.LandingThrusterSuspension) { return tex_landing_thruster_suspension; }