* replicate it * use collision observer to simplify * pass entity of player that receives cash for a duplicate head
95 lines
2.5 KiB
Rust
95 lines
2.5 KiB
Rust
use crate::{
|
|
GameState, global_observer,
|
|
physics_layers::GameLayer,
|
|
player::Player,
|
|
protocol::{GltfSceneRoot, PlaySound, is_server},
|
|
server_observer,
|
|
tb_entities::CashSpawn,
|
|
};
|
|
use avian3d::prelude::*;
|
|
use bevy::prelude::*;
|
|
use bevy_replicon::prelude::*;
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Component, Reflect, Default, Deserialize, Serialize)]
|
|
#[reflect(Component)]
|
|
#[require(Transform)]
|
|
pub struct Cash;
|
|
|
|
#[derive(Component, Reflect, Default)]
|
|
#[reflect(Component)]
|
|
struct CashText;
|
|
|
|
#[derive(Component, Reflect, Default, Serialize, Deserialize, PartialEq)]
|
|
pub struct CashInventory {
|
|
pub cash: i32,
|
|
}
|
|
|
|
#[derive(EntityEvent)]
|
|
pub struct CashCollectEvent {
|
|
pub entity: Entity,
|
|
}
|
|
|
|
pub fn plugin(app: &mut App) {
|
|
app.add_systems(OnEnter(GameState::Playing), setup.run_if(is_server));
|
|
app.add_systems(Update, rotate.run_if(in_state(GameState::Playing)));
|
|
|
|
server_observer!(app, on_cash_collected);
|
|
}
|
|
|
|
fn setup(mut commands: Commands, query: Query<Entity, With<CashSpawn>>) {
|
|
for entity in query.iter() {
|
|
commands
|
|
.entity(entity)
|
|
.insert((
|
|
Name::new("cash"),
|
|
GltfSceneRoot::Cash,
|
|
Cash,
|
|
Collider::cuboid(2., 3.0, 2.),
|
|
CollisionLayers::new(GameLayer::CollectibleSensors, LayerMask::ALL),
|
|
RigidBody::Kinematic,
|
|
CollisionEventsEnabled,
|
|
Sensor,
|
|
Replicated,
|
|
))
|
|
.observe(on_cash_collision);
|
|
}
|
|
}
|
|
|
|
fn on_cash_collected(
|
|
trigger: On<CashCollectEvent>,
|
|
mut commands: Commands,
|
|
mut query_player: Query<&mut CashInventory, With<Player>>,
|
|
) {
|
|
if let Ok(mut cash) = query_player.get_mut(trigger.entity) {
|
|
commands.server_trigger(ToClients {
|
|
mode: SendMode::Broadcast,
|
|
message: PlaySound::CashCollect,
|
|
});
|
|
|
|
cash.cash += 100;
|
|
}
|
|
}
|
|
|
|
fn on_cash_collision(
|
|
trigger: On<CollisionStart>,
|
|
mut commands: Commands,
|
|
query_player: Query<&Player>,
|
|
) {
|
|
let collectable = trigger.event().collider1;
|
|
let collider = trigger.event().collider2;
|
|
|
|
if query_player.contains(collider) {
|
|
commands.trigger(CashCollectEvent { entity: collider });
|
|
commands.entity(collectable).despawn();
|
|
}
|
|
}
|
|
|
|
fn rotate(time: Res<Time>, mut query: Query<&mut Rotation, With<Cash>>) {
|
|
for mut rotation in query.iter_mut() {
|
|
rotation.0 = rotation
|
|
.0
|
|
.mul_quat(Quat::from_rotation_y(time.delta_secs()));
|
|
}
|
|
}
|