mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-26 03:27:44 +00:00
Merge branch 'action_data_update_pr' into develop_c
This commit is contained in:
commit
b3367cba63
8 changed files with 123 additions and 60 deletions
|
@ -1038,6 +1038,7 @@ namespace Sapphire::Common
|
|||
DamageDealtTrigger = 9,
|
||||
Shield = 10,
|
||||
MPRestore = 11,
|
||||
Haste = 12,
|
||||
};
|
||||
|
||||
enum class ActionTypeFilter : int32_t
|
||||
|
|
|
@ -79,6 +79,14 @@ bool Action::Action::init()
|
|||
|
||||
m_castTimeMs = static_cast< uint32_t >( m_actionData->cast100ms * 100 );
|
||||
m_recastTimeMs = static_cast< uint32_t >( m_actionData->recast100ms * 100 );
|
||||
auto actionCategory = static_cast< Common::ActionCategory >( m_actionData->actionCategory );
|
||||
if( actionCategory == Common::ActionCategory::Spell || actionCategory == Common::ActionCategory::Weaponskill )
|
||||
{
|
||||
auto haste = m_pSource->getStatValue( Common::BaseParam::Haste );
|
||||
m_castTimeMs = static_cast< uint32_t >( m_castTimeMs * ( m_pSource->getStatValue( Common::BaseParam::Haste ) / 100.0f ) );
|
||||
m_recastTimeMs = static_cast< uint32_t >( m_recastTimeMs * ( m_pSource->getStatValue( Common::BaseParam::Haste ) / 100.0f ) );
|
||||
}
|
||||
|
||||
m_cooldownGroup = m_actionData->cooldownGroup;
|
||||
m_range = m_actionData->range;
|
||||
m_effectRange = m_actionData->effectRange;
|
||||
|
|
|
@ -3508,4 +3508,7 @@ ActionLut::StatusEffectTable ActionLut::m_statusEffectTable =
|
|||
//Lucid Dreaming, ルーシッドドリーム: MPRestore, value 50
|
||||
{ 1204, { 11, 50, 0, 0, 0 } },
|
||||
|
||||
//Presence of Mind, 神速魔: Haste, 20%
|
||||
{ 157, { 12, 20, 0, 0, 0 } },
|
||||
|
||||
};
|
||||
|
|
|
@ -735,6 +735,7 @@ void Sapphire::Entity::BNpc::calculateStats()
|
|||
m_baseStats.pie = static_cast< uint32_t >( base );
|
||||
m_baseStats.skillSpeed = static_cast< uint32_t >( paramGrowthInfo->baseSpeed );
|
||||
m_baseStats.spellSpeed = static_cast< uint32_t >( paramGrowthInfo->baseSpeed );
|
||||
m_baseStats.haste = 100;
|
||||
m_baseStats.accuracy = static_cast< uint32_t >( paramGrowthInfo->baseSpeed );
|
||||
m_baseStats.critHitRate = static_cast< uint32_t >( paramGrowthInfo->baseSpeed );
|
||||
m_baseStats.attackPotMagic = static_cast< uint32_t >( paramGrowthInfo->baseSpeed );
|
||||
|
|
|
@ -494,8 +494,8 @@ void Sapphire::Entity::Chara::addStatusEffect( StatusEffect::StatusEffectPtr pEf
|
|||
if( nextSlot == -1 )
|
||||
return;
|
||||
|
||||
pEffect->applyStatus();
|
||||
m_statusEffectMap[ nextSlot ] = pEffect;
|
||||
pEffect->applyStatus();
|
||||
|
||||
auto statusEffectAdd = makeZonePacket< FFXIVIpcEffectResult >( getId() );
|
||||
|
||||
|
@ -595,14 +595,14 @@ void Sapphire::Entity::Chara::removeStatusEffect( uint8_t effectSlotId, bool sen
|
|||
|
||||
statusEffectFreeSlot( effectSlotId );
|
||||
|
||||
m_statusEffectMap.erase( effectSlotId );
|
||||
|
||||
auto pEffect = pEffectIt->second;
|
||||
pEffect->removeStatus();
|
||||
|
||||
if( sendActorControl )
|
||||
sendToInRangeSet( makeActorControl( getId(), StatusEffectLose, pEffect->getId() ), isPlayer() );
|
||||
|
||||
m_statusEffectMap.erase( effectSlotId );
|
||||
|
||||
if( sendStatusList )
|
||||
sendStatusEffectUpdate();
|
||||
}
|
||||
|
@ -942,6 +942,18 @@ uint32_t Sapphire::Entity::Chara::getStatValue( Sapphire::Common::BaseParam base
|
|||
break;
|
||||
}
|
||||
|
||||
case Common::BaseParam::Haste:
|
||||
{
|
||||
value = m_baseStats.haste;
|
||||
for( auto const& statusIt : m_statusEffectMap )
|
||||
{
|
||||
auto effectEntry = statusIt.second->getEffectEntry();
|
||||
if( static_cast< Common::StatusEffectType >( effectEntry.effectType ) == Common::StatusEffectType::Haste )
|
||||
value -= effectEntry.effectValue1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Common::BaseParam::CriticalHit:
|
||||
{
|
||||
value = m_baseStats.critHitRate;
|
||||
|
|
|
@ -47,6 +47,7 @@ namespace Sapphire::Entity
|
|||
uint32_t healingPotMagic = 0;
|
||||
uint32_t determination = 0;
|
||||
uint32_t skillSpeed = 0;
|
||||
uint32_t haste = 0;
|
||||
|
||||
uint32_t resistSlow = 0;
|
||||
uint32_t resistSilence = 0;
|
||||
|
|
|
@ -280,6 +280,7 @@ void Sapphire::Entity::Player::calculateStats()
|
|||
m_baseStats.pie = static_cast< uint32_t >( base );
|
||||
m_baseStats.skillSpeed = paramGrowthInfo->baseSpeed;
|
||||
m_baseStats.spellSpeed = paramGrowthInfo->baseSpeed;
|
||||
m_baseStats.haste = 100;
|
||||
m_baseStats.accuracy = paramGrowthInfo->baseSpeed;
|
||||
m_baseStats.critHitRate = paramGrowthInfo->baseSpeed;
|
||||
m_baseStats.attackPotMagic = paramGrowthInfo->baseSpeed;
|
||||
|
@ -332,7 +333,7 @@ void Sapphire::Entity::Player::sendStats()
|
|||
statPacket->data().healingMagicPotency = getStatValue( Common::BaseParam::HealingMagicPotency );
|
||||
statPacket->data().skillSpeed = getStatValue( Common::BaseParam::SkillSpeed );
|
||||
statPacket->data().spellSpeed = getStatValue( Common::BaseParam::SpellSpeed );
|
||||
statPacket->data().haste = 100;
|
||||
statPacket->data().haste = getStatValue( Common::BaseParam::Haste );
|
||||
statPacket->data().criticalHit = getStatValue( Common::BaseParam::CriticalHit );
|
||||
statPacket->data().defense = getStatValue( Common::BaseParam::Defense );
|
||||
statPacket->data().magicDefense = getStatValue( Common::BaseParam::MagicDefense );
|
||||
|
@ -1128,7 +1129,7 @@ void Sapphire::Entity::Player::update( uint64_t tickCount )
|
|||
actor->getPos().x, actor->getPos().y, actor->getPos().z ) <= range )
|
||||
{
|
||||
|
||||
if( ( tickCount - m_lastAttack ) > mainWeap->getDelay() )
|
||||
if( ( tickCount - m_lastAttack ) > ( static_cast< float >( mainWeap->getDelay() ) * ( getStatValue( Common::BaseParam::Haste ) / 100.0f ) ) )
|
||||
{
|
||||
m_lastAttack = tickCount;
|
||||
autoAttack( actor->getAsChara() );
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include "Actor/Player.h"
|
||||
#include "Actor/Chara.h"
|
||||
#include "Actor/Actor.h"
|
||||
|
||||
|
@ -64,31 +65,39 @@ void Sapphire::StatusEffect::StatusEffect::registerTickEffect( uint8_t type, uin
|
|||
|
||||
std::pair< uint8_t, uint32_t > Sapphire::StatusEffect::StatusEffect::getTickEffect()
|
||||
{
|
||||
auto statusEffectType = static_cast< Common::StatusEffectType >( m_effectEntry.effectType );
|
||||
if( statusEffectType == Common::StatusEffectType::Dot )
|
||||
switch( static_cast< Common::StatusEffectType >( m_effectEntry.effectType ) )
|
||||
{
|
||||
auto value = m_value;
|
||||
if( m_cachedSourceCrit > Sapphire::Math::CalcStats::range100( Sapphire::Math::CalcStats::rng ) )
|
||||
case Common::StatusEffectType::Dot:
|
||||
{
|
||||
value *= m_cachedSourceCritBonus;
|
||||
auto value = m_value;
|
||||
if( m_cachedSourceCrit > Sapphire::Math::CalcStats::range100( Sapphire::Math::CalcStats::rng ) )
|
||||
{
|
||||
value *= m_cachedSourceCritBonus;
|
||||
}
|
||||
value *= 1.0f + ( ( Sapphire::Math::CalcStats::range100( Sapphire::Math::CalcStats::rng ) - 50.0f ) / 1000.0f );
|
||||
m_currTickEffect = std::make_pair( 1, value );
|
||||
break;
|
||||
}
|
||||
value *= 1.0f + ( ( Sapphire::Math::CalcStats::range100( Sapphire::Math::CalcStats::rng ) - 50.0f ) / 1000.0f );
|
||||
m_currTickEffect = std::make_pair( 1, value );
|
||||
}
|
||||
else if( statusEffectType == Common::StatusEffectType::Hot )
|
||||
{
|
||||
auto value = m_value;
|
||||
if( m_cachedSourceCrit > Sapphire::Math::CalcStats::range100( Sapphire::Math::CalcStats::rng ) )
|
||||
|
||||
case Common::StatusEffectType::Hot:
|
||||
{
|
||||
value *= m_cachedSourceCritBonus;
|
||||
auto value = m_value;
|
||||
if( m_cachedSourceCrit > Sapphire::Math::CalcStats::range100( Sapphire::Math::CalcStats::rng ) )
|
||||
{
|
||||
value *= m_cachedSourceCritBonus;
|
||||
}
|
||||
value *= 1.0f + ( ( Sapphire::Math::CalcStats::range100( Sapphire::Math::CalcStats::rng ) - 50.0f ) / 1000.0f );
|
||||
m_currTickEffect = std::make_pair( 2, value );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
m_currTickEffect = std::make_pair( 0, 0 );
|
||||
break;
|
||||
}
|
||||
value *= 1.0f + ( ( Sapphire::Math::CalcStats::range100( Sapphire::Math::CalcStats::rng ) - 50.0f ) / 1000.0f );
|
||||
m_currTickEffect = std::make_pair( 2, value );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currTickEffect = std::make_pair( 0, 0 );
|
||||
}
|
||||
|
||||
return m_currTickEffect;
|
||||
}
|
||||
|
||||
|
@ -123,59 +132,86 @@ uint16_t Sapphire::StatusEffect::StatusEffect::getParam() const
|
|||
void Sapphire::StatusEffect::StatusEffect::applyStatus()
|
||||
{
|
||||
m_startTime = Util::getTimeMs();
|
||||
if( m_lastTick == 0 )
|
||||
m_lastTick = m_startTime;
|
||||
|
||||
auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >();
|
||||
auto statusEffectType = static_cast< Common::StatusEffectType >( m_effectEntry.effectType );
|
||||
if( statusEffectType == Common::StatusEffectType::Dot )
|
||||
pScriptMgr->onStatusReceive( m_targetActor, m_id );
|
||||
|
||||
switch( static_cast< Common::StatusEffectType >( m_effectEntry.effectType ) )
|
||||
{
|
||||
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() )
|
||||
case Common::StatusEffectType::Dot:
|
||||
{
|
||||
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 );
|
||||
}
|
||||
}
|
||||
auto wepDmg = Sapphire::Math::CalcStats::getWeaponDamage( m_sourceActor );
|
||||
auto damage = Sapphire::Math::CalcStats::calcDamageBaseOnPotency( *m_sourceActor, m_effectEntry.effectValue2, wepDmg );
|
||||
|
||||
m_value = Sapphire::Math::CalcStats::applyDamageReceiveMultiplier( *m_targetActor, damage,
|
||||
m_effectEntry.effectValue1 == static_cast< int32_t >( Common::ActionTypeFilter::Physical ) ? Common::AttackType::Physical :
|
||||
( 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 );
|
||||
}
|
||||
else if( statusEffectType == Common::StatusEffectType::Hot )
|
||||
{
|
||||
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"
|
||||
{
|
||||
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 )
|
||||
if( static_cast< Common::StatusEffectType >( effectEntry.effectType ) != Common::StatusEffectType::DamageMultiplier )
|
||||
continue;
|
||||
heal *= 1.0f + ( effectEntry.effectValue2 / 100.0f );
|
||||
if( effectEntry.effectValue1 & m_effectEntry.effectValue1 )
|
||||
{
|
||||
damage *= 1.0f + ( effectEntry.effectValue2 / 100.0f );
|
||||
}
|
||||
}
|
||||
}
|
||||
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 );
|
||||
}
|
||||
|
||||
pScriptMgr->onStatusReceive( m_targetActor, m_id );
|
||||
m_value = Sapphire::Math::CalcStats::applyDamageReceiveMultiplier( *m_targetActor, damage,
|
||||
m_effectEntry.effectValue1 == static_cast< int32_t >( Common::ActionTypeFilter::Physical ) ? Common::AttackType::Physical :
|
||||
( 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;
|
||||
}
|
||||
|
||||
case Common::StatusEffectType::Hot:
|
||||
{
|
||||
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"
|
||||
{
|
||||
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 );
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
case Common::StatusEffectType::Haste:
|
||||
{
|
||||
auto pPlayer = m_targetActor->getAsPlayer();
|
||||
if( pPlayer )
|
||||
pPlayer->sendStats();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Sapphire::StatusEffect::StatusEffect::removeStatus()
|
||||
{
|
||||
auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >();
|
||||
pScriptMgr->onStatusTimeOut( m_targetActor, m_id );
|
||||
|
||||
switch( static_cast< Common::StatusEffectType >( m_effectEntry.effectType ) )
|
||||
{
|
||||
case Common::StatusEffectType::Haste:
|
||||
{
|
||||
auto pPlayer = m_targetActor->getAsPlayer();
|
||||
if( pPlayer )
|
||||
pPlayer->sendStats();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t Sapphire::StatusEffect::StatusEffect::getId() const
|
||||
|
|
Loading…
Add table
Reference in a new issue