1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-26 14:37:44 +00:00
This commit is contained in:
Mordred Admin 2017-12-07 12:09:13 +01:00
commit 624a872a1a
11 changed files with 143 additions and 20 deletions

View file

@ -815,7 +815,7 @@ struct FFXIVIpcPlayerStats : FFXIVIpcBasePacket<PlayerStats>
uint32_t unknown; uint32_t unknown;
uint32_t unknown_1; uint32_t unknown_1;
uint32_t unknown_2; uint32_t unknown_2;
uint32_t parry; uint32_t tenacity;
uint32_t attack; uint32_t attack;
uint32_t defense; uint32_t defense;
uint32_t accuracy; uint32_t accuracy;
@ -837,7 +837,11 @@ struct FFXIVIpcPlayerStats : FFXIVIpcBasePacket<PlayerStats>
uint32_t skillSpeed; uint32_t skillSpeed;
uint32_t spellSpeed1; uint32_t spellSpeed1;
uint32_t spellSpeedMod; 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 resistanceSlow;
uint32_t resistanceSilence; uint32_t resistanceSilence;
uint32_t resistanceBlind; uint32_t resistanceBlind;
@ -846,7 +850,7 @@ struct FFXIVIpcPlayerStats : FFXIVIpcBasePacket<PlayerStats>
uint32_t resistanceSleep; uint32_t resistanceSleep;
uint32_t resistanceBind; uint32_t resistanceBind;
uint32_t resistanceHeavy; uint32_t resistanceHeavy;
uint32_t unknown_7[9]; uint32_t unknown_7[9]; // possibly level sync stats.
}; };
/** /**
@ -881,10 +885,11 @@ struct FFXIVIpcPlayerStateFlags : FFXIVIpcBasePacket<PlayerStateFlags>
struct FFXIVIpcPlayerClassInfo : FFXIVIpcBasePacket<PlayerClassInfo> struct FFXIVIpcPlayerClassInfo : FFXIVIpcBasePacket<PlayerClassInfo>
{ {
uint16_t classId; uint16_t classId;
uint16_t unknown; uint8_t unknown;
uint16_t level; uint8_t isSpecialist;
uint16_t level1; uint16_t level; // Locks actions, equipment, prob more
uint8_t unknownFields[48]; uint16_t level1; // Locks roles, prob more
uint32_t roleActions[10];
}; };
/** /**

View file

@ -200,7 +200,7 @@ void Core::Network::SapphireAPI::deleteCharacter( std::string name, uint32_t acc
g_charaDb.execute( "DELETE FROM charaitemcrystal WHERE CharacterId LIKE '" + std::to_string( id ) + "';" ); g_charaDb.execute( "DELETE FROM charaitemcrystal WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
g_charaDb.execute( "DELETE FROM charaiteminventory WHERE CharacterId LIKE '" + std::to_string( id ) + "';" ); g_charaDb.execute( "DELETE FROM charaiteminventory WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
g_charaDb.execute( "DELETE FROM charaitemgearset WHERE CharacterId LIKE '" + std::to_string( id ) + "';" ); g_charaDb.execute( "DELETE FROM charaitemgearset WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
g_charaDb.execute( "DELETE FROM charaquest WHERE CharacterId LIKE '" + std::to_string( id ) + "';" ); g_charaDb.execute( "DELETE FROM charaquestnew WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
} }
std::vector< Core::PlayerMinimal > Core::Network::SapphireAPI::getCharList( uint32_t accountId ) std::vector< Core::PlayerMinimal > Core::Network::SapphireAPI::getCharList( uint32_t accountId )

View file

@ -80,7 +80,7 @@ public:
uint32_t mnd = 0; uint32_t mnd = 0;
uint32_t pie = 0; uint32_t pie = 0;
uint32_t parry = 0; uint32_t tenacity = 0;
uint32_t attack = 0; uint32_t attack = 0;
uint32_t defense = 0; uint32_t defense = 0;
uint32_t accuracy = 0; uint32_t accuracy = 0;

View file

@ -236,12 +236,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.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.pie = static_cast< uint32_t >( base * ( static_cast< float >( classInfo.mod_pie ) / 100 ) + tribeInfo.mod_pie );
m_baseStats.skillSpeed = paramGrowthInfo.base_secondary; m_baseStats.skillSpeed = paramGrowthInfo.base_secondary;
m_baseStats.spellSpeed = paramGrowthInfo.base_secondary; m_baseStats.spellSpeed = paramGrowthInfo.base_secondary;
m_baseStats.accuracy = paramGrowthInfo.base_secondary; m_baseStats.accuracy = paramGrowthInfo.base_secondary;
m_baseStats.critHitRate = paramGrowthInfo.base_secondary; m_baseStats.critHitRate = paramGrowthInfo.base_secondary;
m_baseStats.attackPotMagic = paramGrowthInfo.base_secondary; m_baseStats.attackPotMagic = paramGrowthInfo.base_secondary;
m_baseStats.healingPotMagic = paramGrowthInfo.base_secondary; m_baseStats.healingPotMagic = paramGrowthInfo.base_secondary;
m_baseStats.tenacity = paramGrowthInfo.base_secondary;
m_baseStats.max_mp = Math::CalcStats::calculateMaxMp( getAsPlayer() ); m_baseStats.max_mp = Math::CalcStats::calculateMaxMp( getAsPlayer() );
@ -434,6 +435,9 @@ void Core::Entity::Player::setZone( uint32_t zoneId )
gcAffPacket.data().gcRank[1] = m_gcRank[1]; gcAffPacket.data().gcRank[1] = m_gcRank[1];
gcAffPacket.data().gcRank[2] = m_gcRank[2]; gcAffPacket.data().gcRank[2] = m_gcRank[2];
queuePacket( gcAffPacket ); queuePacket( gcAffPacket );
m_itemLevel = getInventory()->calculateEquippedGearItemLevel();
sendItemLevel();
} }
ZoneChannelPacket< FFXIVIpcInitZone > initZonePacket( getId() ); ZoneChannelPacket< FFXIVIpcInitZone > initZonePacket( getId() );
@ -1577,6 +1581,11 @@ void Core::Entity::Player::setOpeningSequence( uint8_t seq )
m_openingSequence = seq; m_openingSequence = seq;
} }
uint16_t Core::Entity::Player::getItemLevel() const
{
return m_itemLevel;
}
/// Tells client to offset their eorzean time by given timestamp. /// Tells client to offset their eorzean time by given timestamp.
void Core::Entity::Player::setEorzeaTimeOffset( uint64_t timestamp ) void Core::Entity::Player::setEorzeaTimeOffset( uint64_t timestamp )
{ {

View file

@ -206,6 +206,10 @@ public:
void unequipItem( Inventory::EquipSlot equipSlotId, ItemPtr pItem ); void unequipItem( Inventory::EquipSlot equipSlotId, ItemPtr pItem );
/*! equip a weapon, possibly forcing a job change */ /*! equip a weapon, possibly forcing a job change */
void equipWeapon( ItemPtr pItem ); void equipWeapon( ItemPtr pItem );
/*! get player ilvl */
uint16_t getItemLevel() const;
/*! send player ilvl */
void sendItemLevel();
/*! get a const pointer to the inventory object */ /*! get a const pointer to the inventory object */
InventoryPtr getInventory() const; InventoryPtr getInventory() const;
/*! get the current main hand model */ /*! get the current main hand model */
@ -592,16 +596,20 @@ private:
uint8_t m_openingSequence; uint8_t m_openingSequence;
uint16_t m_itemLevel;
InventoryPtr m_pInventory; InventoryPtr m_pInventory;
std::map< uint32_t, Event::EventPtr > m_eventMap; std::map< uint32_t, Event::EventPtr > m_eventMap;
std::map< uint32_t, uint8_t > m_playerIdToSpawnIdMap; // maps player to spawn id 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_freeSpawnIdQueue; // queue with spawn ids free to be assigned
std::queue< uint8_t > m_freeHateSlotQueue; // queue with "hate slots" 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_actorIdTohateSlotMap;
std::map< uint32_t, uint8_t > m_questIdToQuestIdx; // quest mapping, quest id to quest container index 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 std::map< uint8_t, uint32_t > m_questIdxToQuestId; // quest mapping, quest container index to questId
boost::shared_ptr< Common::QuestActive > m_activeQuests[30]; boost::shared_ptr< Common::QuestActive > m_activeQuests[30];
int16_t m_questTracking[5]; int16_t m_questTracking[5];
uint8_t m_stateFlags[7]; uint8_t m_stateFlags[7];
uint8_t m_gmRank; uint8_t m_gmRank;
uint16_t zoneId; uint16_t zoneId;

