Finish split
This commit is contained in:
parent
89023a8e6f
commit
9225c94160
21 changed files with 197 additions and 186 deletions
|
@ -1,13 +1,2 @@
|
||||||
pub mod abilities;
|
|
||||||
pub mod attributes;
|
|
||||||
pub mod experience;
|
|
||||||
pub mod items;
|
|
||||||
pub mod mobs;
|
pub mod mobs;
|
||||||
pub mod save_game;
|
|
||||||
|
|
||||||
pub use abilities::*;
|
|
||||||
pub use attributes::*;
|
|
||||||
pub use experience::*;
|
|
||||||
pub use items::*;
|
|
||||||
pub use mobs::*;
|
pub use mobs::*;
|
||||||
pub use save_game::*;
|
|
||||||
|
|
|
@ -7,27 +7,16 @@ pub mod selfcast;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use cgmath::Vector2;
|
use cgmath::Vector2;
|
||||||
use engine::prelude::*;
|
use engine::prelude::*;
|
||||||
|
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;
|
||||||
|
|
||||||
use crate::game::{content::prelude::*, game::GameHandle};
|
use crate::game::content::prelude::*;
|
||||||
|
|
||||||
use crate::Game;
|
use crate::Game;
|
||||||
|
|
||||||
pub trait Ability: Send + Sync {
|
|
||||||
fn data(&self) -> &AbilityLoader;
|
|
||||||
fn name(&self) -> &str;
|
|
||||||
|
|
||||||
fn execute(
|
|
||||||
&self,
|
|
||||||
owner: Entity,
|
|
||||||
components: &mut MultiMut<'_>,
|
|
||||||
direction: Vector2<f32>,
|
|
||||||
book: &AbilityBook,
|
|
||||||
game: &GameHandle,
|
|
||||||
entities: &mut Entities<'_>,
|
|
||||||
events: &mut ContentEvents<'_>,
|
|
||||||
) -> Result<()>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn handle_npc_death<'a>(
|
pub fn handle_npc_death<'a>(
|
||||||
game: &Game,
|
game: &Game,
|
||||||
s: &mut impl SceneEntities,
|
s: &mut impl SceneEntities,
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::*;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use cgmath::{Deg, Vector3};
|
use cgmath::{Deg, Vector3};
|
||||||
|
use rpg_components::{components::abilityloader::AbilityLoader, damage_type::DamageType};
|
||||||
|
|
||||||
pub struct ArcInfo {
|
pub struct ArcInfo {
|
||||||
pub radius: f32,
|
pub radius: f32,
|
||||||
|
@ -32,13 +33,16 @@ impl OnHitParticles {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn(&self, scene: &mut SceneContents<'_>, game_handle: &GameHandle) -> Result<()> {
|
fn spawn(&self, scene: &mut SceneContents<'_>, game_handle: &GameHandle) -> Result<()> {
|
||||||
|
let game = game_handle.upgrade();
|
||||||
|
|
||||||
let mut entity = AbilityLoader::create_on_hit_particles(
|
let mut entity = AbilityLoader::create_on_hit_particles(
|
||||||
|
game.engine(),
|
||||||
self.particle_system_info.clone(),
|
self.particle_system_info.clone(),
|
||||||
&self.collision_sound,
|
&self.collision_sound,
|
||||||
&game_handle.upgrade(),
|
|
||||||
self.position,
|
self.position,
|
||||||
self.offset,
|
self.offset,
|
||||||
scene.particle_system_vulkan_objects(),
|
scene.particle_system_vulkan_objects(),
|
||||||
|
|s| game.build_data_path(s),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if let Some(arc_info) = &self.arc_info {
|
if let Some(arc_info) = &self.arc_info {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use rpg_components::components::abilityloader::AbilityLoader;
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
pub use super::{Ability, AbilityType};
|
|
||||||
|
|
||||||
pub use super::projectile::{Projectile, ProjectileMarker};
|
|
||||||
pub use super::selfcast::SelfCast;
|
|
||||||
// pub use super::slide::{Slide, SlideCreateInfo};
|
|
||||||
|
|
||||||
pub use super::ability_addon::{AbilityAddon, AbilityAddonCollection, AbilityAddonTypes};
|
|
||||||
pub use super::ability_book::AbilityBook;
|
|
||||||
|
|
||||||
pub use super::on_hit_particles::{ArcInfo, OnHitParticles};
|
pub use super::on_hit_particles::{ArcInfo, OnHitParticles};
|
||||||
pub use super::particle_spawn::{ParticleSpawn, ParticleSpawnExecutor};
|
pub use super::particle_spawn::{ParticleSpawn, ParticleSpawnExecutor};
|
||||||
|
pub use super::projectile::{Projectile, ProjectileMarker};
|
||||||
|
pub use super::selfcast::SelfCast;
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
use engine::prelude::*;
|
use engine::prelude::*;
|
||||||
|
use rpg_components::{
|
||||||
|
components::{abilityloader::AbilityLoader, statistics::Statistics},
|
||||||
|
damage_type::DamageType,
|
||||||
|
items::{ability_addon::AbilityAddonCollection, ability_book::AbilityBook},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::game::content::abilities::handle_npc_death;
|
use crate::game::content::abilities::handle_npc_death;
|
||||||
|
|
||||||
|
@ -55,15 +60,9 @@ impl ComponentDebug for ProjectileMarker {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Projectile {
|
pub struct Projectile;
|
||||||
data: AbilityLoader,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Projectile {
|
impl Projectile {
|
||||||
pub fn new(data: AbilityLoader) -> Result<Self> {
|
|
||||||
Ok(Projectile { data })
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hit_event(
|
fn hit_event(
|
||||||
me: Entity,
|
me: Entity,
|
||||||
collider: Entity,
|
collider: Entity,
|
||||||
|
@ -232,17 +231,9 @@ impl Projectile {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ability for Projectile {
|
impl Projectile {
|
||||||
fn data(&self) -> &AbilityLoader {
|
pub fn execute(
|
||||||
&self.data
|
ability: &AbilityLoader,
|
||||||
}
|
|
||||||
|
|
||||||
fn name(&self) -> &str {
|
|
||||||
self.data.name()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn execute(
|
|
||||||
&self,
|
|
||||||
_owner: Entity,
|
_owner: Entity,
|
||||||
owner_components: &mut MultiMut<'_>,
|
owner_components: &mut MultiMut<'_>,
|
||||||
direction: Vector2<f32>,
|
direction: Vector2<f32>,
|
||||||
|
@ -268,7 +259,7 @@ impl Ability for Projectile {
|
||||||
|
|
||||||
let projectile_size = book.addons().size();
|
let projectile_size = book.addons().size();
|
||||||
let projectile_speed = book.addons().projectile_speed();
|
let projectile_speed = book.addons().projectile_speed();
|
||||||
let projectile_distance = self.data.settings.parameter.distance + book.addons().distance();
|
let projectile_distance = ability.settings.parameter.distance + book.addons().distance();
|
||||||
|
|
||||||
let ability_data = book.ability().data();
|
let ability_data = book.ability().data();
|
||||||
|
|
||||||
|
@ -281,7 +272,7 @@ impl Ability for Projectile {
|
||||||
|
|
||||||
let mut projectile_entity = game
|
let mut projectile_entity = game
|
||||||
.entity_manager()
|
.entity_manager()
|
||||||
.load_entity(game.engine().assets(), &self.data.settings.meta.entity)?;
|
.load_entity(game.engine().assets(), &ability.settings.meta.entity)?;
|
||||||
|
|
||||||
{
|
{
|
||||||
// alter the hitbox parameters
|
// alter the hitbox parameters
|
||||||
|
@ -332,7 +323,7 @@ impl Ability for Projectile {
|
||||||
));
|
));
|
||||||
|
|
||||||
let mut projectile_movement = Movement::new(
|
let mut projectile_movement = Movement::new(
|
||||||
self.data.settings.parameter.speed + projectile_speed,
|
ability.settings.parameter.speed + projectile_speed,
|
||||||
projectile_entity.get_component_mut::<Audio>().ok(),
|
projectile_entity.get_component_mut::<Audio>().ok(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -363,7 +354,7 @@ impl Ability for Projectile {
|
||||||
}
|
}
|
||||||
|
|
||||||
projectile_entity.insert_component(ability_location_info);
|
projectile_entity.insert_component(ability_location_info);
|
||||||
projectile_entity.insert_component(self.data.clone());
|
projectile_entity.insert_component(ability.clone());
|
||||||
projectile_entity.insert_component(projectile_movement);
|
projectile_entity.insert_component(projectile_movement);
|
||||||
projectile_entity.insert_component(ProjectileMarker);
|
projectile_entity.insert_component(ProjectileMarker);
|
||||||
Faction::copy(owner_components, &mut projectile_entity);
|
Faction::copy(owner_components, &mut projectile_entity);
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use engine::prelude::*;
|
use engine::prelude::*;
|
||||||
|
use rpg_components::{
|
||||||
|
components::{abilityloader::AbilityLoader, statistics::Statistics},
|
||||||
|
items::ability_book::AbilityBook,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::game::{
|
use crate::game::{
|
||||||
content::prelude::*,
|
content::prelude::*,
|
||||||
|
@ -13,27 +17,11 @@ use std::sync::{Arc, Mutex, MutexGuard};
|
||||||
|
|
||||||
use super::particle_spawn::ParticleSpawn;
|
use super::particle_spawn::ParticleSpawn;
|
||||||
|
|
||||||
pub struct SelfCast {
|
pub struct SelfCast;
|
||||||
data: AbilityLoader,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SelfCast {
|
impl SelfCast {
|
||||||
pub fn new(data: AbilityLoader) -> Result<Self> {
|
pub fn execute(
|
||||||
Ok(SelfCast { data })
|
ability: &AbilityLoader,
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Ability for SelfCast {
|
|
||||||
fn data(&self) -> &AbilityLoader {
|
|
||||||
&self.data
|
|
||||||
}
|
|
||||||
|
|
||||||
fn name(&self) -> &str {
|
|
||||||
self.data.name()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn execute(
|
|
||||||
&self,
|
|
||||||
owner: Entity,
|
owner: Entity,
|
||||||
owner_components: &mut MultiMut<'_>,
|
owner_components: &mut MultiMut<'_>,
|
||||||
direction: Vector2<f32>,
|
direction: Vector2<f32>,
|
||||||
|
@ -46,18 +34,18 @@ impl Ability for SelfCast {
|
||||||
let owner_stats = owner_components.get::<Statistics>()?;
|
let owner_stats = owner_components.get::<Statistics>()?;
|
||||||
let hit_box = owner_components.get::<HitBox>()?;
|
let hit_box = owner_components.get::<HitBox>()?;
|
||||||
|
|
||||||
let mut base_damage = self.data.damage(book.level(), book.addons(), owner_stats);
|
let mut base_damage = ability.damage(book.level(), book.addons(), owner_stats);
|
||||||
|
|
||||||
let range = self.data.settings.parameter.radius * book.addons().size();
|
let range = ability.settings.parameter.radius * book.addons().size();
|
||||||
|
|
||||||
let (mut entity_object, particle_spawn) = AreaOfEffect::new(
|
let (mut entity_object, particle_spawn) = AreaOfEffect::new(
|
||||||
direction,
|
direction,
|
||||||
location.position(),
|
location.position(),
|
||||||
Deg(self.data.settings.parameter.arc),
|
Deg(ability.settings.parameter.arc),
|
||||||
range,
|
range,
|
||||||
hit_box.height() * 0.75,
|
hit_box.height() * 0.75,
|
||||||
owner,
|
owner,
|
||||||
self.data.clone(),
|
ability.clone(),
|
||||||
base_damage,
|
base_damage,
|
||||||
game_handle.clone(),
|
game_handle.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
|
@ -4,6 +4,10 @@ use crate::Result;
|
||||||
use engine::prelude::*;
|
use engine::prelude::*;
|
||||||
|
|
||||||
use cgmath::{vec2, InnerSpace, Vector2, Vector3};
|
use cgmath::{vec2, InnerSpace, Vector2, Vector3};
|
||||||
|
use rpg_components::ability_type::AbilityType;
|
||||||
|
use rpg_components::components::ability_slots::AbilitySlots;
|
||||||
|
use rpg_components::components::character_status::CharacterStatus;
|
||||||
|
use rpg_components::damage_type::DamageType;
|
||||||
|
|
||||||
// space between user and ai hitbox
|
// space between user and ai hitbox
|
||||||
const SAFETY_RADIUS: f32 = 0.3;
|
const SAFETY_RADIUS: f32 = 0.3;
|
||||||
|
@ -59,15 +63,27 @@ impl SimpleAI {
|
||||||
let now = scene_contents.now();
|
let now = scene_contents.now();
|
||||||
|
|
||||||
// check if ability can be cast
|
// check if ability can be cast
|
||||||
if book.validate_use(
|
if !animation_info.is_locked()
|
||||||
now,
|
&& book.validate_use(now, character_status, location)?
|
||||||
animation,
|
{
|
||||||
draw,
|
{
|
||||||
animation_info,
|
// TODO: further separation of animation types (bows, ...)
|
||||||
character_status,
|
let animation_type =
|
||||||
// movement,
|
match book.ability().data().settings.parameter.damage_type {
|
||||||
location,
|
DamageType::Physical => AnimationType::Attack,
|
||||||
)? {
|
_ => AnimationType::Cast,
|
||||||
|
};
|
||||||
|
|
||||||
|
animation_info.set_animation(
|
||||||
|
animation,
|
||||||
|
draw,
|
||||||
|
Some(animation_type),
|
||||||
|
now,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
let owner = unsafe {
|
let owner = unsafe {
|
||||||
scene_contents.entities.entity_mut_unchecked(self.owner)?
|
scene_contents.entities.entity_mut_unchecked(self.owner)?
|
||||||
};
|
};
|
||||||
|
@ -76,14 +92,20 @@ impl SimpleAI {
|
||||||
|
|
||||||
// actually cast the ability
|
// actually cast the ability
|
||||||
println!("ai casts ability");
|
println!("ai casts ability");
|
||||||
book.execute(
|
|
||||||
&mut multi_mut,
|
match book.ability().data().settings.parameter.ability_type {
|
||||||
self.owner,
|
AbilityType::Projectile => Projectile::execute(
|
||||||
location.direction(),
|
book.ability().data(),
|
||||||
game,
|
self.owner,
|
||||||
&mut scene_contents.entities,
|
&mut multi_mut,
|
||||||
&mut scene_contents.events,
|
location.direction(),
|
||||||
)?;
|
book,
|
||||||
|
game,
|
||||||
|
&mut scene_contents.entities,
|
||||||
|
&mut scene_contents.events,
|
||||||
|
)?,
|
||||||
|
AbilityType::SelfCast => todo!(),
|
||||||
|
}
|
||||||
|
|
||||||
can_move = false;
|
can_move = false;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use cgmath::{Deg, Vector2, Vector3};
|
use cgmath::{Deg, Vector2, Vector3};
|
||||||
|
use rpg_components::components::abilityloader::AbilityLoader;
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
|
@ -2,6 +2,10 @@ use std::{collections::HashSet, time::Duration};
|
||||||
|
|
||||||
use cgmath::{vec2, Deg, InnerSpace, Matrix2, Vector2};
|
use cgmath::{vec2, Deg, InnerSpace, Matrix2, Vector2};
|
||||||
use engine::prelude::*;
|
use engine::prelude::*;
|
||||||
|
use rpg_components::{
|
||||||
|
components::{abilityloader::AbilityLoader, statistics::Statistics},
|
||||||
|
damage_type::DamageType,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use cgmath::Vector3;
|
use cgmath::Vector3;
|
||||||
|
use rpg_components::damage_type::DamageType;
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,10 @@ use crate::*;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use cgmath::Vector3;
|
use cgmath::Vector3;
|
||||||
use engine::prelude::*;
|
use engine::prelude::*;
|
||||||
|
use rpg_components::{
|
||||||
|
components::{level::Level, npc_type::NPCType},
|
||||||
|
items::Loot,
|
||||||
|
};
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ pub mod hitbox;
|
||||||
pub mod movement;
|
pub mod movement;
|
||||||
|
|
||||||
mod ability_location_info;
|
mod ability_location_info;
|
||||||
mod abilityloader;
|
|
||||||
pub mod ai;
|
pub mod ai;
|
||||||
mod aoe;
|
mod aoe;
|
||||||
pub mod aoe_arc;
|
pub mod aoe_arc;
|
||||||
|
@ -13,34 +12,21 @@ mod ghost;
|
||||||
pub mod health_bar;
|
pub mod health_bar;
|
||||||
mod loot_stash;
|
mod loot_stash;
|
||||||
mod npc_name;
|
mod npc_name;
|
||||||
mod npc_type;
|
|
||||||
|
|
||||||
pub use self::{ai::*, aoe_arc::AreaOfEffectArc};
|
pub use self::{ai::*, aoe_arc::AreaOfEffectArc};
|
||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
ability_location_info::*,
|
ability_location_info::*,
|
||||||
ability_slots::*,
|
|
||||||
abilityloader::AbilityLoader,
|
|
||||||
animation_info::AnimationInfo,
|
animation_info::AnimationInfo,
|
||||||
aoe::*,
|
aoe::*,
|
||||||
attributes::*,
|
|
||||||
character_status::CharacterStatus,
|
|
||||||
crafting_materials::*,
|
|
||||||
damage_number::*,
|
damage_number::*,
|
||||||
entity_faction::*,
|
entity_faction::*,
|
||||||
ghost::*,
|
ghost::*,
|
||||||
health_bar::*,
|
health_bar::*,
|
||||||
hitbox::{CollisionEventType, HitBox},
|
hitbox::{CollisionEventType, HitBox},
|
||||||
inventory::*,
|
|
||||||
item_slots::*,
|
|
||||||
level::*,
|
|
||||||
loot_stash::*,
|
loot_stash::*,
|
||||||
macros::AttributeAssociation,
|
|
||||||
movement::Movement,
|
movement::Movement,
|
||||||
npc_name::NPCName,
|
npc_name::NPCName,
|
||||||
npc_type::*,
|
|
||||||
statistic_types::*,
|
|
||||||
statistics::*,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
pub mod abilities;
|
pub mod abilities;
|
||||||
pub mod components;
|
pub mod components;
|
||||||
pub mod mechanics;
|
|
||||||
pub mod objects;
|
pub mod objects;
|
||||||
|
|
||||||
pub mod lightning;
|
pub mod lightning;
|
||||||
|
|
|
@ -2,11 +2,30 @@ use anyhow::Result;
|
||||||
use assetpath::AssetPath;
|
use assetpath::AssetPath;
|
||||||
use cgmath::{vec2, Vector2};
|
use cgmath::{vec2, Vector2};
|
||||||
use engine::prelude::*;
|
use engine::prelude::*;
|
||||||
use rpg_components::components::{crafting_materials::CraftingMaterials, statistics::Statistics};
|
use rpg_components::{
|
||||||
|
ability_type::AbilityType,
|
||||||
|
components::{
|
||||||
|
ability_slots::AbilitySlots,
|
||||||
|
attributes::Attributes,
|
||||||
|
character_status::CharacterStatus,
|
||||||
|
crafting_materials::CraftingMaterials,
|
||||||
|
inventory::Inventory,
|
||||||
|
item_slots::ItemSlotContainer,
|
||||||
|
level::{Level, LevelUpEvent},
|
||||||
|
statistics::Statistics,
|
||||||
|
},
|
||||||
|
config::{
|
||||||
|
attributes::AttributeSettings,
|
||||||
|
experience::ExperienceSettings,
|
||||||
|
save_game::{save_game_dir, SaveGame},
|
||||||
|
},
|
||||||
|
damage_type::DamageType,
|
||||||
|
items::{ItemSystem, Rarities},
|
||||||
|
};
|
||||||
|
|
||||||
use super::super::prelude::*;
|
use super::super::prelude::*;
|
||||||
|
|
||||||
use crate::{game::configloader::*, GameHandle};
|
use crate::GameHandle;
|
||||||
|
|
||||||
use std::{sync::Arc, time::Duration};
|
use std::{sync::Arc, time::Duration};
|
||||||
|
|
||||||
|
@ -246,19 +265,59 @@ impl Hero {
|
||||||
let direction = location.direction();
|
let direction = location.direction();
|
||||||
|
|
||||||
if let Some(ability_book) = abilities.book_mut(index) {
|
if let Some(ability_book) = abilities.book_mut(index) {
|
||||||
if ability_book.validate_use(
|
if !animation_info.is_locked()
|
||||||
time,
|
&& ability_book.validate_use(time, character_status, location)?
|
||||||
animation,
|
{
|
||||||
draw,
|
|
||||||
animation_info,
|
|
||||||
character_status,
|
|
||||||
location,
|
|
||||||
)? {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
multi_mut.clear_all_usages();
|
multi_mut.clear_all_usages();
|
||||||
}
|
}
|
||||||
|
|
||||||
ability_book.execute(multi_mut, hero, direction, game_handle, entities, events)?;
|
{
|
||||||
|
// TODO: further separation of animation types (bows, ...)
|
||||||
|
let animation_type =
|
||||||
|
match ability_book.ability().data().settings.parameter.damage_type {
|
||||||
|
DamageType::Physical => AnimationType::Attack,
|
||||||
|
_ => AnimationType::Cast,
|
||||||
|
};
|
||||||
|
|
||||||
|
animation_info.set_animation(
|
||||||
|
animation,
|
||||||
|
draw,
|
||||||
|
Some(animation_type),
|
||||||
|
time,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
match ability_book
|
||||||
|
.ability()
|
||||||
|
.data()
|
||||||
|
.settings
|
||||||
|
.parameter
|
||||||
|
.ability_type
|
||||||
|
{
|
||||||
|
AbilityType::Projectile => Projectile::execute(
|
||||||
|
ability_book.ability().data(),
|
||||||
|
hero,
|
||||||
|
multi_mut,
|
||||||
|
direction,
|
||||||
|
&ability_book,
|
||||||
|
game_handle,
|
||||||
|
entities,
|
||||||
|
events,
|
||||||
|
)?,
|
||||||
|
AbilityType::SelfCast => SelfCast::execute(
|
||||||
|
ability_book.ability().data(),
|
||||||
|
hero,
|
||||||
|
multi_mut,
|
||||||
|
direction,
|
||||||
|
&ability_book,
|
||||||
|
game_handle,
|
||||||
|
entities,
|
||||||
|
events,
|
||||||
|
)?,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +339,8 @@ impl Hero {
|
||||||
pub fn save(&self, scene: &Scene) -> Result<()> {
|
pub fn save(&self, scene: &Scene) -> Result<()> {
|
||||||
let mut save_game = SaveGame::default();
|
let mut save_game = SaveGame::default();
|
||||||
|
|
||||||
save_game.file_name = AssetPath::from((save_game_dir(), format!("{}.savegame", self.name)));
|
save_game.file_name =
|
||||||
|
AssetPath::from((save_game_dir("gavania"), format!("{}.savegame", self.name)));
|
||||||
|
|
||||||
let entity = scene.entity(self.entity)?;
|
let entity = scene.entity(self.entity)?;
|
||||||
|
|
||||||
|
@ -341,15 +401,17 @@ impl Hero {
|
||||||
let mut multi_mut = entity_object.multi_mut();
|
let mut multi_mut = entity_object.multi_mut();
|
||||||
|
|
||||||
let draw = multi_mut.get::<Draw>().unwrap();
|
let draw = multi_mut.get::<Draw>().unwrap();
|
||||||
|
let game = game_handle.upgrade();
|
||||||
|
|
||||||
let mut items = match hero_create_type {
|
let mut items = match hero_create_type {
|
||||||
HeroCreateType::SaveGame(save_game) => ItemSlotContainer::load(
|
HeroCreateType::SaveGame(save_game) => ItemSlotContainer::load(
|
||||||
save_game,
|
save_game,
|
||||||
game_handle,
|
game.item_settings.clone(),
|
||||||
draw,
|
draw,
|
||||||
multi_mut.get::<ItemSlotContainer>()?.item_meshes().clone(),
|
multi_mut.get::<ItemSlotContainer>()?.item_meshes().clone(),
|
||||||
|
&game.item_system(),
|
||||||
)?,
|
)?,
|
||||||
HeroCreateType::New(_) => ItemSlotContainer::empty(game_handle, draw)?,
|
HeroCreateType::New(_) => ItemSlotContainer::empty(game.item_settings.clone(), draw)?,
|
||||||
};
|
};
|
||||||
|
|
||||||
items.set_item_change_callback(draw, multi_mut.get::<Location>()?)?;
|
items.set_item_change_callback(draw, multi_mut.get::<Location>()?)?;
|
||||||
|
@ -371,10 +433,14 @@ impl Hero {
|
||||||
hero_create_type: &HeroCreateType,
|
hero_create_type: &HeroCreateType,
|
||||||
game_handle: GameHandle,
|
game_handle: GameHandle,
|
||||||
) -> Result<AbilitySlots> {
|
) -> Result<AbilitySlots> {
|
||||||
|
let game = game_handle.upgrade();
|
||||||
|
|
||||||
match hero_create_type {
|
match hero_create_type {
|
||||||
HeroCreateType::SaveGame(save_game) => AbilitySlots::load(save_game, game_handle),
|
HeroCreateType::SaveGame(save_game) => {
|
||||||
|
AbilitySlots::load(game.item_system(), save_game)
|
||||||
|
}
|
||||||
HeroCreateType::New(_) => {
|
HeroCreateType::New(_) => {
|
||||||
let mut abilities = AbilitySlots::empty(game_handle.clone());
|
let mut abilities = AbilitySlots::empty(game.item_system());
|
||||||
|
|
||||||
let book = game_handle.upgrade().item_system().ability_book(
|
let book = game_handle.upgrade().item_system().ability_book(
|
||||||
"Basic Attack",
|
"Basic Attack",
|
||||||
|
|
|
@ -4,12 +4,23 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::game::content::prelude::*;
|
use crate::game::content::prelude::*;
|
||||||
use crate::{game::game::GameHandle, Rarities};
|
use crate::game::game::GameHandle;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use assetpath::AssetPath;
|
use assetpath::AssetPath;
|
||||||
use cgmath::{vec3, Deg, InnerSpace, Vector3, Zero};
|
use cgmath::{vec3, Deg, InnerSpace, Vector3, Zero};
|
||||||
use engine::prelude::*;
|
use engine::prelude::*;
|
||||||
|
use rpg_components::{
|
||||||
|
components::{
|
||||||
|
ability_slots::AbilitySlots,
|
||||||
|
attributes::Attributes,
|
||||||
|
character_status::CharacterStatus,
|
||||||
|
level::Level,
|
||||||
|
npc_type::{NPCBoss, NPCElite, NPCNormal, NPCType},
|
||||||
|
statistics::Statistics,
|
||||||
|
},
|
||||||
|
items::Rarities,
|
||||||
|
};
|
||||||
|
|
||||||
const NPC_BASE_STATS: u32 = 2;
|
const NPC_BASE_STATS: u32 = 2;
|
||||||
|
|
||||||
|
@ -339,8 +350,9 @@ impl NPCFactory {
|
||||||
let ai = SimpleAI::new(6.0, 9.0, entity_object.as_entity());
|
let ai = SimpleAI::new(6.0, 9.0, entity_object.as_entity());
|
||||||
|
|
||||||
// abilities
|
// abilities
|
||||||
let abilities =
|
// TODO
|
||||||
AbilitySlots::load_for_npc(level.level(), npc_settings, game_handle.clone())?;
|
// let abilities =
|
||||||
|
// AbilitySlots::load_for_npc(level.level(), npc_settings, game_handle.clone())?;
|
||||||
|
|
||||||
// ========== insert components ==========
|
// ========== insert components ==========
|
||||||
entity_object.insert_component(movement);
|
entity_object.insert_component(movement);
|
||||||
|
@ -348,7 +360,7 @@ impl NPCFactory {
|
||||||
entity_object.insert_component(stats);
|
entity_object.insert_component(stats);
|
||||||
entity_object.insert_component(character_status);
|
entity_object.insert_component(character_status);
|
||||||
entity_object.insert_component(level);
|
entity_object.insert_component(level);
|
||||||
entity_object.insert_component(abilities);
|
// entity_object.insert_component(abilities);
|
||||||
entity_object.insert_component(npc_name);
|
entity_object.insert_component(npc_name);
|
||||||
|
|
||||||
entity_object.insert_component(ai);
|
entity_object.insert_component(ai);
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
pub use super::objects::hero::{Hero, MainUser};
|
|
||||||
|
|
||||||
pub use super::abilities::prelude::*;
|
pub use super::abilities::prelude::*;
|
||||||
pub use super::mechanics::prelude::*;
|
|
||||||
|
|
||||||
pub use super::components::*;
|
pub use super::components::*;
|
||||||
|
pub use super::lightning::{Lightning, LightningMarker};
|
||||||
|
pub use super::objects::hero::{Hero, MainUser};
|
||||||
pub use super::objects::{
|
pub use super::objects::{
|
||||||
entity_manager::EntityManager,
|
entity_manager::EntityManager,
|
||||||
entity_tags::EntityTags,
|
entity_tags::EntityTags,
|
||||||
|
@ -13,5 +10,3 @@ pub use super::objects::{
|
||||||
},
|
},
|
||||||
npc::{NPCAbilitySlot, NPCFactory, NPCSettings},
|
npc::{NPCAbilitySlot, NPCFactory, NPCSettings},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use super::lightning::{Lightning, LightningMarker};
|
|
||||||
|
|
|
@ -7,6 +7,11 @@ use assetpath::AssetPath;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use lua_wrapper::LuaFunction;
|
use lua_wrapper::LuaFunction;
|
||||||
|
use rpg_components::config::abilities::AbilitySettings;
|
||||||
|
use rpg_components::config::attributes::AttributeSettings;
|
||||||
|
use rpg_components::config::experience::ExperienceSettings;
|
||||||
|
use rpg_components::config::items::ItemSettings;
|
||||||
|
use rpg_components::items::ItemSystem;
|
||||||
|
|
||||||
// std
|
// std
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
|
@ -47,42 +47,6 @@ macro_rules! load {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! load_npc {
|
|
||||||
($me: ident, $save_game:ident, $level:ident, $($index:literal,)+) => {
|
|
||||||
paste::expr! {
|
|
||||||
$(
|
|
||||||
if $save_game.[<ability_ $index>].used {
|
|
||||||
let item_system = $me.game_handle.upgrade().item_system();
|
|
||||||
|
|
||||||
let ability = &$save_game.[<ability_ $index>];
|
|
||||||
|
|
||||||
let mut addons = Vec::new();
|
|
||||||
|
|
||||||
for addon in ability.addons.iter() {
|
|
||||||
let mut split = addon.split('|');
|
|
||||||
|
|
||||||
let rarity = Rarities::from_str(&split.nth(0).unwrap())?;
|
|
||||||
let addon_type = AbilityAddonTypes::from_str(&split.nth(0).unwrap())?;
|
|
||||||
|
|
||||||
addons.push(Some(item_system.addon(rarity, addon_type)));
|
|
||||||
}
|
|
||||||
|
|
||||||
let ability_level = ($level as f32 * ability.level).ceil() as u32;
|
|
||||||
|
|
||||||
let book = item_system.ability_book(
|
|
||||||
&ability.name,
|
|
||||||
ability.rarity,
|
|
||||||
addons,
|
|
||||||
ability_level,
|
|
||||||
);
|
|
||||||
|
|
||||||
$me.abilities[$index] = Some(book);
|
|
||||||
}
|
|
||||||
)+
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! store {
|
macro_rules! store {
|
||||||
($me: ident, $save_game:ident, $($index:literal,)+) => {
|
($me: ident, $save_game:ident, $($index:literal,)+) => {
|
||||||
paste::expr! {
|
paste::expr! {
|
||||||
|
|
|
@ -5,17 +5,17 @@ use crate::items::{ItemAffix, Rarities};
|
||||||
use std::env::var;
|
use std::env::var;
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
pub fn save_game_dir() -> String {
|
pub fn save_game_dir(game: &str) -> String {
|
||||||
let b = var("LOCALAPPDATA").expect("couldn't get local appdata variable");
|
let b = var("LOCALAPPDATA").expect("couldn't get local appdata variable");
|
||||||
|
|
||||||
format!("{}\\gavania\\saves\\", b)
|
format!("{b}\\{game}\\saves\\")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
pub fn save_game_dir() -> String {
|
pub fn save_game_dir(game: &str) -> String {
|
||||||
let b = var("HOME").expect("couldn't get HOME variable");
|
let b = var("HOME").expect("couldn't get HOME variable");
|
||||||
|
|
||||||
format!("{}/.local/share/gavania/saves/", b)
|
format!("{b}/.local/share/{game}/saves/")
|
||||||
}
|
}
|
||||||
|
|
||||||
create_settings_section!(
|
create_settings_section!(
|
||||||
|
|
|
@ -120,10 +120,6 @@ impl AbilityBook {
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
// don't allow anything while being animation locked
|
// don't allow anything while being animation locked
|
||||||
|
|
||||||
// if animation_info.is_locked() {
|
|
||||||
// return Ok(false);
|
|
||||||
// }
|
|
||||||
|
|
||||||
if let Some(cast_information) = &self.last_cast {
|
if let Some(cast_information) = &self.last_cast {
|
||||||
let total_cool_down = Duration::from_secs_f32({
|
let total_cool_down = Duration::from_secs_f32({
|
||||||
let d: Duration = self.ability.data().settings.parameter.cool_down.into();
|
let d: Duration = self.ability.data().settings.parameter.cool_down.into();
|
||||||
|
|
Loading…
Reference in a new issue