diff --git a/src/common/Common.h b/src/common/Common.h index cb4c1283..18ff37f2 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -931,6 +931,18 @@ namespace Sapphire::Common uint16_t cost; }; + enum LevelTableEntry : uint8_t + { + PIE, + MP, + MAIN, + SUB, + DIV, + HP, + ELMT, + THREAT + }; + using PlayerStateFlagList = std::vector< PlayerStateFlag >; } diff --git a/src/world/Action/Action.cpp b/src/world/Action/Action.cpp index b4a08918..dfadbdaf 100644 --- a/src/world/Action/Action.cpp +++ b/src/world/Action/Action.cpp @@ -5,6 +5,8 @@ #include "Framework.h" #include "Script/ScriptMgr.h" +#include + #include "Actor/Player.h" #include "Actor/BNpc.h" @@ -302,7 +304,8 @@ void Sapphire::Action::Action::calculateActionCost() } case ActionPrimaryCostType::MagicPoints: { - calculateMPCost( m_primaryCost ); + // todo: not sure if we should store the final value like this? + m_primaryCost = Math::CalcStats::calculateMpCost( *m_pSource, m_primaryCost ); break; } case ActionPrimaryCostType::TacticsPoints: @@ -325,88 +328,6 @@ void Sapphire::Action::Action::calculateActionCost() // todo: secondary cost type needs to be handled } -// todo: this shouldn't be in action and instead be in some general stat calc util -void Sapphire::Action::Action::calculateMPCost( uint16_t baseCost ) -{ - 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 = baseCost; - - // 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_primaryCost is the base cost, cost is the multiplier for the current player level - m_primaryCost = static_cast< uint16_t >( std::round( cost * baseCost ) ); - - if( auto player = m_pSource->getAsPlayer() ) - player->sendDebug( "calculated mp cost: {0}", m_primaryCost ); -} - bool Sapphire::Action::Action::precheck() { if( auto player = m_pSource->getAsPlayer() ) diff --git a/src/world/Math/CalcStats.cpp b/src/world/Math/CalcStats.cpp index c1c7bcb7..4b027efc 100644 --- a/src/world/Math/CalcStats.cpp +++ b/src/world/Math/CalcStats.cpp @@ -184,11 +184,91 @@ uint32_t CalcStats::calculateMaxMp( PlayerPtr pPlayer, Sapphire::FrameworkPtr pF return result; } +uint16_t CalcStats::calculateMpCost( const Sapphire::Entity::Chara& chara, uint16_t baseCost ) +{ + auto level = chara.getLevel(); + + // each level range is 1-10, 11-20, 21-30, ... therefore: + // level 50 should be in the 4th group, not the 5t + // dividing by 10 on the border will break this unless we subtract 1 + auto levelGroup = std::max< decltype( level ) >( level - 1, 1 ) / 10; + + float cost = baseCost; + + // thanks to andrew for helping me figure this shit out + // played with this some more and it seems to be accurate for everything i've tried + 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 0; + } + } + + return static_cast< uint16_t >( std::round( cost * baseCost ) ); +} + float CalcStats::pBlk( const Chara& chara ) { auto level = chara.getLevel(); float blockRate = static_cast< float >( chara.getBonusStat( Common::BaseParam::BlockRate ) ); - float levelVal = static_cast< float >( levelTable[ level ][ 4 ] ); + float levelVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::DIV ] ); return std::floor( ( 30 * blockRate ) / levelVal + 10 ); } @@ -201,8 +281,8 @@ float CalcStats::pDhr( const Chara& chara ) float dhRate = static_cast< float >( chara.getBonusStat( Common::BaseParam::DirectHitRate ) ) + baseStats.accuracy; - float divVal = static_cast< float >( levelTable[ level ][ 4 ] ); - float subVal = static_cast< float >( levelTable[ level ][ 3 ] ); + float divVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::DIV ] ); + float subVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::SUB ] ); return std::floor( 550.f * ( dhRate - subVal ) / divVal ) / 10.f; } @@ -215,8 +295,8 @@ float CalcStats::pChr( const Chara& chara ) float chRate = static_cast< float >( chara.getBonusStat( Common::BaseParam::CriticalHit ) ) + baseStats.critHitRate; - float divVal = static_cast< float >( levelTable[ level ][ 4 ] ); - float subVal = static_cast< float >( levelTable[ level ][ 3 ] ); + float divVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::DIV ] ); + float subVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::SUB ] ); return std::floor( 200.f * ( chRate - subVal ) / divVal + 50.f ) / 10.f; } diff --git a/src/world/Math/CalcStats.h b/src/world/Math/CalcStats.h index 29436bf9..e8c4b5f9 100644 --- a/src/world/Math/CalcStats.h +++ b/src/world/Math/CalcStats.h @@ -16,9 +16,12 @@ namespace Sapphire::Math static uint32_t calculateMaxHp( Sapphire::Entity::PlayerPtr pPlayer, FrameworkPtr pFw ); + static uint16_t calculateMpCost( const Sapphire::Entity::Chara& chara, uint16_t baseCost ); + static float pBlk( const Sapphire::Entity::Chara& ); static float pDhr( const Sapphire::Entity::Chara& ); static float pChr( const Sapphire::Entity::Chara& ); + private: };