mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-25 19:17:45 +00:00
Implement blood weapon and delirium mp restore.
This commit is contained in:
parent
3892934a60
commit
35d8082715
9 changed files with 65 additions and 17 deletions
|
@ -1046,6 +1046,7 @@ namespace Sapphire::Common
|
|||
Haste = 12,
|
||||
InstantCast = 13,
|
||||
BlockParryRateBonus = 14,
|
||||
MPRestorePerGCD = 15,
|
||||
};
|
||||
|
||||
enum class ActionTypeFilter : int32_t
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 } },
|
||||
|
||||
};
|
||||
|
|
|
@ -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() )
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue