From 9803a59673409ff62e1328da5fa0fe1b2a1c33ca Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 23 Mar 2019 11:48:49 +1100 Subject: [PATCH 1/8] minor cleanup and move mp cost calc into calcstats --- src/common/Common.h | 12 +++++ src/world/Action/Action.cpp | 87 ++-------------------------------- src/world/Math/CalcStats.cpp | 90 ++++++++++++++++++++++++++++++++++-- src/world/Math/CalcStats.h | 3 ++ 4 files changed, 104 insertions(+), 88 deletions(-) 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: }; From ce3473ae6d65a1870de4066cccde8a237a942ed2 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 23 Mar 2019 11:53:21 +1100 Subject: [PATCH 2/8] style fix, not sure how that happened --- src/world/Math/CalcStats.cpp | 14 +++++++------- src/world/Math/CalcStats.h | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/world/Math/CalcStats.cpp b/src/world/Math/CalcStats.cpp index 4b027efc..8d334234 100644 --- a/src/world/Math/CalcStats.cpp +++ b/src/world/Math/CalcStats.cpp @@ -191,7 +191,7 @@ uint16_t CalcStats::calculateMpCost( const Sapphire::Entity::Chara& chara, uint1 // 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; + auto levelGroup = std::max< uint8_t >( level - 1, 1 ) / 10; float cost = baseCost; @@ -207,7 +207,7 @@ uint16_t CalcStats::calculateMpCost( const Sapphire::Entity::Chara& chara, uint1 break; } - // level 11-20 + // level 11-20 case 1: { // r^2 = 1 @@ -215,7 +215,7 @@ uint16_t CalcStats::calculateMpCost( const Sapphire::Entity::Chara& chara, uint1 break; } - // level 21-30 + // level 21-30 case 2: { // r^2 = 1 @@ -223,7 +223,7 @@ uint16_t CalcStats::calculateMpCost( const Sapphire::Entity::Chara& chara, uint1 break; } - // level 31-40 + // level 31-40 case 3: { // r^2 = 1 @@ -231,7 +231,7 @@ uint16_t CalcStats::calculateMpCost( const Sapphire::Entity::Chara& chara, uint1 break; } - // level 41-50 + // level 41-50 case 4: { // r^2 = 1 @@ -239,7 +239,7 @@ uint16_t CalcStats::calculateMpCost( const Sapphire::Entity::Chara& chara, uint1 break; } - // level 51-60 + // level 51-60 case 5: { // r^2 = 1 @@ -247,7 +247,7 @@ uint16_t CalcStats::calculateMpCost( const Sapphire::Entity::Chara& chara, uint1 break; } - // level 61-70 + // level 61-70 case 6: { // r^2 = 0.9998 diff --git a/src/world/Math/CalcStats.h b/src/world/Math/CalcStats.h index e8c4b5f9..e49b7b14 100644 --- a/src/world/Math/CalcStats.h +++ b/src/world/Math/CalcStats.h @@ -16,10 +16,30 @@ namespace Sapphire::Math static uint32_t calculateMaxHp( Sapphire::Entity::PlayerPtr pPlayer, FrameworkPtr pFw ); + /*! + * @brief Calculates the MP cost of a spell given its base cost + * @param chara The Chara that is casting the action + * @param baseCost The action cost + * @return The total MP to be consumed by a successful cast + */ static uint16_t calculateMpCost( const Sapphire::Entity::Chara& chara, uint16_t baseCost ); + /*! + * @brief Calculates the probability of a block happening + * @return + */ static float pBlk( const Sapphire::Entity::Chara& ); + + /*! + * @brief Calculates the probability of a direct hit happening + * @return + */ static float pDhr( const Sapphire::Entity::Chara& ); + + /*! + * @brief Calculates the probability of a critical hit happening + * @return + */ static float pChr( const Sapphire::Entity::Chara& ); private: From ba5fc6781d8bd47ea1ad95bf9766c281d82a6722 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 23 Mar 2019 16:57:00 +1100 Subject: [PATCH 3/8] rename ScriptObject getFramework to framework for consistency --- src/scripts/common/GilShop.cpp | 2 +- src/scripts/common/aethernet/Aetheryte.cpp | 2 +- src/scripts/common/aethernet/HousingAethernet.cpp | 4 ++-- src/scripts/common/eobj/HousingEstateEntrance.cpp | 2 +- src/scripts/common/housing/CmnDefHousingSignboard.cpp | 2 +- src/scripts/common/warptaxi/WarpTaxi.cpp | 6 +++--- src/world/Script/NativeScriptApi.cpp | 2 +- src/world/Script/NativeScriptApi.h | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/scripts/common/GilShop.cpp b/src/scripts/common/GilShop.cpp index f3ae1a21..a57a1ecd 100644 --- a/src/scripts/common/GilShop.cpp +++ b/src/scripts/common/GilShop.cpp @@ -31,7 +31,7 @@ private: // buy if( result.param2 == 1 ) { - auto shopMgr = getFramework()->get< Sapphire::World::Manager::ShopMgr >(); + auto shopMgr = framework()->get< Sapphire::World::Manager::ShopMgr >(); shopMgr->purchaseGilShopItem( player, result.eventId, result.param3, result.param4 ); } diff --git a/src/scripts/common/aethernet/Aetheryte.cpp b/src/scripts/common/aethernet/Aetheryte.cpp index 878bd61f..2ba4f14a 100644 --- a/src/scripts/common/aethernet/Aetheryte.cpp +++ b/src/scripts/common/aethernet/Aetheryte.cpp @@ -108,7 +108,7 @@ public: void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override { - auto pExdData = getFramework()->get< Sapphire::Data::ExdDataGenerated >(); + auto pExdData = framework()->get< Sapphire::Data::ExdDataGenerated >(); if( !pExdData ) return; diff --git a/src/scripts/common/aethernet/HousingAethernet.cpp b/src/scripts/common/aethernet/HousingAethernet.cpp index 6375ea5b..1e49410b 100644 --- a/src/scripts/common/aethernet/HousingAethernet.cpp +++ b/src/scripts/common/aethernet/HousingAethernet.cpp @@ -21,7 +21,7 @@ public: { player.playScene( eventId, 0, HIDE_HOTBAR | NO_DEFAULT_CAMERA, [this, eventId]( Entity::Player& player, const Event::SceneResult& result ) { - auto pExdData = getFramework()->get< Sapphire::Data::ExdDataGenerated >(); + auto pExdData = framework()->get< Sapphire::Data::ExdDataGenerated >(); if( !pExdData ) return; @@ -42,7 +42,7 @@ public: // moving a player inside an event will crash the game so we end it hre player.eventFinish( eventId, 1 ); - auto playerMgr = getFramework()->get< Sapphire::World::Manager::PlayerMgr >(); + auto playerMgr = framework()->get< Sapphire::World::Manager::PlayerMgr >(); playerMgr->movePlayerToLandDestination( player, pHousingAethernet->level, housingZone->getWardNum() ); } ); } diff --git a/src/scripts/common/eobj/HousingEstateEntrance.cpp b/src/scripts/common/eobj/HousingEstateEntrance.cpp index f2e6856d..0c7733de 100644 --- a/src/scripts/common/eobj/HousingEstateEntrance.cpp +++ b/src/scripts/common/eobj/HousingEstateEntrance.cpp @@ -26,7 +26,7 @@ public: if( result.param2 != 1 ) return; - auto terriMgr = getFramework()->get< Sapphire::World::Manager::TerritoryMgr >(); + auto terriMgr = framework()->get< Sapphire::World::Manager::TerritoryMgr >(); if( !terriMgr ) return; diff --git a/src/scripts/common/housing/CmnDefHousingSignboard.cpp b/src/scripts/common/housing/CmnDefHousingSignboard.cpp index 8fed872e..941ebec7 100644 --- a/src/scripts/common/housing/CmnDefHousingSignboard.cpp +++ b/src/scripts/common/housing/CmnDefHousingSignboard.cpp @@ -26,7 +26,7 @@ public: { auto callback = [ this ]( Entity::Player& player, const Event::SceneResult& result ) { - auto pFw = getFramework(); + auto pFw = framework(); if( !pFw ) return LandPurchaseResult::ERR_INTERNAL; // Purchase Land diff --git a/src/scripts/common/warptaxi/WarpTaxi.cpp b/src/scripts/common/warptaxi/WarpTaxi.cpp index 4c772565..e867cb12 100644 --- a/src/scripts/common/warptaxi/WarpTaxi.cpp +++ b/src/scripts/common/warptaxi/WarpTaxi.cpp @@ -27,12 +27,12 @@ public: player.eventFinish( 1310721, 0 ); player.eventFinish( getId(), 1 ); - auto exdData = getFramework()->get< Sapphire::Data::ExdDataGenerated >(); + auto exdData = framework()->get< Sapphire::Data::ExdDataGenerated >(); auto warp = exdData->get< Sapphire::Data::Warp >( getId() ); if( !warp ) return; - auto playerMgr = getFramework()->get< Sapphire::World::Manager::PlayerMgr >(); + auto playerMgr = framework()->get< Sapphire::World::Manager::PlayerMgr >(); playerMgr->movePlayerToLandDestination( player, warp->level, result.param3 ); } else @@ -56,7 +56,7 @@ public: void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override { - auto exdData = getFramework()->get< Sapphire::Data::ExdDataGenerated >(); + auto exdData = framework()->get< Sapphire::Data::ExdDataGenerated >(); if( !exdData ) return; diff --git a/src/world/Script/NativeScriptApi.cpp b/src/world/Script/NativeScriptApi.cpp index 4b45a333..6069c011 100644 --- a/src/world/Script/NativeScriptApi.cpp +++ b/src/world/Script/NativeScriptApi.cpp @@ -37,7 +37,7 @@ namespace Sapphire::ScriptAPI m_framework = fw; } - Sapphire::Framework* ScriptObject::getFramework() const + Sapphire::Framework* ScriptObject::framework() const { return m_framework; } diff --git a/src/world/Script/NativeScriptApi.h b/src/world/Script/NativeScriptApi.h index 9b2fdb6f..c534590e 100644 --- a/src/world/Script/NativeScriptApi.h +++ b/src/world/Script/NativeScriptApi.h @@ -61,7 +61,7 @@ namespace Sapphire::ScriptAPI * * @return A pointer to Core::Framework */ - virtual Sapphire::Framework* getFramework() const; + virtual Sapphire::Framework* framework() const; }; From 5802c813fe902e306aa1f2f4fb20fc2934cd16b4 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 23 Mar 2019 17:02:47 +1100 Subject: [PATCH 4/8] more naming and style consistency in ScriptAPI --- src/world/Script/NativeScriptApi.cpp | 8 ++++---- src/world/Script/NativeScriptApi.h | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/world/Script/NativeScriptApi.cpp b/src/world/Script/NativeScriptApi.cpp index 6069c011..3eeb5912 100644 --- a/src/world/Script/NativeScriptApi.cpp +++ b/src/world/Script/NativeScriptApi.cpp @@ -102,8 +102,8 @@ namespace Sapphire::ScriptAPI /////////////////////////////////////////////////////////////////// - EventScript::EventScript( uint32_t questId ) : - ScriptObject( questId, typeid( EventScript ).hash_code() ) + EventScript::EventScript( uint32_t eventId ) : + ScriptObject( eventId, typeid( EventScript ).hash_code() ) { } @@ -131,8 +131,8 @@ namespace Sapphire::ScriptAPI { } - void - EventScript::onEventItem( Entity::Player& player, uint32_t eventItemId, uint32_t eventId, uint32_t castTime, uint64_t targetId ) + void EventScript::onEventItem( Entity::Player& player, uint32_t eventItemId, uint32_t eventId, uint32_t castTime, + uint64_t targetId ) { } diff --git a/src/world/Script/NativeScriptApi.h b/src/world/Script/NativeScriptApi.h index c534590e..49fa1288 100644 --- a/src/world/Script/NativeScriptApi.h +++ b/src/world/Script/NativeScriptApi.h @@ -161,7 +161,7 @@ namespace Sapphire::ScriptAPI } public: - explicit EventScript( uint32_t questId ); + explicit EventScript( uint32_t eventId ); virtual void onTalk( uint32_t eventId, Sapphire::Entity::Player& player, uint64_t actorId ); @@ -171,12 +171,12 @@ namespace Sapphire::ScriptAPI virtual void onEnterTerritory( Sapphire::Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2 ); - virtual void onWithinRange( Sapphire::Entity::Player& player, uint32_t eventId, uint32_t param1, float x, float y, float z ); + virtual void onWithinRange( Sapphire::Entity::Player& player, uint32_t eventId, uint32_t param1,float x, float y, float z ); virtual void onOutsideRange( Sapphire::Entity::Player& player, uint32_t eventId, uint32_t param1, float x, float y, float z ); - virtual void - onEventItem( Sapphire::Entity::Player& player, uint32_t eventItemId, uint32_t eventId, uint32_t castTime, uint64_t targetId ); + virtual void onEventItem( Sapphire::Entity::Player& player, uint32_t eventItemId, uint32_t eventId, uint32_t castTime, + uint64_t targetId ); virtual void onEventHandlerTradeReturn( Sapphire::Entity::Player& player, uint32_t eventId, uint16_t subEvent, uint16_t param, uint32_t catalogId ); @@ -228,7 +228,7 @@ namespace Sapphire::ScriptAPI virtual void onUpdate( Sapphire::InstanceContent& instance, uint32_t currTime ); virtual void onEnterTerritory( Sapphire::InstanceContent& instance, Sapphire::Entity::Player& player, uint32_t eventId, - uint16_t param1, uint16_t param2 ); + uint16_t param1, uint16_t param2 ); }; } From 789b5dfd9ef2788e6c5867d53177689eb909b65e Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 23 Mar 2019 20:59:41 +1100 Subject: [PATCH 5/8] add rudimentary action comboing, doesn't highlight actions on the hotbar --- .../action/darkknight/ActionHardSlash3617.cpp | 22 ++++++++++++++++ .../darkknight/ActionPowerSlash3627.cpp | 22 ++++++++++++++++ .../darkknight/ActionSpinningSlash3619.cpp | 22 ++++++++++++++++ .../darkknight/ActionSyphonStrike3623.cpp | 22 ++++++++++++++++ src/world/Action/Action.cpp | 26 +++++++++++++++++++ src/world/Action/Action.h | 2 ++ src/world/Actor/Chara.cpp | 10 +++++++ src/world/Actor/Chara.h | 5 ++++ 8 files changed, 131 insertions(+) create mode 100644 src/scripts/action/darkknight/ActionHardSlash3617.cpp create mode 100644 src/scripts/action/darkknight/ActionPowerSlash3627.cpp create mode 100644 src/scripts/action/darkknight/ActionSpinningSlash3619.cpp create mode 100644 src/scripts/action/darkknight/ActionSyphonStrike3623.cpp diff --git a/src/scripts/action/darkknight/ActionHardSlash3617.cpp b/src/scripts/action/darkknight/ActionHardSlash3617.cpp new file mode 100644 index 00000000..6b582c04 --- /dev/null +++ b/src/scripts/action/darkknight/ActionHardSlash3617.cpp @@ -0,0 +1,22 @@ +#include