73 lines
1.9 KiB
Rust
73 lines
1.9 KiB
Rust
use crate::{
|
|
GameState,
|
|
ai::Ai,
|
|
character::AnimatedCharacter,
|
|
head::ActiveHead,
|
|
head_drop::HeadDrops,
|
|
heads::{ActiveHeads, HEAD_COUNT, HeadState},
|
|
heads_database::HeadsDatabase,
|
|
hitpoints::{Hitpoints, Kill},
|
|
keys::KeySpawn,
|
|
tb_entities::EnemySpawn,
|
|
};
|
|
use bevy::prelude::*;
|
|
use std::collections::HashMap;
|
|
|
|
#[derive(Component, Reflect)]
|
|
#[reflect(Component)]
|
|
pub struct Npc;
|
|
|
|
pub fn plugin(app: &mut App) {
|
|
app.add_systems(OnEnter(GameState::Playing), init);
|
|
}
|
|
|
|
fn init(mut commands: Commands, query: Query<(Entity, &EnemySpawn)>, heads_db: Res<HeadsDatabase>) {
|
|
//TODO: move into HeadsDatabase
|
|
let mut names: HashMap<String, usize> = HashMap::default();
|
|
for i in 0..HEAD_COUNT {
|
|
names.insert(heads_db.head_key(i).to_string(), i);
|
|
}
|
|
|
|
for (e, spawn) in query.iter() {
|
|
let id = names[&spawn.head];
|
|
commands
|
|
.entity(e)
|
|
.insert((
|
|
Hitpoints::new(100),
|
|
Npc,
|
|
ActiveHead(id),
|
|
ActiveHeads::new([
|
|
Some(HeadState::new(id, heads_db.as_ref())),
|
|
None,
|
|
None,
|
|
None,
|
|
None,
|
|
]),
|
|
))
|
|
.insert_if(Ai, || !spawn.disable_ai)
|
|
.with_child((
|
|
Name::from("body-rig"),
|
|
AnimatedCharacter::new(id).with_rotation(),
|
|
))
|
|
.observe(on_kill);
|
|
}
|
|
}
|
|
|
|
fn on_kill(
|
|
trigger: Trigger<Kill>,
|
|
mut commands: Commands,
|
|
query: Query<(&Transform, &EnemySpawn, &ActiveHead)>,
|
|
) {
|
|
let Ok((transform, enemy, head)) = query.get(trigger.target()) else {
|
|
return;
|
|
};
|
|
|
|
commands.trigger(HeadDrops(transform.translation, head.0));
|
|
|
|
commands.entity(trigger.target()).despawn();
|
|
|
|
if !enemy.key.is_empty() {
|
|
commands.trigger(KeySpawn(transform.translation, enemy.key.clone()));
|
|
}
|
|
}
|