View file

@ -1,17 +1,21 @@
#include <src/servers/Server_Common/Common.h> #include <src/servers/Server_Common/Common.h>
#include <src/servers/Server_Common/Exd/ExdData.h>
#include <src/servers/Server_Common/Network/GamePacket.h>
#include <src/servers/Server_Common/Logging/Logger.h>
#include "Player.h" #include "Player.h"
#include "src/servers/Server_Zone/Zone/ZoneMgr.h" #include "src/servers/Server_Zone/Zone/ZoneMgr.h"
#include "src/servers/Server_Zone/Zone/Zone.h" #include "src/servers/Server_Zone/Zone/Zone.h"
#include <src/servers/Server_Common/Network/GamePacket.h> #include "src/servers/Server_Zone/Network/PacketWrappers/ActorControlPacket142.h"
#include "src/servers/Server_Zone/Network/PacketWrappers/ActorControlPacket143.h" #include "src/servers/Server_Zone/Network/PacketWrappers/ActorControlPacket143.h"
#include "src/servers/Server_Zone/Inventory/Inventory.h" #include "src/servers/Server_Zone/Inventory/Inventory.h"
#include "src/servers/Server_Zone/Inventory/Item.h" #include "src/servers/Server_Zone/Inventory/Item.h"
extern Core::Logger g_log;
using namespace Core::Common; using namespace Core::Common;
using namespace Core::Network::Packets; using namespace Core::Network::Packets;
using namespace Core::Network::Packets::Server; using namespace Core::Network::Packets::Server;
@ -21,6 +25,11 @@ Core::InventoryPtr Core::Entity::Player::getInventory() const
return m_pInventory; return m_pInventory;
} }
void Core::Entity::Player::sendItemLevel()
{
queuePacket( ActorControlPacket142( getId(), SetItemLevel, getItemLevel(), 0 ) );
}
// TODO: This has to be redone and simplified // TODO: This has to be redone and simplified
void Core::Entity::Player::equipWeapon( Core::ItemPtr pItem ) void Core::Entity::Player::equipWeapon( Core::ItemPtr pItem )
{ {
@ -77,10 +86,10 @@ void Core::Entity::Player::equipWeapon( Core::ItemPtr pItem )
} }
// equip an item // equip an item
void Core::Entity::Player::equipItem( Inventory::EquipSlot equipSlotId, Core::ItemPtr pItem, bool sendModel ) void Core::Entity::Player::equipItem( Inventory::EquipSlot equipSlotId, Core::ItemPtr pItem, bool sendUpdate )
{ {
// Console->outDebOnly("Equipping into slot %i", equipSlotID); //g_log.debug( "Equipping into slot " + std::to_string( equipSlotId ) );
uint64_t model = pItem->getModelId1(); uint64_t model = pItem->getModelId1();
uint64_t model2 = pItem->getModelId2(); uint64_t model2 = pItem->getModelId2();
@ -109,14 +118,21 @@ void Core::Entity::Player::equipItem( Inventory::EquipSlot equipSlotId, Core::It
} }
if( sendModel ) if( sendUpdate )
{
this->sendModel(); this->sendModel();
m_itemLevel = getInventory()->calculateEquippedGearItemLevel();
sendItemLevel();
}
} }
void Core::Entity::Player::unequipItem( Inventory::EquipSlot equipSlotId, ItemPtr pItem ) void Core::Entity::Player::unequipItem( Inventory::EquipSlot equipSlotId, ItemPtr pItem )
{ {
m_modelEquip[static_cast< uint8_t >( equipSlotId )] = 0; m_modelEquip[static_cast< uint8_t >( equipSlotId )] = 0;
sendModel(); sendModel();
m_itemLevel = getInventory()->calculateEquippedGearItemLevel();
sendItemLevel();
} }
uint32_t Core::Entity::Player::getCurrency( uint8_t type ) const uint32_t Core::Entity::Player::getCurrency( uint8_t type ) const

