From 089712dd9d53066aef7ae2e31b6005b3668cb123 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 9 Feb 2019 23:14:30 +1100 Subject: [PATCH] change action cost system to allow for a variable amount of costs --- src/common/Common.h | 3 +- src/world/Action/Action.cpp | 185 ++++++++++++++++++++---------------- src/world/Action/Action.h | 15 ++- 3 files changed, 119 insertions(+), 84 deletions(-) diff --git a/src/common/Common.h b/src/common/Common.h index 55d4c5d9..1354b687 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -538,8 +538,9 @@ namespace Sapphire::Common Unaspected = 7 // Doesn't imply magical unaspected damage - could be unaspected physical }; - enum ActionCostType : uint8_t + enum class ActionCostType : uint8_t { + None = 0, // ? MagicPoints = 3, TacticsPoints = 5, ClassGaugeWAR = 22, diff --git a/src/world/Action/Action.cpp b/src/world/Action/Action.cpp index 2718d72f..e8e22681 100644 --- a/src/world/Action/Action.cpp +++ b/src/world/Action/Action.cpp @@ -32,11 +32,14 @@ Sapphire::Action::Action::Action( Entity::CharaPtr caster, uint32_t actionId, { m_castTime = static_cast< uint32_t >( action->cast100ms ) * 100; - m_costType = static_cast< Common::ActionCostType >( action->costType ); - m_cost = action->cost; + m_actionCost.fill( { Common::ActionCostType::None, 0 } ); - if( caster->isPlayer() && isCastedAction() ) - calculateMPCost(); + m_actionCost[ 0 ] = { + static_cast< Common::ActionCostType >( action->costType ), + action->cost + }; + + calculateActionCost(); } uint32_t Sapphire::Action::Action::getId() const @@ -44,84 +47,6 @@ uint32_t Sapphire::Action::Action::getId() const return m_id; } -void Sapphire::Action::Action::calculateMPCost() -{ - auto level = m_pSource->getLevel(); - - // each level range is 1-10, 11-20, 21-30, ... therefore: - // level 50 should be in the 4th group, not the 5th - // dividing by 10 on the border will break this unless we subtract 1 - auto levelGroup = std::max< uint8_t >( level - 1, 1 ) / 10; - - float cost = m_cost; - - // thanks to andrew for helping me figure this shit out, should be pretty accurate - switch( levelGroup ) - { - // level 1-10 - case 0: - { - // r^2 = 0.9999 - cost = 0.0952f * level + 0.9467f; - break; - } - - // level 11-20 - case 1: - { - // r^2 = 1 - cost = 0.19f * level; - break; - } - - // level 21-30 - case 2: - { - // r^2 = 1 - cost = 0.38f * level - 3.8f; - break; - } - - // level 31-40 - case 3: - { - // r^2 = 1 - cost = 0.6652f * level - 12.358f; - break; - } - - // level 41-50 - case 4: - { - // r^2 = 1 - cost = 1.2352f * level - 35.159f; - break; - } - - // level 51-60 - case 5: - { - // r^2 = 1 - cost = 0.0654f * std::exp( 0.1201f * level ); - break; - } - - // level 61-70 - case 6: - { - // r^2 = 0.9998 - cost = 0.2313f * ( level * level ) - 26.98f * level + 875.21f; - break; - } - - default: - return; - } - - // m_cost is the base cost, cost is the multiplier for the current player level - m_cost = static_cast< uint16_t >( std::round( cost * m_cost ) ); -} - void Sapphire::Action::Action::subtractCostFromCaster() { if( !m_pSource->isPlayer() ) @@ -353,3 +278,99 @@ void Sapphire::Action::Action::healTarget( uint32_t amount, Entity::Chara& chara // todo: make sure that we don't add the same actor more than once m_effects[ EffectPacketIdentity::HealingEffect ].m_hitActors.emplace_back( chara.getId() ); } + +const Sapphire::Action::Action::ActionCostArray& Sapphire::Action::Action::getCostArray() const +{ + return m_actionCost; +} + +void Sapphire::Action::Action::calculateActionCost() +{ + for( uint8_t i = 0; i < m_actionCost.size(); ++i ) + { + auto& entry = m_actionCost[ i ]; + + if( entry.m_costType == ActionCostType::MagicPoints ) + calculateMPCost( i ); + } +} + +void Sapphire::Action::Action::calculateMPCost( uint8_t costArrayIndex ) +{ + auto level = m_pSource->getLevel(); + + // each level range is 1-10, 11-20, 21-30, ... therefore: + // level 50 should be in the 4th group, not the 5th + // dividing by 10 on the border will break this unless we subtract 1 + auto levelGroup = std::max< uint8_t >( level - 1, 1 ) / 10; + + auto& costEntry = m_actionCost[ costArrayIndex ]; + + float cost = costEntry.m_cost; + + // thanks to andrew for helping me figure this shit out, should be pretty accurate + switch( levelGroup ) + { + // level 1-10 + case 0: + { + // r^2 = 0.9999 + cost = 0.0952f * level + 0.9467f; + break; + } + + // level 11-20 + case 1: + { + // r^2 = 1 + cost = 0.19f * level; + break; + } + + // level 21-30 + case 2: + { + // r^2 = 1 + cost = 0.38f * level - 3.8f; + break; + } + + // level 31-40 + case 3: + { + // r^2 = 1 + cost = 0.6652f * level - 12.358f; + break; + } + + // level 41-50 + case 4: + { + // r^2 = 1 + cost = 1.2352f * level - 35.159f; + break; + } + + // level 51-60 + case 5: + { + // r^2 = 1 + cost = 0.0654f * std::exp( 0.1201f * level ); + break; + } + + // level 61-70 + case 6: + { + // r^2 = 0.9998 + cost = 0.2313f * ( level * level ) - 26.98f * level + 875.21f; + break; + } + + default: + return; + } + + // m_cost is the base cost, cost is the multiplier for the current player level + costEntry.m_cost = static_cast< uint16_t >( std::round( cost * costEntry.m_cost ) ); +} \ No newline at end of file diff --git a/src/world/Action/Action.h b/src/world/Action/Action.h index d8b57507..389c6c6b 100644 --- a/src/world/Action/Action.h +++ b/src/world/Action/Action.h @@ -18,6 +18,14 @@ namespace Sapphire::Action { public: + struct ActionCostEntry + { + Common::ActionCostType m_costType; + uint16_t m_cost; + }; + + using ActionCostArray = std::array< ActionCostEntry, 2 >; + Action(); Action( Entity::CharaPtr caster, uint32_t actionId, Data::ActionPtr action, FrameworkPtr fw ); @@ -38,6 +46,8 @@ namespace Sapphire::Action uint32_t getCastTime() const; void setCastTime( uint32_t castTime ); + const ActionCostArray& getCostArray() const; + /*! * @brief Tests whether the action is instantly usable or has a cast assoc'd with it * @return true if action has a cast time @@ -74,7 +84,8 @@ namespace Sapphire::Action protected: - void calculateMPCost(); + void calculateActionCost(); + void calculateMPCost( uint8_t costArrayIndex ); void subtractCostFromCaster(); /*! @@ -99,6 +110,8 @@ namespace Sapphire::Action Common::ActionCostType m_costType; uint16_t m_cost; + ActionCostArray m_actionCost; + uint64_t m_startTime; uint32_t m_castTime;