92 lines
3.3 KiB
Rust
92 lines
3.3 KiB
Rust
use crate::{
|
|
fighter::{FighterInvulnerabilityState, baked_animation::BakedFighterAnimations},
|
|
game_settings::GameSettings,
|
|
materials::fighter_material::{FighterMaterial, FighterMesh},
|
|
};
|
|
use bevy::prelude::*;
|
|
|
|
#[derive(Component, Clone)]
|
|
pub struct FighterAnimations {
|
|
/// The single animation source for gameplay and the visual skeleton.
|
|
pub baked: Handle<BakedFighterAnimations>,
|
|
}
|
|
|
|
#[derive(Clone, Copy, Default, PartialEq)]
|
|
pub enum LastKnownInvulnerabilityState {
|
|
#[default]
|
|
Vulnerable,
|
|
Intangible,
|
|
Invulnerable,
|
|
}
|
|
|
|
impl From<&FighterInvulnerabilityState> for LastKnownInvulnerabilityState {
|
|
fn from(value: &FighterInvulnerabilityState) -> Self {
|
|
match value {
|
|
FighterInvulnerabilityState::Vulnerable => Self::Vulnerable,
|
|
FighterInvulnerabilityState::Invulnerable { .. } => Self::Invulnerable,
|
|
FighterInvulnerabilityState::Intangible { .. } => Self::Intangible,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Component, Clone, Default)]
|
|
pub struct FighterInvulnerabilityVisualState {
|
|
pub last_known_state: LastKnownInvulnerabilityState,
|
|
pub frames_in_state: u32,
|
|
}
|
|
|
|
pub fn update_status_colors(
|
|
mut fighters: Query<(
|
|
&FighterInvulnerabilityState,
|
|
&mut FighterInvulnerabilityVisualState,
|
|
)>,
|
|
meshes: Query<(&FighterMesh, &MeshMaterial3d<FighterMaterial>)>,
|
|
mut materials: ResMut<Assets<FighterMaterial>>,
|
|
game_settings: Res<GameSettings>,
|
|
) {
|
|
for (invuln_state, mut invuln_state_visual) in &mut fighters {
|
|
let curr_state = invuln_state.into();
|
|
let last_known_state = invuln_state_visual.last_known_state;
|
|
if curr_state != last_known_state {
|
|
invuln_state_visual.last_known_state = curr_state;
|
|
invuln_state_visual.frames_in_state = 0;
|
|
}
|
|
}
|
|
for (mesh, mat) in meshes {
|
|
let (_, invuln_state_visual) = fighters
|
|
.get(mesh.fighter)
|
|
.expect("Material should have relevant fighter available");
|
|
|
|
let status_color = match invuln_state_visual.last_known_state {
|
|
LastKnownInvulnerabilityState::Vulnerable => bevy::color::palettes::css::WHITE.into(),
|
|
LastKnownInvulnerabilityState::Invulnerable => {
|
|
game_settings.fighter_common.intangible_color
|
|
}
|
|
LastKnownInvulnerabilityState::Intangible => {
|
|
game_settings.fighter_common.intangible_color
|
|
}
|
|
};
|
|
|
|
let intensity = match invuln_state_visual.last_known_state {
|
|
LastKnownInvulnerabilityState::Vulnerable => 0.0,
|
|
LastKnownInvulnerabilityState::Invulnerable | LastKnownInvulnerabilityState::Intangible => {
|
|
let cycle_frames = invuln_state_visual.frames_in_state
|
|
% game_settings.fighter_common.intangible_pulse_duration;
|
|
1.0 - cycle_frames as f32
|
|
/ ((game_settings.fighter_common.intangible_pulse_duration) as f32)
|
|
}
|
|
};
|
|
|
|
let mut material = materials
|
|
.get_mut(mat.id())
|
|
.expect("Material should exist here...");
|
|
material
|
|
.extension
|
|
.update_status_color(status_color.into(), intensity);
|
|
}
|
|
|
|
for (_, mut invuln_state_visual) in fighters {
|
|
invuln_state_visual.frames_in_state = invuln_state_visual.frames_in_state.saturating_add(1);
|
|
}
|
|
}
|