use bevy::prelude::*; use bevy_xpbd_3d::prelude::*; use bevy::scene::SceneInstance; use bevy::math::DVec3; use crate::{actor, audio, camera, chat, commands, effects, hud, nature, var, world}; pub const ENGINE_SPEED_FACTOR: f32 = 30.0; const MAX_TRANSMISSION_DISTANCE: f32 = 60.0; const MAX_INTERACT_DISTANCE: f32 = 30.0; pub struct ActorPlugin; impl Plugin for ActorPlugin { fn build(&self, app: &mut App) { app.add_systems(PreUpdate, ( handle_player_death, )); app.add_systems(FixedUpdate, ( update_physics_lifeforms, handle_wants_maxrotation, handle_wants_maxvelocity, handle_gforce, )); app.add_systems(Update, ( handle_input, handle_collisions, handle_damage, )); app.add_systems(PostUpdate, ( handle_vehicle_enter_exit, )); app.add_event::(); app.add_event::(); } } #[derive(Copy, Clone)] pub enum DamageType { Unknown, Mental, Trauma, Asphyxiation, //Poison, //Radiation, //Freeze, //Burn, } #[derive(Event)] pub struct PlayerDiesEvent(pub DamageType); #[derive(Event)] pub struct VehicleEnterExitEvent { vehicle: Entity, driver: Entity, is_entering: bool, is_player: bool } #[derive(Component)] pub struct Actor { pub id: String, pub name: Option, pub camdistance: f32, } impl Default for Actor { fn default() -> Self { Self { id: "".to_string(), name: None, camdistance: 15.0, } } } #[derive(Component)] pub struct HitPoints { pub current: f32, pub max: f32, pub damage: f32, pub damagetype: DamageType, } impl Default for HitPoints { fn default() -> Self { Self { current: 100.0, max: 100.0, damage: 0.0, damagetype: DamageType::Unknown, } } } #[derive(Component)] pub struct ExperiencesGForce { pub gforce: f32, pub damage_threshold: f32, pub visual_effect_threshold: f32, pub visual_effect: f32, pub last_linear_velocity: DVec3, pub ignore_gforce_seconds: f32, } impl Default for ExperiencesGForce { fn default() -> Self { Self { gforce: 0.0, damage_threshold: 100.0, visual_effect_threshold: 20.0, visual_effect: 0.0, last_linear_velocity: DVec3::splat(0.0), ignore_gforce_seconds: 0.0, }}} #[derive(Component)] pub struct Player; // Attached to the suit of the player #[derive(Component)] pub struct PlayerDrivesThis; // Attached to the entered vehicle #[derive(Component)] pub struct PlayerCamera; // Attached to the actor to use as point of view #[derive(Component)] pub struct ActorEnteringVehicle; #[derive(Component)] pub struct ActorVehicleBeingEntered; #[derive(Component)] pub struct WantsMaxRotation(pub f64); #[derive(Component)] pub struct WantsMaxVelocity(pub f64); #[derive(Component)] pub struct LifeForm { pub is_alive: bool, pub adrenaline: f32, pub adrenaline_baseline: f32, pub adrenaline_jolt: f32, } impl Default for LifeForm { fn default() -> Self { Self { is_alive: true, adrenaline: 0.3, adrenaline_baseline: 0.3, adrenaline_jolt: 0.0, }}} #[derive(Component)] pub struct Vehicle { stored_drivers_collider: Option, } impl Default for Vehicle { fn default() -> Self { Self { stored_drivers_collider: None, }}} #[derive(Copy, Clone, PartialEq)] pub enum EngineType { Monopropellant, Rocket, Ion, } #[derive(Component)] pub struct Engine { pub thrust_forward: f32, pub thrust_back: f32, pub thrust_sideways: f32, pub reaction_wheels: f32, pub engine_type: EngineType, pub warmup_seconds: f32, pub current_warmup: f32, } impl Default for Engine { fn default() -> Self { Self { thrust_forward: 1.0, thrust_back: 1.0, thrust_sideways: 1.0, reaction_wheels: 1.0, engine_type: EngineType::Monopropellant, warmup_seconds: 1.5, current_warmup: 0.0, } } } #[derive(Component)] pub struct Suit { pub oxygen: f32, pub power: f32, pub oxygen_max: f32, pub power_max: f32, pub integrity: f32, // [0.0 - 1.0] } impl Default for Suit { fn default() -> Self { SUIT_SIMPLE } } const SUIT_SIMPLE: Suit = Suit { power: 1e5, power_max: 1e5, oxygen: nature::OXY_D, oxygen_max: nature::OXY_D, integrity: 1.0, }; pub fn update_physics_lifeforms( time: Res