Skip to content

Commit

Permalink
Added basic build mode for structures
Browse files Browse the repository at this point in the history
  • Loading branch information
AnthonyTornetta committed Oct 25, 2023
1 parent 30919bb commit 7c7b132
Show file tree
Hide file tree
Showing 19 changed files with 333 additions and 18 deletions.
Binary file added cosmos_client/assets/images/blocks/build_block.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 5 additions & 2 deletions cosmos_client/src/entities/player/player_movement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use bevy::prelude::*;
use bevy_rapier3d::prelude::Velocity;
use cosmos_core::structure::ship::pilot::Pilot;
use cosmos_core::structure::ship::{build_mode::BuildMode, pilot::Pilot};

use crate::{
input::inputs::{CosmosInputs, InputChecker, InputHandler},
Expand All @@ -15,7 +15,10 @@ use crate::{
fn process_player_movement(
time: Res<Time>,
input_handler: InputChecker,
mut query: Query<(Entity, &mut Velocity, &Transform, Option<&PlayerAlignment>), (With<LocalPlayer>, Without<Pilot>)>,
mut query: Query<
(Entity, &mut Velocity, &Transform, Option<&PlayerAlignment>),
(With<LocalPlayer>, Without<Pilot>, Without<BuildMode>),
>,
cam_query: Query<&Transform, With<MainCamera>>,
parent_query: Query<&Parent>,
global_transform_query: Query<&GlobalTransform>,
Expand Down
5 changes: 5 additions & 0 deletions cosmos_client/src/input/inputs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ pub enum CosmosInputs {
ToggleInventory,
/// "Shift-Clicking" an item in minecraft
AutoMoveItem,

/// Toggles the player between being in build mode and not on a ship
ToggleBuildMode,
}

fn init_input(mut input_handler: ResMut<CosmosInputHandler>) {
Expand Down Expand Up @@ -154,6 +157,8 @@ fn init_input(mut input_handler: ResMut<CosmosInputHandler>) {

input_handler.set_keycode(CosmosInputs::ToggleInventory, KeyCode::T);
input_handler.set_keycode(CosmosInputs::AutoMoveItem, KeyCode::ShiftLeft);

input_handler.set_keycode(CosmosInputs::ToggleBuildMode, KeyCode::B);
}

#[derive(Resource, Default, Debug)]
Expand Down
27 changes: 26 additions & 1 deletion cosmos_client/src/netty/gameplay/receiver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,12 @@ use cosmos_core::{
dynamic_structure::DynamicStructure,
full_structure::FullStructure,
planet::{biosphere::BiosphereMarker, planet_builder::TPlanetBuilder},
ship::{pilot::Pilot, ship_builder::TShipBuilder, Ship},
ship::{
build_mode::{EnterBuildModeEvent, ExitBuildModeEvent},
pilot::Pilot,
ship_builder::TShipBuilder,
Ship,
},
ChunkInitEvent, Structure,
},
};
Expand Down Expand Up @@ -173,6 +178,8 @@ pub(crate) fn client_sync_players(
mut pilot_change_event_writer: EventWriter<ChangePilotEvent>,
mut requested_entities: ResMut<RequestedEntities>,
time: Res<Time>,

(mut build_mode_enter, mut build_mode_exit): (EventWriter<EnterBuildModeEvent>, EventWriter<ExitBuildModeEvent>),
) {
let client_id = transport.client_id();

Expand Down Expand Up @@ -580,6 +587,24 @@ pub(crate) fn client_sync_players(
}
}
}
ServerReliableMessages::PlayerEnterBuildMode {
player_entity,
structure_entity,
} => {
if let Some(player_entity) = network_mapping.client_from_server(&player_entity) {
if let Some(structure_entity) = network_mapping.client_from_server(&structure_entity) {
build_mode_enter.send(EnterBuildModeEvent {
player_entity,
structure_entity,
});
}
}
}
ServerReliableMessages::PlayerExitBuildMode { player_entity } => {
if let Some(player_entity) = network_mapping.client_from_server(&player_entity) {
build_mode_exit.send(ExitBuildModeEvent { player_entity });
}
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion cosmos_client/src/structure/planet/align_player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ pub enum Axis {
Z,
}

#[derive(Debug, Component, Default)]
#[derive(Debug, Component, Default, Clone, Copy, PartialEq, Eq)]
/// Used to represent the player's orientation on a planet
pub struct PlayerAlignment(pub Axis);

Expand Down
109 changes: 109 additions & 0 deletions cosmos_client/src/structure/ship/build_mode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
//! Handles the build mode logic on the client-side
use bevy::{
prelude::{in_state, App, IntoSystemConfigs, Query, Res, ResMut, Transform, Update, Vec3, With, Without},
time::Time,
};
use bevy_rapier3d::prelude::Velocity;
use bevy_renet::renet::RenetClient;
use cosmos_core::{
netty::{client_reliable_messages::ClientReliableMessages, cosmos_encoder, NettyChannelClient},
structure::{chunk::CHUNK_DIMENSIONSF, ship::build_mode::BuildMode},
};

use crate::{
input::inputs::{CosmosInputs, InputChecker, InputHandler},
netty::flags::LocalPlayer,
rendering::MainCamera,
state::game_state::GameState,
structure::planet::align_player::{self, PlayerAlignment},
};

fn exit_build_mode(
input_handler: InputChecker,
local_player_in_build_mode: Query<(), (With<LocalPlayer>, With<BuildMode>)>,
mut client: ResMut<RenetClient>,
) {
if local_player_in_build_mode.get_single().is_ok() {
if input_handler.check_just_pressed(CosmosInputs::ToggleBuildMode) {
client.send_message(
NettyChannelClient::Reliable,
cosmos_encoder::serialize(&ClientReliableMessages::ExitBuildMode),
);
}
}
}

fn control_build_mode(
input_handler: InputChecker,
cam_query: Query<&Transform, With<MainCamera>>,
time: Res<Time>,
mut query: Query<(&mut Transform, &mut Velocity, Option<&PlayerAlignment>), (With<LocalPlayer>, With<BuildMode>, Without<MainCamera>)>,
) {
if let Ok((mut transform, mut velocity, player_alignment)) = query.get_single_mut() {
velocity.linvel = Vec3::ZERO;
velocity.angvel = Vec3::ZERO;

let cam_trans = transform.mul_transform(*cam_query.single());

let max_speed: f32 = match input_handler.check_pressed(CosmosInputs::Sprint) {
false => 5.0,
true => 20.0,
};

let mut forward = cam_trans.forward();
let mut right = cam_trans.right();
let up = transform.up();

match player_alignment.copied().unwrap_or_default().0 {
align_player::Axis::X => {
forward.x = 0.0;
right.x = 0.0;
}
align_player::Axis::Y => {
forward.y = 0.0;
right.y = 0.0;
}
align_player::Axis::Z => {
forward.z = 0.0;
right.z = 0.0;
}
}

forward = forward.normalize_or_zero() * max_speed;
right = right.normalize_or_zero() * max_speed;
let movement_up = up * max_speed;

let time = time.delta_seconds();

if input_handler.check_pressed(CosmosInputs::MoveForward) {
transform.translation += forward * time;
}
if input_handler.check_pressed(CosmosInputs::MoveBackward) {
transform.translation -= forward * time;
}
if input_handler.check_pressed(CosmosInputs::MoveUp) {
transform.translation += movement_up * time;
}
if input_handler.check_pressed(CosmosInputs::MoveDown) {
transform.translation -= movement_up * time;
}
if input_handler.check_pressed(CosmosInputs::MoveLeft) {
transform.translation -= right * time;
}
if input_handler.check_pressed(CosmosInputs::MoveRight) {
transform.translation += right * time;
}

let max = CHUNK_DIMENSIONSF * 10.0;

transform.translation = transform.translation.clamp(Vec3::new(-max, -max, -max), Vec3::new(max, max, max));
}
}

pub(super) fn register(app: &mut App) {
app.add_systems(
Update,
(exit_build_mode, control_build_mode).chain().run_if(in_state(GameState::Playing)),
);
}
8 changes: 5 additions & 3 deletions cosmos_client/src/structure/ship/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use cosmos_core::{
physics::location::{handle_child_syncing, Location},
structure::{
chunk::CHUNK_DIMENSIONSF,
ship::{pilot::Pilot, Ship},
ship::{build_mode::BuildMode, pilot::Pilot, Ship},
Structure,
},
};
Expand All @@ -22,6 +22,7 @@ use crate::{
state::game_state::GameState,
};

pub mod build_mode;
pub mod client_ship_builder;
pub mod ship_movement;

Expand Down Expand Up @@ -129,14 +130,14 @@ fn respond_to_collisions(
}

fn remove_parent_when_too_far(
mut query: Query<(Entity, &Parent, &mut Location, &Transform), (With<LocalPlayer>, Without<Ship>)>,
mut query: Query<(Entity, &Parent, &mut Location, &Transform), (With<LocalPlayer>, Without<Ship>, Without<BuildMode>)>,
is_ship: Query<&Location, With<Ship>>,
mut commands: Commands,
mut renet_client: ResMut<RenetClient>,
) {
if let Ok((player_entity, parent, mut player_loc, player_trans)) = query.get_single_mut() {
if let Ok(ship_loc) = is_ship.get(parent.get()) {
if player_loc.distance_sqrd(ship_loc).sqrt() >= CHUNK_DIMENSIONSF * 2.0 {
if player_loc.distance_sqrd(ship_loc).sqrt() >= CHUNK_DIMENSIONSF * 10.0 {
commands.entity(player_entity).remove_parent();

player_loc.last_transform_loc = Some(player_trans.translation);
Expand All @@ -151,6 +152,7 @@ fn remove_parent_when_too_far(
}

pub(super) fn register(app: &mut App) {
build_mode::register(app);
client_ship_builder::register(app);
ship_movement::register(app);

Expand Down
3 changes: 2 additions & 1 deletion cosmos_client/src/structure/ship/ship_movement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use bevy_renet::renet::RenetClient;
use cosmos_core::netty::client_reliable_messages::ClientReliableMessages;
use cosmos_core::netty::client_unreliable_messages::ClientUnreliableMessages;
use cosmos_core::netty::{cosmos_encoder, NettyChannelClient};
use cosmos_core::structure::ship::build_mode::BuildMode;
use cosmos_core::structure::ship::pilot::Pilot;
use cosmos_core::structure::ship::ship_movement::ShipMovement;

Expand All @@ -19,7 +20,7 @@ use crate::window::setup::DeltaCursorPosition;

fn process_ship_movement(
input_handler: InputChecker,
query: Query<Entity, (With<LocalPlayer>, With<Pilot>)>,
query: Query<Entity, (With<LocalPlayer>, With<Pilot>, Without<BuildMode>)>,
mut client: ResMut<RenetClient>,
mut crosshair_offset: ResMut<CrosshairOffset>,
cursor_delta_position: Res<DeltaCursorPosition>,
Expand Down
7 changes: 7 additions & 0 deletions cosmos_core/src/block/blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,13 @@ fn add_cosmos_blocks(
.create(),
);

blocks.register(
BlockBuilder::new("cosmos:build_block", 2.0)
.add_property(BlockProperty::Opaque)
.add_property(BlockProperty::Full)
.create(),
);

loading.finish_loading(id, &mut end_writer);
}

Expand Down
1 change: 1 addition & 0 deletions cosmos_core/src/block/hardness/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ fn register_block_hardness(blocks: Res<Registry<Block>>, mut registry: ResMut<Re
register_hardness(&mut registry, 100.0, &blocks, "cosmos:ship_core");
register_hardness(&mut registry, 20.0, &blocks, "cosmos:energy_cell");
register_hardness(&mut registry, 20.0, &blocks, "cosmos:reactor");
register_hardness(&mut registry, 20.0, &blocks, "cosmos:build_block");
register_hardness(&mut registry, 20.0, &blocks, "cosmos:laser_cannon");
register_hardness(&mut registry, 20.0, &blocks, "cosmos:thruster");
register_hardness(&mut registry, 20.0, &blocks, "cosmos:light");
Expand Down
4 changes: 4 additions & 0 deletions cosmos_core/src/netty/client_reliable_messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,8 @@ pub enum ClientReliableMessages {
/// The ship the player wants to walk on
ship_entity: Entity,
},
/// Sent whenever a client wants to exit build mode
///
/// Requires server confirmation via [`ServerReliableMessages::PlayerExitBuildMode`] or client will do nothing
ExitBuildMode,
}
12 changes: 12 additions & 0 deletions cosmos_core/src/netty/server_reliable_messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,16 @@ pub enum ServerReliableMessages {
/// The ship the player is walking on
ship_entity: Entity,
},
/// Sent when a player enters build mode
PlayerEnterBuildMode {
/// The player entity on the server
player_entity: Entity,
/// The structure entity they're building on the server
structure_entity: Entity,
},
/// Sent whenever a player exits build mode
PlayerExitBuildMode {
/// The server's player entity that's exiting
player_entity: Entity,
},
}
59 changes: 59 additions & 0 deletions cosmos_core/src/structure/ship/build_mode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//! Handles build-mode functionality
//!
//! Note that build mode is currently only intended for ships, but is not yet manually limited to only ships.
use bevy::prelude::{App, BuildChildren, Commands, Component, Entity, Event, EventReader, Update};
use bevy_rapier3d::prelude::{RigidBodyDisabled, Sensor};

#[derive(Component, Default)]
/// Denotes that a player is in build mode
pub struct BuildMode;

#[derive(Event)]
/// This event is sent when a player is entering build mode
pub struct EnterBuildModeEvent {
/// The player that's entering build mode
pub player_entity: Entity,
/// The structure they are entering build mode for
///
/// Multiple players can be building on the same structure
pub structure_entity: Entity,
}

#[derive(Event)]
/// This event is sent when a player is done being in build mode
pub struct ExitBuildModeEvent {
/// The player done being in build mode
pub player_entity: Entity,
}

fn enter_build_mode_listener(mut commands: Commands, mut event_reader: EventReader<EnterBuildModeEvent>) {
for ev in event_reader.iter() {
let Some(mut ecmds) = commands.get_entity(ev.player_entity) else {
continue;
};

ecmds
.insert(BuildMode::default())

Check failure on line 37 in cosmos_core/src/structure/ship/build_mode.rs

View workflow job for this annotation

GitHub Actions / clippy

use of `default` to create a unit struct

error: use of `default` to create a unit struct --> cosmos_core/src/structure/ship/build_mode.rs:37:30 | 37 | .insert(BuildMode::default()) | ^^^^^^^^^^^ help: remove this call to `default` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#default_constructed_unit_structs = note: `-D clippy::default-constructed-unit-structs` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::default_constructed_unit_structs)]`
.insert(RigidBodyDisabled)
.insert(Sensor)
.set_parent(ev.structure_entity);
}
}

fn exit_build_mode_listener(mut commands: Commands, mut event_reader: EventReader<ExitBuildModeEvent>) {
for ev in event_reader.iter() {
let Some(mut ecmds) = commands.get_entity(ev.player_entity) else {
continue;
};

// Keep them as a child of the ship
ecmds.remove::<BuildMode>().remove::<RigidBodyDisabled>().remove::<Sensor>();
}
}

pub(super) fn register(app: &mut App) {
app.add_systems(Update, (enter_build_mode_listener, exit_build_mode_listener))
.add_event::<EnterBuildModeEvent>()
.add_event::<ExitBuildModeEvent>();
}
2 changes: 2 additions & 0 deletions cosmos_core/src/structure/ship/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use bevy::prelude::Component;
use bevy::prelude::States;
use bevy::reflect::Reflect;

pub mod build_mode;
pub mod core;
pub mod pilot;
pub mod ship_builder;
Expand All @@ -21,4 +22,5 @@ pub(super) fn register<T: States + Clone + Copy>(app: &mut App, playing_state: T
ship_movement::register(app);
core::register(app, playing_state);
ship_builder::register(app);
build_mode::register(app);
}
Loading

0 comments on commit 7c7b132

Please sign in to comment.