From a1b56e525acc3ff012fa66bb04d2eed198d662ad Mon Sep 17 00:00:00 2001 From: Maru Date: Thu, 16 Nov 2017 00:03:36 -0200 Subject: [PATCH] Packet definitions; Item level (WIP); Packetdef for PlayerStats and PlayerClassInfo. ItemLvl currently broken and not optimized (constantly calling to calc due to equipitem). --- .../Network/PacketDef/Zone/ServerZoneDef.h | 19 ++++++++------ src/servers/Server_Zone/Actor/Actor.h | 2 +- src/servers/Server_Zone/Actor/Player.cpp | 19 ++++++++++---- src/servers/Server_Zone/Actor/Player.h | 8 ++++++ .../Server_Zone/Actor/PlayerInventory.cpp | 21 +++++++++++++--- .../Server_Zone/Inventory/Inventory.cpp | 25 +++++++++++++++++++ src/servers/Server_Zone/Inventory/Inventory.h | 2 ++ src/servers/Server_Zone/Inventory/Item.cpp | 6 +++++ src/servers/Server_Zone/Inventory/Item.h | 3 +++ .../Network/Handlers/ActionHandler.cpp | 5 ++++ 10 files changed, 94 insertions(+), 16 deletions(-) diff --git a/src/servers/Server_Common/Network/PacketDef/Zone/ServerZoneDef.h b/src/servers/Server_Common/Network/PacketDef/Zone/ServerZoneDef.h index a73346d2..cb535a34 100644 --- a/src/servers/Server_Common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/servers/Server_Common/Network/PacketDef/Zone/ServerZoneDef.h @@ -815,7 +815,7 @@ struct FFXIVIpcPlayerStats : FFXIVIpcBasePacket uint32_t unknown; uint32_t unknown_1; uint32_t unknown_2; - uint32_t parry; + uint32_t tenacity; uint32_t attack; uint32_t defense; uint32_t accuracy; @@ -837,7 +837,11 @@ struct FFXIVIpcPlayerStats : FFXIVIpcBasePacket uint32_t skillSpeed; uint32_t spellSpeed1; uint32_t spellSpeedMod; - uint32_t unknown_6[5]; + uint32_t unknown_6; + uint32_t craftsmanship; + uint32_t control; + uint32_t gathering; + uint32_t perception; uint32_t resistanceSlow; uint32_t resistanceSilence; uint32_t resistanceBlind; @@ -846,7 +850,7 @@ struct FFXIVIpcPlayerStats : FFXIVIpcBasePacket uint32_t resistanceSleep; uint32_t resistanceBind; uint32_t resistanceHeavy; - uint32_t unknown_7[9]; + uint32_t unknown_7[9]; // possibly level sync stats. }; /** @@ -881,10 +885,11 @@ struct FFXIVIpcPlayerStateFlags : FFXIVIpcBasePacket struct FFXIVIpcPlayerClassInfo : FFXIVIpcBasePacket { uint16_t classId; - uint16_t unknown; - uint16_t level; - uint16_t level1; - uint8_t unknownFields[48]; + uint8_t unknown; + uint8_t isSpecialist; + uint16_t level; // Locks actions, equipment, prob more + uint16_t level1; // Locks roles, prob more + uint32_t roleActions[10]; }; /** diff --git a/src/servers/Server_Zone/Actor/Actor.h b/src/servers/Server_Zone/Actor/Actor.h index 5a784f28..43649cae 100644 --- a/src/servers/Server_Zone/Actor/Actor.h +++ b/src/servers/Server_Zone/Actor/Actor.h @@ -77,7 +77,7 @@ public: uint32_t mnd = 0; uint32_t pie = 0; - uint32_t parry = 0; + uint32_t tenacity = 0; uint32_t attack = 0; uint32_t defense = 0; uint32_t accuracy = 0; diff --git a/src/servers/Server_Zone/Actor/Player.cpp b/src/servers/Server_Zone/Actor/Player.cpp index ba865229..5ad7819f 100644 --- a/src/servers/Server_Zone/Actor/Player.cpp +++ b/src/servers/Server_Zone/Actor/Player.cpp @@ -235,12 +235,13 @@ void Core::Entity::Player::calculateStats() m_baseStats.mnd = static_cast< uint32_t >( base * ( static_cast< float >( classInfo.mod_mnd ) / 100 ) + tribeInfo.mod_mnd ); m_baseStats.pie = static_cast< uint32_t >( base * ( static_cast< float >( classInfo.mod_pie ) / 100 ) + tribeInfo.mod_pie ); - m_baseStats.skillSpeed = paramGrowthInfo.base_secondary; - m_baseStats.spellSpeed = paramGrowthInfo.base_secondary; - m_baseStats.accuracy = paramGrowthInfo.base_secondary; - m_baseStats.critHitRate = paramGrowthInfo.base_secondary; - m_baseStats.attackPotMagic = paramGrowthInfo.base_secondary; + m_baseStats.skillSpeed = paramGrowthInfo.base_secondary; + m_baseStats.spellSpeed = paramGrowthInfo.base_secondary; + m_baseStats.accuracy = paramGrowthInfo.base_secondary; + m_baseStats.critHitRate = paramGrowthInfo.base_secondary; + m_baseStats.attackPotMagic = paramGrowthInfo.base_secondary; m_baseStats.healingPotMagic = paramGrowthInfo.base_secondary; + m_baseStats.tenacity = paramGrowthInfo.base_secondary; m_baseStats.max_mp = Data::CalcBattle::calculateMaxMp( getAsPlayer() ); @@ -433,6 +434,9 @@ void Core::Entity::Player::setZone( uint32_t zoneId ) gcAffPacket.data().gcRank[1] = m_gcRank[1]; gcAffPacket.data().gcRank[2] = m_gcRank[2]; queuePacket( gcAffPacket ); + + m_itemLevel = getInventory()->calculateEquippedGearItemLevel(); + sendItemLevel(); } GamePacketNew< FFXIVIpcInitZone, ServerZoneIpcType > initZonePacket( getId() ); @@ -1575,6 +1579,11 @@ void Core::Entity::Player::setOpeningSequence( uint8_t seq ) m_openingSequence = seq; } +uint16_t Core::Entity::Player::getItemLevel() const +{ + return m_itemLevel; +} + /// Tells client to offset their eorzean time by given timestamp. void Core::Entity::Player::setEorzeaTimeOffset( uint64_t timestamp ) { diff --git a/src/servers/Server_Zone/Actor/Player.h b/src/servers/Server_Zone/Actor/Player.h index bc38df16..61207f67 100644 --- a/src/servers/Server_Zone/Actor/Player.h +++ b/src/servers/Server_Zone/Actor/Player.h @@ -206,6 +206,10 @@ public: void unequipItem( Inventory::EquipSlot equipSlotId, ItemPtr pItem ); /*! equip a weapon, possibly forcing a job change */ void equipWeapon( ItemPtr pItem ); + /*! get player ilvl */ + uint16_t getItemLevel() const; + /*! send player ilvl */ + void sendItemLevel(); /*! get a const pointer to the inventory object */ InventoryPtr getInventory() const; /*! get the current main hand model */ @@ -591,16 +595,20 @@ private: uint8_t m_openingSequence; + uint16_t m_itemLevel; InventoryPtr m_pInventory; + std::map< uint32_t, Event::EventPtr > m_eventMap; std::map< uint32_t, uint8_t > m_playerIdToSpawnIdMap; // maps player to spawn id std::queue< uint8_t > m_freeSpawnIdQueue; // queue with spawn ids free to be assigned std::queue< uint8_t > m_freeHateSlotQueue; // queue with "hate slots" free to be assigned std::map< uint32_t, uint8_t > m_actorIdTohateSlotMap; + std::map< uint32_t, uint8_t > m_questIdToQuestIdx; // quest mapping, quest id to quest container index std::map< uint8_t, uint32_t > m_questIdxToQuestId; // quest mapping, quest container index to questId boost::shared_ptr< Common::QuestActive > m_activeQuests[30]; int16_t m_questTracking[5]; + uint8_t m_stateFlags[7]; uint8_t m_gmRank; uint16_t zoneId; diff --git a/src/servers/Server_Zone/Actor/PlayerInventory.cpp b/src/servers/Server_Zone/Actor/PlayerInventory.cpp index acc6632c..3b516c19 100644 --- a/src/servers/Server_Zone/Actor/PlayerInventory.cpp +++ b/src/servers/Server_Zone/Actor/PlayerInventory.cpp @@ -1,17 +1,21 @@ #include +#include +#include +#include #include "Player.h" #include "src/servers/Server_Zone/Zone/ZoneMgr.h" #include "src/servers/Server_Zone/Zone/Zone.h" -#include - +#include "src/servers/Server_Zone/Network/PacketWrappers/ActorControlPacket142.h" #include "src/servers/Server_Zone/Network/PacketWrappers/ActorControlPacket143.h" #include "src/servers/Server_Zone/Inventory/Inventory.h" #include "src/servers/Server_Zone/Inventory/Item.h" +extern Core::Logger g_log; + using namespace Core::Common; using namespace Core::Network::Packets; using namespace Core::Network::Packets::Server; @@ -21,6 +25,11 @@ Core::InventoryPtr Core::Entity::Player::getInventory() const return m_pInventory; } +void Core::Entity::Player::sendItemLevel() +{ + queuePacket( ActorControlPacket142( getId(), SetItemLevel, getItemLevel(), 0 ) ); +} + // TODO: This has to be redone and simplified void Core::Entity::Player::equipWeapon( Core::ItemPtr pItem ) { @@ -80,7 +89,7 @@ void Core::Entity::Player::equipWeapon( Core::ItemPtr pItem ) void Core::Entity::Player::equipItem( Inventory::EquipSlot equipSlotId, Core::ItemPtr pItem, bool sendModel ) { - // Console->outDebOnly("Equipping into slot %i", equipSlotID); + //g_log.debug( "Equipping into slot " + std::to_string( equipSlotId ) ); uint64_t model = pItem->getModelId1(); uint64_t model2 = pItem->getModelId2(); @@ -111,12 +120,18 @@ void Core::Entity::Player::equipItem( Inventory::EquipSlot equipSlotId, Core::It if( sendModel ) this->sendModel(); + + m_itemLevel = getInventory()->calculateEquippedGearItemLevel(); + sendItemLevel(); } void Core::Entity::Player::unequipItem( Inventory::EquipSlot equipSlotId, ItemPtr pItem ) { m_modelEquip[static_cast< uint8_t >( equipSlotId )] = 0; sendModel(); + + m_itemLevel = getInventory()->calculateEquippedGearItemLevel(); + sendItemLevel(); } uint32_t Core::Entity::Player::getCurrency( uint8_t type ) const diff --git a/src/servers/Server_Zone/Inventory/Inventory.cpp b/src/servers/Server_Zone/Inventory/Inventory.cpp index f7d908ed..ff97f6ae 100644 --- a/src/servers/Server_Zone/Inventory/Inventory.cpp +++ b/src/servers/Server_Zone/Inventory/Inventory.cpp @@ -13,6 +13,7 @@ #include "src/servers/Server_Zone/Network/PacketWrappers/ServerNoticePacket.h" #include +#include #include "src/servers/Server_Zone/Forwards.h" #include "src/servers/Server_Zone/Network/PacketWrappers/ActorControlPacket143.h" @@ -828,6 +829,30 @@ void Core::Inventory::send() } +uint16_t Core::Inventory::calculateEquippedGearItemLevel() +{ + uint32_t iLvlResult = 0; + + for ( uint16_t i = 0; i < sizeof( m_inventoryMap[GearSet0] ); i++ ) + { + auto currItem = m_inventoryMap[GearSet0]->getItem( i ); + + if ( currItem ) + { + g_log.debug( std::to_string( currItem->getId() ) + " ilvl: " + std::to_string( currItem->getItemLevel() ) ); + iLvlResult += currItem->getItemLevel(); + + // If weapon isn't one-handed + if ( currItem->getCategory() != ItemCategory::CnjWep || + currItem->getCategory() != ItemCategory::ThmWep ) + iLvlResult += currItem->getItemLevel(); + } + } + + return boost::algorithm::clamp( iLvlResult / 12, 0, 9999 ); +} + + uint8_t Core::Inventory::getFreeSlotsInBags() { uint8_t slots = 0; diff --git a/src/servers/Server_Zone/Inventory/Inventory.h b/src/servers/Server_Zone/Inventory/Inventory.h index ffceb393..c0ceb727 100644 --- a/src/servers/Server_Zone/Inventory/Inventory.h +++ b/src/servers/Server_Zone/Inventory/Inventory.h @@ -153,6 +153,8 @@ public: bool updateContainer( uint16_t containerId, uint8_t slotId, ItemPtr pItem ); + /*! calculate and return player ilvl based off equipped gear */ + uint16_t calculateEquippedGearItemLevel(); /*! return the current amount of currency of type */ uint32_t getCurrency( CurrencyType type ); /*! add amount to the current of type */ diff --git a/src/servers/Server_Zone/Inventory/Item.cpp b/src/servers/Server_Zone/Inventory/Item.cpp index 7de51628..b95d25e9 100644 --- a/src/servers/Server_Zone/Inventory/Item.cpp +++ b/src/servers/Server_Zone/Inventory/Item.cpp @@ -30,6 +30,7 @@ Core::Item::Item( uint64_t uId, uint32_t catalogId, uint64_t model1, uint64_t mo m_magicalDmg = itemInfo->magical_damage; m_weaponDmg = ( m_physicalDmg != 0 ) ? m_physicalDmg : m_magicalDmg; m_autoAttackDmg = static_cast< float >( m_weaponDmg * m_delayMs ) / 3000; + m_itemLevel = itemInfo->item_level; } Core::Item::~Item() @@ -57,6 +58,11 @@ uint16_t Core::Item::getMagicalDmg() const return m_magicalDmg; } +uint16_t Core::Item::getItemLevel() const +{ + return m_itemLevel; +} + uint16_t Core::Item::getWeaponDmg() const { return m_weaponDmg; diff --git a/src/servers/Server_Zone/Inventory/Item.h b/src/servers/Server_Zone/Inventory/Item.h index 8c0c7310..a72cdfe9 100644 --- a/src/servers/Server_Zone/Inventory/Item.h +++ b/src/servers/Server_Zone/Inventory/Item.h @@ -50,6 +50,8 @@ public: float getAutoAttackDmg() const; + uint16_t getItemLevel() const; + protected: uint32_t m_id; @@ -71,6 +73,7 @@ protected: uint16_t m_magicalDmg; uint16_t m_weaponDmg; float m_autoAttackDmg; + uint16_t m_itemLevel; }; diff --git a/src/servers/Server_Zone/Network/Handlers/ActionHandler.cpp b/src/servers/Server_Zone/Network/Handlers/ActionHandler.cpp index 113e5bab..c605dfbb 100644 --- a/src/servers/Server_Zone/Network/Handlers/ActionHandler.cpp +++ b/src/servers/Server_Zone/Network/Handlers/ActionHandler.cpp @@ -230,10 +230,15 @@ void Core::Network::GameConnection::actionHandler( const Packets::GamePacket& in } break; } + case 0x1B5: // Dye item + { + break; + } default: { g_log.debug( "[" + std::to_string( m_pSession->getId() ) + "] Unhandled action: " + boost::str( boost::format( "%|04X|" ) % (uint32_t) ( commandId & 0xFFFF ) ) ); + break; } } }