View file

@ -13,6 +13,7 @@
#include "src/servers/Server_Zone/Network/PacketWrappers/ServerNoticePacket.h" #include "src/servers/Server_Zone/Network/PacketWrappers/ServerNoticePacket.h"
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/algorithm/clamp.hpp>
#include "src/servers/Server_Zone/Forwards.h" #include "src/servers/Server_Zone/Forwards.h"
#include "src/servers/Server_Zone/Network/PacketWrappers/ActorControlPacket143.h" #include "src/servers/Server_Zone/Network/PacketWrappers/ActorControlPacket143.h"
@ -438,6 +439,30 @@ bool Core::Inventory::removeCrystal( CrystalType type, uint32_t amount )
return true; return true;
} }
bool Core::Inventory::isOneHandedWeapon( ItemUICategory weaponCategory )
{
switch ( weaponCategory )
{
case ItemUICategory::AlchemistsPrimaryTool:
case ItemUICategory::ArmorersPrimaryTool:
case ItemUICategory::BotanistsPrimaryTool:
case ItemUICategory::CulinariansPrimaryTool:
case ItemUICategory::OnehandedConjurersArm:
case ItemUICategory::CarpentersPrimaryTool:
case ItemUICategory::FishersPrimaryTool:
case ItemUICategory::GladiatorsArm:
case ItemUICategory::GoldsmithsPrimaryTool:
case ItemUICategory::LeatherworkersPrimaryTool:
case ItemUICategory::MinersPrimaryTool:
case ItemUICategory::OnehandedThaumaturgesArm:
case ItemUICategory::WeaversPrimaryTool:
case ItemUICategory::BlacksmithsPrimaryTool:
return true;
default:
return false;
}
}
bool Core::Inventory::isObtainable( uint32_t catalogId, uint8_t quantity ) bool Core::Inventory::isObtainable( uint32_t catalogId, uint8_t quantity )
{ {
@ -450,7 +475,8 @@ int16_t Core::Inventory::addItem( uint16_t inventoryId, int8_t slotId, uint32_t
auto itemInfo = g_exdData.getItemInfo( catalogId ); auto itemInfo = g_exdData.getItemInfo( catalogId );
if( !itemInfo ) // if item data doesn't exist or it's a blank field
if( !itemInfo || itemInfo->item_level == 0 )
{ {
return -1; return -1;
} }
@ -828,6 +854,40 @@ void Core::Inventory::send()
} }
uint16_t Core::Inventory::calculateEquippedGearItemLevel()
{
uint32_t iLvlResult = 0;
auto gearSetMap = m_inventoryMap[GearSet0]->getItemMap();
auto it = gearSetMap.begin();
while ( it != gearSetMap.end() )
{
auto currItem = it->second;
if ( currItem )
{
iLvlResult += currItem->getItemLevel();
// If item is weapon and isn't one-handed
if ( currItem->isWeapon() && !isOneHandedWeapon( currItem->getCategory() ) )
{
iLvlResult += currItem->getItemLevel();
}
else
{
g_log.debug( "Is one handed" );
}
}
it++;
}
return boost::algorithm::clamp( iLvlResult / 12, 0, 9999 );
}
uint8_t Core::Inventory::getFreeSlotsInBags() uint8_t Core::Inventory::getFreeSlotsInBags()
{ {
uint8_t slots = 0; uint8_t slots = 0;

View file

@ -153,6 +153,10 @@ public:
bool updateContainer( uint16_t containerId, uint8_t slotId, ItemPtr pItem ); bool updateContainer( uint16_t containerId, uint8_t slotId, ItemPtr pItem );
/*! heck if weapon category qualifies the weapon as onehanded */
bool isOneHandedWeapon( Common::ItemUICategory weaponCategory );
/*! calculate and return player ilvl based off equipped gear */
uint16_t calculateEquippedGearItemLevel();
/*! return the current amount of currency of type */ /*! return the current amount of currency of type */
uint32_t getCurrency( CurrencyType type ); uint32_t getCurrency( CurrencyType type );
/*! add amount to the current of type */ /*! add amount to the current of type */

View file

@ -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_magicalDmg = itemInfo->magical_damage;
m_weaponDmg = ( m_physicalDmg != 0 ) ? m_physicalDmg : m_magicalDmg; m_weaponDmg = ( m_physicalDmg != 0 ) ? m_physicalDmg : m_magicalDmg;
m_autoAttackDmg = static_cast< float >( m_weaponDmg * m_delayMs ) / 3000; m_autoAttackDmg = static_cast< float >( m_weaponDmg * m_delayMs ) / 3000;
m_itemLevel = itemInfo->item_level;
} }
Core::Item::~Item() Core::Item::~Item()
@ -57,11 +58,21 @@ uint16_t Core::Item::getMagicalDmg() const
return m_magicalDmg; return m_magicalDmg;
} }
uint16_t Core::Item::getItemLevel() const
{
return m_itemLevel;
}
uint16_t Core::Item::getWeaponDmg() const uint16_t Core::Item::getWeaponDmg() const
{ {
return m_weaponDmg; return m_weaponDmg;
} }
bool Core::Item::isWeapon() const
{
return (m_weaponDmg != 0);
}
uint32_t Core::Item::getId() const uint32_t Core::Item::getId() const
{ {
return m_id; return m_id;

View file

@ -48,8 +48,12 @@ public:
uint16_t getWeaponDmg() const; uint16_t getWeaponDmg() const;
bool isWeapon() const;
float getAutoAttackDmg() const; float getAutoAttackDmg() const;
uint16_t getItemLevel() const;
protected: protected:
uint32_t m_id; uint32_t m_id;
@ -71,6 +75,7 @@ protected:
uint16_t m_magicalDmg; uint16_t m_magicalDmg;
uint16_t m_weaponDmg; uint16_t m_weaponDmg;
float m_autoAttackDmg; float m_autoAttackDmg;
uint16_t m_itemLevel;
}; };

View file

@ -228,10 +228,15 @@ void Core::Network::GameConnection::actionHandler( const Packets::GamePacket& in
} }
break; break;
} }
case 0x1B5: // Dye item
{
break;
}
default: default:
{ {
g_log.debug( "[" + std::to_string( m_pSession->getId() ) + "] Unhandled action: " + g_log.debug( "[" + std::to_string( m_pSession->getId() ) + "] Unhandled action: " +
boost::str( boost::format( "%|04X|" ) % (uint32_t) ( commandId & 0xFFFF ) ) ); boost::str( boost::format( "%|04X|" ) % (uint32_t) ( commandId & 0xFFFF ) ) );
break;
} }
} }
} }