2017-08-19 00:18:40 +02:00
|
|
|
#include <src/servers/Server_Common/Common.h>
|
2017-11-16 00:03:36 -02:00
|
|
|
#include <src/servers/Server_Common/Exd/ExdData.h>
|
|
|
|
#include <src/servers/Server_Common/Network/GamePacket.h>
|
|
|
|
#include <src/servers/Server_Common/Logging/Logger.h>
|
2017-08-08 13:53:47 +02:00
|
|
|
|
|
|
|
#include "Player.h"
|
|
|
|
|
2017-08-18 17:16:15 +02:00
|
|
|
#include "src/servers/Server_Zone/Zone/ZoneMgr.h"
|
|
|
|
#include "src/servers/Server_Zone/Zone/Zone.h"
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2017-11-16 00:03:36 -02:00
|
|
|
#include "src/servers/Server_Zone/Network/PacketWrappers/ActorControlPacket142.h"
|
2017-08-18 17:16:15 +02:00
|
|
|
#include "src/servers/Server_Zone/Network/PacketWrappers/ActorControlPacket143.h"
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2017-08-18 17:16:15 +02:00
|
|
|
#include "src/servers/Server_Zone/Inventory/Inventory.h"
|
|
|
|
#include "src/servers/Server_Zone/Inventory/Item.h"
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2017-11-16 00:03:36 -02:00
|
|
|
extern Core::Logger g_log;
|
|
|
|
|
2017-08-08 13:53:47 +02:00
|
|
|
using namespace Core::Common;
|
|
|
|
using namespace Core::Network::Packets;
|
|
|
|
using namespace Core::Network::Packets::Server;
|
|
|
|
|
2017-09-04 01:36:19 -03:00
|
|
|
Core::InventoryPtr Core::Entity::Player::getInventory() const
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
|
|
|
return m_pInventory;
|
|
|
|
}
|
|
|
|
|
2017-11-16 00:03:36 -02:00
|
|
|
void Core::Entity::Player::sendItemLevel()
|
|
|
|
{
|
|
|
|
queuePacket( ActorControlPacket142( getId(), SetItemLevel, getItemLevel(), 0 ) );
|
|
|
|
}
|
|
|
|
|
2017-08-08 13:53:47 +02:00
|
|
|
// TODO: This has to be redone and simplified
|
|
|
|
void Core::Entity::Player::equipWeapon( Core::ItemPtr pItem )
|
|
|
|
{
|
|
|
|
ClassJob currentClass = static_cast< ClassJob >( getClass() );
|
|
|
|
|
|
|
|
switch( pItem->getCategory() )
|
|
|
|
{
|
|
|
|
case ItemCategory::PugWep:
|
|
|
|
if( currentClass != ClassJob::CLASS_PUGILIST &&
|
|
|
|
currentClass != ClassJob::JOB_MONK )
|
|
|
|
setClassJob( ClassJob::CLASS_PUGILIST );
|
|
|
|
break;
|
|
|
|
case ItemCategory::GlaWep:
|
|
|
|
if( currentClass != ClassJob::CLASS_GLADIATOR &&
|
|
|
|
currentClass != ClassJob::JOB_KNIGHT )
|
|
|
|
setClassJob( ClassJob::CLASS_GLADIATOR );
|
|
|
|
break;
|
|
|
|
case ItemCategory::MrdWep:
|
|
|
|
if( currentClass != ClassJob::CLASS_MARAUDER &&
|
|
|
|
currentClass != ClassJob::JOB_WARRIOR )
|
|
|
|
setClassJob( ClassJob::CLASS_MARAUDER );
|
|
|
|
break;
|
|
|
|
case ItemCategory::ArcWep:
|
|
|
|
if( currentClass != ClassJob::CLASS_ARCHER &&
|
|
|
|
currentClass != ClassJob::JOB_BARD )
|
|
|
|
setClassJob( ClassJob::CLASS_ARCHER );
|
|
|
|
break;
|
|
|
|
case ItemCategory::LncWep:
|
|
|
|
if( currentClass != ClassJob::CLASS_LANCER &&
|
|
|
|
currentClass != ClassJob::JOB_DRAGON )
|
|
|
|
setClassJob( ClassJob::CLASS_LANCER );
|
|
|
|
break;
|
|
|
|
case ItemCategory::ThmWep:
|
|
|
|
case ItemCategory::Thm2Wep:
|
|
|
|
if( currentClass != ClassJob::CLASS_THAUMATURGE &&
|
2017-08-20 02:46:06 -03:00
|
|
|
currentClass != ClassJob::JOB_BLACKMAGE )
|
2017-08-08 13:53:47 +02:00
|
|
|
setClassJob( ClassJob::CLASS_THAUMATURGE );
|
|
|
|
break;
|
|
|
|
case ItemCategory::CnjWep:
|
|
|
|
case ItemCategory::Cnj2Wep:
|
|
|
|
if( currentClass != ClassJob::CLASS_CONJURER &&
|
2017-08-20 02:46:06 -03:00
|
|
|
currentClass != ClassJob::JOB_WHITEMAGE )
|
2017-08-08 13:53:47 +02:00
|
|
|
setClassJob( ClassJob::CLASS_CONJURER );
|
|
|
|
break;
|
|
|
|
case ItemCategory::ArnWep:
|
|
|
|
if( currentClass != ClassJob::CLASS_ARCANIST &&
|
|
|
|
currentClass != ClassJob::JOB_SUMMONER &&
|
|
|
|
currentClass != ClassJob::JOB_SCHOLAR )
|
|
|
|
setClassJob( ClassJob::CLASS_ARCANIST );
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// equip an item
|
|
|
|
void Core::Entity::Player::equipItem( Inventory::EquipSlot equipSlotId, Core::ItemPtr pItem, bool sendModel )
|
|
|
|
{
|
|
|
|
|
2017-11-16 00:03:36 -02:00
|
|
|
//g_log.debug( "Equipping into slot " + std::to_string( equipSlotId ) );
|
2017-08-08 13:53:47 +02:00
|
|
|
|
|
|
|
uint64_t model = pItem->getModelId1();
|
|
|
|
uint64_t model2 = pItem->getModelId2();
|
|
|
|
|
|
|
|
switch( equipSlotId )
|
|
|
|
{
|
|
|
|
case Inventory::EquipSlot::MainHand:
|
|
|
|
m_modelMainWeapon = model;
|
|
|
|
m_modelSubWeapon = model2;
|
|
|
|
// TODO: add job change upon changing weapon if needed
|
|
|
|
// equipWeapon( pItem );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Inventory::EquipSlot::OffHand:
|
|
|
|
m_modelSubWeapon = model;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Inventory::EquipSlot::SoulCrystal:
|
|
|
|
// TODO: add Job change on equipping crystal
|
|
|
|
// change job
|
|
|
|
break;
|
|
|
|
|
|
|
|
default: // any other slot
|
|
|
|
m_modelEquip[static_cast< uint8_t >( equipSlotId )] = static_cast< uint32_t >( model );
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if( sendModel )
|
|
|
|
this->sendModel();
|
2017-11-16 00:03:36 -02:00
|
|
|
|
|
|
|
m_itemLevel = getInventory()->calculateEquippedGearItemLevel();
|
|
|
|
sendItemLevel();
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Entity::Player::unequipItem( Inventory::EquipSlot equipSlotId, ItemPtr pItem )
|
|
|
|
{
|
|
|
|
m_modelEquip[static_cast< uint8_t >( equipSlotId )] = 0;
|
|
|
|
sendModel();
|
2017-11-16 00:03:36 -02:00
|
|
|
|
|
|
|
m_itemLevel = getInventory()->calculateEquippedGearItemLevel();
|
|
|
|
sendItemLevel();
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t Core::Entity::Player::getCurrency( uint8_t type ) const
|
|
|
|
{
|
|
|
|
return m_pInventory->getCurrency( static_cast< Inventory::CurrencyType >( type ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: these next functions are so similar that they could likely be simplified
|
|
|
|
void Core::Entity::Player::addCurrency( uint8_t type, uint32_t amount )
|
|
|
|
{
|
|
|
|
if( !m_pInventory->addCurrency( static_cast< Inventory::CurrencyType >( type ), amount ) )
|
|
|
|
return;
|
|
|
|
|
2017-08-20 22:31:23 +02:00
|
|
|
GamePacketNew< FFXIVIpcUpdateInventorySlot, ServerZoneIpcType > invUpPacket( getId() );
|
2017-08-08 13:53:47 +02:00
|
|
|
invUpPacket.data().containerId = Inventory::InventoryType::Currency;
|
|
|
|
invUpPacket.data().catalogId = 1;
|
|
|
|
invUpPacket.data().quantity = m_pInventory->getCurrency( static_cast< Inventory::CurrencyType >( type ) );
|
|
|
|
invUpPacket.data().slot = static_cast< uint8_t >( type ) - 1;
|
|
|
|
|
|
|
|
queuePacket( invUpPacket );
|
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Entity::Player::removeCurrency( uint8_t type, uint32_t amount )
|
|
|
|
{
|
|
|
|
if( !m_pInventory->removeCurrency( static_cast< Inventory::CurrencyType >( type ), amount ) )
|
|
|
|
return;
|
|
|
|
|
2017-08-20 22:31:23 +02:00
|
|
|
GamePacketNew< FFXIVIpcUpdateInventorySlot, ServerZoneIpcType > invUpPacket( getId() );
|
2017-08-08 13:53:47 +02:00
|
|
|
invUpPacket.data().containerId = Inventory::InventoryType::Currency;
|
|
|
|
invUpPacket.data().catalogId = 1;
|
|
|
|
invUpPacket.data().quantity = m_pInventory->getCurrency( static_cast< Inventory::CurrencyType >( type ) );
|
|
|
|
invUpPacket.data().slot = static_cast< uint8_t >( type ) - 1;
|
|
|
|
|
|
|
|
queuePacket( invUpPacket );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t Core::Entity::Player::getCrystal( uint8_t type ) const
|
|
|
|
{
|
|
|
|
return m_pInventory->getCrystal( static_cast< Inventory::CrystalType >( type ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Entity::Player::addCrystal( uint8_t type, uint32_t amount )
|
|
|
|
{
|
|
|
|
if( !m_pInventory->addCrystal( static_cast< Inventory::CrystalType >( type ), amount ) )
|
|
|
|
return;
|
|
|
|
|
2017-08-20 22:31:23 +02:00
|
|
|
GamePacketNew< FFXIVIpcUpdateInventorySlot, ServerZoneIpcType > invUpPacket( getId() );
|
2017-08-08 13:53:47 +02:00
|
|
|
invUpPacket.data().containerId = Inventory::InventoryType::Crystal;
|
|
|
|
invUpPacket.data().catalogId = static_cast< uint8_t >( type ) + 1;
|
|
|
|
invUpPacket.data().quantity = m_pInventory->getCrystal( static_cast< Inventory::CrystalType >( type ) );
|
|
|
|
invUpPacket.data().slot = static_cast< uint8_t >( type ) - 1;
|
|
|
|
|
|
|
|
queuePacket( invUpPacket );
|
|
|
|
|
|
|
|
queuePacket( ActorControlPacket143( getId(), ItemObtainIcon, static_cast< uint8_t >( type ) + 1, amount ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Entity::Player::removeCrystal( uint8_t type, uint32_t amount )
|
|
|
|
{
|
|
|
|
if( !m_pInventory->removeCrystal( static_cast< Inventory::CrystalType >( type ), amount ) )
|
|
|
|
return;
|
|
|
|
|
2017-08-20 22:31:23 +02:00
|
|
|
GamePacketNew< FFXIVIpcUpdateInventorySlot, ServerZoneIpcType > invUpPacket( getId() );
|
2017-08-08 13:53:47 +02:00
|
|
|
invUpPacket.data().containerId = Inventory::InventoryType::Crystal;
|
|
|
|
invUpPacket.data().catalogId = static_cast< uint8_t >( type ) + 1;
|
|
|
|
invUpPacket.data().quantity = m_pInventory->getCrystal( static_cast< Inventory::CrystalType >( type ) );
|
|
|
|
invUpPacket.data().slot = static_cast< uint8_t >( type ) - 1;
|
|
|
|
|
|
|
|
queuePacket( invUpPacket );
|
|
|
|
}
|
|
|
|
|
2017-10-22 18:53:58 -07:00
|
|
|
bool Core::Entity::Player::tryAddItem( uint16_t catalogId, uint32_t quantity )
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
|
|
|
|
2017-10-22 18:53:58 -07:00
|
|
|
for( uint16_t i = 0; i < 4; i++ )
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
|
|
|
if( m_pInventory->addItem( i, -1, catalogId, quantity ) != -1 )
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-10-22 18:53:58 -07:00
|
|
|
bool Core::Entity::Player::addItem( uint16_t containerId, uint16_t catalogId, uint32_t quantity )
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
|
|
|
if( m_pInventory->addItem( containerId, -1, catalogId, quantity ) != -1 )
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Entity::Player::sendInventory() const
|
|
|
|
{
|
|
|
|
m_pInventory->send();
|
|
|
|
}
|
|
|
|
|