1
Fork 0
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:
collett 2020-03-21 18:25:19 +09:00
parent 3892934a60
commit 35d8082715
9 changed files with 65 additions and 17 deletions

View file

@ -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

View file

@ -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;

View file

@ -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 );

View file

@ -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 } },
}; };

View file

@ -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() )

View file

@ -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;

View file

@ -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 );

View file

@ -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;
} }

View file

@ -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();