use bevy::prelude::*; use crate::{nature, settings, actor, audio, hud}; pub const ENGINE_SPEED_FACTOR: f32 = 30.0; const MIN_INTERACT_DISTANCE: f32 = 30.0; const NO_RIDE: u32 = 0; pub struct ActorPlugin; impl Plugin for ActorPlugin { fn build(&self, app: &mut App) { app.register_type::(); app.add_systems(FixedUpdate, ( update_physics_lifeforms, )); app.add_systems(Update, ( handle_new_conversations, handle_send_messages, handle_conversations, handle_input, handle_chat_scripts, handle_vehicle_enter_exit, )); app.add_event::(); app.add_event::(); app.add_event::(); app.add_event::(); } } #[derive(Event)] pub struct StartConversationEvent { pub talker: Talker, } #[derive(Event)] pub struct SendMessageEvent { pub conv_id: String, pub conv_label: String, pub text: String, } #[derive(Event)] pub struct ChatScriptEvent { name: String, param: String, param2: String, } #[derive(Event)] pub struct VehicleEnterExitEvent { vehicle: Entity, driver: Entity, is_entering: bool, is_player: bool } #[derive(Component)] pub struct Actor { pub id: String, pub hp: f32, pub m: f32, // mass pub v: Vec3, // velocity pub angular_momentum: Quat, pub inside_entity: u32, } impl Default for Actor { fn default() -> Self { Self { id: "".to_string(), hp: 100.0, m: 100.0, v: Vec3::ZERO, inside_entity: NO_RIDE, angular_momentum: Quat::from_euler(EulerRot::XYZ, 0.001, 0.01, 0.003), } } } #[derive(Component)] pub struct Player; #[derive(Component)] pub struct PlayerDrivesThis; #[derive(Component)] pub struct PlayerInConversation; #[derive(Component)] pub struct InConversationWithPlayer; #[derive(Component)] pub struct ActorEnteringVehicle; #[derive(Component)] pub struct ActorVehicleBeingEntered; #[derive(Debug)] #[derive(Component, Reflect, Default)] #[reflect(Component)] pub struct ChatBranch { pub id: String, pub name: String, pub label: String, pub delay: f64, pub sound: String, pub level: String, pub reply: String, pub goto: String, pub choice: String, pub script: String, pub script_parameter: String, pub script_parameter2: String, } #[derive(Component)] pub struct Chat { pub id: String, pub label: String, pub timer: f64, } #[derive(Component)] #[derive(Clone)] pub struct Talker { pub pronoun: String, pub conv_id: String, } impl Default for Talker { fn default() -> Self { Self { pronoun: "they/them".to_string(), conv_id: "error".to_string(), }}} #[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; #[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: 1e5, }; pub fn update_physics_lifeforms( time: Res