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,
|
Haste = 12,
|
||||||
InstantCast = 13,
|
InstantCast = 13,
|
||||||
BlockParryRateBonus = 14,
|
BlockParryRateBonus = 14,
|
||||||
|
MPRestorePerGCD = 15,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ActionTypeFilter : int32_t
|
enum class ActionTypeFilter : int32_t
|
||||||
|
|
|
@ -464,12 +464,12 @@ std::pair< uint32_t, Common::ActionHitSeverityType > Action::Action::calcDamage(
|
||||||
if( m_isAutoAttack )
|
if( m_isAutoAttack )
|
||||||
return Math::CalcStats::calcAutoAttackDamage( *m_pSource, potency );
|
return Math::CalcStats::calcAutoAttackDamage( *m_pSource, potency );
|
||||||
else
|
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 )
|
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()
|
void Action::Action::buildEffects()
|
||||||
|
@ -508,6 +508,15 @@ void Action::Action::buildEffects()
|
||||||
for( auto& actor : m_hitActors )
|
for( auto& actor : m_hitActors )
|
||||||
{
|
{
|
||||||
victimCounter++;
|
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 )
|
if( m_lutEntry.damagePotency > 0 )
|
||||||
{
|
{
|
||||||
Common::AttackType attackType = static_cast< Common::AttackType >( m_actionData->attackType );
|
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 ) );
|
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 )
|
bool Action::Action::isAttackTypePhysical( Common::AttackType attackType )
|
||||||
{
|
{
|
||||||
return attackType == Common::AttackType::Physical;
|
return attackType == Common::AttackType::Physical;
|
||||||
|
|
|
@ -132,6 +132,7 @@ namespace Sapphire::World::Action
|
||||||
|
|
||||||
bool isPhysical() const;
|
bool isPhysical() const;
|
||||||
bool isMagical() const;
|
bool isMagical() const;
|
||||||
|
bool isGCD() const;
|
||||||
|
|
||||||
static bool isAttackTypePhysical( Common::AttackType attackType );
|
static bool isAttackTypePhysical( Common::AttackType attackType );
|
||||||
static bool isAttackTypeMagical( Common::AttackType attackType );
|
static bool isAttackTypeMagical( Common::AttackType attackType );
|
||||||
|
|
|
@ -3533,4 +3533,8 @@ ActionLut::StatusEffectTable ActionLut::m_statusEffectTable =
|
||||||
//Sheltron, シェルトロン: BlockParryRateBonus, block 100%, parry 0%
|
//Sheltron, シェルトロン: BlockParryRateBonus, block 100%, parry 0%
|
||||||
{ 1856, { 14, 0, 100, 0, 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() )
|
for( const auto& statusIt : player.getStatusEffectMap() )
|
||||||
{
|
{
|
||||||
statusIt.second->onBeforeActionStart( currentAction );
|
statusIt.second->onBeforeActionStart( currentAction.get() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( currentAction->isInterrupted() )
|
if( currentAction->isInterrupted() )
|
||||||
|
|
|
@ -651,7 +651,7 @@ float CalcStats::calcHealBaseOnPotency( const Sapphire::Entity::Chara& chara, ui
|
||||||
return factor;
|
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 );
|
auto factor = calcDamageBaseOnPotency( chara, ptc, wepDmg );
|
||||||
Sapphire::Common::ActionHitSeverityType hitType = Sapphire::Common::ActionHitSeverityType::NormalDamage;
|
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 );
|
factor *= 1.0f + ( ( getRandomNumber0To99() - 50.0f ) / 1000.0f );
|
||||||
|
|
||||||
Common::ActionTypeFilter actionTypeFilter = Common::ActionTypeFilter::Unknown;
|
Common::ActionTypeFilter actionTypeFilter = Common::ActionTypeFilter::Physical;
|
||||||
if( World::Action::Action::isAttackTypePhysical( attackType ) )
|
if( pAction )
|
||||||
actionTypeFilter = Common::ActionTypeFilter::Physical;
|
{
|
||||||
else if( World::Action::Action::isAttackTypeMagical( attackType ) )
|
if( pAction->isMagical() )
|
||||||
actionTypeFilter = Common::ActionTypeFilter::Magical;
|
actionTypeFilter = Common::ActionTypeFilter::Magical;
|
||||||
|
}
|
||||||
|
|
||||||
for( auto const& entry : chara.getStatusEffectMap() )
|
for( auto const& entry : chara.getStatusEffectMap() )
|
||||||
{
|
{
|
||||||
|
@ -775,7 +776,7 @@ float CalcStats::applyHealingReceiveMultiplier( const Sapphire::Entity::Chara& c
|
||||||
return heal;
|
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 );
|
auto factor = calcHealBaseOnPotency( chara, ptc, wepDmg );
|
||||||
Sapphire::Common::ActionHitSeverityType hitType = Sapphire::Common::ActionHitSeverityType::NormalHeal;
|
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 )
|
if( static_cast< Common::StatusEffectType >( effectEntry.effectType ) != Common::StatusEffectType::HealCastMultiplier )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( actionCategory == Common::ActionCategory::Spell ) // must be a "cast"
|
if( pAction->isGCD() ) // must be a "cast"
|
||||||
{
|
{
|
||||||
factor *= 1.0f + ( effectEntry.effectValue2 / 100.0f );
|
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 );
|
auto wepDmg = Sapphire::Math::CalcStats::getWeaponDamage( pCharaVictim );
|
||||||
// any magical reflect damage exists?
|
// 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 );
|
damage.first = Math::CalcStats::applyDamageReceiveMultiplier( *pCharaAttacker, damage.first, Common::AttackType::Physical );
|
||||||
|
|
||||||
return damage;
|
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 > 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 applyDamageReceiveMultiplier( const Sapphire::Entity::Chara& chara, float originalDamage, Common::AttackType attackType );
|
||||||
|
|
||||||
static float applyHealingReceiveMultiplier( const Sapphire::Entity::Chara& chara, float originalHeal );
|
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 );
|
static uint32_t primaryStatValue( const Sapphire::Entity::Chara& chara );
|
||||||
|
|
||||||
|
|
|
@ -276,7 +276,7 @@ void Sapphire::StatusEffect::StatusEffect::replaceEffectEntry( Sapphire::World::
|
||||||
m_effectEntry = entryOverride;
|
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
|
// todo: add script function for this if needed
|
||||||
//auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >();
|
//auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >();
|
||||||
|
@ -295,7 +295,7 @@ void Sapphire::StatusEffect::StatusEffect::onBeforeActionStart( Sapphire::World:
|
||||||
if( action->getId() != m_effectEntry.effectValue2 &&
|
if( action->getId() != m_effectEntry.effectValue2 &&
|
||||||
action->getId() != m_effectEntry.effectValue3 &&
|
action->getId() != m_effectEntry.effectValue3 &&
|
||||||
action->getId() != m_effectEntry.effectValue4 )
|
action->getId() != m_effectEntry.effectValue4 )
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
if( m_effectEntry.effectValue1 > 0 )
|
if( m_effectEntry.effectValue1 > 0 )
|
||||||
{
|
{
|
||||||
|
@ -333,4 +333,28 @@ void Sapphire::StatusEffect::StatusEffect::refresh( Sapphire::World::Action::Sta
|
||||||
{
|
{
|
||||||
m_effectEntry = newEntry;
|
m_effectEntry = newEntry;
|
||||||
refresh();
|
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 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();
|
void applyStatus();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue