1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-26 06:27:45 +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_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<PlayerStats>
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<PlayerStats>
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<PlayerStateFlags>
struct FFXIVIpcPlayerClassInfo : FFXIVIpcBasePacket<PlayerClassInfo>
{
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];
};
/**

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 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 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 )

View file

@ -80,7 +80,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;

View file

@ -242,6 +242,7 @@ void Core::Entity::Player::calculateStats()
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 = 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[2] = m_gcRank[2];
queuePacket( gcAffPacket );
m_itemLevel = getInventory()->calculateEquippedGearItemLevel();
sendItemLevel();
}
ZoneChannelPacket< FFXIVIpcInitZone > initZonePacket( getId() );
@ -1577,6 +1581,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 )
{

View file

@ -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 */
@ -592,16 +596,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;

View file

@ -1,17 +1,21 @@
#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 "src/servers/Server_Zone/Zone/ZoneMgr.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/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 )
{
@ -77,10 +86,10 @@ void Core::Entity::Player::equipWeapon( Core::ItemPtr pItem )
}
// 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 model2 = pItem->getModelId2();
@ -109,14 +118,21 @@ void Core::Entity::Player::equipItem( Inventory::EquipSlot equipSlotId, Core::It
}
if( sendModel )
if( sendUpdate )
{
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

View file

@ -13,6 +13,7 @@
#include "src/servers/Server_Zone/Network/PacketWrappers/ServerNoticePacket.h"
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/clamp.hpp>
#include "src/servers/Server_Zone/Forwards.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;
}
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 )
{
@ -450,7 +475,8 @@ int16_t Core::Inventory::addItem( uint16_t inventoryId, int8_t slotId, uint32_t
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;
}
@ -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 slots = 0;

View file

@ -153,6 +153,10 @@ public:
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 */
uint32_t getCurrency( CurrencyType 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_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,11 +58,21 @@ 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;
}
bool Core::Item::isWeapon() const
{
return (m_weaponDmg != 0);
}
uint32_t Core::Item::getId() const
{
return m_id;

View file

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

View file

@ -228,10 +228,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;
}
}
}