118 lines
4.2 KiB
Rust
118 lines
4.2 KiB
Rust
use crate::{
|
|
abilities::BuildExplosionSprite,
|
|
animation::AnimationFlags,
|
|
camera::{CameraArmRotation, CameraTarget},
|
|
character::{self, AnimatedCharacter},
|
|
control::{
|
|
controller_common::{MovementSpeedFactor, PlayerCharacterController},
|
|
controls::ControllerSettings,
|
|
},
|
|
global_observer,
|
|
head::ActiveHead,
|
|
heads::ActiveHeads,
|
|
loading_assets::GameAssets,
|
|
player::{Player, PlayerBodyMesh},
|
|
utils::triggers::TriggerAppExt,
|
|
};
|
|
use avian3d::prelude::{AngularVelocity, CollisionLayers, LinearVelocity};
|
|
use bevy::prelude::*;
|
|
use happy_feet::{
|
|
grounding::GroundingState,
|
|
prelude::{
|
|
Character, CharacterDrag, CharacterGravity, CharacterMovement, GroundFriction, Grounding,
|
|
GroundingConfig, KinematicVelocity, MoveInput, SteppingConfig,
|
|
},
|
|
};
|
|
use lightyear::prelude::{
|
|
ActionsChannel, AppComponentExt, PredictionMode, PredictionRegistrationExt,
|
|
};
|
|
use lightyear_serde::{
|
|
SerializationError, reader::ReadInteger, registry::SerializeFns, writer::WriteInteger,
|
|
};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
pub fn plugin(app: &mut App) {
|
|
app.register_component::<ActiveHead>();
|
|
app.register_component::<ActiveHeads>();
|
|
app.register_component::<AngularVelocity>();
|
|
app.register_component::<AnimatedCharacter>();
|
|
app.register_component::<AnimationFlags>();
|
|
app.register_component::<CameraArmRotation>();
|
|
app.register_component::<CameraTarget>();
|
|
app.register_component::<Character>();
|
|
app.register_component::<character::Character>();
|
|
app.register_component::<CharacterDrag>();
|
|
app.register_component::<CharacterGravity>();
|
|
app.register_component::<CharacterMovement>();
|
|
app.register_component::<CollisionLayers>();
|
|
app.register_component::<ControllerSettings>();
|
|
app.register_component::<GltfSceneRoot>();
|
|
app.register_component::<GroundFriction>();
|
|
app.register_component::<Grounding>();
|
|
app.register_component::<GroundingConfig>();
|
|
app.register_component::<GroundingState>();
|
|
app.register_component::<KinematicVelocity>();
|
|
app.register_component::<LinearVelocity>();
|
|
app.register_component::<MoveInput>();
|
|
app.register_component::<MovementSpeedFactor>();
|
|
app.register_component::<Name>();
|
|
app.register_component::<Player>();
|
|
app.register_component::<PlayerBodyMesh>();
|
|
app.register_component::<PlayerCharacterController>();
|
|
app.register_component::<SteppingConfig>();
|
|
app.register_component::<Transform>()
|
|
.add_prediction(PredictionMode::Full)
|
|
.add_should_rollback(transform_should_rollback);
|
|
// `Visibility` isn't `(De)Serialize`, so we have to provide custom serde for it.
|
|
app.register_component_custom_serde::<Visibility>(SerializeFns {
|
|
serialize: |comp, writer| writer.write_u8(*comp as u8).map_err(SerializationError::Io),
|
|
deserialize: |reader| {
|
|
let byte = reader.read_u8().map_err(SerializationError::Io)?;
|
|
Ok(match byte {
|
|
0 => Visibility::Inherited,
|
|
1 => Visibility::Hidden,
|
|
2 => Visibility::Visible,
|
|
_ => return Err(SerializationError::InvalidValue),
|
|
})
|
|
},
|
|
});
|
|
|
|
app.replicate_trigger::<BuildExplosionSprite, ActionsChannel>();
|
|
|
|
global_observer!(app, spawn_gltf_scene_roots);
|
|
}
|
|
|
|
fn transform_should_rollback(this: &Transform, that: &Transform) -> bool {
|
|
this.translation.distance_squared(that.translation) >= 0.01f32.powf(2.)
|
|
}
|
|
|
|
#[derive(Component, Reflect, Serialize, Deserialize, PartialEq)]
|
|
#[reflect(Component)]
|
|
pub enum GltfSceneRoot {
|
|
Projectile(String),
|
|
}
|
|
|
|
fn spawn_gltf_scene_roots(
|
|
trigger: Trigger<OnAdd, GltfSceneRoot>,
|
|
mut commands: Commands,
|
|
gltf_roots: Query<&GltfSceneRoot>,
|
|
assets: Res<GameAssets>,
|
|
gltfs: Res<Assets<Gltf>>,
|
|
) -> Result {
|
|
let root = gltf_roots.get(trigger.target())?;
|
|
|
|
let (gltf, index) = match root {
|
|
GltfSceneRoot::Projectile(addr) => (
|
|
assets.projectiles[format!("{addr}.glb").as_str()].clone(),
|
|
0,
|
|
),
|
|
};
|
|
let gltf = gltfs.get(&gltf).unwrap();
|
|
|
|
let scene = gltf.scenes[index].clone();
|
|
|
|
commands.entity(trigger.target()).insert(SceneRoot(scene));
|
|
|
|
Ok(())
|
|
}
|