use crate::prelude::*;
use crate::ecs::ThrustEvent;
use crate::server::ConnectedNetworkEntity;
pub fn server_thrust_plugin(app: &mut App) {
app
.add_systems(Update, process_thrust_events);
}
pub fn process_thrust_events(
mut events: MessageReader<FromClient<ThrustEvent>>,
clients: Query<&ConnectedNetworkEntity>,
q_ls_me: Query<Entity, With<crate::ecs::Me>>,
) {
for FromClient {
client_id,
message: event,
} in events.read()
{
let player_hearty_entity = match client_id {
ClientId::Client(client_entity) => {
let ConnectedNetworkEntity {
game_entity: player_hearty_entity,
} = clients.get(*client_entity).unwrap();
player_hearty_entity
},
ClientId::Server => &q_ls_me.iter().next().unwrap()
};
let thrust_solution = &event.0;
if !thrust_solution.converged { return };
/* TODO: @tm85: have fun!
TODO: The ThrustSolution contains a set of thrusters that should be on.
TODO: All other thrusters should be off.
TODO: If a thruster should be on, apply it's force vector at it's point
TODO: (RigidBodyForces::apply_force_at_point,
TODO: note this is worldspace!! [GlobalTransform is your friend])
TODO: Note that this is only an event handler, and will only run
TODO: when the client sends us a NEW thrust solution.
TODO: You probably want to add a Component to the player entity (player_hearty_entity,
TODO: it's also the hearty part entity) that stores the current ThrustSolution
TODO: and applies it every tick, since avian's ExternalForces only apply for a single
TODO: physics tick and must be applied every tick to be continuous.
TODO: Hint: you probably want a mut commands: Commands in this system,
TODO: and then insert a component with commands.entity(hearty).insert(YourNewComponent)
TODO: To do this, create a new system (e.g. apply_thrust) or something, and apply thrust
TODO: there, every tick (Update). Register it with the plugin above.
TODO: I'll leave you to that. Have fun! ping me if you've got questions, I'll be up
TODO: a while so can help you decipher the attachment system if need be.
TODO: Overall, your goal is:
TODO: - find all parts in the ship (hint: query for Parts on the ship (hearty))
TODO: - for each part, find all thrusters (hint: query for PartThrusters on the part)
TODO: - for each thruster, if it's on (check if it's in the player's current thrust soln)
TODO: - apply a force at the correct point
TODO: Much of the same logic is done in the client counterpart, to calculate effective
TODO: force for the solver. Take a look at client::ship::thrusters.
TODO: Note that relationship components (eg Parts, PartThrusters) wont exist if there are
TODO: no children - eg hearty won't have Parts if nothing is attached, a part won't have
TODO: PartThrusters if it has no thrusters.
TODO: Handle this with Option<&Component> in the query
*/
}
}