2024-08-23 11:22:09 +00:00
|
|
|
pub mod on_hit_particles;
|
|
|
|
pub mod particle_spawn;
|
|
|
|
pub mod prelude;
|
|
|
|
pub mod projectile;
|
|
|
|
pub mod selfcast;
|
|
|
|
|
|
|
|
use anyhow::Result;
|
|
|
|
use cgmath::Vector2;
|
|
|
|
use engine::prelude::*;
|
2024-08-25 07:11:52 +00:00
|
|
|
use entity_manager::*;
|
2024-08-24 13:36:58 +00:00
|
|
|
use rpg_components::components::character_status::CharacterStatus;
|
|
|
|
use rpg_components::components::level::{Level, LevelUpEvent};
|
|
|
|
use rpg_components::components::npc_type::{NPCBoss, NPCElite, NPCNormal, NPCType};
|
|
|
|
use rpg_components::components::statistics::Statistics;
|
|
|
|
use rpg_components::damage_type::DamageType;
|
2024-08-23 11:22:09 +00:00
|
|
|
|
2024-08-24 13:36:58 +00:00
|
|
|
use crate::game::content::prelude::*;
|
2024-08-23 11:22:09 +00:00
|
|
|
|
|
|
|
use crate::Game;
|
|
|
|
|
|
|
|
pub fn handle_npc_death<'a>(
|
|
|
|
game: &Game,
|
|
|
|
s: &mut impl SceneEntities,
|
|
|
|
collider: Entity,
|
|
|
|
mut collider_components: MultiMut<'a>,
|
|
|
|
) -> Result<()> {
|
|
|
|
// check if collider is dead, if so potentially create a loot chest and destroy the entity
|
|
|
|
|
|
|
|
if let Ok(collider_status) = collider_components.get::<CharacterStatus>() {
|
|
|
|
if collider_status.is_dead() {
|
|
|
|
let collider_level = collider_components.get::<Level>()?;
|
|
|
|
let collider_location = collider_components.get::<Location>()?;
|
|
|
|
|
|
|
|
if collider_components.get::<FactionPlayer>().is_ok() {
|
|
|
|
let npc_movement = collider_components.get::<Movement>()?;
|
|
|
|
npc_movement.set_direction(Vector2::zero());
|
|
|
|
|
|
|
|
let mut grave_stone = game
|
|
|
|
.entity_manager()
|
|
|
|
.load_entity(game.engine().assets(), "Grave Stone")?;
|
|
|
|
|
|
|
|
#[cfg(debug_assertions)]
|
|
|
|
{
|
|
|
|
grave_stone.debug_name = Some(format!("Player Grave Stone ({})", collider));
|
|
|
|
}
|
|
|
|
|
|
|
|
Location::new_and_setup(&mut grave_stone)?
|
|
|
|
.set_position(collider_location.position());
|
|
|
|
|
|
|
|
s.add_entity(grave_stone)?;
|
|
|
|
} else if collider_components.get::<FactionNPC>().is_ok() {
|
|
|
|
let npc_hitbox = collider_components.get::<HitBox>()?;
|
|
|
|
|
|
|
|
let ghost = Ghost::new(
|
|
|
|
&game,
|
|
|
|
collider_location,
|
|
|
|
npc_hitbox.radius(),
|
|
|
|
npc_hitbox.height(),
|
|
|
|
s.now(),
|
|
|
|
)?;
|
|
|
|
|
|
|
|
s.add_entity(ghost)?;
|
|
|
|
s.remove_entity(collider)?;
|
|
|
|
|
|
|
|
if let Some(loot_chest) = LootStash::handle_npc_death(
|
|
|
|
&game,
|
|
|
|
collider_level,
|
|
|
|
collider_location,
|
|
|
|
if collider_components.get::<NPCNormal>().is_ok() {
|
|
|
|
NPCType::Normal
|
|
|
|
} else if collider_components.get::<NPCElite>().is_ok() {
|
|
|
|
NPCType::Elite
|
|
|
|
} else if collider_components.get::<NPCBoss>().is_ok() {
|
|
|
|
NPCType::Boss
|
|
|
|
} else {
|
|
|
|
unreachable!("missing component!");
|
|
|
|
},
|
|
|
|
)? {
|
|
|
|
s.add_entity(loot_chest)?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn damage_and_experience(
|
|
|
|
base_damage: u32,
|
|
|
|
damage_type: DamageType,
|
|
|
|
collider_multi_mut: &mut MultiMut<'_>,
|
|
|
|
mut owner_components: MultiMut<'_>,
|
|
|
|
scene: &mut SceneContents<'_>,
|
|
|
|
) -> Result<()> {
|
|
|
|
if let Ok(collider_current_status) = collider_multi_mut.get::<CharacterStatus>() {
|
|
|
|
if let Ok(collider_stats) = collider_multi_mut.get::<Statistics>() {
|
|
|
|
if let Ok(collider_level) = collider_multi_mut.get::<Level>() {
|
|
|
|
let resistance = collider_stats.calculate_resistance(damage_type);
|
|
|
|
|
|
|
|
if resistance < base_damage {
|
|
|
|
let damage = base_damage - resistance;
|
|
|
|
let owner_status = owner_components.get::<CharacterStatus>()?;
|
|
|
|
|
|
|
|
collider_current_status.apply_damage(damage as f32);
|
|
|
|
scene.write_event(DamageEvent {
|
|
|
|
damage,
|
|
|
|
damage_type,
|
|
|
|
position: collider_multi_mut.get::<Location>()?.position(),
|
|
|
|
});
|
|
|
|
|
|
|
|
if collider_current_status.is_dead() {
|
|
|
|
if owner_components.get::<FactionPlayer>().is_ok() {
|
|
|
|
if !owner_status.is_dead() {
|
|
|
|
let level = owner_components.get::<Level>()?;
|
|
|
|
|
|
|
|
if level.add_experience(
|
|
|
|
collider_level.level(),
|
|
|
|
if collider_multi_mut.get::<NPCNormal>().is_ok() {
|
|
|
|
NPCType::Normal
|
|
|
|
} else if collider_multi_mut.get::<NPCElite>().is_ok() {
|
|
|
|
NPCType::Elite
|
|
|
|
} else if collider_multi_mut.get::<NPCBoss>().is_ok() {
|
|
|
|
NPCType::Boss
|
|
|
|
} else {
|
|
|
|
unreachable!("missing component!");
|
|
|
|
},
|
|
|
|
)? {
|
|
|
|
scene.write_event(LevelUpEvent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|