diff --git a/src/common/CommonGen.h b/src/common/CommonGen.h index 4833e57a..b5c65e44 100644 --- a/src/common/CommonGen.h +++ b/src/common/CommonGen.h @@ -30,6 +30,16 @@ enum class ActionCategory : uint8_t AdrenalineRush = 15, }; +/////////////////////////////////////////////////////////// +//AttackType.exd +enum class AttackType : int32_t +{ + Physical = -1, + None = 0, + Magic = 5, + LimitBreak = 8, +}; + /////////////////////////////////////////////////////////// //BaseParam.exd enum class BaseParam : uint8_t diff --git a/src/tools/exd_common_gen/main.cpp b/src/tools/exd_common_gen/main.cpp index 768b53c4..ea044d14 100644 --- a/src/tools/exd_common_gen/main.cpp +++ b/src/tools/exd_common_gen/main.cpp @@ -116,6 +116,7 @@ int main( int argc, char** argv ) result += "namespace Sapphire::Common {\n"; result += generateEnum( "ActionCategory", 0, "uint8_t" ); + result += generateEnum( "AttackType", 0, "int8_t" ); result += generateEnum( "BaseParam", 1, "uint8_t" ); result += generateEnum( "BeastReputationRank", 1, "uint8_t" ); result += generateEnum( "BeastTribe", 11, "uint8_t" ); diff --git a/src/world/Action/Action.cpp b/src/world/Action/Action.cpp index 60cb1774..c0f68a8a 100644 --- a/src/world/Action/Action.cpp +++ b/src/world/Action/Action.cpp @@ -458,7 +458,7 @@ void Action::Action::buildEffects() if( m_lutEntry.damagePotency > 0 ) { auto dmg = calcDamage( isCorrectCombo() ? m_lutEntry.damageComboPotency : m_lutEntry.damagePotency ); - dmg.first = Math::CalcStats::applyDamageReceiveMultiplier( *actor, dmg.first, m_actionData->attackType ); + dmg.first = Math::CalcStats::applyDamageReceiveMultiplier( *actor, dmg.first, static_cast< Common::AttackType >( m_actionData->attackType ) ); m_effectBuilder->damage( actor, actor, dmg.first, dmg.second ); if( dmg.first > 0 ) @@ -475,7 +475,7 @@ void Action::Action::buildEffects() if( m_lutEntry.selfHealPotency > 0 ) // actions with self heal { auto heal = calcHealing( m_lutEntry.selfHealPotency ); - heal.first = Math::CalcStats::applyHealingReceiveMultiplier( *m_pSource, heal.first, 0 ); + heal.first = Math::CalcStats::applyHealingReceiveMultiplier( *m_pSource, heal.first ); m_effectBuilder->heal( actor, m_pSource, heal.first, heal.second, Common::ActionEffectResultFlag::EffectOnSource ); } @@ -494,7 +494,7 @@ void Action::Action::buildEffects() else if( m_lutEntry.healPotency > 0 ) { auto heal = calcHealing( m_lutEntry.healPotency ); - heal.first = Math::CalcStats::applyHealingReceiveMultiplier( *actor, heal.first, 0 ); + heal.first = Math::CalcStats::applyHealingReceiveMultiplier( *actor, heal.first ); m_effectBuilder->heal( actor, actor, heal.first, heal.second ); if( m_lutEntry.gainMPPercentage > 0 && shouldRestoreMP ) @@ -804,24 +804,20 @@ Data::ActionPtr Action::Action::getActionData() const bool Action::Action::isPhysical() const { - return isAttackTypePhysical( m_actionData->attackType ); + return isAttackTypePhysical( static_cast< Common::AttackType >( m_actionData->attackType ) ); } bool Action::Action::isMagical() const { - return isAttackTypeMagical( m_actionData->attackType ); + return isAttackTypeMagical( static_cast< Common::AttackType >( m_actionData->attackType ) ); } -bool Action::Action::isAttackTypePhysical( int8_t attackType ) +bool Action::Action::isAttackTypePhysical( Common::AttackType attackType ) { - return attackType == -1 || - attackType == 1 || - attackType == 2 || - attackType == 3 || - attackType == 4; + return attackType == Common::AttackType::Physical; } -bool Action::Action::isAttackTypeMagical( int8_t attackType ) +bool Action::Action::isAttackTypeMagical( Common::AttackType attackType ) { - return attackType == 5; + return attackType == Common::AttackType::Magic; } \ No newline at end of file diff --git a/src/world/Action/Action.h b/src/world/Action/Action.h index 2c6ba94a..5786f93b 100644 --- a/src/world/Action/Action.h +++ b/src/world/Action/Action.h @@ -123,8 +123,8 @@ namespace Sapphire::World::Action bool isPhysical() const; bool isMagical() const; - static bool isAttackTypePhysical( int8_t attackType ); - static bool isAttackTypeMagical( int8_t attackType ); + static bool isAttackTypePhysical( Common::AttackType attackType ); + static bool isAttackTypeMagical( Common::AttackType attackType ); /*! * @brief Starts the cast. Finishes it immediately if there is no cast time (weaponskills). diff --git a/src/world/Actor/BNpc.cpp b/src/world/Actor/BNpc.cpp index 537e9aec..05c5406e 100644 --- a/src/world/Actor/BNpc.cpp +++ b/src/world/Actor/BNpc.cpp @@ -693,7 +693,7 @@ void Sapphire::Entity::BNpc::autoAttack( CharaPtr pTarget ) auto pRNGMgr = m_pFw->get< World::Manager::RNGMgr >(); auto damage = Math::CalcStats::calcAutoAttackDamage( *this ); - damage.first = Math::CalcStats::applyDamageReceiveMultiplier( *pTarget, damage.first, -1 ); + damage.first = Math::CalcStats::applyDamageReceiveMultiplier( *pTarget, damage.first, Common::AttackType::Physical ); auto effectPacket = std::make_shared< Server::EffectPacket >( getId(), pTarget->getId(), 7 ); effectPacket->setRotation( Util::floatToUInt16Rot( getRot() ) ); Common::EffectEntry effectEntry{}; diff --git a/src/world/Actor/Chara.cpp b/src/world/Actor/Chara.cpp index c560a69d..3fcc35e9 100644 --- a/src/world/Actor/Chara.cpp +++ b/src/world/Actor/Chara.cpp @@ -502,7 +502,7 @@ void Sapphire::Entity::Chara::autoAttack( CharaPtr pTarget ) srand( static_cast< uint32_t >( tick ) ); auto damage = static_cast< uint16_t >( 10 + rand() % 12 ); - damage = Math::CalcStats::applyDamageReceiveMultiplier( *pTarget, damage, -1 ); + damage = Math::CalcStats::applyDamageReceiveMultiplier( *pTarget, damage, Common::AttackType::Physical ); auto effectPacket = std::make_shared< Server::EffectPacket >( getId(), pTarget->getId(), 7 ); effectPacket->setRotation( Util::floatToUInt16Rot( getRot() ) ); diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index f2be253c..ad08d0be 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -1576,7 +1576,7 @@ void Sapphire::Entity::Player::autoAttack( CharaPtr pTarget ) auto variation = static_cast< uint32_t >( pRNGMgr->getRandGenerator< float >( 0, 3 ).next() ); auto damage = Math::CalcStats::calcAutoAttackDamage( *this ); - damage.first = Math::CalcStats::applyDamageReceiveMultiplier( *pTarget, damage.first, -1 ); + damage.first = Math::CalcStats::applyDamageReceiveMultiplier( *pTarget, damage.first, Common::AttackType::Physical ); if( getClass() == ClassJob::Machinist || getClass() == ClassJob::Bard || getClass() == ClassJob::Archer ) { diff --git a/src/world/Math/CalcStats.cpp b/src/world/Math/CalcStats.cpp index b94a34d7..5b00b9a3 100644 --- a/src/world/Math/CalcStats.cpp +++ b/src/world/Math/CalcStats.cpp @@ -626,14 +626,19 @@ std::pair< float, Sapphire::Common::ActionHitSeverityType > CalcStats::calcActio factor *= 1.0f + ( ( range100( rng ) - 50.0f ) / 1000.0f ); + uint8_t actionType = 0; + if( action.isPhysical() ) + actionType = Sapphire::World::Action::EffectActionTypeFilterPhysical; + else if( action.isMagical() ) + actionType = Sapphire::World::Action::EffectActionTypeFilterMagical; + for( auto const& entry : chara.getStatusEffectMap() ) { auto status = entry.second; auto effectEntry = status->getEffectEntry(); if( effectEntry.effectType != Sapphire::World::Action::EffectTypeDamageMultiplier ) continue; - uint8_t actionType = action.isPhysical() ? Sapphire::World::Action::EffectActionTypeFilterPhysical : - ( action.isMagical() ? Sapphire::World::Action::EffectActionTypeFilterMagical : 0 ); + if( effectEntry.effectValue1 & actionType ) { factor *= 1.0f + ( effectEntry.effectValue2 / 100.0f ); @@ -643,20 +648,23 @@ std::pair< float, Sapphire::Common::ActionHitSeverityType > CalcStats::calcActio return std::pair( factor, hitType ); } -float CalcStats::applyDamageReceiveMultiplier( const Sapphire::Entity::Chara& chara, float originalDamage, int8_t attackType ) +float CalcStats::applyDamageReceiveMultiplier( const Sapphire::Entity::Chara& chara, float originalDamage, Sapphire::Common::AttackType attackType ) { float damage = originalDamage; + + uint8_t actionType = 0; + if( World::Action::Action::isAttackTypePhysical( attackType ) ) + actionType = Sapphire::World::Action::EffectActionTypeFilterPhysical; + else if( World::Action::Action::isAttackTypeMagical( attackType ) ) + actionType = Sapphire::World::Action::EffectActionTypeFilterMagical; + for( auto const& entry : chara.getStatusEffectMap() ) { auto status = entry.second; auto effectEntry = status->getEffectEntry(); if( effectEntry.effectType != Sapphire::World::Action::EffectTypeDamageReceiveMultiplier ) continue; - uint8_t actionType = 0; - if( World::Action::Action::isAttackTypePhysical( attackType ) ) - actionType = Sapphire::World::Action::EffectActionTypeFilterPhysical; - else if( World::Action::Action::isAttackTypeMagical( attackType ) ) - actionType = Sapphire::World::Action::EffectActionTypeFilterMagical; + if( effectEntry.effectValue1 & actionType ) { damage *= ( 1.0f + ( effectEntry.effectValue2 / 100.0f ) ); @@ -665,7 +673,7 @@ float CalcStats::applyDamageReceiveMultiplier( const Sapphire::Entity::Chara& ch return damage; } -float CalcStats::applyHealingReceiveMultiplier( const Sapphire::Entity::Chara& chara, float originalHeal, int8_t healType ) +float CalcStats::applyHealingReceiveMultiplier( const Sapphire::Entity::Chara& chara, float originalHeal ) { float heal = originalHeal; for( auto const& entry : chara.getStatusEffectMap() ) diff --git a/src/world/Math/CalcStats.h b/src/world/Math/CalcStats.h index 100cac8c..b57ceee3 100644 --- a/src/world/Math/CalcStats.h +++ b/src/world/Math/CalcStats.h @@ -139,9 +139,9 @@ namespace Sapphire::Math static std::pair< float, Common::ActionHitSeverityType > calcActionDamage( const Sapphire::Entity::Chara& chara, const Sapphire::World::Action::Action& action, uint32_t ptc, float wepDmg ); - static float applyDamageReceiveMultiplier( const Sapphire::Entity::Chara& chara, float originalDamage, int8_t attackType ); + static float applyDamageReceiveMultiplier( const Sapphire::Entity::Chara& chara, float originalDamage, Common::AttackType attackType ); - static float applyHealingReceiveMultiplier( const Sapphire::Entity::Chara& chara, float originalHeal, int8_t healType ); + static float applyHealingReceiveMultiplier( const Sapphire::Entity::Chara& chara, float originalHeal ); static std::pair< float, Common::ActionHitSeverityType > calcActionHealing( const Sapphire::Entity::Chara& chara, const Sapphire::World::Action::Action& action, uint32_t ptc, float wepDmg ); diff --git a/src/world/StatusEffect/StatusEffect.cpp b/src/world/StatusEffect/StatusEffect.cpp index 7d740efa..5d3503d8 100644 --- a/src/world/StatusEffect/StatusEffect.cpp +++ b/src/world/StatusEffect/StatusEffect.cpp @@ -138,8 +138,8 @@ void Sapphire::StatusEffect::StatusEffect::applyStatus() } m_cachedHotOrDotValue = Sapphire::Math::CalcStats::applyDamageReceiveMultiplier( *m_targetActor, damage, - m_effectEntry.effectValue1 == Sapphire::World::Action::EffectActionTypeFilterPhysical ? -1 : - ( m_effectEntry.effectValue1 == Sapphire::World::Action::EffectActionTypeFilterMagical ? 5 : -128 ) ); + m_effectEntry.effectValue1 == Sapphire::World::Action::EffectActionTypeFilterPhysical ? Common::AttackType::Physical : + ( m_effectEntry.effectValue1 == Sapphire::World::Action::EffectActionTypeFilterMagical ? Common::AttackType::Magic : Common::AttackType::None ) ); m_cachedSourceCrit = Sapphire::Math::CalcStats::criticalHitProbability( *m_sourceActor, Sapphire::World::Action::EffectCritDHBonusFilterDamage ); m_cachedSourceCritBonus = Sapphire::Math::CalcStats::criticalHitBonus( *m_sourceActor ); } @@ -159,7 +159,7 @@ void Sapphire::StatusEffect::StatusEffect::applyStatus() heal *= 1.0f + ( effectEntry.effectValue2 / 100.0f ); } } - m_cachedHotOrDotValue = Sapphire::Math::CalcStats::applyHealingReceiveMultiplier( *m_targetActor, heal, m_effectEntry.effectValue1 ); + m_cachedHotOrDotValue = Sapphire::Math::CalcStats::applyHealingReceiveMultiplier( *m_targetActor, heal ); m_cachedSourceCrit = Sapphire::Math::CalcStats::criticalHitProbability( *m_sourceActor, Sapphire::World::Action::EffectCritDHBonusFilterHeal ); m_cachedSourceCritBonus = Sapphire::Math::CalcStats::criticalHitBonus( *m_sourceActor ); }