2018-03-06 22:22:19 +01:00
|
|
|
#include <Exd/ExdDataGenerated.h>
|
|
|
|
#include <Util/Util.h>
|
|
|
|
#include <Network/PacketDef/Zone/ServerZoneDef.h>
|
|
|
|
#include <Logging/Logger.h>
|
2017-08-08 13:53:47 +02:00
|
|
|
|
|
|
|
#include <algorithm>
|
2020-03-01 01:00:57 +11:00
|
|
|
#include <Service.h>
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2020-01-14 21:59:05 +09:00
|
|
|
#include "Actor/Player.h"
|
2018-02-20 22:46:44 +01:00
|
|
|
#include "Actor/Chara.h"
|
2017-12-08 23:27:59 +01:00
|
|
|
#include "Actor/Actor.h"
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2020-01-14 23:24:06 +09:00
|
|
|
#include "Action/Action.h"
|
|
|
|
|
2018-03-02 07:22:25 -03:00
|
|
|
#include "Script/ScriptMgr.h"
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2020-01-10 21:24:35 +09:00
|
|
|
#include "Math/CalcStats.h"
|
|
|
|
|
2017-08-08 13:53:47 +02:00
|
|
|
#include "StatusEffect.h"
|
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
using namespace Sapphire::Common;
|
|
|
|
using namespace Sapphire::Network::Packets;
|
|
|
|
using namespace Sapphire::Network::Packets::Server;
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
Sapphire::StatusEffect::StatusEffect::StatusEffect( uint32_t id, Entity::CharaPtr sourceActor, Entity::CharaPtr targetActor,
|
2020-03-01 01:00:57 +11:00
|
|
|
uint32_t duration, uint32_t tickRate ) :
|
2018-12-29 00:53:52 +01:00
|
|
|
m_id( id ),
|
|
|
|
m_sourceActor( sourceActor ),
|
|
|
|
m_targetActor( targetActor ),
|
|
|
|
m_duration( duration ),
|
|
|
|
m_startTime( 0 ),
|
|
|
|
m_tickRate( tickRate ),
|
|
|
|
m_lastTick( 0 ),
|
2020-01-13 03:05:54 +09:00
|
|
|
m_value( 0 ),
|
2020-01-10 21:24:35 +09:00
|
|
|
m_cachedSourceCrit( 0 ),
|
2020-01-14 23:24:06 +09:00
|
|
|
m_cachedSourceCritBonus( 0 ),
|
|
|
|
m_markToRemove( false )
|
2018-12-29 00:53:52 +01:00
|
|
|
{
|
2020-03-01 01:00:57 +11:00
|
|
|
auto& exdData = Common::Service< Data::ExdDataGenerated >::ref();
|
|
|
|
auto entry = exdData.get< Sapphire::Data::Status >( id );
|
2018-08-29 21:40:59 +02:00
|
|
|
m_name = entry->name;
|
|
|
|
|
|
|
|
std::replace( m_name.begin(), m_name.end(), ' ', '_' );
|
|
|
|
std::replace( m_name.begin(), m_name.end(), ':', '_' );
|
|
|
|
std::replace( m_name.begin(), m_name.end(), '&', '_' );
|
|
|
|
std::replace( m_name.begin(), m_name.end(), '+', 'p' );
|
2018-10-26 08:25:20 +02:00
|
|
|
Util::eraseAll( m_name, '\'' );
|
|
|
|
Util::eraseAll( m_name, '&' );
|
|
|
|
Util::eraseAll( m_name, '-' );
|
|
|
|
Util::eraseAll( m_name, '(' );
|
|
|
|
Util::eraseAll( m_name, ')' );
|
2020-01-10 21:24:35 +09:00
|
|
|
|
|
|
|
if( Sapphire::World::Action::ActionLut::validStatusEffectExists( id ) )
|
|
|
|
m_effectEntry = Sapphire::World::Action::ActionLut::getStatusEffectEntry( id );
|
|
|
|
else
|
2020-01-12 03:29:52 +09:00
|
|
|
m_effectEntry.effectType = static_cast< uint32_t >( Common::StatusEffectType::Invalid );
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
Sapphire::StatusEffect::StatusEffect::~StatusEffect()
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
void Sapphire::StatusEffect::StatusEffect::registerTickEffect( uint8_t type, uint32_t param )
|
2017-08-15 11:51:59 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
m_currTickEffect = std::make_pair( type, param );
|
2017-08-15 11:51:59 +02:00
|
|
|
}
|
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
std::pair< uint8_t, uint32_t > Sapphire::StatusEffect::StatusEffect::getTickEffect()
|
2017-08-15 11:51:59 +02:00
|
|
|
{
|
2020-01-14 21:59:05 +09:00
|
|
|
switch( static_cast< Common::StatusEffectType >( m_effectEntry.effectType ) )
|
2020-01-10 21:24:35 +09:00
|
|
|
{
|
2020-01-14 21:59:05 +09:00
|
|
|
case Common::StatusEffectType::Dot:
|
2020-01-10 21:24:35 +09:00
|
|
|
{
|
2020-01-14 21:59:05 +09:00
|
|
|
auto value = m_value;
|
2020-01-15 18:07:06 +09:00
|
|
|
if( m_cachedSourceCrit > Sapphire::Math::CalcStats::getRandomNumber0To99() )
|
2020-01-14 21:59:05 +09:00
|
|
|
{
|
|
|
|
value *= m_cachedSourceCritBonus;
|
|
|
|
}
|
2020-01-15 18:07:06 +09:00
|
|
|
value *= 1.0f + ( ( Sapphire::Math::CalcStats::getRandomNumber0To99() - 50.0f ) / 1000.0f );
|
2020-01-14 21:59:05 +09:00
|
|
|
m_currTickEffect = std::make_pair( 1, value );
|
|
|
|
break;
|
2020-01-10 21:24:35 +09:00
|
|
|
}
|
2020-01-14 21:59:05 +09:00
|
|
|
|
|
|
|
case Common::StatusEffectType::Hot:
|
2020-01-10 21:24:35 +09:00
|
|
|
{
|
2020-01-14 21:59:05 +09:00
|
|
|
auto value = m_value;
|
2020-01-15 18:07:06 +09:00
|
|
|
if( m_cachedSourceCrit > Sapphire::Math::CalcStats::getRandomNumber0To99() )
|
2020-01-14 21:59:05 +09:00
|
|
|
{
|
|
|
|
value *= m_cachedSourceCritBonus;
|
|
|
|
}
|
2020-01-15 18:07:06 +09:00
|
|
|
value *= 1.0f + ( ( Sapphire::Math::CalcStats::getRandomNumber0To99() - 50.0f ) / 1000.0f );
|
2020-01-14 21:59:05 +09:00
|
|
|
m_currTickEffect = std::make_pair( 2, value );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
m_currTickEffect = std::make_pair( 0, 0 );
|
|
|
|
break;
|
2020-01-10 21:24:35 +09:00
|
|
|
}
|
|
|
|
}
|
2020-01-14 21:59:05 +09:00
|
|
|
|
2020-01-14 17:37:25 +09:00
|
|
|
return m_currTickEffect;
|
2017-08-15 11:51:59 +02:00
|
|
|
}
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
void Sapphire::StatusEffect::StatusEffect::onTick()
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
m_lastTick = Util::getTimeMs();
|
2020-03-01 01:00:57 +11:00
|
|
|
|
|
|
|
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
|
|
|
|
scriptMgr.onStatusTick( m_targetActor, *this );
|
2020-01-14 17:15:05 +09:00
|
|
|
|
|
|
|
auto statusEffectType = static_cast< Common::StatusEffectType >( m_effectEntry.effectType );
|
|
|
|
if( statusEffectType == Common::StatusEffectType::MPRestore )
|
|
|
|
{
|
|
|
|
m_targetActor->restoreMP( m_effectEntry.effectValue1 * 10 );
|
|
|
|
}
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
uint32_t Sapphire::StatusEffect::StatusEffect::getSrcActorId() const
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
return m_sourceActor->getId();
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
uint32_t Sapphire::StatusEffect::StatusEffect::getTargetActorId() const
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
return m_targetActor->getId();
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
uint16_t Sapphire::StatusEffect::StatusEffect::getParam() const
|
2017-08-10 16:12:54 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
return m_param;
|
2017-08-10 16:12:54 +02:00
|
|
|
}
|
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
void Sapphire::StatusEffect::StatusEffect::applyStatus()
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
m_startTime = Util::getTimeMs();
|
2020-03-01 01:00:57 +11:00
|
|
|
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
|
2020-03-02 05:37:15 +09:00
|
|
|
scriptMgr.onStatusReceive( m_targetActor, m_id );
|
2020-01-10 21:24:35 +09:00
|
|
|
|
2020-01-14 21:59:05 +09:00
|
|
|
switch( static_cast< Common::StatusEffectType >( m_effectEntry.effectType ) )
|
|
|
|
{
|
|
|
|
case Common::StatusEffectType::Dot:
|
2020-01-10 21:24:35 +09:00
|
|
|
{
|
2020-01-14 21:59:05 +09:00
|
|
|
auto wepDmg = Sapphire::Math::CalcStats::getWeaponDamage( m_sourceActor );
|
|
|
|
auto damage = Sapphire::Math::CalcStats::calcDamageBaseOnPotency( *m_sourceActor, m_effectEntry.effectValue2, wepDmg );
|
|
|
|
|
|
|
|
for( auto const& entry : m_sourceActor->getStatusEffectMap() )
|
2020-01-10 21:24:35 +09:00
|
|
|
{
|
2020-01-14 21:59:05 +09:00
|
|
|
auto status = entry.second;
|
|
|
|
auto effectEntry = status->getEffectEntry();
|
|
|
|
if( static_cast< Common::StatusEffectType >( effectEntry.effectType ) != Common::StatusEffectType::DamageMultiplier )
|
|
|
|
continue;
|
|
|
|
if( effectEntry.effectValue1 & m_effectEntry.effectValue1 )
|
|
|
|
{
|
|
|
|
damage *= 1.0f + ( effectEntry.effectValue2 / 100.0f );
|
|
|
|
}
|
2020-01-10 21:24:35 +09:00
|
|
|
}
|
|
|
|
|
2020-01-14 21:59:05 +09:00
|
|
|
m_value = Sapphire::Math::CalcStats::applyDamageReceiveMultiplier( *m_targetActor, damage,
|
2020-01-12 03:29:52 +09:00
|
|
|
m_effectEntry.effectValue1 == static_cast< int32_t >( Common::ActionTypeFilter::Physical ) ? Common::AttackType::Physical :
|
2020-01-14 21:59:05 +09:00
|
|
|
( m_effectEntry.effectValue1 == static_cast< int32_t >( Common::ActionTypeFilter::Magical ) ? Common::AttackType::Magical : Common::AttackType::Unknown_0 ) );
|
|
|
|
m_cachedSourceCrit = Sapphire::Math::CalcStats::criticalHitProbability( *m_sourceActor, Common::CritDHBonusFilter::Damage );
|
|
|
|
m_cachedSourceCritBonus = Sapphire::Math::CalcStats::criticalHitBonus( *m_sourceActor );
|
|
|
|
break;
|
|
|
|
}
|
2020-01-10 21:24:35 +09:00
|
|
|
|
2020-01-14 21:59:05 +09:00
|
|
|
case Common::StatusEffectType::Hot:
|
2020-01-10 21:24:35 +09:00
|
|
|
{
|
2020-01-14 21:59:05 +09:00
|
|
|
auto wepDmg = Sapphire::Math::CalcStats::getWeaponDamage( m_sourceActor );
|
|
|
|
auto heal = Sapphire::Math::CalcStats::calcHealBaseOnPotency( *m_sourceActor, m_effectEntry.effectValue2, wepDmg );
|
|
|
|
|
|
|
|
if( m_effectEntry.effectValue1 == 0 ) // this value is always 0 atm, if statement here just in case there is a hot that isn't a "cast"
|
2020-01-10 21:24:35 +09:00
|
|
|
{
|
2020-01-14 21:59:05 +09:00
|
|
|
for( auto const& entry : m_sourceActor->getStatusEffectMap() )
|
|
|
|
{
|
|
|
|
auto status = entry.second;
|
|
|
|
auto effectEntry = status->getEffectEntry();
|
|
|
|
if( static_cast< Common::StatusEffectType >( effectEntry.effectType ) != Common::StatusEffectType::HealCastMultiplier )
|
|
|
|
continue;
|
|
|
|
heal *= 1.0f + ( effectEntry.effectValue2 / 100.0f );
|
|
|
|
}
|
2020-01-10 21:24:35 +09:00
|
|
|
}
|
2020-01-14 21:59:05 +09:00
|
|
|
m_value = Sapphire::Math::CalcStats::applyHealingReceiveMultiplier( *m_targetActor, heal );
|
|
|
|
m_cachedSourceCrit = Sapphire::Math::CalcStats::criticalHitProbability( *m_sourceActor, Common::CritDHBonusFilter::Heal );
|
|
|
|
m_cachedSourceCritBonus = Sapphire::Math::CalcStats::criticalHitBonus( *m_sourceActor );
|
|
|
|
break;
|
2020-01-10 21:24:35 +09:00
|
|
|
}
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2020-01-14 21:59:05 +09:00
|
|
|
case Common::StatusEffectType::Haste:
|
|
|
|
{
|
|
|
|
auto pPlayer = m_targetActor->getAsPlayer();
|
|
|
|
if( pPlayer )
|
|
|
|
pPlayer->sendStats();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
void Sapphire::StatusEffect::StatusEffect::removeStatus()
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2020-03-01 01:00:57 +11:00
|
|
|
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
|
|
|
|
scriptMgr.onStatusTimeOut( m_targetActor, m_id );
|
2020-01-14 21:59:05 +09:00
|
|
|
|
|
|
|
switch( static_cast< Common::StatusEffectType >( m_effectEntry.effectType ) )
|
|
|
|
{
|
|
|
|
case Common::StatusEffectType::Haste:
|
|
|
|
{
|
|
|
|
auto pPlayer = m_targetActor->getAsPlayer();
|
|
|
|
if( pPlayer )
|
|
|
|
pPlayer->sendStats();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2020-03-15 23:24:44 +09:00
|
|
|
|
|
|
|
// lol just hack it and hardcode this shit
|
|
|
|
if( m_markToRemove && m_id == 1178 )
|
|
|
|
{
|
|
|
|
if( auto drk = m_sourceActor->getAsPlayer() )
|
|
|
|
{
|
|
|
|
if( drk->getClass() == Common::ClassJob::Darkknight )
|
|
|
|
{
|
|
|
|
drk->gaugeDrkSetDarkArts( true );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
uint32_t Sapphire::StatusEffect::StatusEffect::getId() const
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
return m_id;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
uint32_t Sapphire::StatusEffect::StatusEffect::getDuration() const
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
return m_duration;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
uint32_t Sapphire::StatusEffect::StatusEffect::getTickRate() const
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
return m_tickRate;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
uint64_t Sapphire::StatusEffect::StatusEffect::getLastTickMs() const
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
return m_lastTick;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
uint64_t Sapphire::StatusEffect::StatusEffect::getStartTimeMs() const
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
return m_startTime;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
void Sapphire::StatusEffect::StatusEffect::setLastTick( uint64_t lastTick )
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
m_lastTick = lastTick;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
void Sapphire::StatusEffect::StatusEffect::setParam( uint16_t param )
|
2017-08-12 22:11:56 -03:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
m_param = param;
|
2017-08-12 22:11:56 -03:00
|
|
|
}
|
2017-08-10 16:12:54 +02:00
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
const std::string& Sapphire::StatusEffect::StatusEffect::getName() const
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
return m_name;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
2020-01-10 21:24:35 +09:00
|
|
|
|
|
|
|
const Sapphire::World::Action::StatusEffectEntry& Sapphire::StatusEffect::StatusEffect::getEffectEntry() const
|
|
|
|
{
|
|
|
|
return m_effectEntry;
|
|
|
|
}
|
2020-01-13 03:05:54 +09:00
|
|
|
|
|
|
|
void Sapphire::StatusEffect::StatusEffect::replaceEffectEntry( Sapphire::World::Action::StatusEffectEntry entryOverride )
|
|
|
|
{
|
|
|
|
m_effectEntry = entryOverride;
|
2020-01-14 23:24:06 +09:00
|
|
|
}
|
|
|
|
|
2020-03-21 18:25:19 +09:00
|
|
|
void Sapphire::StatusEffect::StatusEffect::onBeforeActionStart( Sapphire::World::Action::Action* action )
|
2020-01-14 23:24:06 +09:00
|
|
|
{
|
|
|
|
// todo: add script function for this if needed
|
|
|
|
//auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >();
|
|
|
|
//pScriptMgr->onBeforeActionStart( m_targetActor, *this );
|
|
|
|
|
|
|
|
switch( static_cast< Common::StatusEffectType >( m_effectEntry.effectType ) )
|
|
|
|
{
|
|
|
|
case Common::StatusEffectType::InstantCast:
|
|
|
|
{
|
|
|
|
if( !action->hasCastTime() )
|
|
|
|
return;
|
|
|
|
// value1: remaining uses
|
|
|
|
// value2-4: affected action ids, or all actions if value2 is 0
|
|
|
|
if( m_effectEntry.effectValue2 != 0 )
|
|
|
|
{
|
|
|
|
if( action->getId() != m_effectEntry.effectValue2 &&
|
|
|
|
action->getId() != m_effectEntry.effectValue3 &&
|
|
|
|
action->getId() != m_effectEntry.effectValue4 )
|
2020-03-21 18:25:19 +09:00
|
|
|
break;
|
2020-01-14 23:24:06 +09:00
|
|
|
}
|
|
|
|
if( m_effectEntry.effectValue1 > 0 )
|
|
|
|
{
|
|
|
|
m_effectEntry.effectValue1--;
|
|
|
|
if( m_effectEntry.effectValue1 == 0 )
|
|
|
|
{
|
2020-01-22 01:20:39 +09:00
|
|
|
markToRemove();
|
2020-01-14 23:24:06 +09:00
|
|
|
}
|
|
|
|
action->setCastTime( 0 );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Sapphire::StatusEffect::StatusEffect::isMarkedToRemove()
|
|
|
|
{
|
|
|
|
return m_markToRemove;
|
2020-01-19 20:00:16 +09:00
|
|
|
}
|
|
|
|
|
2020-01-22 01:20:39 +09:00
|
|
|
void Sapphire::StatusEffect::StatusEffect::markToRemove()
|
|
|
|
{
|
|
|
|
m_markToRemove = true;
|
|
|
|
}
|
|
|
|
|
2020-01-19 20:00:16 +09:00
|
|
|
void Sapphire::StatusEffect::StatusEffect::refresh()
|
|
|
|
{
|
|
|
|
m_value = 0;
|
|
|
|
m_cachedSourceCritBonus = 0;
|
|
|
|
m_cachedSourceCrit = 0;
|
|
|
|
applyStatus();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Sapphire::StatusEffect::StatusEffect::refresh( Sapphire::World::Action::StatusEffectEntry newEntry )
|
|
|
|
{
|
|
|
|
m_effectEntry = newEntry;
|
|
|
|
refresh();
|
2020-03-21 18:25:19 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2020-01-13 03:05:54 +09:00
|
|
|
}
|