Avian & BTB upgrade (#40)

This commit is contained in:
extrawurst
2025-05-13 23:25:58 +02:00
committed by GitHub
parent 334eacfd1c
commit c69a528625
15 changed files with 348 additions and 363 deletions

View File

@@ -4,13 +4,31 @@ use crate::{
use bevy::{
ecs::system::SystemParam, platform::collections::HashMap, prelude::*, scene::SceneInstanceReady,
};
use std::time::Duration;
use std::{f32::consts::PI, time::Duration};
#[derive(Component, Debug)]
pub struct ProjectileOrigin;
#[derive(Component, Debug)]
pub struct AnimatedCharacter(pub usize);
pub struct AnimatedCharacter {
head: usize,
rotate_180: bool,
}
impl AnimatedCharacter {
pub fn new(head: usize) -> Self {
Self {
head,
rotate_180: false,
}
}
pub fn with_rotation(self) -> Self {
let mut s = self;
s.rotate_180 = true;
s
}
}
#[derive(Component, Debug)]
struct AnimatedCharacterAsset(pub Handle<Gltf>);
@@ -59,7 +77,7 @@ fn spawn(
heads_db: Res<HeadsDatabase>,
) {
for (entity, character) in query.iter() {
let key = heads_db.head_key(character.0);
let key = heads_db.head_key(character.head);
let handle = assets
.characters
@@ -71,10 +89,17 @@ fn spawn(
});
let asset = gltf_assets.get(handle).unwrap();
let mut t =
Transform::from_translation(Vec3::new(0., -1.45, 0.)).with_scale(Vec3::splat(1.2));
if character.rotate_180 {
t.rotate_y(PI);
}
commands
.entity(entity)
.insert((
Transform::from_translation(Vec3::new(0., -1.45, 0.)).with_scale(Vec3::splat(1.2)),
t,
SceneRoot(asset.scenes[0].clone()),
AnimatedCharacterAsset(handle.clone()),
))

View File

@@ -24,12 +24,8 @@ pub fn kinematic_controller_collisions(
// Iterate through collisions and move the kinematic body to resolve penetration
for contacts in collisions.iter() {
// Get the rigid body entities of the colliders (colliders could be children)
let Ok(
[
&ColliderOf { rigid_body: rb1 },
&ColliderOf { rigid_body: rb2 },
],
) = collider_rbs.get_many([contacts.entity1, contacts.entity2])
let Ok([&ColliderOf { body: rb1 }, &ColliderOf { body: rb2 }]) =
collider_rbs.get_many([contacts.collider1, contacts.collider2])
else {
continue;
};

View File

@@ -62,7 +62,7 @@ fn movement(
rig_transform_q: Option<Single<&GlobalTransform, With<PlayerBodyMesh>>>,
time: Res<Time>,
) {
let move_dir = Vec2::new(0.0, 50.) * time.delta_secs();
let move_dir = Vec2::new(0.0, 70.) * time.delta_secs();
for (movement_acceleration, mut linear_velocity) in &mut controllers {
let mut direction = move_dir.extend(0.0).xzy();

View File

@@ -118,7 +118,9 @@ fn main() {
);
app.add_plugins(PhysicsPlugins::default());
app.add_plugins(Sprite3dPlugin);
app.add_plugins(TrenchBroomPlugin(TrenchBroomConfig::new("hedz")));
app.add_plugins(TrenchBroomPlugins(
TrenchBroomConfig::new("hedz").icon(None),
));
app.add_plugins(UiGradientsPlugin);
app.add_plugins(RonAssetPlugin::<HeadDatabaseAsset>::new(&["headsdb.ron"]));
@@ -167,6 +169,7 @@ fn main() {
app.add_plugins(head_drop::plugin);
app.add_plugins(trail::plugin);
app.add_plugins(heal_effect::plugin);
app.add_plugins(tb_entities::plugin);
app.init_state::<GameState>();
@@ -276,8 +279,11 @@ fn music(assets: Res<AudioAssets>, mut commands: Commands) {
));
}
fn write_trenchbroom_config(server: Res<TrenchBroomServer>) {
if let Err(e) = server.config.write_folder("trenchbroom/hedz") {
fn write_trenchbroom_config(server: Res<TrenchBroomServer>, type_registry: Res<AppTypeRegistry>) {
if let Err(e) = server
.config
.write_game_config("trenchbroom/hedz", &type_registry.read())
{
warn!("Failed to write trenchbroom config: {}", e);
}
}

View File

@@ -45,7 +45,10 @@ fn init(mut commands: Commands, query: Query<(Entity, &EnemySpawn)>, heads_db: R
]),
))
.insert_if(Ai, || !spawn.disable_ai)
.with_child((Name::from("body-rig"), AnimatedCharacter(id)))
.with_child((
Name::from("body-rig"),
AnimatedCharacter::new(id).with_rotation(),
))
.observe(on_kill);
}
}

View File

@@ -29,6 +29,7 @@ pub struct Player;
struct PlayerAnimations;
#[derive(Component, Default)]
#[require(Transform, Visibility)]
pub struct PlayerBodyMesh;
pub fn plugin(app: &mut App) {
@@ -83,11 +84,9 @@ fn spawn(
CharacterControllerBundle::new(collider, gravity),
children![(
Name::new("player-rig"),
Transform::default(),
Visibility::default(),
PlayerBodyMesh,
CameraArmRotation,
children![AnimatedCharacter(0)]
children![AnimatedCharacter::new(0)]
)],
));
@@ -219,7 +218,7 @@ fn on_update_head(
commands
.entity(body_mesh)
.with_child(AnimatedCharacter(trigger.0));
.with_child(AnimatedCharacter::new(trigger.0));
//TODO: make part of full character mesh later
if head_db.head_stats(trigger.0).controls == HeadControls::Plane {

View File

@@ -11,8 +11,8 @@ use crate::loading_assets::GameAssets;
use crate::physics_layers::GameLayer;
#[derive(PointClass, Component, Reflect, Default)]
#[reflect(Component)]
#[require(Transform)]
#[reflect(QuakeClass, Component)]
#[base(Transform)]
#[component(on_add = Self::on_add)]
#[model({ "path": "models/spawn.glb" })]
pub struct SpawnPoint {}
@@ -35,80 +35,81 @@ impl SpawnPoint {
}
#[derive(SolidClass, Component, Reflect, Default)]
#[reflect(Component)]
#[reflect(QuakeClass, Component)]
#[geometry(GeometryProvider::new().convex_collider())]
pub struct Worldspawn;
#[derive(SolidClass, Component, Reflect, Default)]
#[reflect(Component)]
#[reflect(QuakeClass, Component)]
#[geometry(GeometryProvider::new())]
#[base(Transform)]
pub struct Water;
#[derive(SolidClass, Component, Reflect, Default)]
#[reflect(Component)]
#[require(Transform)]
#[reflect(QuakeClass, Component)]
#[base(Transform)]
#[geometry(GeometryProvider::new().convex_collider())]
pub struct Crates;
#[derive(SolidClass, Component, Reflect, Default)]
#[reflect(Component)]
#[require(Transform)]
#[reflect(QuakeClass, Component)]
#[base(Transform)]
#[geometry(GeometryProvider::new().convex_collider())]
pub struct NamedEntity {
pub name: String,
}
#[derive(SolidClass, Component, Reflect, Default)]
#[reflect(Component)]
#[require(Transform, Target)]
#[reflect(QuakeClass, Component)]
#[base(Transform, Target)]
#[geometry(GeometryProvider::new().convex_collider())]
pub struct Platform;
#[derive(PointClass, Component, Reflect, Default)]
#[reflect(Component)]
#[require(Transform)]
#[reflect(QuakeClass, Component)]
#[base(Transform)]
pub struct PlatformTarget {
pub targetname: String,
}
#[derive(SolidClass, Component, Reflect, Default)]
#[reflect(Component)]
#[require(Transform, Target)]
#[reflect(QuakeClass, Component)]
#[base(Transform, Target)]
#[geometry(GeometryProvider::new().convex_collider())]
pub struct Movable {
pub name: String,
}
#[derive(PointClass, Component, Reflect, Default)]
#[reflect(Component)]
#[require(Transform)]
#[reflect(QuakeClass, Component)]
#[base(Transform)]
pub struct MoveTarget {
pub targetname: String,
}
#[derive(PointClass, Component, Reflect, Default)]
#[reflect(Component)]
#[require(Transform)]
#[reflect(QuakeClass, Component)]
#[base(Transform)]
pub struct CameraTarget {
pub targetname: String,
}
#[derive(PointClass, Component, Reflect, Default)]
#[reflect(Component)]
#[require(Transform, Target)]
#[reflect(QuakeClass, Component)]
#[base(Transform, Target)]
pub struct CutsceneCamera {
pub name: String,
pub targetname: String,
}
#[derive(PointClass, Component, Reflect, Default)]
#[reflect(Component)]
#[require(Transform, Target)]
#[reflect(QuakeClass, Component)]
#[base(Transform, Target)]
pub struct CutsceneCameraMovementEnd;
#[derive(PointClass, Component, Reflect, Default)]
#[reflect(Component)]
#[require(Transform)]
#[reflect(QuakeClass, Component)]
#[base(Transform)]
#[component(on_add = Self::on_add)]
#[model({ "path": "models/alien_naked.glb" })]
pub struct EnemySpawn {
@@ -149,8 +150,8 @@ impl EnemySpawn {
}
#[derive(PointClass, Component, Reflect, Default)]
#[reflect(Component)]
#[require(Transform)]
#[reflect(QuakeClass, Component)]
#[base(Transform)]
#[component(on_add = Self::on_add)]
#[model({ "path": "models/cash.glb" })]
pub struct CashSpawn {}
@@ -174,3 +175,20 @@ impl CashSpawn {
));
}
}
pub fn plugin(app: &mut App) {
app.register_type::<SpawnPoint>();
app.register_type::<Worldspawn>();
app.register_type::<Water>();
app.register_type::<Crates>();
app.register_type::<NamedEntity>();
app.register_type::<Platform>();
app.register_type::<PlatformTarget>();
app.register_type::<Movable>();
app.register_type::<MoveTarget>();
app.register_type::<CameraTarget>();
app.register_type::<CutsceneCamera>();
app.register_type::<CutsceneCameraMovementEnd>();
app.register_type::<EnemySpawn>();
app.register_type::<CashSpawn>();
}