From 35d8082715823fe86b4d9f986f17f99c59d6393f Mon Sep 17 00:00:00 2001 From: collett Date: Sat, 21 Mar 2020 18:25:19 +0900 Subject: [PATCH] Implement blood weapon and delirium mp restore. --- src/common/Common.h | 1 + src/world/Action/Action.cpp | 19 +++++++++++++++-- src/world/Action/Action.h | 1 + src/world/Action/ActionLutData.cpp | 4 ++++ src/world/Manager/ActionMgr.cpp | 2 +- src/world/Math/CalcStats.cpp | 19 +++++++++-------- src/world/Math/CalcStats.h | 4 ++-- src/world/StatusEffect/StatusEffect.cpp | 28 +++++++++++++++++++++++-- src/world/StatusEffect/StatusEffect.h | 4 +++- 9 files changed, 65 insertions(+), 17 deletions(-) diff --git a/src/common/Common.h b/src/common/Common.h index c6a1e1bc..0e3013a4 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -1046,6 +1046,7 @@ namespace Sapphire::Common Haste = 12, InstantCast = 13, BlockParryRateBonus = 14, + MPRestorePerGCD = 15, }; enum class ActionTypeFilter : int32_t diff --git a/src/world/Action/Action.cpp b/src/world/Action/Action.cpp index d6df5c62..9567055c 100644 --- a/src/world/Action/Action.cpp +++ b/src/world/Action/Action.cpp @@ -464,12 +464,12 @@ std::pair< uint32_t, Common::ActionHitSeverityType > Action::Action::calcDamage( if( m_isAutoAttack ) return Math::CalcStats::calcAutoAttackDamage( *m_pSource, potency ); else - return Math::CalcStats::calcActionDamage( this, *m_pSource, static_cast< Common::AttackType >( m_actionData->attackType ), potency, Math::CalcStats::getWeaponDamage( m_pSource ) ); + return Math::CalcStats::calcActionDamage( this, *m_pSource, potency, Math::CalcStats::getWeaponDamage( m_pSource ) ); } std::pair< uint32_t, Common::ActionHitSeverityType > Action::Action::calcHealing( uint32_t potency ) { - return Math::CalcStats::calcActionHealing( this, *m_pSource, static_cast< Common::ActionCategory >( m_actionData->actionCategory ), potency, Math::CalcStats::getWeaponDamage( m_pSource ) ); + return Math::CalcStats::calcActionHealing( this, *m_pSource, potency, Math::CalcStats::getWeaponDamage( m_pSource ) ); } void Action::Action::buildEffects() @@ -508,6 +508,15 @@ void Action::Action::buildEffects() for( auto& actor : m_hitActors ) { victimCounter++; + bool shouldHitThisTarget = true; + for( const auto& statusIt : getSourceChara()->getStatusEffectMap() ) + { + bool result = statusIt.second->onActionHitTarget( this, actor.get(), victimCounter ); + if( !result ) + shouldHitThisTarget = false; + } + if( !shouldHitThisTarget ) + continue; if( m_lutEntry.damagePotency > 0 ) { Common::AttackType attackType = static_cast< Common::AttackType >( m_actionData->attackType ); @@ -1134,6 +1143,12 @@ bool Action::Action::isMagical() const return isAttackTypeMagical( static_cast< Common::AttackType >( m_actionData->attackType ) ); } +bool Action::Action::isGCD() const +{ + auto actionCategory = static_cast< Common::ActionCategory >( m_actionData->actionCategory ); + return actionCategory == Common::ActionCategory::Weaponskill || actionCategory == Common::ActionCategory::Spell; +} + bool Action::Action::isAttackTypePhysical( Common::AttackType attackType ) { return attackType == Common::AttackType::Physical; diff --git a/src/world/Action/Action.h b/src/world/Action/Action.h index 5470ce98..95eaff8b 100644 --- a/src/world/Action/Action.h +++ b/src/world/Action/Action.h @@ -132,6 +132,7 @@ namespace Sapphire::World::Action bool isPhysical() const; bool isMagical() const; + bool isGCD() const; static bool isAttackTypePhysical( Common::AttackType attackType ); static bool isAttackTypeMagical( Common::AttackType attackType ); diff --git a/src/world/Action/ActionLutData.cpp b/src/world/Action/ActionLutData.cpp index baeed358..5103eb77 100644 --- a/src/world/Action/ActionLutData.cpp +++ b/src/world/Action/ActionLutData.cpp @@ -3533,4 +3533,8 @@ ActionLut::StatusEffectTable ActionLut::m_statusEffectTable = //Sheltron, シェルトロン: BlockParryRateBonus, block 100%, parry 0% { 1856, { 14, 0, 100, 0, 0 } }, + { 742, { 15, 6, 0, 0, 0 } }, + + { 1972, { 15, 2, 7392, 7391, 0 } }, + }; diff --git a/src/world/Manager/ActionMgr.cpp b/src/world/Manager/ActionMgr.cpp index b33c77a7..d6a22cad 100644 --- a/src/world/Manager/ActionMgr.cpp +++ b/src/world/Manager/ActionMgr.cpp @@ -96,7 +96,7 @@ void World::Manager::ActionMgr::bootstrapAction( Entity::Player& player, { for( const auto& statusIt : player.getStatusEffectMap() ) { - statusIt.second->onBeforeActionStart( currentAction ); + statusIt.second->onBeforeActionStart( currentAction.get() ); } if( currentAction->isInterrupted() ) diff --git a/src/world/Math/CalcStats.cpp b/src/world/Math/CalcStats.cpp index 406c7c0f..7f3f9114 100644 --- a/src/world/Math/CalcStats.cpp +++ b/src/world/Math/CalcStats.cpp @@ -651,7 +651,7 @@ float CalcStats::calcHealBaseOnPotency( const Sapphire::Entity::Chara& chara, ui return factor; } -std::pair< float, Sapphire::Common::ActionHitSeverityType > CalcStats::calcActionDamage( Sapphire::World::Action::Action* pAction, const Sapphire::Entity::Chara& chara, Sapphire::Common::AttackType attackType, uint32_t ptc, float wepDmg ) +std::pair< float, Sapphire::Common::ActionHitSeverityType > CalcStats::calcActionDamage( Sapphire::World::Action::Action* pAction, const Sapphire::Entity::Chara& chara, uint32_t ptc, float wepDmg ) { auto factor = calcDamageBaseOnPotency( chara, ptc, wepDmg ); Sapphire::Common::ActionHitSeverityType hitType = Sapphire::Common::ActionHitSeverityType::NormalDamage; @@ -698,11 +698,12 @@ std::pair< float, Sapphire::Common::ActionHitSeverityType > CalcStats::calcActio factor *= 1.0f + ( ( getRandomNumber0To99() - 50.0f ) / 1000.0f ); - Common::ActionTypeFilter actionTypeFilter = Common::ActionTypeFilter::Unknown; - if( World::Action::Action::isAttackTypePhysical( attackType ) ) - actionTypeFilter = Common::ActionTypeFilter::Physical; - else if( World::Action::Action::isAttackTypeMagical( attackType ) ) - actionTypeFilter = Common::ActionTypeFilter::Magical; + Common::ActionTypeFilter actionTypeFilter = Common::ActionTypeFilter::Physical; + if( pAction ) + { + if( pAction->isMagical() ) + actionTypeFilter = Common::ActionTypeFilter::Magical; + } for( auto const& entry : chara.getStatusEffectMap() ) { @@ -775,7 +776,7 @@ float CalcStats::applyHealingReceiveMultiplier( const Sapphire::Entity::Chara& c return heal; } -std::pair< float, Sapphire::Common::ActionHitSeverityType > CalcStats::calcActionHealing( Sapphire::World::Action::Action* pAction, const Sapphire::Entity::Chara& chara, Sapphire::Common::ActionCategory actionCategory, uint32_t ptc, float wepDmg ) +std::pair< float, Sapphire::Common::ActionHitSeverityType > CalcStats::calcActionHealing( Sapphire::World::Action::Action* pAction, const Sapphire::Entity::Chara& chara, uint32_t ptc, float wepDmg ) { auto factor = calcHealBaseOnPotency( chara, ptc, wepDmg ); Sapphire::Common::ActionHitSeverityType hitType = Sapphire::Common::ActionHitSeverityType::NormalHeal; @@ -808,7 +809,7 @@ std::pair< float, Sapphire::Common::ActionHitSeverityType > CalcStats::calcActio if( static_cast< Common::StatusEffectType >( effectEntry.effectType ) != Common::StatusEffectType::HealCastMultiplier ) continue; - if( actionCategory == Common::ActionCategory::Spell ) // must be a "cast" + if( pAction->isGCD() ) // must be a "cast" { factor *= 1.0f + ( effectEntry.effectValue2 / 100.0f ); } @@ -835,7 +836,7 @@ std::pair< float, Sapphire::Common::ActionHitSeverityType > CalcStats::calcDamag { auto wepDmg = Sapphire::Math::CalcStats::getWeaponDamage( pCharaVictim ); // any magical reflect damage exists? - auto damage = Sapphire::Math::CalcStats::calcActionDamage( nullptr, *pCharaVictim, Common::AttackType::Physical, effectEntry.effectValue2, wepDmg ); + auto damage = Sapphire::Math::CalcStats::calcActionDamage( nullptr, *pCharaVictim, effectEntry.effectValue2, wepDmg ); damage.first = Math::CalcStats::applyDamageReceiveMultiplier( *pCharaAttacker, damage.first, Common::AttackType::Physical ); return damage; diff --git a/src/world/Math/CalcStats.h b/src/world/Math/CalcStats.h index 021090f9..67324c4e 100644 --- a/src/world/Math/CalcStats.h +++ b/src/world/Math/CalcStats.h @@ -140,13 +140,13 @@ namespace Sapphire::Math static std::pair< float, Common::ActionHitSeverityType > calcAutoAttackDamage( const Sapphire::Entity::Chara& chara, uint32_t ptc ); - static std::pair< float, Common::ActionHitSeverityType > calcActionDamage( World::Action::Action* pAction, const Sapphire::Entity::Chara& chara, Common::AttackType attackType, uint32_t ptc, float wepDmg ); + static std::pair< float, Common::ActionHitSeverityType > calcActionDamage( World::Action::Action* pAction, const Sapphire::Entity::Chara& chara, uint32_t ptc, float wepDmg ); static float applyDamageReceiveMultiplier( const Sapphire::Entity::Chara& chara, float originalDamage, Common::AttackType attackType ); static float applyHealingReceiveMultiplier( const Sapphire::Entity::Chara& chara, float originalHeal ); - static std::pair< float, Common::ActionHitSeverityType > calcActionHealing( World::Action::Action* pAction, const Sapphire::Entity::Chara& chara, Sapphire::Common::ActionCategory actionCategory, uint32_t ptc, float wepDmg ); + static std::pair< float, Common::ActionHitSeverityType > calcActionHealing( World::Action::Action* pAction, const Sapphire::Entity::Chara& chara, uint32_t ptc, float wepDmg ); static uint32_t primaryStatValue( const Sapphire::Entity::Chara& chara ); diff --git a/src/world/StatusEffect/StatusEffect.cpp b/src/world/StatusEffect/StatusEffect.cpp index 272e0d9b..ec50620a 100644 --- a/src/world/StatusEffect/StatusEffect.cpp +++ b/src/world/StatusEffect/StatusEffect.cpp @@ -276,7 +276,7 @@ void Sapphire::StatusEffect::StatusEffect::replaceEffectEntry( Sapphire::World:: m_effectEntry = entryOverride; } -void Sapphire::StatusEffect::StatusEffect::onBeforeActionStart( Sapphire::World::Action::ActionPtr action ) +void Sapphire::StatusEffect::StatusEffect::onBeforeActionStart( Sapphire::World::Action::Action* action ) { // todo: add script function for this if needed //auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >(); @@ -295,7 +295,7 @@ void Sapphire::StatusEffect::StatusEffect::onBeforeActionStart( Sapphire::World: if( action->getId() != m_effectEntry.effectValue2 && action->getId() != m_effectEntry.effectValue3 && action->getId() != m_effectEntry.effectValue4 ) - return; + break; } if( m_effectEntry.effectValue1 > 0 ) { @@ -333,4 +333,28 @@ void Sapphire::StatusEffect::StatusEffect::refresh( Sapphire::World::Action::Sta { m_effectEntry = newEntry; refresh(); +} + +bool Sapphire::StatusEffect::StatusEffect::onActionHitTarget( World::Action::Action* action, Entity::Chara* victim, int victimCounter ) +{ + switch( static_cast< Common::StatusEffectType >( m_effectEntry.effectType ) ) + { + case Common::StatusEffectType::MPRestorePerGCD: + { + if( victimCounter == 1 && action->isGCD() ) + { + if( m_effectEntry.effectValue2 != 0 ) + { + if( action->getId() != m_effectEntry.effectValue2 && + action->getId() != m_effectEntry.effectValue3 && + action->getId() != m_effectEntry.effectValue4 ) + break; + } + float restored = 0.01f * m_targetActor->getMaxMp() * m_effectEntry.effectValue1; + action->getEffectbuilder()->restoreMP( m_targetActor, m_targetActor, static_cast< uint32_t >( restored ) ); + } + break; + } + } + return true; } \ No newline at end of file diff --git a/src/world/StatusEffect/StatusEffect.h b/src/world/StatusEffect/StatusEffect.h index 9ad8b8d1..72bf82d0 100644 --- a/src/world/StatusEffect/StatusEffect.h +++ b/src/world/StatusEffect/StatusEffect.h @@ -19,7 +19,9 @@ public: void onTick(); - void onBeforeActionStart( World::Action::ActionPtr action ); + void onBeforeActionStart( World::Action::Action* action ); + + bool onActionHitTarget( World::Action::Action* action, Entity::Chara* victim, int victimCounter ); void applyStatus();