1
Fork 0
mirror of https://github.com/redstrate/Kawari.git synced 2025-04-19 22:36:49 +00:00

Fill out more fields of damage action results

Now we can actually set whether the damage was physical, magical,
aspected etc. This is not yet exposed in the Lua API.
This commit is contained in:
Joshua Goins 2025-04-18 13:11:29 -04:00
parent d507547dd3
commit 510d07e3e4
4 changed files with 120 additions and 23 deletions

View file

@ -712,8 +712,8 @@ async fn client_loop(
{ {
for effect in &effects_builder.effects { for effect in &effects_builder.effects {
match effect.kind { match effect.kind {
EffectKind::Damage => { EffectKind::Damage { amount, .. } => {
actor.hp = actor.hp.saturating_sub(effect.value as u32); actor.hp = actor.hp.saturating_sub(amount as u32);
} }
_ => todo!() _ => todo!()
} }

View file

@ -2,27 +2,110 @@ use binrw::binrw;
use crate::common::{ObjectTypeId, read_quantized_rotation, write_quantized_rotation}; use crate::common::{ObjectTypeId, read_quantized_rotation, write_quantized_rotation};
// TODO: this might be a flag?
#[binrw] #[binrw]
#[derive(Debug, Eq, PartialEq, Clone, Copy, Default)] #[derive(Debug, Eq, PartialEq, Clone, Copy, Default)]
#[brw(repr = u8)] #[brw(repr = u8)]
pub enum DamageKind {
#[default]
Normal = 0x0,
Critical = 0x1,
DirectHit = 0x2,
}
#[binrw]
#[derive(Debug, Eq, PartialEq, Clone, Copy, Default)]
pub enum EffectKind { pub enum EffectKind {
#[default] #[default]
Miss = 0, // FIXME: is this correct? #[brw(magic = 0u8)]
Damage = 3, Miss, // FIXME: is this correct?
BeginCombo = 27, #[brw(magic = 3u8)]
Damage {
damage_kind: DamageKind,
#[br(temp)]
#[bw(calc = 0)]
param1: u8,
#[br(calc = DamageType::from(param1 & 0x0F))]
#[bw(ignore)]
damage_type: DamageType,
#[br(calc = DamageElement::from(param1 >> 4))]
#[bw(ignore)]
damage_element: DamageElement,
bonus_percent: u8,
unk3: u8,
unk4: u8,
amount: u16,
},
#[brw(magic = 27u8)]
BeginCombo,
}
#[derive(Debug, Eq, PartialEq, Clone, Copy, Default)]
pub enum DamageType {
Unknown,
Slashing,
Piercing,
Blunt,
Shot,
Magic,
Breath,
#[default]
Physical,
LimitBreak,
}
impl From<u8> for DamageType {
fn from(value: u8) -> Self {
match value {
0 => Self::Unknown,
1 => Self::Slashing,
2 => Self::Piercing,
3 => Self::Blunt,
4 => Self::Shot,
5 => Self::Magic,
6 => Self::Breath,
7 => Self::Physical,
8 => Self::LimitBreak,
_ => Self::Unknown,
}
}
}
#[derive(Debug, Eq, PartialEq, Clone, Copy, Default)]
pub enum DamageElement {
Unknown,
Fire,
Ice,
Air,
Earth,
Lightning,
Water,
#[default]
Unaspected,
}
impl From<u8> for DamageElement {
fn from(value: u8) -> Self {
match value {
0 => Self::Unknown,
1 => Self::Fire,
2 => Self::Ice,
3 => Self::Air,
4 => Self::Earth,
5 => Self::Lightning,
6 => Self::Water,
7 => Self::Unaspected,
_ => Self::Unknown,
}
}
} }
#[binrw] #[binrw]
#[brw(little)] #[brw(little)]
#[derive(Debug, Clone, Copy, Default)] #[derive(Debug, Clone, Copy, Default)]
pub struct ActionEffect { pub struct ActionEffect {
#[brw(pad_size_to = 8)]
pub kind: EffectKind, pub kind: EffectKind,
pub param0: u8,
pub param1: u8,
pub param2: u8,
pub param3: u8,
pub param4: u8,
pub value: u16,
} }
#[binrw] #[binrw]
@ -85,13 +168,18 @@ mod tests {
assert_eq!(action_result.unk5, [0; 6]); assert_eq!(action_result.unk5, [0; 6]);
// effect 0: attack // effect 0: attack
assert_eq!(action_result.effects[0].kind, EffectKind::Damage); assert_eq!(
assert_eq!(action_result.effects[0].param0, 0); action_result.effects[0].kind,
assert_eq!(action_result.effects[0].param1, 113); EffectKind::Damage {
assert_eq!(action_result.effects[0].param2, 0); damage_kind: DamageKind::Normal,
assert_eq!(action_result.effects[0].param3, 0); damage_type: DamageType::Slashing,
assert_eq!(action_result.effects[0].param4, 0); damage_element: DamageElement::Unaspected,
assert_eq!(action_result.effects[0].value, 22); bonus_percent: 0,
unk3: 0,
unk4: 0,
amount: 22
}
);
// effect 1: start action combo // effect 1: start action combo
assert_eq!(action_result.effects[1].kind, EffectKind::BeginCombo); assert_eq!(action_result.effects[1].kind, EffectKind::BeginCombo);

View file

@ -60,7 +60,9 @@ mod event_start;
pub use event_start::EventStart; pub use event_start::EventStart;
mod action_result; mod action_result;
pub use action_result::{ActionEffect, ActionResult, EffectKind}; pub use action_result::{
ActionEffect, ActionResult, DamageElement, DamageKind, DamageType, EffectKind,
};
mod actor_move; mod actor_move;
pub use actor_move::ActorMove; pub use actor_move::ActorMove;

View file

@ -9,7 +9,8 @@ use crate::{
use super::{ use super::{
PlayerData, StatusEffects, Zone, PlayerData, StatusEffects, Zone,
ipc::{ ipc::{
ActionEffect, ActorSetPos, EffectKind, EventPlay, ServerZoneIpcData, ServerZoneIpcSegment, ActionEffect, ActorSetPos, DamageElement, DamageKind, DamageType, EffectKind, EventPlay,
ServerZoneIpcData, ServerZoneIpcSegment,
}, },
}; };
@ -173,9 +174,15 @@ impl UserData for EffectsBuilder {
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) { fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
methods.add_method_mut("damage", |_, this, amount: u16| { methods.add_method_mut("damage", |_, this, amount: u16| {
this.effects.push(ActionEffect { this.effects.push(ActionEffect {
kind: EffectKind::Damage, kind: EffectKind::Damage {
value: amount, damage_kind: DamageKind::Normal,
param1: 133, damage_type: DamageType::Slashing,
damage_element: DamageElement::Unaspected,
bonus_percent: 0,
unk3: 0,
unk4: 0,
amount,
},
..Default::default() ..Default::default()
}); });
Ok(()) Ok(())