1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-25 19:17:45 +00:00

Create lut entry for auto attacks so we won't have three different places that do damage.

of course more dumb mistake fixes.
This commit is contained in:
collett 2020-01-12 17:46:18 +09:00
parent e08643f380
commit 64a1c4033b
8 changed files with 61 additions and 52 deletions

View file

@ -50,7 +50,8 @@ Action::Action::Action( Entity::CharaPtr caster, uint32_t actionId, uint16_t seq
m_targetId( 0 ),
m_startTime( 0 ),
m_interruptType( Common::ActionInterruptType::None ),
m_sequence( sequence )
m_sequence( sequence ),
m_isAutoAttack( false )
{
}
@ -288,7 +289,8 @@ void Action::Action::start()
// todo: m_recastTimeMs needs to be adjusted for player sks/sps
auto actionStartPkt = makeActorControlSelf( m_pSource->getId(), ActorControlType::ActionStart, 1, getId(),
m_recastTimeMs / 10 );
player->queuePacket( actionStartPkt );
if( player )
player->queuePacket( actionStartPkt );
auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >();
@ -406,7 +408,10 @@ void Action::Action::execute()
std::pair< uint32_t, Common::ActionHitSeverityType > Action::Action::calcDamage( uint32_t potency )
{
return Math::CalcStats::calcActionDamage( *m_pSource, static_cast< Common::AttackType >( m_actionData->attackType ), potency, Math::CalcStats::getWeaponDamage( m_pSource ) );
if( m_isAutoAttack )
return Math::CalcStats::calcAutoAttackDamage( *m_pSource, potency );
else
return Math::CalcStats::calcActionDamage( *m_pSource, static_cast< Common::AttackType >( m_actionData->attackType ), potency, Math::CalcStats::getWeaponDamage( m_pSource ) );
}
std::pair< uint32_t, Common::ActionHitSeverityType > Action::Action::calcHealing( uint32_t potency )
@ -472,7 +477,7 @@ void Action::Action::buildEffects()
if( reflectDmg.first > 0 )
{
m_effectBuilder->damage( actor, m_pSource, dmg.first, dmg.second, Common::ActionEffectResultFlag::Reflected );
m_effectBuilder->damage( actor, m_pSource, reflectDmg.first, reflectDmg.second, Common::ActionEffectResultFlag::Reflected );
}
if( isCorrectCombo() && shouldApplyComboSucceedEffect )
@ -813,6 +818,11 @@ Data::ActionPtr Action::Action::getActionData() const
return m_actionData;
}
void Action::Action::setAutoAttack()
{
m_isAutoAttack = true;
}
bool Action::Action::isPhysical() const
{
return isAttackTypePhysical( static_cast< Common::AttackType >( m_actionData->attackType ) );

View file

@ -52,6 +52,8 @@ namespace Sapphire::World::Action
bool isComboAction() const;
void setAutoAttack();
/*!
* @brief Checks if a chara has enough resources available to cast the action (tp/mp/etc)
* @return true if they have the required resources
@ -188,6 +190,7 @@ namespace Sapphire::World::Action
bool m_canTargetFriendly;
bool m_canTargetHostile;
bool m_canTargetDead;
bool m_isAutoAttack;
Common::ActionInterruptType m_interruptType;

View file

@ -2816,6 +2816,14 @@ ActionLut::Lut ActionLut::m_actionLut =
//Hagakure, 葉隠
{ 7495, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
//attack, 攻撃
//has damage: potency 110, combo potency 0, directional potency 0
{ 7, { 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
//Shot, ショット
//has damage: potency 110, combo potency 0, directional potency 0
{ 8, { 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
};
ActionLut::StatusEffectTable ActionLut::m_statusEffectTable =

View file

@ -94,8 +94,8 @@ void EffectBuilder::applyStatusEffect( Entity::CharaPtr& target, Entity::CharaPt
void EffectBuilder::buildAndSendPackets()
{
auto targetCount = m_resolvedEffects.size();
Logger::debug( "EffectBuilder result: " );
Logger::debug( "Targets afflicted: {}", targetCount );
//Logger::debug( "EffectBuilder result: " );
//Logger::debug( "Targets afflicted: {}", targetCount );
auto globalSequence = m_sourceChara->getCurrentTerritory()->getNextEffectSequence();
@ -184,7 +184,7 @@ std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( uint32_
assert( !resultList->empty() );
auto firstResult = resultList->data()[ 0 ];
pEffectTargetId[ targetIndex ] = firstResult->getTarget()->getId();
Logger::debug( " - id: {}", pEffectTargetId[ targetIndex ] );
//Logger::debug( " - id: {}", pEffectTargetId[ targetIndex ] );
for( auto i = 0; i < resultList->size(); i++ )
{
@ -213,7 +213,7 @@ std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( uint32_
auto resultList = m_resolvedEffects.begin()->second;
assert( !resultList->empty() );
auto firstResult = resultList->data()[ 0 ];
Logger::debug( " - id: {}", firstResult->getTarget()->getId() );
//Logger::debug( " - id: {}", firstResult->getTarget()->getId() );
auto seq = m_sourceChara->getCurrentTerritory()->getNextEffectSequence();

View file

@ -680,10 +680,7 @@ void Sapphire::Entity::BNpc::setFlag( uint32_t flag )
}
/*!
Autoattack prototype implementation
TODO: move the check if the autoAttack can be performed to the callee
also rename autoAttack to autoAttack as that is more elaborate
On top of that, this only solves attacks from melee classes.
TODO: this only solves attacks from melee classes.
Will have to be extended for ranged attacks.
\param ActorPtr the autoAttack is performed on
@ -698,18 +695,20 @@ void Sapphire::Entity::BNpc::autoAttack( CharaPtr pTarget )
pTarget->onActionHostile( getAsChara() );
m_lastAttack = tick;
auto pSource = getAsChara();
auto damage = Math::CalcStats::calcAutoAttackDamage( *this );
damage.first = Math::CalcStats::applyDamageReceiveMultiplier( *pTarget, damage.first, Common::AttackType::Physical );
auto reflectDmg = Math::CalcStats::calcDamageReflect( pSource, pTarget, damage.first, Common::ActionTypeFilter::Physical );
auto exdData = m_pFw->get< Data::ExdDataGenerated >();
assert( exdData );
auto actionData = exdData->get< Data::Action >( 7 );
assert( actionData );
auto action = World::Action::make_Action( getAsChara(), 7, 0, actionData, m_pFw );
World::Action::EffectBuilder effectBuilder( pSource, 7, 0 );
effectBuilder.damage( pTarget, pTarget, damage.first, damage.second );
if( reflectDmg.first > 0 )
action->setTargetId( pTarget->getId() );
action->setPos( getPos() );
action->setAutoAttack();
if( action->init() )
{
effectBuilder.damage( pTarget, pSource, reflectDmg.first, reflectDmg.second, Common::ActionEffectResultFlag::Reflected );
action->start();
}
effectBuilder.buildAndSendPackets();
}
}

View file

@ -1565,32 +1565,31 @@ uint32_t Sapphire::Entity::Player::getPersistentEmote() const
void Sapphire::Entity::Player::autoAttack( CharaPtr pTarget )
{
auto mainWeap = getItemAt( Common::GearSet0, Common::GearSetSlot::MainHand );
pTarget->onActionHostile( getAsChara() );
auto pSource = getAsChara();
auto damage = Math::CalcStats::calcAutoAttackDamage( *this );
damage.first = Math::CalcStats::applyDamageReceiveMultiplier( *pTarget, damage.first, Common::AttackType::Physical );
auto reflectDmg = Math::CalcStats::calcDamageReflect( pSource, pTarget, damage.first, Common::ActionTypeFilter::Physical );
World::Action::EffectBuilderPtr effectBuilder = nullptr;
auto exdData = m_pFw->get< Data::ExdDataGenerated >();
assert( exdData );
World::Action::ActionPtr action;
if( getClass() == ClassJob::Machinist || getClass() == ClassJob::Bard || getClass() == ClassJob::Archer )
{
effectBuilder = World::Action::make_EffectBuilder( pSource, 8, 0 );
auto actionData = exdData->get< Data::Action >( 8 );
assert( actionData );
action = World::Action::make_Action( getAsChara(), 8, 0, actionData, m_pFw );
}
else
{
effectBuilder = World::Action::make_EffectBuilder( pSource, 7, 0 );
auto actionData = exdData->get< Data::Action >( 7 );
assert( actionData );
action = World::Action::make_Action( getAsChara(), 7, 0, actionData, m_pFw );
}
effectBuilder->damage( pTarget, pTarget, damage.first, damage.second );
if( reflectDmg.first > 0 )
action->setTargetId( pTarget->getId() );
action->setPos( getPos() );
action->setAutoAttack();
if( action->init() )
{
effectBuilder->damage( pTarget, pSource, reflectDmg.first, reflectDmg.second, Common::ActionEffectResultFlag::Reflected );
action->start();
}
effectBuilder->buildAndSendPackets();
}

View file

@ -252,15 +252,8 @@ float CalcStats::potency( uint16_t potency )
return potency / 100.f;
}
float CalcStats::autoAttackPotency( const Sapphire::Entity::Chara& chara )
float CalcStats::autoAttackPotency( const Sapphire::Entity::Chara& chara, uint32_t aaPotency )
{
uint32_t aaPotency = AUTO_ATTACK_POTENCY;
if( chara.getRole() == Common::Role::RangedPhysical )
{
aaPotency = RANGED_AUTO_ATTACK_POTENCY;
}
float autoAttackDelay = 2.5f;
// fetch actual auto attack delay if its a player
if( chara.isPlayer() )
@ -495,12 +488,12 @@ float CalcStats::healingMagicPotency( const Sapphire::Entity::Chara& chara )
return std::floor( 100.f * ( chara.getStatValue( Common::BaseParam::HealingMagicPotency ) - 292.f ) / 264.f + 100.f ) / 100.f;
}
std::pair< float, Sapphire::Common::ActionHitSeverityType > CalcStats::calcAutoAttackDamage( const Sapphire::Entity::Chara& chara )
std::pair< float, Sapphire::Common::ActionHitSeverityType > CalcStats::calcAutoAttackDamage( const Sapphire::Entity::Chara& chara, uint32_t ptc )
{
// D = ⌊ f(ptc) × f(aa) × f(ap) × f(det) × f(tnc) × traits ⌋ × f(ss) ⌋ ×
// f(chr) ⌋ × f(dhr) ⌋ × rand[ 0.95, 1.05 ] ⌋ × buff_1 ⌋ × buff... ⌋
auto pot = autoAttackPotency( chara );
auto pot = autoAttackPotency( chara, ptc );
auto aa = autoAttack( chara );
auto ap = getPrimaryAttackPower( chara );
auto det = determination( chara );

View file

@ -11,9 +11,6 @@ namespace Sapphire::Math
class CalcStats
{
public:
static const uint32_t AUTO_ATTACK_POTENCY = 110;
static const uint32_t RANGED_AUTO_ATTACK_POTENCY = 100;
static float calculateBaseStat( const Entity::Chara& chara );
static uint32_t calculateMaxHp( Sapphire::Entity::PlayerPtr pPlayer, FrameworkPtr pFw );
@ -40,7 +37,7 @@ namespace Sapphire::Math
*/
static float potency( uint16_t potency );
static float autoAttackPotency( const Sapphire::Entity::Chara& chara );
static float autoAttackPotency( const Sapphire::Entity::Chara& chara, uint32_t aaPotency );
/*!
* @brief Weapon damage is the contribution the weapon's damage rating
@ -135,7 +132,7 @@ namespace Sapphire::Math
static float calcHealBaseOnPotency( const Sapphire::Entity::Chara& chara, uint32_t ptc, float wepDmg );
static std::pair< float, Common::ActionHitSeverityType > calcAutoAttackDamage( const Sapphire::Entity::Chara& chara );
static std::pair< float, Common::ActionHitSeverityType > calcAutoAttackDamage( const Sapphire::Entity::Chara& chara, uint32_t ptc );
static std::pair< float, Common::ActionHitSeverityType > calcActionDamage( const Sapphire::Entity::Chara& chara, Common::AttackType attackType, uint32_t ptc, float wepDmg );