engine/gavania-core/src/game/content/abilities/mod.rs

140 lines
5.2 KiB
Rust
Raw Normal View History

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(())
}