From edef711afb19dd5404e5f0666f685d5362232d73 Mon Sep 17 00:00:00 2001 From: Maru Date: Sat, 19 Aug 2017 16:50:50 -0300 Subject: [PATCH 1/4] Weapon Damage property; Auto-attack for magical weapons; --- .../chai/skill/{ => cnj}/skillDef_119.chai | 2 +- .../chai/skill/{ => cnj}/skillDef_120.chai | 6 +++--- .../chai/skill/{ => cnj}/skillDef_121.chai | 4 ++-- .../chai/skill/{ => cnj}/skillDef_127.chai | 6 +++--- bin/scripts/chai/skill/cnj/skillDef_128.chai | 18 ++++++++++++++++++ bin/scripts/chai/skill/pgl/skillDef_53.chai | 18 ++++++++++++++++++ bin/scripts/chai/skill/skillDef_6.chai | 4 ++-- src/servers/Server_Common/Exd/ExdData.cpp | 1 + src/servers/Server_Common/Exd/ExdData.h | 3 ++- src/servers/Server_Zone/Actor/Player.cpp | 2 +- src/servers/Server_Zone/Inventory/Item.cpp | 14 +++++++++++++- src/servers/Server_Zone/Inventory/Item.h | 6 ++++++ 12 files changed, 70 insertions(+), 14 deletions(-) rename bin/scripts/chai/skill/{ => cnj}/skillDef_119.chai (73%) rename bin/scripts/chai/skill/{ => cnj}/skillDef_120.chai (60%) rename bin/scripts/chai/skill/{ => cnj}/skillDef_121.chai (88%) rename bin/scripts/chai/skill/{ => cnj}/skillDef_127.chai (58%) create mode 100644 bin/scripts/chai/skill/cnj/skillDef_128.chai create mode 100644 bin/scripts/chai/skill/pgl/skillDef_53.chai diff --git a/bin/scripts/chai/skill/skillDef_119.chai b/bin/scripts/chai/skill/cnj/skillDef_119.chai similarity index 73% rename from bin/scripts/chai/skill/skillDef_119.chai rename to bin/scripts/chai/skill/cnj/skillDef_119.chai index dcf945b2..2c25a2df 100644 --- a/bin/scripts/chai/skill/skillDef_119.chai +++ b/bin/scripts/chai/skill/cnj/skillDef_119.chai @@ -10,7 +10,7 @@ class skillDef_119Def def onFinish( player, target ) { - player.handleScriptSkill( STD_DAMAGE, 119, 30, 0, target ); + player.handleScriptSkill( STD_DAMAGE, 119, 140, 0, target ); } }; diff --git a/bin/scripts/chai/skill/skillDef_120.chai b/bin/scripts/chai/skill/cnj/skillDef_120.chai similarity index 60% rename from bin/scripts/chai/skill/skillDef_120.chai rename to bin/scripts/chai/skill/cnj/skillDef_120.chai index 8966d095..ec78e907 100644 --- a/bin/scripts/chai/skill/skillDef_120.chai +++ b/bin/scripts/chai/skill/cnj/skillDef_120.chai @@ -1,5 +1,5 @@ -// Skill Name: Sprint -// Skill ID: 3 +// Skill Name: Cure +// Skill ID: 120 class skillDef_120Def { @@ -10,7 +10,7 @@ class skillDef_120Def def onFinish( player, target ) { - player.handleScriptSkill( STD_HEAL, 120, 1000, 0, target ); + player.handleScriptSkill( STD_HEAL, 120, 450, 0, target ); } }; diff --git a/bin/scripts/chai/skill/skillDef_121.chai b/bin/scripts/chai/skill/cnj/skillDef_121.chai similarity index 88% rename from bin/scripts/chai/skill/skillDef_121.chai rename to bin/scripts/chai/skill/cnj/skillDef_121.chai index 8fb8dd3d..a3d56093 100644 --- a/bin/scripts/chai/skill/skillDef_121.chai +++ b/bin/scripts/chai/skill/cnj/skillDef_121.chai @@ -1,5 +1,5 @@ -// Skill Name: Sprint -// Skill ID: 3 +// Skill Name: Aero +// Skill ID: 121 class skillDef_121Def { diff --git a/bin/scripts/chai/skill/skillDef_127.chai b/bin/scripts/chai/skill/cnj/skillDef_127.chai similarity index 58% rename from bin/scripts/chai/skill/skillDef_127.chai rename to bin/scripts/chai/skill/cnj/skillDef_127.chai index 7317c106..88baf71d 100644 --- a/bin/scripts/chai/skill/skillDef_127.chai +++ b/bin/scripts/chai/skill/cnj/skillDef_127.chai @@ -1,5 +1,5 @@ -// Skill Name: Sprint -// Skill ID: 3 +// Skill Name: Stone II +// Skill ID: 127 class skillDef_127Def { @@ -10,7 +10,7 @@ class skillDef_127Def def onFinish( player, target ) { - player.handleScriptSkill( STD_DAMAGE, 127, 1000, 0, target ); + player.handleScriptSkill( STD_DAMAGE, 127, 200, 0, target ); } }; diff --git a/bin/scripts/chai/skill/cnj/skillDef_128.chai b/bin/scripts/chai/skill/cnj/skillDef_128.chai new file mode 100644 index 00000000..74b58e85 --- /dev/null +++ b/bin/scripts/chai/skill/cnj/skillDef_128.chai @@ -0,0 +1,18 @@ +// Skill Name: Repose +// Skill ID: 128 + +class skillDef_128Def +{ + def skillDef_128Def() + { + + } + + def onFinish( player, target ) + { + target.addStatusEffectByIdIfNotExist(3, 30000, 0); + } + +}; + +GLOBAL skillDef_128 = skillDef_128Def(); diff --git a/bin/scripts/chai/skill/pgl/skillDef_53.chai b/bin/scripts/chai/skill/pgl/skillDef_53.chai new file mode 100644 index 00000000..0ebbb980 --- /dev/null +++ b/bin/scripts/chai/skill/pgl/skillDef_53.chai @@ -0,0 +1,18 @@ +// Skill Name: Bootshine +// Skill ID: 53 + +class skillDef_53Def +{ + def skillDef_53Def() + { + + } + + def onFinish( player, target ) + { + player.handleScriptSkill( STD_DAMAGE, 53, 140, 0, target ); + } + +}; + +GLOBAL skillDef_53 = skillDef_53Def(); diff --git a/bin/scripts/chai/skill/skillDef_6.chai b/bin/scripts/chai/skill/skillDef_6.chai index 4f39b99b..8c5c61a1 100644 --- a/bin/scripts/chai/skill/skillDef_6.chai +++ b/bin/scripts/chai/skill/skillDef_6.chai @@ -1,5 +1,5 @@ -// Skill Name: Sprint -// Skill ID: 3 +// Skill Name: Return +// Skill ID: 6 class skillDef_6Def { diff --git a/src/servers/Server_Common/Exd/ExdData.cpp b/src/servers/Server_Common/Exd/ExdData.cpp index 965f1cc8..7004089d 100644 --- a/src/servers/Server_Common/Exd/ExdData.cpp +++ b/src/servers/Server_Common/Exd/ExdData.cpp @@ -426,6 +426,7 @@ boost::shared_ptr< Core::Data::ItemInfo > info->model_primary = getField< uint64_t >( row, 45 ); info->model_secondary = getField< uint64_t >( row, 46 ); info->physical_damage = getField< uint16_t >( row, 49 ); + info->magical_damage = getField< uint16_t >( row, 50 ); info->delayMs = getField< uint16_t >( row, 51 ); info->is_unique = getField< int16_t >( row, 64 ) != 0 ? true : false; info->is_untradeable = getField< uint8_t >( row, 65 ) != 0 ? true : false; diff --git a/src/servers/Server_Common/Exd/ExdData.h b/src/servers/Server_Common/Exd/ExdData.h index 4ae67281..11103c87 100644 --- a/src/servers/Server_Common/Exd/ExdData.h +++ b/src/servers/Server_Common/Exd/ExdData.h @@ -211,8 +211,9 @@ namespace Core { uint64_t model_primary; //28 uint64_t model_secondary; //29 uint16_t physical_damage; //49 + uint16_t magical_damage; //50 + uint16_t delayMs; //51 uint32_t class_job_requirement; //58 - uint16_t delayMs; //59 bool is_unique; //72 bool is_untradeable; //73 uint32_t class_job_index; //86 diff --git a/src/servers/Server_Zone/Actor/Player.cpp b/src/servers/Server_Zone/Actor/Player.cpp index f5b65b49..a1f28e38 100644 --- a/src/servers/Server_Zone/Actor/Player.cpp +++ b/src/servers/Server_Zone/Actor/Player.cpp @@ -1462,7 +1462,7 @@ void Core::Entity::Player::autoAttack( ActorPtr pTarget ) //uint64_t tick = Util::getTimeMs(); //srand(static_cast< uint32_t >(tick)); - uint32_t damage = mainWeap->getAutoAttackDmg() + rand() % 12; + uint32_t damage = mainWeap->getAutoAttackDmg(); uint32_t variation = 0 + rand() % 3; if( getClass() == 5 || getClass() == 23 || getClass() == 31 ) diff --git a/src/servers/Server_Zone/Inventory/Item.cpp b/src/servers/Server_Zone/Inventory/Item.cpp index 8c165493..7de51628 100644 --- a/src/servers/Server_Zone/Inventory/Item.cpp +++ b/src/servers/Server_Zone/Inventory/Item.cpp @@ -27,7 +27,9 @@ Core::Item::Item( uint64_t uId, uint32_t catalogId, uint64_t model1, uint64_t mo auto itemInfo = g_exdData.getItemInfo( catalogId ); m_delayMs = itemInfo->delayMs; m_physicalDmg = itemInfo->physical_damage; - m_autoAttackDmg = float( m_physicalDmg * m_delayMs ) / 3000; + m_magicalDmg = itemInfo->magical_damage; + m_weaponDmg = ( m_physicalDmg != 0 ) ? m_physicalDmg : m_magicalDmg; + m_autoAttackDmg = static_cast< float >( m_weaponDmg * m_delayMs ) / 3000; } Core::Item::~Item() @@ -50,6 +52,16 @@ uint16_t Core::Item::getPhysicalDmg() const return m_physicalDmg; } +uint16_t Core::Item::getMagicalDmg() const +{ + return m_magicalDmg; +} + +uint16_t Core::Item::getWeaponDmg() const +{ + return m_weaponDmg; +} + uint32_t Core::Item::getId() const { return m_id; diff --git a/src/servers/Server_Zone/Inventory/Item.h b/src/servers/Server_Zone/Inventory/Item.h index f082ca0e..8c0c7310 100644 --- a/src/servers/Server_Zone/Inventory/Item.h +++ b/src/servers/Server_Zone/Inventory/Item.h @@ -44,6 +44,10 @@ public: uint16_t getPhysicalDmg() const; + uint16_t getMagicalDmg() const; + + uint16_t getWeaponDmg() const; + float getAutoAttackDmg() const; @@ -64,6 +68,8 @@ protected: uint16_t m_delayMs; uint16_t m_physicalDmg; + uint16_t m_magicalDmg; + uint16_t m_weaponDmg; float m_autoAttackDmg; }; From 71309e3be79b11e7669febe96871f2113eaaa761 Mon Sep 17 00:00:00 2001 From: Maru Date: Sun, 20 Aug 2017 02:46:06 -0300 Subject: [PATCH 2/4] Cast interrupting; Skeleton of battle calculation stuff; --- src/servers/Server_Common/Common.h | 14 ++--- src/servers/Server_Common/Exd/ExdData.cpp | 2 +- src/servers/Server_Zone/Actor/CalcBattle.cpp | 60 +++++++++++++++++++ src/servers/Server_Zone/Actor/CalcBattle.h | 24 ++++++++ src/servers/Server_Zone/Actor/Player.cpp | 12 +++- .../Server_Zone/Actor/PlayerInventory.cpp | 4 +- .../Network/Handlers/ActionHandler.cpp | 6 +- 7 files changed, 108 insertions(+), 14 deletions(-) create mode 100644 src/servers/Server_Zone/Actor/CalcBattle.cpp create mode 100644 src/servers/Server_Zone/Actor/CalcBattle.h diff --git a/src/servers/Server_Common/Common.h b/src/servers/Server_Common/Common.h index d5f6ff50..e0d96326 100644 --- a/src/servers/Server_Common/Common.h +++ b/src/servers/Server_Common/Common.h @@ -253,16 +253,16 @@ namespace Core { JOB_WARRIOR = 21, // warrior JOB_DRAGON = 22, // dragoon JOB_BARD = 23, // bard - JOB_WHITE = 24, // white mage - JOB_BLACK = 25, // black mage + JOB_WHITEMAGE = 24, // white mage + JOB_BLACKMAGE = 25, // black mage CLASS_ARCANIST = 26, // arcanist JOB_SUMMONER = 27, // summoner JOB_SCHOLAR = 28, // scholar - CLASS_ROGUE = 29, - JOB_NINJA = 30, - JOB_MACHINIST = 31, // machinist - JOB_DARKKNIGHT = 32, // darknight - JOB_ASTROLOGIAN = 33, // astro + CLASS_ROGUE = 29, // rogue + JOB_NINJA = 30, // ninja + JOB_MACHINIST = 31, // machinist + JOB_DARKKNIGHT = 32, // darknight + JOB_ASTROLOGIAN = 33, // astro JOB_SAMURAI = 34, // sam JOB_REDMAGE = 35, // red mage diff --git a/src/servers/Server_Common/Exd/ExdData.cpp b/src/servers/Server_Common/Exd/ExdData.cpp index 7004089d..738039f5 100644 --- a/src/servers/Server_Common/Exd/ExdData.cpp +++ b/src/servers/Server_Common/Exd/ExdData.cpp @@ -239,8 +239,8 @@ bool Core::Data::ExdData::loadParamGrowInfo() info.piety_scalar = getField< uint16_t >( fields, 3 ); // 3 info.mp_const = getField< int32_t >( fields, 4 ); // 4 info.base_secondary = getField< int32_t >( fields, 5 );// 5 - info.hp_mod = getField< uint16_t >( fields, 8 ); // 8 info.quest_exp_mod = getField< uint8_t >( fields, 7 ); // 7 + info.hp_mod = getField< uint16_t >(fields, 8); // 8 m_paramGrowthInfoMap[id] = info; diff --git a/src/servers/Server_Zone/Actor/CalcBattle.cpp b/src/servers/Server_Zone/Actor/CalcBattle.cpp new file mode 100644 index 00000000..cebdabb1 --- /dev/null +++ b/src/servers/Server_Zone/Actor/CalcBattle.cpp @@ -0,0 +1,60 @@ +#include "CalcBattle.h" + +#include + +#include "Actor.h" +#include "Player.h" + +using namespace Core::Entity; + +extern Core::Data::ExdData g_exdData; + +/* + Class used for battle-related formulas and calculatio ns. + Big thanks to the Theoryjerks group! + + NOTE: + Formulas here shouldn't be considered final. It's possible that the formula it was based on is correct but + wasn't implemented correctly here, or approximated things due to limited knowledge of how things work in retail. + It's also possible that we're using formulas that were correct for previous patches, but not the current version. + + TODO: + + Vitality HP modifier. I can only find values for levels 50~70. + HP calculation. Not a lot limiting us here. It should be next. + Damage outgoing calculations. This includes auto-attacks, etc. + Stats. Will need to align stats from retail with what we have. + +*/ + +uint32_t Core::Entity::CalcBattle::measureHp( ActorPtr pActor ) +{ + // todo: reduce autos here + + PlayerPtr pPlayer = pActor->getAsPlayer(); + + auto classInfoIt = g_exdData.m_classJobInfoMap.find( pPlayer->getClass() ); + auto paramGrowthInfoIt = g_exdData.m_paramGrowthInfoMap.find( pPlayer->getLevel() ); + + return 10; +} + +uint32_t Core::Entity::CalcBattle::measureHeal( ActorPtr pActor, uint32_t potency ) +{ + // todo: reduce autos here + + PlayerPtr pPlayer = pActor->getAsPlayer(); + + auto classInfoIt = g_exdData.m_classJobInfoMap.find( pPlayer->getClass() ); + auto paramGrowthInfoIt = g_exdData.m_paramGrowthInfoMap.find( pPlayer->getLevel() ); + + if (classInfoIt == g_exdData.m_classJobInfoMap.end() || + paramGrowthInfoIt == g_exdData.m_paramGrowthInfoMap.end()) + return 0; + + + auto jobModVal = classInfoIt->second; + + // consider 3% variation + return potency / 10; +} \ No newline at end of file diff --git a/src/servers/Server_Zone/Actor/CalcBattle.h b/src/servers/Server_Zone/Actor/CalcBattle.h new file mode 100644 index 00000000..8e91a5d5 --- /dev/null +++ b/src/servers/Server_Zone/Actor/CalcBattle.h @@ -0,0 +1,24 @@ +#ifndef _CALCBATTLE_H +#define _CALCBATTLE_H + +#include +#include "Actor.h" + +namespace Core { +namespace Entity { + + class CalcBattle + { + public: + + static uint32_t measureHp( ActorPtr Player ); + static uint32_t measureHeal( ActorPtr Player, uint32_t potency ); + + private: + + }; + +} +} + +#endif \ No newline at end of file diff --git a/src/servers/Server_Zone/Actor/Player.cpp b/src/servers/Server_Zone/Actor/Player.cpp index a1f28e38..1f92296c 100644 --- a/src/servers/Server_Zone/Actor/Player.cpp +++ b/src/servers/Server_Zone/Actor/Player.cpp @@ -44,6 +44,7 @@ #include "src/servers/Server_Zone/Action/EventAction.h" #include "src/servers/Server_Zone/Action/EventItemAction.h" #include "src/servers/Server_Zone/Zone/ZonePosition.h" +#include "src/servers/Server_Zone/Actor/CalcBattle.h" #include extern Core::Logger g_log; @@ -1465,7 +1466,9 @@ void Core::Entity::Player::autoAttack( ActorPtr pTarget ) uint32_t damage = mainWeap->getAutoAttackDmg(); uint32_t variation = 0 + rand() % 3; - if( getClass() == 5 || getClass() == 23 || getClass() == 31 ) + if (getClass() == JOB_MACHINIST || + getClass() == JOB_BARD || + getClass() == CLASS_ARCHER) { GamePacketNew< FFXIVIpcEffect > effectPacket(getId()); effectPacket.data().targetId = pTarget->getId(); @@ -1544,7 +1547,10 @@ void Core::Entity::Player::handleScriptSkill( uint32_t type, uint32_t actionId, case Core::Common::HandleSkillType::StdHeal: { + uint32_t calculatedHeal = CalcBattle::measureHeal( shared_from_this(), param1 ); + sendDebug( "STD_HEAL" ); + GamePacketNew< FFXIVIpcEffect > effectPacket( getId() ); effectPacket.data().targetId = pTarget.getId(); effectPacket.data().actionAnimationId = actionId; @@ -1554,14 +1560,14 @@ void Core::Entity::Player::handleScriptSkill( uint32_t type, uint32_t actionId, effectPacket.data().numEffects = 1; effectPacket.data().rotation = Math::Util::floatToUInt16Rot( getRotation() ); effectPacket.data().effectTarget = pTarget.getId(); - effectPacket.data().effects[0].param1 = param1; + effectPacket.data().effects[0].param1 = calculatedHeal; effectPacket.data().effects[0].unknown_1 = 4; effectPacket.data().effects[0].unknown_2 = 1; effectPacket.data().effects[0].unknown_3 = 7; sendToInRangeSet( effectPacket, true ); - pTarget.heal( param1 ); + pTarget.heal( calculatedHeal ); break; } diff --git a/src/servers/Server_Zone/Actor/PlayerInventory.cpp b/src/servers/Server_Zone/Actor/PlayerInventory.cpp index 9084792e..3563f232 100644 --- a/src/servers/Server_Zone/Actor/PlayerInventory.cpp +++ b/src/servers/Server_Zone/Actor/PlayerInventory.cpp @@ -56,13 +56,13 @@ void Core::Entity::Player::equipWeapon( Core::ItemPtr pItem ) case ItemCategory::ThmWep: case ItemCategory::Thm2Wep: if( currentClass != ClassJob::CLASS_THAUMATURGE && - currentClass != ClassJob::JOB_BLACK ) + currentClass != ClassJob::JOB_BLACKMAGE ) setClassJob( ClassJob::CLASS_THAUMATURGE ); break; case ItemCategory::CnjWep: case ItemCategory::Cnj2Wep: if( currentClass != ClassJob::CLASS_CONJURER && - currentClass != ClassJob::JOB_WHITE ) + currentClass != ClassJob::JOB_WHITEMAGE ) setClassJob( ClassJob::CLASS_CONJURER ); break; case ItemCategory::ArnWep: diff --git a/src/servers/Server_Zone/Network/Handlers/ActionHandler.cpp b/src/servers/Server_Zone/Network/Handlers/ActionHandler.cpp index 3bf560d5..3c800eb4 100644 --- a/src/servers/Server_Zone/Network/Handlers/ActionHandler.cpp +++ b/src/servers/Server_Zone/Network/Handlers/ActionHandler.cpp @@ -106,7 +106,11 @@ void Core::Network::GameConnection::actionHandler( const Packets::GamePacket& in pPlayer->changeTarget( targetId ); break; } - + case 0x69: // Cancel cast + { + pPlayer->getCurrentAction()->setInterrupted(); + break; + } case 0x133: // Update howtos seen { uint32_t howToId = static_cast< uint32_t >( param1 ); From 43917a62732711b485dd7b0f381c6f7b5a93148d Mon Sep 17 00:00:00 2001 From: Maru Date: Sun, 20 Aug 2017 19:20:37 -0300 Subject: [PATCH 3/4] CalcBattle stuff; --- src/servers/Server_Common/Exd/ExdData.cpp | 2 +- src/servers/Server_Common/Exd/ExdData.h | 2 +- src/servers/Server_Zone/Actor/Actor.cpp | 11 ++- src/servers/Server_Zone/Actor/Actor.h | 92 ++++++++++---------- src/servers/Server_Zone/Actor/CalcBattle.cpp | 91 ++++++++++++++++--- src/servers/Server_Zone/Actor/CalcBattle.h | 6 +- src/servers/Server_Zone/Actor/Player.cpp | 23 +---- 7 files changed, 142 insertions(+), 85 deletions(-) diff --git a/src/servers/Server_Common/Exd/ExdData.cpp b/src/servers/Server_Common/Exd/ExdData.cpp index 738039f5..6ccc8646 100644 --- a/src/servers/Server_Common/Exd/ExdData.cpp +++ b/src/servers/Server_Common/Exd/ExdData.cpp @@ -236,7 +236,7 @@ bool Core::Data::ExdData::loadParamGrowInfo() uint32_t id = row.first; info.level = id; info.needed_exp = getField< int32_t >( fields, 0 ); - info.piety_scalar = getField< uint16_t >( fields, 3 ); // 3 + info.mp_mod = getField< uint16_t >( fields, 3 ); // 3 info.mp_const = getField< int32_t >( fields, 4 ); // 4 info.base_secondary = getField< int32_t >( fields, 5 );// 5 info.quest_exp_mod = getField< uint8_t >( fields, 7 ); // 7 diff --git a/src/servers/Server_Common/Exd/ExdData.h b/src/servers/Server_Common/Exd/ExdData.h index 11103c87..3a9e32f8 100644 --- a/src/servers/Server_Common/Exd/ExdData.h +++ b/src/servers/Server_Common/Exd/ExdData.h @@ -116,7 +116,7 @@ namespace Core { uint32_t needed_exp; int16_t hp_mod; int32_t mp_const; - int16_t piety_scalar; + int16_t mp_mod; int32_t base_secondary; uint16_t quest_exp_mod; }; diff --git a/src/servers/Server_Zone/Actor/Actor.cpp b/src/servers/Server_Zone/Actor/Actor.cpp index d3cc4e66..cfc75249 100644 --- a/src/servers/Server_Zone/Actor/Actor.cpp +++ b/src/servers/Server_Zone/Actor/Actor.cpp @@ -79,6 +79,12 @@ Core::Entity::Actor::Stance Core::Entity::Actor::getStance() const return m_currentStance; } +/*! \return actor stats */ +Core::Entity::Actor::ActorStats Core::Entity::Actor::getStats() const +{ + return m_baseStats; +} + /*! \return current HP */ uint32_t Core::Entity::Actor::getHp() const { @@ -207,11 +213,8 @@ void Core::Entity::Actor::die() // fire onDeath event onDeath(); - bool selfNeedsUpdate = false; - // if the actor is a player, the update needs to be send to himself too - if( isPlayer() ) - selfNeedsUpdate = true; + bool selfNeedsUpdate = isPlayer(); sendToInRangeSet( ActorControlPacket142( m_id, SetStatus, static_cast< uint8_t>( ActorStatus::Dead ) ), selfNeedsUpdate ); diff --git a/src/servers/Server_Zone/Actor/Actor.h b/src/servers/Server_Zone/Actor/Actor.h index a3809cce..49ec397c 100644 --- a/src/servers/Server_Zone/Actor/Actor.h +++ b/src/servers/Server_Zone/Actor/Actor.h @@ -55,6 +55,51 @@ public: SMachine = 0x08 }; + struct ActorStats + { + uint32_t max_mp = 0; + uint32_t max_hp = 0; + + uint32_t str = 0; + uint32_t dex = 0; + uint32_t vit = 0; + uint32_t inte = 0; + uint32_t mnd = 0; + uint32_t pie = 0; + + uint32_t parry = 0; + uint32_t attack = 0; + uint32_t defense = 0; + uint32_t accuracy = 0; + uint32_t spellSpeed = 0; + uint32_t magicDefense = 0; + uint32_t critHitRate = 0; + uint32_t resistSlash = 0; + uint32_t resistPierce = 0; + uint32_t resistBlunt = 0; + uint32_t attackPotMagic = 0; + uint32_t healingPotMagic = 0; + uint32_t determination = 0; + uint32_t skillSpeed = 0; + + uint32_t resistSlow = 0; + uint32_t resistSilence = 0; + uint32_t resistBlind = 0; + uint32_t resistPoison = 0; + uint32_t resistStun = 0; + uint32_t resistSleep = 0; + uint32_t resistBind = 0; + uint32_t resistHeavy = 0; + + uint32_t resistFire = 0; + uint32_t resistIce = 0; + uint32_t resistWind = 0; + uint32_t resistEarth = 0; + uint32_t resistLightning = 0; + uint32_t resistWater = 0; + + } m_baseStats; + protected: // TODO: The position class should probably be abolished and // the FFXIV_POS struct used instead ( the functions in there @@ -106,51 +151,6 @@ protected: /*! Container for status effects */ StatusEffect::StatusEffectContainerPtr m_pStatusEffectContainer; - struct - { - uint32_t max_mp = 0; - uint32_t max_hp = 0; - - uint32_t str = 0; - uint32_t dex = 0; - uint32_t vit = 0; - uint32_t inte = 0; - uint32_t mnd = 0; - uint32_t pie = 0; - - uint32_t parry = 0; - uint32_t attack = 0; - uint32_t defense = 0; - uint32_t accuracy = 0; - uint32_t spellSpeed = 0; - uint32_t magicDefense = 0; - uint32_t critHitRate = 0; - uint32_t resistSlash = 0; - uint32_t resistPierce = 0; - uint32_t resistBlunt = 0; - uint32_t attackPotMagic = 0; - uint32_t healingPotMagic = 0; - uint32_t determination = 0; - uint32_t skillSpeed = 0; - - uint32_t resistSlow = 0; - uint32_t resistSilence = 0; - uint32_t resistBlind = 0; - uint32_t resistPoison = 0; - uint32_t resistStun = 0; - uint32_t resistSleep = 0; - uint32_t resistBind = 0; - uint32_t resistHeavy = 0; - - uint32_t resistFire = 0; - uint32_t resistIce = 0; - uint32_t resistWind = 0; - uint32_t resistEarth = 0; - uint32_t resistLightning = 0; - uint32_t resistWater = 0; - - } m_baseStats; - public: Actor(); @@ -189,6 +189,8 @@ public: void setStance( Stance stance ); + ActorStats getStats() const; + uint32_t getHp() const; uint32_t getMp() const; diff --git a/src/servers/Server_Zone/Actor/CalcBattle.cpp b/src/servers/Server_Zone/Actor/CalcBattle.cpp index cebdabb1..c551659c 100644 --- a/src/servers/Server_Zone/Actor/CalcBattle.cpp +++ b/src/servers/Server_Zone/Actor/CalcBattle.cpp @@ -1,6 +1,7 @@ #include "CalcBattle.h" #include +#include #include "Actor.h" #include "Player.h" @@ -8,9 +9,10 @@ using namespace Core::Entity; extern Core::Data::ExdData g_exdData; +extern Core::Logger g_log; /* - Class used for battle-related formulas and calculatio ns. + Class used for battle-related formulas and calculations. Big thanks to the Theoryjerks group! NOTE: @@ -20,31 +22,94 @@ extern Core::Data::ExdData g_exdData; TODO: - Vitality HP modifier. I can only find values for levels 50~70. - HP calculation. Not a lot limiting us here. It should be next. + Base HP val modifier. I can only find values for levels 50~70. + Attack power (and healing power). Need more researchg on this. Damage outgoing calculations. This includes auto-attacks, etc. - Stats. Will need to align stats from retail with what we have. */ -uint32_t Core::Entity::CalcBattle::measureHp( ActorPtr pActor ) +uint32_t Core::Entity::CalcBattle::calculateBaseStat(PlayerPtr pPlayer) { - // todo: reduce autos here + // Don't know too much about this formula, but seems to work for some of the levels tested. + // Originally from Player.cpp, calculateStats(). - PlayerPtr pPlayer = pActor->getAsPlayer(); + float base = 0.0f; + uint8_t level = pPlayer->getLevel(); - auto classInfoIt = g_exdData.m_classJobInfoMap.find( pPlayer->getClass() ); - auto paramGrowthInfoIt = g_exdData.m_paramGrowthInfoMap.find( pPlayer->getLevel() ); + if (level < 51) + base = static_cast(0.053f * (level * level) + (1.022f * level) - 0.907f + 20); + else + base = static_cast(1.627f * level + 120.773f); - return 10; + return base; } -uint32_t Core::Entity::CalcBattle::measureHeal( ActorPtr pActor, uint32_t potency ) +// ROUNDDOWN(JobModHP * (BaseHP / 100)) + ROUNDDOWN(VitHPMod / 100 * (VIT - BaseDET)) + +uint32_t Core::Entity::CalcBattle::calculateMaxHp( PlayerPtr pPlayer ) { - // todo: reduce autos here + // TODO: Replace ApproxBaseHP with something that can get us a BaseHP reliably. + // Is there any way to pull BaseHP without having to manually use a pet for every level, and using the values from a table? - PlayerPtr pPlayer = pActor->getAsPlayer(); + auto classInfoIt = g_exdData.m_classJobInfoMap.find(pPlayer->getClass()); + auto paramGrowthInfoIt = g_exdData.m_paramGrowthInfoMap.find(pPlayer->getLevel()); + float baseStat = calculateBaseStat(pPlayer); + uint16_t vit = pPlayer->getStats().vit; + uint16_t hp_mod = paramGrowthInfoIt->second.hp_mod; + uint16_t jobModHp = classInfoIt->second.mod_hp; + uint16_t approxBaseHp = 0; // Read above + + // These values are not precise. + if (pPlayer->getLevel() > 50) + approxBaseHp = 0.1452f * paramGrowthInfoIt->second.mp_const + 1356.6f; + else + approxBaseHp = paramGrowthInfoIt->second.mp_const * 0.525f; + + uint16_t result = floor( jobModHp * ( approxBaseHp / 100.0f ) ) + floor( hp_mod / 100.0f * ( vit - baseStat ) ); + + g_log.error("MaxHP: " + std::to_string(result) + + " vit is " + std::to_string(vit) + + " basestat is " + std::to_string(baseStat) + + " hp_mod is " + std::to_string(hp_mod) + + " approxBaseHp is " + std::to_string(approxBaseHp) + + " jobmodhp is " + std::to_string(jobModHp) + ); + + return result; +} + +// Floor[(Floor[(283 - 218) * (540/100)] + 8840) * (115/100)] +// Floor[(Floor[(Piety - BaseDet) (PieMPMod / 100)] + BaseMP) * (JobModMP / 100)] +// ROUNDDOWN(((ROUNDDOWN(((PIE - BaseDET) * PieMPMod/100),0) + BaseMP) * JobModMP / 100),0) + +uint32_t Core::Entity::CalcBattle::calculateMaxMp( PlayerPtr pPlayer ) +{ + auto classInfoIt = g_exdData.m_classJobInfoMap.find(pPlayer->getClass()); + auto paramGrowthInfoIt = g_exdData.m_paramGrowthInfoMap.find(pPlayer->getLevel()); + + float baseStat = calculateBaseStat( pPlayer ); + uint16_t piety = pPlayer->getStats().pie; + uint16_t piety_scalar = paramGrowthInfoIt->second.mp_mod; + uint16_t jobModMp = classInfoIt->second.mod_mpcpgp; + uint16_t baseMp = paramGrowthInfoIt->second.mp_const; + + uint16_t result = floor( floor( piety - baseStat ) * ( piety_scalar / 100 ) + baseMp ) * jobModMp / 100; + + g_log.error("MaxMP: " + std::to_string(result) + + " piety is " + std::to_string(piety) + + " basestat is " + std::to_string(baseStat) + + " mp_mod is " + std::to_string(piety_scalar) + + " baseMp is " + std::to_string(baseMp) + + " jobmodmp is " + std::to_string(jobModMp) + ); + + return result; +} + + +uint32_t Core::Entity::CalcBattle::calculateHealValue( PlayerPtr pPlayer, uint32_t potency ) +{ auto classInfoIt = g_exdData.m_classJobInfoMap.find( pPlayer->getClass() ); auto paramGrowthInfoIt = g_exdData.m_paramGrowthInfoMap.find( pPlayer->getLevel() ); diff --git a/src/servers/Server_Zone/Actor/CalcBattle.h b/src/servers/Server_Zone/Actor/CalcBattle.h index 8e91a5d5..bfdf0fba 100644 --- a/src/servers/Server_Zone/Actor/CalcBattle.h +++ b/src/servers/Server_Zone/Actor/CalcBattle.h @@ -11,8 +11,10 @@ namespace Entity { { public: - static uint32_t measureHp( ActorPtr Player ); - static uint32_t measureHeal( ActorPtr Player, uint32_t potency ); + static uint32_t calculateBaseStat( PlayerPtr pPlayer ); + static uint32_t calculateMaxMp( PlayerPtr pPlayer ); + static uint32_t calculateMaxHp( PlayerPtr pPlayer ); + static uint32_t calculateHealValue( PlayerPtr pPlayer, uint32_t potency ); private: diff --git a/src/servers/Server_Zone/Actor/Player.cpp b/src/servers/Server_Zone/Actor/Player.cpp index 325858a2..8b3803a9 100644 --- a/src/servers/Server_Zone/Actor/Player.cpp +++ b/src/servers/Server_Zone/Actor/Player.cpp @@ -204,12 +204,7 @@ void Core::Entity::Player::calculateStats() auto paramGrowthInfo = paramGrowthInfoIt->second; // TODO: put formula somewhere else... - float base = 0.0f; - - if( level < 51 ) - base = 0.053f * ( level * level ) + ( 1.022f * level ) - 0.907f + 20; - else - base = 1.627f * level + 120.773f; + float base = CalcBattle::calculateBaseStat( getAsPlayer() ); m_baseStats.str = base * ( static_cast< float >( classInfo.mod_str ) / 100 ) + tribeInfo.mod_str; m_baseStats.dex = base * ( static_cast< float >( classInfo.mod_dex ) / 100 ) + tribeInfo.mod_dex; @@ -225,15 +220,9 @@ void Core::Entity::Player::calculateStats() m_baseStats.attackPotMagic = paramGrowthInfo.base_secondary; m_baseStats.healingPotMagic = paramGrowthInfo.base_secondary; - m_baseStats.max_mp = floor( - floor( - ( ( m_baseStats.pie - base ) * ( static_cast< float >( paramGrowthInfo.piety_scalar ) / 100 ) ) + paramGrowthInfo.mp_const ) * ( static_cast< float >( classInfo.mod_mpcpgp ) / 100 ) - ); + m_baseStats.max_mp = CalcBattle::calculateMaxMp( getAsPlayer() ); - m_baseStats.max_hp = floor( - floor( - ( ( m_baseStats.vit - base ) * ( ( static_cast< float >( paramGrowthInfo.piety_scalar ) ) / 100 ) ) + paramGrowthInfo.hp_mod ) * ( static_cast< float >( classInfo.mod_hp * 0.9f ) / 100 ) * 15 - ); + m_baseStats.max_hp = CalcBattle::calculateMaxHp( getAsPlayer() ); if( m_mp > m_baseStats.max_mp ) m_mp = m_baseStats.max_mp; @@ -1536,15 +1525,11 @@ void Core::Entity::Player::handleScriptSkill( uint32_t type, uint32_t actionId, case Core::Common::HandleSkillType::StdHeal: { - uint32_t calculatedHeal = CalcBattle::measureHeal( shared_from_this(), param1 ); + uint32_t calculatedHeal = CalcBattle::calculateHealValue( getAsPlayer(), param1 ); sendDebug( "STD_HEAL" ); -<<<<<<< HEAD - GamePacketNew< FFXIVIpcEffect > effectPacket( getId() ); -======= GamePacketNew< FFXIVIpcEffect, ServerZoneIpcType > effectPacket( getId() ); ->>>>>>> 0e8a5c38209f993e65acfdd0e5e0cf1920089fb5 effectPacket.data().targetId = pTarget.getId(); effectPacket.data().actionAnimationId = actionId; effectPacket.data().unknown_2 = 0; From e1f6a13f072b37e2467dd2151dc4298eef0ec28f Mon Sep 17 00:00:00 2001 From: Maru Date: Sun, 20 Aug 2017 19:27:06 -0300 Subject: [PATCH 4/4] Style, commenting; --- src/servers/Server_Zone/Actor/CalcBattle.cpp | 56 +++++++------------- src/servers/Server_Zone/Actor/CalcBattle.h | 1 + 2 files changed, 20 insertions(+), 37 deletions(-) diff --git a/src/servers/Server_Zone/Actor/CalcBattle.cpp b/src/servers/Server_Zone/Actor/CalcBattle.cpp index c551659c..2ac8f563 100644 --- a/src/servers/Server_Zone/Actor/CalcBattle.cpp +++ b/src/servers/Server_Zone/Actor/CalcBattle.cpp @@ -1,15 +1,12 @@ -#include "CalcBattle.h" - #include -#include +#include "CalcBattle.h" #include "Actor.h" #include "Player.h" using namespace Core::Entity; extern Core::Data::ExdData g_exdData; -extern Core::Logger g_log; /* Class used for battle-related formulas and calculations. @@ -28,65 +25,58 @@ extern Core::Logger g_log; */ -uint32_t Core::Entity::CalcBattle::calculateBaseStat(PlayerPtr pPlayer) -{ - // Don't know too much about this formula, but seems to work for some of the levels tested. - // Originally from Player.cpp, calculateStats(). +// Don't know too much about this formula, but seems to work for some of the levels tested. +// Originally from Player.cpp, calculateStats(). +uint32_t CalcBattle::calculateBaseStat( PlayerPtr pPlayer ) +{ float base = 0.0f; uint8_t level = pPlayer->getLevel(); if (level < 51) - base = static_cast(0.053f * (level * level) + (1.022f * level) - 0.907f + 20); + base = static_cast( 0.053f * ( level * level ) + (1.022f * level) - 0.907f + 20 ); else - base = static_cast(1.627f * level + 120.773f); + base = static_cast( 1.627f * level + 120.773f ); return base; } +// Leggerless' HP Formula // ROUNDDOWN(JobModHP * (BaseHP / 100)) + ROUNDDOWN(VitHPMod / 100 * (VIT - BaseDET)) -uint32_t Core::Entity::CalcBattle::calculateMaxHp( PlayerPtr pPlayer ) +uint32_t CalcBattle::calculateMaxHp( PlayerPtr pPlayer ) { // TODO: Replace ApproxBaseHP with something that can get us a BaseHP reliably. // Is there any way to pull BaseHP without having to manually use a pet for every level, and using the values from a table? - auto classInfoIt = g_exdData.m_classJobInfoMap.find(pPlayer->getClass()); - auto paramGrowthInfoIt = g_exdData.m_paramGrowthInfoMap.find(pPlayer->getLevel()); + auto classInfoIt = g_exdData.m_classJobInfoMap.find( pPlayer->getClass() ); + auto paramGrowthInfoIt = g_exdData.m_paramGrowthInfoMap.find( pPlayer->getLevel() ); - float baseStat = calculateBaseStat(pPlayer); + float baseStat = calculateBaseStat( pPlayer ); uint16_t vit = pPlayer->getStats().vit; uint16_t hp_mod = paramGrowthInfoIt->second.hp_mod; uint16_t jobModHp = classInfoIt->second.mod_hp; uint16_t approxBaseHp = 0; // Read above // These values are not precise. - if (pPlayer->getLevel() > 50) + if ( pPlayer->getLevel() > 50 ) approxBaseHp = 0.1452f * paramGrowthInfoIt->second.mp_const + 1356.6f; else approxBaseHp = paramGrowthInfoIt->second.mp_const * 0.525f; uint16_t result = floor( jobModHp * ( approxBaseHp / 100.0f ) ) + floor( hp_mod / 100.0f * ( vit - baseStat ) ); - g_log.error("MaxHP: " + std::to_string(result) - + " vit is " + std::to_string(vit) - + " basestat is " + std::to_string(baseStat) - + " hp_mod is " + std::to_string(hp_mod) - + " approxBaseHp is " + std::to_string(approxBaseHp) - + " jobmodhp is " + std::to_string(jobModHp) - ); return result; } -// Floor[(Floor[(283 - 218) * (540/100)] + 8840) * (115/100)] -// Floor[(Floor[(Piety - BaseDet) (PieMPMod / 100)] + BaseMP) * (JobModMP / 100)] +// Leggerless' MP Formula // ROUNDDOWN(((ROUNDDOWN(((PIE - BaseDET) * PieMPMod/100),0) + BaseMP) * JobModMP / 100),0) -uint32_t Core::Entity::CalcBattle::calculateMaxMp( PlayerPtr pPlayer ) +uint32_t CalcBattle::calculateMaxMp( PlayerPtr pPlayer ) { - auto classInfoIt = g_exdData.m_classJobInfoMap.find(pPlayer->getClass()); - auto paramGrowthInfoIt = g_exdData.m_paramGrowthInfoMap.find(pPlayer->getLevel()); + auto classInfoIt = g_exdData.m_classJobInfoMap.find( pPlayer->getClass() ); + auto paramGrowthInfoIt = g_exdData.m_paramGrowthInfoMap.find( pPlayer->getLevel() ); float baseStat = calculateBaseStat( pPlayer ); uint16_t piety = pPlayer->getStats().pie; @@ -96,24 +86,16 @@ uint32_t Core::Entity::CalcBattle::calculateMaxMp( PlayerPtr pPlayer ) uint16_t result = floor( floor( piety - baseStat ) * ( piety_scalar / 100 ) + baseMp ) * jobModMp / 100; - g_log.error("MaxMP: " + std::to_string(result) - + " piety is " + std::to_string(piety) - + " basestat is " + std::to_string(baseStat) - + " mp_mod is " + std::to_string(piety_scalar) - + " baseMp is " + std::to_string(baseMp) - + " jobmodmp is " + std::to_string(jobModMp) - ); - return result; } -uint32_t Core::Entity::CalcBattle::calculateHealValue( PlayerPtr pPlayer, uint32_t potency ) +uint32_t CalcBattle::calculateHealValue( PlayerPtr pPlayer, uint32_t potency ) { auto classInfoIt = g_exdData.m_classJobInfoMap.find( pPlayer->getClass() ); auto paramGrowthInfoIt = g_exdData.m_paramGrowthInfoMap.find( pPlayer->getLevel() ); - if (classInfoIt == g_exdData.m_classJobInfoMap.end() || + if ( classInfoIt == g_exdData.m_classJobInfoMap.end() || paramGrowthInfoIt == g_exdData.m_paramGrowthInfoMap.end()) return 0; diff --git a/src/servers/Server_Zone/Actor/CalcBattle.h b/src/servers/Server_Zone/Actor/CalcBattle.h index bfdf0fba..9d0cdcb1 100644 --- a/src/servers/Server_Zone/Actor/CalcBattle.h +++ b/src/servers/Server_Zone/Actor/CalcBattle.h @@ -2,6 +2,7 @@ #define _CALCBATTLE_H #include + #include "Actor.h" namespace Core {