use avian3d::prelude::*; use bevy::{ ecs::{component::HookContext, world::DeferredWorld}, math::*, prelude::*, }; use bevy_trenchbroom::prelude::*; use crate::cash::Cash; use crate::loading_assets::GameAssets; use crate::physics_layers::GameLayer; #[derive(PointClass, Component, Reflect, Default)] #[reflect(QuakeClass, Component)] #[base(Transform)] #[component(on_add = Self::on_add)] #[model({ "path": "models/spawn.glb" })] pub struct SpawnPoint {} impl SpawnPoint { fn on_add(mut world: DeferredWorld, HookContext { entity, .. }: HookContext) { let Some(assets) = world.get_resource::() else { return; }; let mesh = assets.mesh_spawn.clone(); world.commands().entity(entity).insert(( Name::new("spawn"), SceneRoot(mesh), RigidBody::Static, ColliderConstructorHierarchy::new(ColliderConstructor::ConvexHullFromMesh), )); } } #[derive(SolidClass, Component, Reflect, Default)] #[reflect(QuakeClass, Component)] #[geometry(GeometryProvider::new().convex_collider())] pub struct Worldspawn; #[derive(SolidClass, Component, Reflect, Default)] #[reflect(QuakeClass, Component)] #[geometry(GeometryProvider::new())] #[base(Transform)] pub struct Water; #[derive(SolidClass, Component, Reflect, Default)] #[reflect(QuakeClass, Component)] #[base(Transform)] #[geometry(GeometryProvider::new().convex_collider())] pub struct Crates; #[derive(SolidClass, Component, Reflect, Default)] #[reflect(QuakeClass, Component)] #[base(Transform)] #[geometry(GeometryProvider::new().convex_collider())] pub struct NamedEntity { pub name: String, } #[derive(SolidClass, Component, Reflect, Default)] #[reflect(QuakeClass, Component)] #[base(Transform, Target)] #[geometry(GeometryProvider::new().convex_collider())] pub struct Platform; #[derive(PointClass, Component, Reflect, Default)] #[reflect(QuakeClass, Component)] #[base(Transform)] pub struct PlatformTarget { pub targetname: String, } #[derive(SolidClass, Component, Reflect, Default)] #[reflect(QuakeClass, Component)] #[base(Transform, Target)] #[geometry(GeometryProvider::new().convex_collider())] pub struct Movable { pub name: String, } #[derive(PointClass, Component, Reflect, Default)] #[reflect(QuakeClass, Component)] #[base(Transform)] pub struct MoveTarget { pub targetname: String, } #[derive(PointClass, Component, Reflect, Default)] #[reflect(QuakeClass, Component)] #[base(Transform)] pub struct CameraTarget { pub targetname: String, } #[derive(PointClass, Component, Reflect, Default)] #[reflect(QuakeClass, Component)] #[base(Transform, Target)] pub struct CutsceneCamera { pub name: String, pub targetname: String, } #[derive(PointClass, Component, Reflect, Default)] #[reflect(QuakeClass, Component)] #[base(Transform, Target)] pub struct CutsceneCameraMovementEnd; #[derive(PointClass, Component, Reflect, Default)] #[reflect(QuakeClass, Component)] #[base(Transform)] #[component(on_add = Self::on_add)] #[model({ "path": "models/alien_naked.glb" })] pub struct EnemySpawn { pub head: String, pub key: String, pub disable_ai: bool, } impl EnemySpawn { fn on_add(mut world: DeferredWorld, HookContext { entity, .. }: HookContext) { //TODO: figure out why this crashes if removed let Some(_assets) = world.get_resource::() else { return; }; let this = world.get_entity(entity).unwrap().get::().unwrap(); let this_transform = world .get_entity(entity) .unwrap() .get::() .unwrap(); let mut this_transform = *this_transform; this_transform.translation += Vec3::new(0., 1.5, 0.); let head = this.head.clone(); world.commands().entity(entity).insert(( this_transform, Name::from(format!("enemy [{}]", head)), Visibility::default(), RigidBody::Dynamic, Collider::capsule(0.6, 2.), CollisionLayers::new(LayerMask(GameLayer::Npc.to_bits()), LayerMask::ALL), LockedAxes::new().lock_rotation_z().lock_rotation_x(), )); } } #[derive(PointClass, Component, Reflect, Default)] #[reflect(QuakeClass, Component)] #[base(Transform)] #[component(on_add = Self::on_add)] #[model({ "path": "models/cash.glb" })] pub struct CashSpawn {} impl CashSpawn { fn on_add(mut world: DeferredWorld, HookContext { entity, .. }: HookContext) { let Some(assets) = world.get_resource::() else { return; }; let mesh = assets.mesh_cash.clone(); world.commands().entity(entity).insert(( Name::new("cash"), SceneRoot(mesh), Cash, Collider::cuboid(2., 3.0, 2.), CollisionLayers::new(LayerMask(GameLayer::Collectibles.to_bits()), LayerMask::ALL), CollisionEventsEnabled, Sensor, )); } } pub fn plugin(app: &mut App) { app.register_type::(); app.register_type::(); app.register_type::(); app.register_type::(); app.register_type::(); app.register_type::(); app.register_type::(); app.register_type::(); app.register_type::(); app.register_type::(); app.register_type::(); app.register_type::(); app.register_type::(); app.register_type::(); }