mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-28 07:07:45 +00:00
some cleanup, kinda working battle dmg calc
This commit is contained in:
parent
7684687664
commit
f3ba1ce6c0
11 changed files with 178 additions and 17 deletions
|
@ -990,6 +990,18 @@ namespace Sapphire::Common
|
|||
CircularAoEPlaced = 7
|
||||
};
|
||||
|
||||
enum class Role : uint8_t
|
||||
{
|
||||
None,
|
||||
Tank,
|
||||
Healer,
|
||||
RangedPhysical,
|
||||
RangedMagical,
|
||||
Melee,
|
||||
Crafter,
|
||||
Gatherer
|
||||
};
|
||||
|
||||
using PlayerStateFlagList = std::vector< PlayerStateFlag >;
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#include "ActionLut.h"
|
||||
#include "EffectBuilder.h"
|
||||
|
||||
#include <Inventory/Item.h>
|
||||
|
||||
#include <Exd/ExdDataGenerated.h>
|
||||
#include <Util/Util.h>
|
||||
#include "Framework.h"
|
||||
|
@ -357,6 +359,32 @@ void Action::Action::execute()
|
|||
}
|
||||
}
|
||||
|
||||
std::pair< uint32_t, Common::ActionHitSeverityType > Action::Action::calcDamage( uint32_t potency )
|
||||
{
|
||||
// todo: what do for npcs?
|
||||
auto wepDmg = 1.f;
|
||||
|
||||
if( auto player = m_pSource->getAsPlayer() )
|
||||
{
|
||||
auto item = player->getEquippedWeapon();
|
||||
assert( item );
|
||||
|
||||
auto role = player->getRole();
|
||||
if( role == Common::Role::RangedMagical || role == Common::Role::Healer )
|
||||
{
|
||||
wepDmg = item->getMagicalDmg();
|
||||
}
|
||||
else
|
||||
{
|
||||
wepDmg = item->getPhysicalDmg();
|
||||
}
|
||||
}
|
||||
|
||||
auto dmg = Math::CalcStats::calcActionDamage( *m_pSource, potency, wepDmg );
|
||||
|
||||
return std::make_pair( dmg, Common::ActionHitSeverityType::NormalDamage );
|
||||
}
|
||||
|
||||
void Action::Action::buildEffects()
|
||||
{
|
||||
snapshotAffectedActors( m_hitActors );
|
||||
|
@ -390,10 +418,16 @@ void Action::Action::buildEffects()
|
|||
{
|
||||
// todo: this is shit
|
||||
if( lutEntry.curePotency > 0 )
|
||||
{
|
||||
|
||||
m_effectBuilder->healTarget( actor, lutEntry.curePotency );
|
||||
}
|
||||
|
||||
else if( lutEntry.potency > 0 )
|
||||
m_effectBuilder->damageTarget( actor, lutEntry.potency );
|
||||
{
|
||||
auto dmg = calcDamage( lutEntry.potency );
|
||||
m_effectBuilder->damageTarget( actor, dmg.first, dmg.second );
|
||||
}
|
||||
}
|
||||
|
||||
m_effectBuilder->buildAndSendPackets();
|
||||
|
|
|
@ -98,6 +98,10 @@ namespace Sapphire::World::Action
|
|||
*/
|
||||
void addDefaultActorFilters();
|
||||
|
||||
std::pair< uint32_t, Common::ActionHitSeverityType > calcDamage( uint32_t potency );
|
||||
|
||||
std::pair< uint32_t, Common::ActionHitSeverityType > calcHealing( uint32_t potency );
|
||||
|
||||
|
||||
std::vector< Entity::CharaPtr >& getHitCharas();
|
||||
|
||||
|
|
|
@ -25,6 +25,11 @@ uint32_t EffectResult::getValue() const
|
|||
return m_value;
|
||||
}
|
||||
|
||||
void EffectResult::setParam( uint8_t param )
|
||||
{
|
||||
m_param = param;
|
||||
}
|
||||
|
||||
void EffectResult::damage( uint32_t amount, Common::ActionHitSeverityType severity )
|
||||
{
|
||||
m_severity = severity;
|
||||
|
@ -49,7 +54,7 @@ Common::EffectEntry EffectResult::buildEffectEntry() const
|
|||
entry.value = getValue();
|
||||
entry.hitSeverity = m_severity;
|
||||
entry.effectType = m_type;
|
||||
|
||||
entry.param = m_param;
|
||||
|
||||
return entry;
|
||||
}
|
|
@ -22,6 +22,8 @@ namespace Sapphire::World::Action
|
|||
|
||||
uint32_t getValue() const;
|
||||
|
||||
void setParam( uint8_t param );
|
||||
|
||||
Common::EffectEntry buildEffectEntry() const;
|
||||
|
||||
private:
|
||||
|
@ -33,6 +35,7 @@ namespace Sapphire::World::Action
|
|||
Common::ActionEffectType m_type;
|
||||
|
||||
uint32_t m_value;
|
||||
uint8_t m_param;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -692,7 +692,7 @@ void Sapphire::Entity::BNpc::autoAttack( CharaPtr pTarget )
|
|||
srand( static_cast< uint32_t >( tick ) );
|
||||
|
||||
auto pRNGMgr = m_pFw->get< World::Manager::RNGMgr >();
|
||||
auto damage = Math::CalcStats::calculateAutoAttackDamage( *this );
|
||||
auto damage = Math::CalcStats::calcAutoAttackDamage( *this );
|
||||
|
||||
auto effectPacket = std::make_shared< Server::EffectPacket >( getId(), pTarget->getId(), 7 );
|
||||
effectPacket->setRotation( Util::floatToUInt16Rot( getRot() ) );
|
||||
|
|
|
@ -123,6 +123,67 @@ void Sapphire::Entity::Chara::setClass( Common::ClassJob classJob )
|
|||
m_class = classJob;
|
||||
}
|
||||
|
||||
Sapphire::Common::Role Sapphire::Entity::Chara::getRole() const
|
||||
{
|
||||
switch( getClass() )
|
||||
{
|
||||
case ClassJob::Gladiator:
|
||||
case ClassJob::Marauder:
|
||||
case ClassJob::Paladin:
|
||||
case ClassJob::Warrior:
|
||||
case ClassJob::Darkknight:
|
||||
case ClassJob::Gunbreaker:
|
||||
return Role::Tank;
|
||||
|
||||
case ClassJob::Pugilist:
|
||||
case ClassJob::Lancer:
|
||||
case ClassJob::Monk:
|
||||
case ClassJob::Dragoon:
|
||||
case ClassJob::Rogue:
|
||||
case ClassJob::Ninja:
|
||||
case ClassJob::Samurai:
|
||||
return Role::Melee;
|
||||
|
||||
case ClassJob::Archer:
|
||||
case ClassJob::Bard:
|
||||
case ClassJob::Machinist:
|
||||
case ClassJob::Dancer:
|
||||
return Role::RangedPhysical;
|
||||
|
||||
case ClassJob::Conjurer:
|
||||
case ClassJob::Whitemage:
|
||||
case ClassJob::Scholar:
|
||||
case ClassJob::Astrologian:
|
||||
return Role::Healer;
|
||||
|
||||
case ClassJob::Thaumaturge:
|
||||
case ClassJob::Blackmage:
|
||||
case ClassJob::Arcanist:
|
||||
case ClassJob::Summoner:
|
||||
case ClassJob::Redmage:
|
||||
case ClassJob::Bluemage:
|
||||
return Role::RangedMagical;
|
||||
|
||||
case ClassJob::Carpenter:
|
||||
case ClassJob::Blacksmith:
|
||||
case ClassJob::Armorer:
|
||||
case ClassJob::Goldsmith:
|
||||
case ClassJob::Leatherworker:
|
||||
case ClassJob::Weaver:
|
||||
case ClassJob::Alchemist:
|
||||
case ClassJob::Culinarian:
|
||||
return Role::Crafter;
|
||||
|
||||
case ClassJob::Miner:
|
||||
case ClassJob::Botanist:
|
||||
case ClassJob::Fisher:
|
||||
return Role::Gatherer;
|
||||
|
||||
default:
|
||||
return Role::None;
|
||||
}
|
||||
}
|
||||
|
||||
/*! \param Id of the target to set */
|
||||
void Sapphire::Entity::Chara::setTargetId( uint64_t targetId )
|
||||
{
|
||||
|
|
|
@ -209,6 +209,8 @@ namespace Sapphire::Entity
|
|||
|
||||
void setClass( Common::ClassJob classJob );
|
||||
|
||||
Common::Role getRole() const;
|
||||
|
||||
void setTargetId( uint64_t targetId );
|
||||
|
||||
uint64_t getTargetId() const;
|
||||
|
|
|
@ -1565,7 +1565,7 @@ void Sapphire::Entity::Player::autoAttack( CharaPtr pTarget )
|
|||
auto pRNGMgr = m_pFw->get< World::Manager::RNGMgr >();
|
||||
auto variation = static_cast< uint32_t >( pRNGMgr->getRandGenerator< float >( 0, 3 ).next() );
|
||||
|
||||
auto damage = Math::CalcStats::calculateAutoAttackDamage( *this );
|
||||
auto damage = Math::CalcStats::calcAutoAttackDamage( *this );
|
||||
|
||||
if( getClass() == ClassJob::Machinist || getClass() == ClassJob::Bard || getClass() == ClassJob::Archer )
|
||||
{
|
||||
|
|
|
@ -219,16 +219,9 @@ float CalcStats::autoAttackPotency( const Sapphire::Entity::Chara& chara )
|
|||
{
|
||||
uint32_t aaPotency = AUTO_ATTACK_POTENCY;
|
||||
|
||||
// check if ranged class
|
||||
switch( chara.getClass() )
|
||||
if( chara.getRole() == Common::Role::RangedPhysical )
|
||||
{
|
||||
case Common::ClassJob::Machinist:
|
||||
case Common::ClassJob::Bard:
|
||||
case Common::ClassJob::Archer:
|
||||
aaPotency = RANGED_AUTO_ATTACK_POTENCY;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
float autoAttackDelay = 2.5f;
|
||||
|
@ -442,7 +435,7 @@ float CalcStats::healingMagicPotency( const Sapphire::Entity::Chara& chara )
|
|||
return std::floor( 100.f * ( chara.getStatValue( Common::BaseParam::HealingMagicPotency ) - 292.f ) / 264.f + 100.f ) / 100.f;
|
||||
}
|
||||
|
||||
float CalcStats::calculateAutoAttackDamage( const Sapphire::Entity::Chara& chara )
|
||||
float CalcStats::calcAutoAttackDamage( const Sapphire::Entity::Chara& chara )
|
||||
{
|
||||
// D = ⌊ f(ptc) × f(aa) × f(ap) × f(det) × f(tnc) × traits ⌋ × f(ss) ⌋ ×
|
||||
// f(chr) ⌋ × f(dhr) ⌋ × rand[ 0.95, 1.05 ] ⌋ × buff_1 ⌋ × buff... ⌋
|
||||
|
@ -451,12 +444,25 @@ float CalcStats::calculateAutoAttackDamage( const Sapphire::Entity::Chara& chara
|
|||
auto aa = autoAttack( chara );
|
||||
auto ap = getPrimaryAttackPower( chara );
|
||||
auto det = determination( chara );
|
||||
auto ten = tenacity( chara );
|
||||
|
||||
Logger::debug( "auto attack: pot: {} aa: {} ap: {} det: {} ten: {}", pot, aa, ap, det, ten );
|
||||
auto ten = 1.f;
|
||||
if( chara.getRole() == Common::Role::Tank )
|
||||
ten = tenacity( chara );
|
||||
|
||||
// todo: everything after tenacity
|
||||
auto factor = std::floor( pot * aa * ap * det * ten );
|
||||
|
||||
constexpr auto format = "auto attack: pot: {} aa: {} ap: {} det: {} ten: {} = {}";
|
||||
|
||||
if( auto player = const_cast< Entity::Chara& >( chara ).getAsPlayer() )
|
||||
{
|
||||
player->sendDebug( format, pot, aa, ap, det, ten, factor );
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::debug( format, pot, aa, ap, det, ten, factor );
|
||||
}
|
||||
|
||||
// todo: traits
|
||||
|
||||
factor = std::floor( factor * speed( chara ) );
|
||||
|
@ -472,6 +478,38 @@ float CalcStats::calculateAutoAttackDamage( const Sapphire::Entity::Chara& chara
|
|||
return factor;
|
||||
}
|
||||
|
||||
float CalcStats::calcActionDamage( const Sapphire::Entity::Chara& chara, uint32_t ptc, float wepDmg )
|
||||
{
|
||||
// D = ⌊ f(pot) × f(wd) × f(ap) × f(det) × f(tnc) × traits ⌋
|
||||
// × f(chr) ⌋ × f(dhr) ⌋ × rand[ 0.95, 1.05 ] ⌋ buff_1 ⌋ × buff_1 ⌋ × buff... ⌋
|
||||
|
||||
auto pot = potency( ptc );
|
||||
auto wd = weaponDamage( chara, wepDmg );
|
||||
auto ap = getPrimaryAttackPower( chara );
|
||||
auto det = determination( chara );
|
||||
|
||||
auto ten = 1.f;
|
||||
if( chara.getRole() == Common::Role::Tank )
|
||||
ten = tenacity( chara );
|
||||
|
||||
auto factor = std::floor( pot * wd * ap * det * ten );
|
||||
|
||||
constexpr auto format = "dmg: pot: {} wd: {} ap: {} det: {} ten: {} = {}";
|
||||
|
||||
if( auto player = const_cast< Entity::Chara& >( chara ).getAsPlayer() )
|
||||
{
|
||||
player->sendDebug( format, pot, wd, ap, det, ten, factor );
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::debug( format, pot, wd, ap, det, ten, factor );
|
||||
}
|
||||
|
||||
// todo: the rest
|
||||
|
||||
return factor;
|
||||
}
|
||||
|
||||
uint32_t CalcStats::primaryStatValue( const Sapphire::Entity::Chara& chara )
|
||||
{
|
||||
return chara.getStatValue( chara.getPrimaryStat() );
|
||||
|
|
|
@ -128,7 +128,9 @@ namespace Sapphire::Math
|
|||
|
||||
////////////////////////////////////////////
|
||||
|
||||
static float calculateAutoAttackDamage( const Sapphire::Entity::Chara& chara );
|
||||
static float calcAutoAttackDamage( const Sapphire::Entity::Chara& chara );
|
||||
|
||||
static float calcActionDamage( const Sapphire::Entity::Chara& chara, uint32_t ptc, float wepDmg );
|
||||
|
||||
static uint32_t primaryStatValue( const Sapphire::Entity::Chara& chara );
|
||||
private:
|
||||
|
|
Loading…
Add table
Reference in a new issue