1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-25 14:07:46 +00:00

Gear matters!

Gear stats are applied now, excluding materia.
This commit is contained in:
Mordred 2019-03-21 18:06:48 +01:00
parent 5ec7904e56
commit 35d859d57a
7 changed files with 110 additions and 30 deletions

View file

@ -20,6 +20,11 @@ bool operator==( const uint8_t& g, const BaseParam& t )
return static_cast< uint8_t >( t ) == g;
}
bool operator!=( const uint8_t& g, const BaseParam& t )
{
return static_cast< uint8_t >( t ) != g;
}
bool operator==( const BeastReputationRank& t, const uint8_t& g )
{
return static_cast< uint8_t >( t ) == g;

View file

@ -65,6 +65,9 @@ namespace Sapphire::Entity
} m_baseStats;
// array for bonuses, 80 to have some spare room.
uint32_t m_bonusStats[80];
protected:
char m_name[34];
/*! Last tick time for the actor ( in ms ) */

View file

@ -311,28 +311,28 @@ void Sapphire::Entity::Player::sendStats()
{
auto statPacket = makeZonePacket< FFXIVIpcPlayerStats >( getId() );
statPacket->data().strength = m_baseStats.str;
statPacket->data().dexterity = m_baseStats.dex;
statPacket->data().vitality = m_baseStats.vit;
statPacket->data().intelligence = m_baseStats.inte;
statPacket->data().mind = m_baseStats.mnd;
statPacket->data().piety = m_baseStats.pie;
statPacket->data().determination = m_baseStats.determination;
statPacket->data().hp = m_baseStats.max_hp;
statPacket->data().mp = m_baseStats.max_mp;
statPacket->data().strength = m_baseStats.str + m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::Strength ) ];
statPacket->data().dexterity = m_baseStats.dex + m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::Dexterity ) ];
statPacket->data().vitality = m_baseStats.vit + m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::Vitality ) ];
statPacket->data().intelligence = m_baseStats.inte + m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::Intelligence ) ];
statPacket->data().mind = m_baseStats.mnd + m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::Mind ) ];
statPacket->data().piety = m_baseStats.pie + m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::Piety ) ];
statPacket->data().determination = m_baseStats.determination + m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::Determination ) ];
statPacket->data().hp = m_baseStats.max_hp + m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::HP ) ];
statPacket->data().mp = m_baseStats.max_mp + m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::MP ) ];
statPacket->data().accuracy = m_baseStats.accuracy;
statPacket->data().attack = m_baseStats.attack;
statPacket->data().attackMagicPotency = m_baseStats.attackPotMagic;
statPacket->data().healingMagicPotency = m_baseStats.healingPotMagic;
statPacket->data().skillSpeed = m_baseStats.skillSpeed;
statPacket->data().spellSpeed = m_baseStats.spellSpeed;
statPacket->data().spellSpeed1 = m_baseStats.spellSpeed;
statPacket->data().attack = m_baseStats.attack + m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::AttackPower ) ];
statPacket->data().attackMagicPotency = m_baseStats.attackPotMagic + m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::AttackMagicPotency ) ];
statPacket->data().healingMagicPotency = m_baseStats.healingPotMagic + m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::HealingMagicPotency ) ];
statPacket->data().skillSpeed = m_baseStats.skillSpeed + m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::SkillSpeed ) ];
statPacket->data().spellSpeed = m_baseStats.spellSpeed + m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::SpellSpeed ) ];
statPacket->data().spellSpeed1 = m_baseStats.spellSpeed + m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::SpellSpeed ) ];
statPacket->data().spellSpeedMod = 100;
statPacket->data().criticalHitRate = m_baseStats.critHitRate;
statPacket->data().defense = m_baseStats.defense;
statPacket->data().magicDefense = m_baseStats.magicDefense;
statPacket->data().tenacity = m_baseStats.tenacity;
statPacket->data().criticalHitRate = m_baseStats.critHitRate + m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::CriticalHit ) ];
statPacket->data().defense = m_baseStats.defense + m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::Defense ) ];
statPacket->data().magicDefense = m_baseStats.magicDefense + m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::MagicDefense ) ];
statPacket->data().tenacity = m_baseStats.tenacity + m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::Tenacity ) ];
queuePacket( statPacket );
}

View file

@ -319,7 +319,7 @@ namespace Sapphire::Entity
void equipItem( Common::GearSetSlot equipSlotId, ItemPtr pItem, bool sendModel );
/*! remove an item from an equipment slot */
void unequipItem( Common::GearSetSlot equipSlotId, ItemPtr pItem );
void unequipItem( Common::GearSetSlot equipSlotId, ItemPtr pItem, bool sendModel );
/*! equip a weapon, possibly forcing a job change */
void equipWeapon( ItemPtr pItem, bool updateClass );

View file

