mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-01 08:27:46 +00:00
Merge pull request #125 from itsMaru/master
Player title implementation;
This commit is contained in:
commit
8bf4325fcc
11 changed files with 101 additions and 17 deletions
|
@ -23,5 +23,9 @@
|
||||||
-- ALTER TABLE `charadetail` CHANGE `OpeningSequence` `OpeningSequence` INT(3) NULL DEFAULT '0';
|
-- ALTER TABLE `charadetail` CHANGE `OpeningSequence` `OpeningSequence` INT(3) NULL DEFAULT '0';
|
||||||
-- -------------------------------------------
|
-- -------------------------------------------
|
||||||
-- update.sql Before Merge into Other SQL's 30/08/2017
|
-- update.sql Before Merge into Other SQL's 30/08/2017
|
||||||
|
-- -------------------------------------------
|
||||||
|
-- ALTER TABLE `charadetail` ADD `EquipDisplayFlags` int(3) DEFAULT '0' AFTER `GMRank`;
|
||||||
|
-- -------------------------------------------
|
||||||
|
-- update.sql before titles added 09/10/2017
|
||||||
|
|
||||||
ALTER TABLE `charadetail` ADD `EquipDisplayFlags` int(3) DEFAULT '0' AFTER `GMRank`;
|
ALTER TABLE `charadetail` CHANGE `TitleList` `Titlelist` BINARY(48) NULL DEFAULT NULL;
|
|
@ -288,6 +288,7 @@ namespace Core {
|
||||||
Aetherytes = 0x00000080, // Attuned aetherytes
|
Aetherytes = 0x00000080, // Attuned aetherytes
|
||||||
HomePoint = 0x00000100, // Current homepoint
|
HomePoint = 0x00000100, // Current homepoint
|
||||||
HowTo = 0x00000200,
|
HowTo = 0x00000200,
|
||||||
|
Title = 0x00000400,
|
||||||
|
|
||||||
HpMp = 0x00000800,
|
HpMp = 0x00000800,
|
||||||
QuestTracker = 0x00001000,
|
QuestTracker = 0x00001000,
|
||||||
|
|
|
@ -114,6 +114,7 @@ namespace Packets {
|
||||||
ActorFreeSpawn = 0x0191, // unchanged for sb
|
ActorFreeSpawn = 0x0191, // unchanged for sb
|
||||||
InitZone = 0x019A, // unchanged for sb
|
InitZone = 0x019A, // unchanged for sb
|
||||||
WeatherChange = 0x01AF, // updated for sb
|
WeatherChange = 0x01AF, // updated for sb
|
||||||
|
PlayerTitleList = 0x01B1, // updated for 4.06
|
||||||
Discovery = 0x01B2, // updated for sb
|
Discovery = 0x01B2, // updated for sb
|
||||||
|
|
||||||
EorzeaTimeOffset = 0x01B4,
|
EorzeaTimeOffset = 0x01B4,
|
||||||
|
|
|
@ -639,6 +639,14 @@ struct FFXIVIpcUpdateClassInfo : FFXIVIpcBasePacket<UpdateClassInfo>
|
||||||
uint32_t restedExp;
|
uint32_t restedExp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Structural representation of the packet sent by the server
|
||||||
|
* to send the titles available to the player
|
||||||
|
*/
|
||||||
|
struct FFXIVIpcPlayerTitleList : FFXIVIpcBasePacket<PlayerTitleList>
|
||||||
|
{
|
||||||
|
uint8_t titleList[48];
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Structural representation of the packet sent by the server
|
* Structural representation of the packet sent by the server
|
||||||
|
|
|
@ -175,6 +175,9 @@ namespace Core {
|
||||||
char unlocks[64];
|
char unlocks[64];
|
||||||
memset( unlocks, 0, 64 );
|
memset( unlocks, 0, 64 );
|
||||||
|
|
||||||
|
char titleList[48];
|
||||||
|
memset( titleList, 0, 48 );
|
||||||
|
|
||||||
int16_t questTracking[5] = { -1, -1, -1, -1, -1 };
|
int16_t questTracking[5] = { -1, -1, -1, -1, -1 };
|
||||||
|
|
||||||
uint16_t size = static_cast< uint16_t >( m_lookMap.size() );
|
uint16_t size = static_cast< uint16_t >( m_lookMap.size() );
|
||||||
|
@ -270,6 +273,7 @@ namespace Core {
|
||||||
" unlocks, "
|
" unlocks, "
|
||||||
" QuestTracking, "
|
" QuestTracking, "
|
||||||
" Aetheryte, "
|
" Aetheryte, "
|
||||||
|
" TitleList, "
|
||||||
" GMRank, "
|
" GMRank, "
|
||||||
" UPDATE_DATE ) "
|
" UPDATE_DATE ) "
|
||||||
" VALUES (" + std::to_string( m_iD ) + ", "
|
" VALUES (" + std::to_string( m_iD ) + ", "
|
||||||
|
@ -285,6 +289,7 @@ namespace Core {
|
||||||
+ "UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)unlocks, 64 ) ) + "'), "
|
+ "UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)unlocks, 64 ) ) + "'), "
|
||||||
+ "UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)questTracking, 10 ) ) + "'), "
|
+ "UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)questTracking, 10 ) ) + "'), "
|
||||||
+ "UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)aetherytes, 12 ) ) + "'),"
|
+ "UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)aetherytes, 12 ) ) + "'),"
|
||||||
|
+ "UNHEX('" + std::string( Util::binaryToHexString( (uint8_t*)titleList, 48 ) ) + "'),"
|
||||||
+ std::to_string( m_gmRank ) + ", NOW());" );
|
+ std::to_string( m_gmRank ) + ", NOW());" );
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1420,10 +1420,39 @@ void Core::Entity::Player::setIsLogin( bool bIsLogin )
|
||||||
m_bIsLogin = bIsLogin;
|
m_bIsLogin = bIsLogin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t * Core::Entity::Player::getTitleList()
|
||||||
|
{
|
||||||
|
return m_titleList;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t Core::Entity::Player::getTitle() const
|
||||||
|
{
|
||||||
|
return m_title;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::Entity::Player::addTitle( uint16_t titleId )
|
||||||
|
{
|
||||||
|
uint16_t index;
|
||||||
|
uint8_t value;
|
||||||
|
Util::valueToFlagByteIndexValue( titleId, value, index );
|
||||||
|
|
||||||
|
m_titleList[index] |= value;
|
||||||
|
setSyncFlag( PlayerSyncFlags::Title );
|
||||||
|
}
|
||||||
|
|
||||||
void Core::Entity::Player::setTitle( uint16_t titleId )
|
void Core::Entity::Player::setTitle( uint16_t titleId )
|
||||||
{
|
{
|
||||||
|
uint16_t index;
|
||||||
|
uint8_t value;
|
||||||
|
Util::valueToFlagByteIndexValue( titleId, value, index );
|
||||||
|
|
||||||
|
if ( ( m_titleList[index] & value ) == 0 ) // Player doesn't have title - bail
|
||||||
|
return;
|
||||||
|
|
||||||
m_title = titleId;
|
m_title = titleId;
|
||||||
|
|
||||||
sendToInRangeSet( ActorControlPacket142( getId(), SetTitle, titleId ), true );
|
sendToInRangeSet( ActorControlPacket142( getId(), SetTitle, titleId ), true );
|
||||||
|
setSyncFlag( PlayerSyncFlags::Title );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::Entity::Player::setEquipDisplayFlags( uint8_t state )
|
void Core::Entity::Player::setEquipDisplayFlags( uint8_t state )
|
||||||
|
|
|
@ -328,7 +328,13 @@ public:
|
||||||
void teleport( uint16_t aetheryteId, uint8_t type = 1 );
|
void teleport( uint16_t aetheryteId, uint8_t type = 1 );
|
||||||
/*! prepares zoning / fades out the screen */
|
/*! prepares zoning / fades out the screen */
|
||||||
void prepareZoning( uint16_t targetZone, bool fadeOut, uint8_t fadoutTime = 0, uint16_t animation = 0 );
|
void prepareZoning( uint16_t targetZone, bool fadeOut, uint8_t fadoutTime = 0, uint16_t animation = 0 );
|
||||||
/*! change player's title */
|
/*! get player's title list (available titles) */
|
||||||
|
uint8_t * getTitleList();
|
||||||
|
/*! get player's active title */
|
||||||
|
uint16_t getTitle() const;
|
||||||
|
/*! add title to player title list */
|
||||||
|
void addTitle( uint16_t titleId );
|
||||||
|
/*! change player's active title */
|
||||||
void setTitle( uint16_t titleId );
|
void setTitle( uint16_t titleId );
|
||||||
/*! change gear param state */
|
/*! change gear param state */
|
||||||
void setEquipDisplayFlags( uint8_t state );
|
void setEquipDisplayFlags( uint8_t state );
|
||||||
|
@ -572,7 +578,7 @@ private:
|
||||||
} m_retainerInfo[8];
|
} m_retainerInfo[8];
|
||||||
|
|
||||||
uint16_t m_title;
|
uint16_t m_title;
|
||||||
uint16_t m_titleList[32];
|
uint8_t m_titleList[48];
|
||||||
uint8_t m_achievement[16];
|
uint8_t m_achievement[16];
|
||||||
uint8_t m_howTo[33];
|
uint8_t m_howTo[33];
|
||||||
uint8_t m_homePoint;
|
uint8_t m_homePoint;
|
||||||
|
|
|
@ -82,7 +82,9 @@ bool Core::Entity::Player::load( uint32_t charId, Core::SessionPtr pSession )
|
||||||
"cd.CFPenaltyUntil, "
|
"cd.CFPenaltyUntil, "
|
||||||
"cd.OpeningSequence, "
|
"cd.OpeningSequence, "
|
||||||
"cd.GMRank, "
|
"cd.GMRank, "
|
||||||
"cd.EquipDisplayFlags "
|
"cd.EquipDisplayFlags, "
|
||||||
|
"cd.ActiveTitle, "
|
||||||
|
"cd.TitleList " // 40
|
||||||
"FROM charabase AS c "
|
"FROM charabase AS c "
|
||||||
" INNER JOIN charadetail AS cd "
|
" INNER JOIN charadetail AS cd "
|
||||||
" ON c.CharacterId = cd.CharacterId "
|
" ON c.CharacterId = cd.CharacterId "
|
||||||
|
@ -176,6 +178,9 @@ bool Core::Entity::Player::load( uint32_t charId, Core::SessionPtr pSession )
|
||||||
m_gmRank = field[37].get< uint8_t >();
|
m_gmRank = field[37].get< uint8_t >();
|
||||||
m_equipDisplayFlags = field[38].get< uint8_t >();
|
m_equipDisplayFlags = field[38].get< uint8_t >();
|
||||||
|
|
||||||
|
m_title = field[39].get< uint8_t >();
|
||||||
|
field[40].getBinary( reinterpret_cast< char* >( m_titleList ), sizeof( m_titleList ) );
|
||||||
|
|
||||||
m_pCell = nullptr;
|
m_pCell = nullptr;
|
||||||
|
|
||||||
if( !loadActiveQuests() || !loadClassData() || !loadSearchInfo() )
|
if( !loadActiveQuests() || !loadClassData() || !loadSearchInfo() )
|
||||||
|
@ -316,6 +321,12 @@ void Core::Entity::Player::createUpdateSql()
|
||||||
if( m_updateFlags & PlayerSyncFlags::HowTo )
|
if( m_updateFlags & PlayerSyncFlags::HowTo )
|
||||||
charaDetailSet.insert( " HowTo = UNHEX('" + std::string( Util::binaryToHexString( static_cast< uint8_t* >( m_howTo ), sizeof( m_howTo ) ) ) + "')" );
|
charaDetailSet.insert( " HowTo = UNHEX('" + std::string( Util::binaryToHexString( static_cast< uint8_t* >( m_howTo ), sizeof( m_howTo ) ) ) + "')" );
|
||||||
|
|
||||||
|
if ( m_updateFlags & PlayerSyncFlags::Title )
|
||||||
|
{
|
||||||
|
charaDetailSet.insert( " ActiveTitle = " + std::to_string( m_title ) );
|
||||||
|
charaDetailSet.insert( " TitleList = UNHEX('" + std::string( Util::binaryToHexString( reinterpret_cast< uint8_t* >( m_titleList ), sizeof( m_titleList ) ) ) + "')" );
|
||||||
|
}
|
||||||
|
|
||||||
if( m_updateFlags & PlayerSyncFlags::Aetherytes )
|
if( m_updateFlags & PlayerSyncFlags::Aetherytes )
|
||||||
charaDetailSet.insert( " Aetheryte = UNHEX('" + std::string( Util::binaryToHexString( reinterpret_cast< uint8_t* >( m_aetheryte ), sizeof( m_aetheryte ) ) ) + "')" );
|
charaDetailSet.insert( " Aetheryte = UNHEX('" + std::string( Util::binaryToHexString( reinterpret_cast< uint8_t* >( m_aetheryte ), sizeof( m_aetheryte ) ) ) + "')" );
|
||||||
|
|
||||||
|
|
|
@ -257,13 +257,6 @@ void Core::DebugCommandHandler::set( char * data, Core::Entity::PlayerPtr pPlaye
|
||||||
pPlayer->sendModel();
|
pPlayer->sendModel();
|
||||||
pPlayer->sendDebug( "Model updated" );
|
pPlayer->sendDebug( "Model updated" );
|
||||||
}
|
}
|
||||||
else if ( subCommand == "title" )
|
|
||||||
{
|
|
||||||
uint32_t titleId;
|
|
||||||
sscanf( params.c_str(), "%d", &titleId );
|
|
||||||
|
|
||||||
pPlayer->setTitle( titleId );
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pPlayer->sendUrgent( subCommand + " is not a valid SET command." );
|
pPlayer->sendUrgent( subCommand + " is not a valid SET command." );
|
||||||
|
@ -311,6 +304,14 @@ void Core::DebugCommandHandler::add( char * data, Core::Entity::PlayerPtr pPlaye
|
||||||
|
|
||||||
pPlayer->addStatusEffect( effect );
|
pPlayer->addStatusEffect( effect );
|
||||||
}
|
}
|
||||||
|
else if ( subCommand == "title" )
|
||||||
|
{
|
||||||
|
uint32_t titleId;
|
||||||
|
sscanf( params.c_str(), "%d", &titleId );
|
||||||
|
|
||||||
|
pPlayer->addTitle( titleId );
|
||||||
|
pPlayer->sendNotice( "Added title (ID: " + std::to_string( titleId ) + ")" );
|
||||||
|
}
|
||||||
else if( subCommand == "spawn" )
|
else if( subCommand == "spawn" )
|
||||||
{
|
{
|
||||||
int32_t model, name;
|
int32_t model, name;
|
||||||
|
@ -333,7 +334,6 @@ void Core::DebugCommandHandler::add( char * data, Core::Entity::PlayerPtr pPlaye
|
||||||
pPlayer->queuePacket( pPe );
|
pPlayer->queuePacket( pPe );
|
||||||
}
|
}
|
||||||
else if( subCommand == "actrl" )
|
else if( subCommand == "actrl" )
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
// temporary research packet
|
// temporary research packet
|
||||||
|
|
|
@ -118,6 +118,19 @@ void Core::Network::GameConnection::actionHandler( const Packets::GamePacket& in
|
||||||
pPlayer->getCurrentAction()->setInterrupted();
|
pPlayer->getCurrentAction()->setInterrupted();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 0x12E: // Set player title
|
||||||
|
{
|
||||||
|
pPlayer->setTitle( param1 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x12F: // Get title list
|
||||||
|
{
|
||||||
|
GamePacketNew< FFXIVIpcPlayerTitleList, ServerZoneIpcType > titleListPacket( pPlayer->getId() );
|
||||||
|
memcpy( titleListPacket.data().titleList, pPlayer->getTitleList(), sizeof( titleListPacket.data().titleList ) );
|
||||||
|
|
||||||
|
pPlayer->queuePacket( titleListPacket );
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 0x133: // Update howtos seen
|
case 0x133: // Update howtos seen
|
||||||
{
|
{
|
||||||
uint32_t howToId = static_cast< uint32_t >( param1 );
|
uint32_t howToId = static_cast< uint32_t >( param1 );
|
||||||
|
|
|
@ -36,36 +36,42 @@ namespace Server {
|
||||||
// TODO: temporary gm rank
|
// TODO: temporary gm rank
|
||||||
//m_data.gmRank = 0xff;
|
//m_data.gmRank = 0xff;
|
||||||
|
|
||||||
|
|
||||||
m_data.currentMount = 0;
|
|
||||||
m_data.classJob = pPlayer->getClass();
|
m_data.classJob = pPlayer->getClass();
|
||||||
//m_data.status = static_cast< uint8_t >( pPlayer->getStatus() );
|
//m_data.status = static_cast< uint8_t >( pPlayer->getStatus() );
|
||||||
|
|
||||||
m_data.hPCurr = pPlayer->getHp();
|
m_data.hPCurr = pPlayer->getHp();
|
||||||
m_data.mPCurr = pPlayer->getMp();
|
m_data.mPCurr = pPlayer->getMp();
|
||||||
m_data.tPCurr = pPlayer->getTp();
|
m_data.tPCurr = pPlayer->getTp();
|
||||||
m_data.hPMax = pPlayer->getMaxHp();
|
m_data.hPMax = pPlayer->getMaxHp();
|
||||||
m_data.mPMax = pPlayer->getMaxMp();
|
m_data.mPMax = pPlayer->getMaxMp();
|
||||||
m_data.gmRank = pPlayer->getGmRank();
|
|
||||||
//m_data.tPMax = 3000;
|
//m_data.tPMax = 3000;
|
||||||
m_data.level = pPlayer->getLevel();
|
m_data.level = pPlayer->getLevel();
|
||||||
|
m_data.gmRank = pPlayer->getGmRank();
|
||||||
memcpy( m_data.look, pPlayer->getLookArray(), 26 );
|
memcpy( m_data.look, pPlayer->getLookArray(), 26 );
|
||||||
|
|
||||||
auto item = pPlayer->getInventory()->getItemAt( Inventory::GearSet0, Inventory::EquipSlot::MainHand );
|
auto item = pPlayer->getInventory()->getItemAt( Inventory::GearSet0, Inventory::EquipSlot::MainHand );
|
||||||
if( item )
|
if( item )
|
||||||
m_data.mainWeaponModel = item->getModelId1();
|
m_data.mainWeaponModel = item->getModelId1();
|
||||||
m_data.secWeaponModel = pPlayer->getModelSubWeapon();
|
m_data.secWeaponModel = pPlayer->getModelSubWeapon();
|
||||||
|
|
||||||
m_data.models[0] = pPlayer->getModelForSlot( Inventory::EquipSlot::Head );
|
m_data.models[0] = pPlayer->getModelForSlot( Inventory::EquipSlot::Head );
|
||||||
m_data.models[1] = pPlayer->getModelForSlot( Inventory::EquipSlot::Body );
|
m_data.models[1] = pPlayer->getModelForSlot( Inventory::EquipSlot::Body );
|
||||||
m_data.models[2] = pPlayer->getModelForSlot( Inventory::EquipSlot::Hands );
|
m_data.models[2] = pPlayer->getModelForSlot( Inventory::EquipSlot::Hands );
|
||||||
m_data.models[3] = pPlayer->getModelForSlot( Inventory::EquipSlot::Legs );
|
m_data.models[3] = pPlayer->getModelForSlot( Inventory::EquipSlot::Legs );
|
||||||
m_data.models[4] = pPlayer->getModelForSlot( Inventory::EquipSlot::Feet );
|
m_data.models[4] = pPlayer->getModelForSlot( Inventory::EquipSlot::Feet );
|
||||||
strcpy( m_data.name, pPlayer->getName().c_str() );
|
strcpy( m_data.name, pPlayer->getName().c_str() );
|
||||||
|
|
||||||
m_data.pos.x = pPlayer->getPos().x;
|
m_data.pos.x = pPlayer->getPos().x;
|
||||||
m_data.pos.y = pPlayer->getPos().y;
|
m_data.pos.y = pPlayer->getPos().y;
|
||||||
m_data.pos.z = pPlayer->getPos().z;
|
m_data.pos.z = pPlayer->getPos().z;
|
||||||
m_data.voice = pPlayer->getVoiceId();
|
|
||||||
|
|
||||||
m_data.rotation = Math::Util::floatToUInt16Rot( pPlayer->getRotation() );
|
m_data.rotation = Math::Util::floatToUInt16Rot( pPlayer->getRotation() );
|
||||||
|
|
||||||
|
|
||||||
|
m_data.title = pPlayer->getTitle();
|
||||||
|
m_data.voice = pPlayer->getVoiceId();
|
||||||
|
m_data.currentMount = 0;
|
||||||
|
|
||||||
m_data.onlineStatus = static_cast< uint8_t >( pPlayer->getOnlineStatus() );
|
m_data.onlineStatus = static_cast< uint8_t >( pPlayer->getOnlineStatus() );
|
||||||
|
|
||||||
//m_data.u23 = 0x04;
|
//m_data.u23 = 0x04;
|
||||||
|
|
Loading…
Add table
Reference in a new issue