From aee78a21e5eeacdfbecccde5d76a202530458583 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sun, 24 Mar 2019 14:25:00 +1100 Subject: [PATCH] add a bunch of stat calc functions in --- src/world/Math/CalcStats.cpp | 132 ++++++++++++++++++++++++++++++++--- src/world/Math/CalcStats.h | 81 ++++++++++++++++++++- 2 files changed, 201 insertions(+), 12 deletions(-) diff --git a/src/world/Math/CalcStats.cpp b/src/world/Math/CalcStats.cpp index 3d26dd3f..3e51ae26 100644 --- a/src/world/Math/CalcStats.cpp +++ b/src/world/Math/CalcStats.cpp @@ -265,16 +265,16 @@ uint16_t CalcStats::calculateMpCost( const Sapphire::Entity::Chara& chara, uint1 return static_cast< uint16_t >( std::round( cost * baseCost ) ); } -float CalcStats::pBlk( const Chara& chara ) +float CalcStats::blockProbability( const Chara& chara ) { auto level = chara.getLevel(); - float blockRate = static_cast< float >( chara.getBonusStat( Common::BaseParam::BlockRate ) ); - float levelVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::DIV ] ); + auto blockRate = static_cast< float >( chara.getBonusStat( Common::BaseParam::BlockRate ) ); + auto levelVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::DIV ] ); return std::floor( ( 30 * blockRate ) / levelVal + 10 ); } -float CalcStats::pDhr( const Chara& chara ) +float CalcStats::directHitProbability( const Chara& chara ) { const auto& baseStats = chara.getStats(); auto level = chara.getLevel(); @@ -282,13 +282,13 @@ 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 ][ Common::LevelTableEntry::DIV ] ); - float subVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::SUB ] ); + auto divVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::DIV ] ); + auto subVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::SUB ] ); return std::floor( 550.f * ( dhRate - subVal ) / divVal ) / 10.f; } -float CalcStats::pChr( const Chara& chara ) +float CalcStats::criticalHitProbability( const Chara& chara ) { const auto& baseStats = chara.getStats(); auto level = chara.getLevel(); @@ -296,8 +296,122 @@ 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 ][ Common::LevelTableEntry::DIV ] ); - float subVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::SUB ] ); + auto divVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::DIV ] ); + auto subVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::SUB ] ); return std::floor( 200.f * ( chRate - subVal ) / divVal + 50.f ) / 10.f; } + + +float CalcStats::potency( uint16_t potency ) +{ + return potency / 100.f; +} + +float CalcStats::weaponDamage( const Sapphire::Entity::Chara& chara, float weaponDamage, bool isMagicDamage ) +{ + const auto& baseStats = chara.getStats(); + auto level = chara.getLevel(); + + auto mainVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::MAIN ] ); + + float jobAttribute = 1.f; +} + +// todo: this is all retarded, needs to be per weapon and etcetc +//uint32_t CalcStats::getPrimaryClassJobAttribute( const Sapphire::Entity::Chara& chara ) +//{ +// +//} + +float CalcStats::calcAttackPower( uint32_t attackPower ) +{ + return std::floor( ( 125.f * ( attackPower - 292.f ) / 292.f ) + 100.f ) / 100.f; +} + +float CalcStats::magicAttackPower( const Sapphire::Entity::Chara& chara ) +{ + const auto& baseStats = chara.getStats(); + + return calcAttackPower( baseStats.attackPotMagic ); +} + +float CalcStats::healingMagicPower( const Sapphire::Entity::Chara& chara ) +{ + const auto& baseStats = chara.getStats(); + + return calcAttackPower( baseStats.healingPotMagic ); +} + +float CalcStats::attackPower( const Sapphire::Entity::Chara& chara ) +{ + const auto& baseStats = chara.getStats(); + + return calcAttackPower( baseStats.attack ); +} + +float CalcStats::determination( const Sapphire::Entity::Chara& chara ) +{ + auto level = chara.getLevel(); + const auto& baseStats = chara.getStats(); + + auto mainVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::MAIN ] ); + auto divVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::DIV ] ); + + return std::floor( 130.f * ( baseStats.determination - mainVal ) / divVal + 1000.f ) / 1000.f; +} + +float CalcStats::tenacity( const Sapphire::Entity::Chara& chara ) +{ + auto level = chara.getLevel(); + const auto& baseStats = chara.getStats(); + + auto subVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::SUB ] ); + auto divVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::DIV ] ); + + return std::floor( 100.f * ( baseStats.tenacity - subVal ) / divVal + 1000.f ) / 1000.f; +} + +float CalcStats::speed( const Sapphire::Entity::Chara& chara ) +{ + auto level = chara.getLevel(); + const auto& baseStats = chara.getStats(); + + auto subVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::SUB ] ); + auto divVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::DIV ] ); + + uint32_t speedVal = 0; + + // check whether we use spellspeed or skillspeed + // todo: this is kinda shitty though + switch( chara.getClass() ) + { + case Common::ClassJob::Arcanist: + case Common::ClassJob::Astrologian: + case Common::ClassJob::Whitemage: + case Common::ClassJob::Redmage: + case Common::ClassJob::Bluemage: + case Common::ClassJob::Blackmage: + case Common::ClassJob::Summoner: + case Common::ClassJob::Scholar: + case Common::ClassJob::Thaumaturge: + speedVal = baseStats.spellSpeed; + break; + + default: + speedVal = baseStats.skillSpeed; + } + + return std::floor( 130.f * ( speedVal - subVal ) / divVal + 1000.f ) / 1000.f; +} + +float CalcStats::criticalHitBonus( const Sapphire::Entity::Chara& chara ) +{ + auto level = chara.getLevel(); + const auto& baseStats = chara.getStats(); + + auto subVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::SUB ] ); + auto divVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::DIV ] ); + + return std::floor( 200.f * ( baseStats.critHitRate - subVal ) / divVal + 1400.f ) / 1000.f; +} \ No newline at end of file diff --git a/src/world/Math/CalcStats.h b/src/world/Math/CalcStats.h index e49b7b14..a7078f6c 100644 --- a/src/world/Math/CalcStats.h +++ b/src/world/Math/CalcStats.h @@ -28,22 +28,97 @@ namespace Sapphire::Math * @brief Calculates the probability of a block happening * @return */ - static float pBlk( const Sapphire::Entity::Chara& ); + static float blockProbability( const Sapphire::Entity::Chara& chara ); /*! * @brief Calculates the probability of a direct hit happening * @return */ - static float pDhr( const Sapphire::Entity::Chara& ); + static float directHitProbability( const Sapphire::Entity::Chara& chara ); /*! * @brief Calculates the probability of a critical hit happening * @return */ - static float pChr( const Sapphire::Entity::Chara& ); + static float criticalHitProbability( const Sapphire::Entity::Chara& chara ); + + /*! + * @brief Calculates the contribution of potency to damage output. + * @param potency The action potency + * @return + */ + static float potency( uint16_t potency ); + + /*! + * @brief Weapon damage is the contribution the weapon's damage rating + * @param chara The source/casting character. + * @param weaponDamage the weapons physical or magic damage + * @param isMagicDamage true if the damage is magical, otherwise it's treated as physical damage + * @return + */ + static float weaponDamage( const Sapphire::Entity::Chara& chara, float weaponDamage, bool isMagicDamage ); + + /*! + * @brief Calculates the contribution of physical attack power to damage dealt + * @param chara The source/casting character. + * @return + */ + static float attackPower( const Sapphire::Entity::Chara& chara ); + + /*! + * @brief Calculates the contribution of magical attack power to damage dealt + * @param chara The source/casting character. + * @return + */ + static float magicAttackPower( const Sapphire::Entity::Chara& chara ); + + /*! + * @brief Calculates the contribution of healing magic power to healing dealt + * @param chara The source/casting character. + * @return + */ + static float healingMagicPower( const Sapphire::Entity::Chara& chara ); + + /*! + * @brief Calculates determinations contribution to damage and healing output. + * @param chara The source/casting character. + * @return Returns a rational number rounded to 3 decimal places. + */ + static float determination( const Sapphire::Entity::Chara& chara ); + + /*! + * @brief Calculates the tenacity contribution to damage, mitigation and healing. + * @param chara The source/casting character. + * @return Returns a rational number rounded to 3 decimal places. + */ + static float tenacity( const Sapphire::Entity::Chara& chara ); + + /*! + * @brief Calculates the bonus granted by either spell speed or skill speed depending on the casters classjob. + * @param chara The source/casting character. + * @return + */ + static float speed( const Sapphire::Entity::Chara& chara ); + + /*! + * @brief Calculates the amount of bonus damaged applied on a critical hit + * @param chara + * @return + */ + static float criticalHitBonus( const Sapphire::Entity::Chara& chara ); + + static float physicalDefense( const Sapphire::Entity::Chara& chara ); + + static float magicDefense( const Sapphire::Entity::Chara& chara ); + + static float blockStrength( const Sapphire::Entity::Chara& chara ); private: + static uint32_t getPrimaryClassJobAttribute( const Sapphire::Entity::Chara& chara ); + + static float calcAttackPower( uint32_t attackPower ); + }; }