@ -228,21 +228,52 @@ void Sapphire::Entity::Player::equipItem( Common::GearSetSlot equipSlotId, ItemP
}
else
updateModels( equipSlotId, pItem, false );
auto baseParams = pItem->getBaseParams();
for( auto i = 0; i < 6; ++i )
{
if( baseParams[ i ].baseParam != static_cast< uint8_t >( Common::BaseParam::None ) )
m_bonusStats[ baseParams[ i ].baseParam ] += baseParams[ i ].value;
}
m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::Defense ) ] += pItem->getDefense();
m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::MagicDefense ) ] += pItem->getDefenseMag();
sendStats();
}
void Sapphire::Entity::Player::unequipItem( Common::GearSetSlot equipSlotId, ItemPtr pItem )
void Sapphire::Entity::Player::unequipItem( Common::GearSetSlot equipSlotId, ItemPtr pItem, bool sendUpdate )
{
auto modelSlot = equipSlotToModelSlot( equipSlotId );
if( modelSlot != GearModelSlot::ModelInvalid )
m_modelEquip[ static_cast< uint8_t >( modelSlot ) ] = 0;
if( sendUpdate )
{
sendModel();
m_itemLevel = calculateEquippedGearItemLevel();
sendItemLevel();
}
if ( equipSlotId == SoulCrystal )
unequipSoulCrystal( pItem );
auto baseParams = pItem->getBaseParams();
for( auto i = 0; i < 6; ++i )
{
if( baseParams[ i ].baseParam != static_cast< uint8_t >( Common::BaseParam::None ) )
m_bonusStats[ baseParams[ i ].baseParam ] -= baseParams[ i ].value;
}
m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::Defense ) ] -= pItem->getDefense();
m_bonusStats[ static_cast< uint8_t >( Common::BaseParam::MagicDefense ) ] -= pItem->getDefenseMag();
if( sendUpdate )
{
sendStats();
}
}
void Sapphire::Entity::Player::unequipSoulCrystal( ItemPtr pItem )
@ -615,7 +646,7 @@ Sapphire::Entity::Player::moveItem( uint16_t fromInventoryId, uint8_t fromSlotId
equipItem( static_cast< GearSetSlot >( toSlot ), tmpItem, true );
if( static_cast< InventoryType >( fromInventoryId ) == GearSet0 )
unequipItem( static_cast< GearSetSlot >( fromSlotId ), tmpItem );
unequipItem( static_cast< GearSetSlot >( fromSlotId ), tmpItem, true );
}
@ -624,6 +655,7 @@ bool Sapphire::Entity::Player::updateContainer( uint16_t storageId, uint8_t slot
{
auto containerType = World::Manager::ItemMgr::getContainerType( storageId );
auto pOldItem = getItemAt( storageId, slotId );
m_storageMap[ storageId ]->setItem( slotId, pItem );
switch( containerType )
@ -639,9 +671,13 @@ bool Sapphire::Entity::Player::updateContainer( uint16_t storageId, uint8_t slot
case GearSet:
{
if( pItem )
{
if( pOldItem )
unequipItem( static_cast< GearSetSlot >( slotId ), pOldItem, false );
equipItem( static_cast< GearSetSlot >( slotId ), pItem, true );
}
else
unequipItem( static_cast< GearSetSlot >( slotId ), pItem );
unequipItem( static_cast< GearSetSlot >( slotId ), pItem, true );
writeInventory( static_cast< InventoryType >( storageId ) );
break;

View file

@ -33,6 +33,22 @@ Sapphire::Item::Item( uint64_t uId, uint32_t catalogId, FrameworkPtr pFw, bool i
m_block = itemInfo->block;
m_defense = itemInfo->defensePhys;
m_defenseMag = itemInfo->defenseMag;
for( int i = 0; i < 6; ++i )
{
m_baseParam[i].baseParam = itemInfo->param[i].baseparam;
m_baseParam[i].value = itemInfo->param[i].value;
}
}
uint16_t Sapphire::Item::getDefense() const
{
return m_defense;
}
uint16_t Sapphire::Item::getDefenseMag() const
{
return m_defenseMag;
}
float Sapphire::Item::getAutoAttackDmg() const
@ -185,3 +201,8 @@ void Sapphire::Item::setReservedFlag( uint32_t flag )
{
m_reservedFlag = flag;
}
Sapphire::Item::BaseParamStruct* Sapphire::Item::getBaseParams()
{
return m_baseParam;
}

View file

@ -11,6 +11,13 @@ namespace Sapphire
{
public:
struct BaseParamStruct
{
uint8_t baseParam;
int16_t value;
};
Item( uint64_t uId, uint32_t catalogId, FrameworkPtr pFw, bool isHq = false );
virtual ~Item() = default;
@ -49,6 +56,10 @@ namespace Sapphire
uint16_t getWeaponDmg() const;
uint16_t getDefense() const;
uint16_t getDefenseMag() const;
bool isWeapon() const;
float getAutoAttackDmg() const;
@ -71,6 +82,7 @@ namespace Sapphire
void setReservedFlag( uint32_t flag );
uint32_t getReservedFlag() const;
BaseParamStruct* getBaseParams();
protected:
uint32_t m_id;
@ -106,6 +118,9 @@ namespace Sapphire
FrameworkPtr m_pFw;
uint32_t m_additionalData;
BaseParamStruct m_baseParam[6];
};
}