mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-27 22:57:45 +00:00
Persistence for cross-class skills
This commit is contained in:
parent
cf32d4fe4d
commit
f4a3c9493b
9 changed files with 54 additions and 8 deletions
1
sql/migrations/20230309164293_AddBorrowAction.sql
Normal file
1
sql/migrations/20230309164293_AddBorrowAction.sql
Normal file
|
@ -0,0 +1 @@
|
|||
ALTER TABLE `characlass` ADD `BorrowAction` binary(40) DEFAULT NULL NULL AFTER `Lvl`;
|
|
@ -256,12 +256,14 @@ void PlayerMinimal::saveAsNew()
|
|||
break;
|
||||
}
|
||||
|
||||
// CharacterId, ClassIdx, Exp, Lvl
|
||||
// CharacterId, ClassIdx, Exp, Lvl, BorrowAction
|
||||
auto stmtClass = g_charaDb.getPreparedStatement( Db::ZoneDbStatements::CHARA_CLASS_INS );
|
||||
stmtClass->setUInt64( 1, m_characterId );
|
||||
stmtClass->setInt( 2, g_exdData.getRow< Excel::ClassJob >( m_class )->data().WorkIndex );
|
||||
stmtClass->setInt( 3, 0 );
|
||||
stmtClass->setInt( 4, 1 );
|
||||
std::vector< uint8_t > borrowActionVec( Common::ARRSIZE_BORROWACTION * 4 );
|
||||
stmtClass->setBinary( 5, borrowActionVec );
|
||||
g_charaDb.directExecute( stmtClass );
|
||||
|
||||
auto stmtSearchInfo = g_charaDb.getPreparedStatement( Db::ZoneDbStatements::CHARA_SEARCHINFO_INS );
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace Sapphire::Common
|
|||
const uint16_t ARRSIZE_UNLOCKS = 64u;
|
||||
const uint16_t ARRSIZE_ORCHESTRION = 40u;
|
||||
const uint16_t ARRSIZE_MONSTERNOTE = 12u;
|
||||
const uint16_t ARRSIZE_BORROWACTION = 10u;
|
||||
|
||||
const uint8_t TOWN_COUNT = 6;
|
||||
|
||||
|
|
|
@ -161,11 +161,11 @@ void Sapphire::Db::ZoneDbConnection::doPrepareStatements()
|
|||
prepareStatement( CHARA_SEL_QUEST, "SELECT * FROM charaquest WHERE CharacterId = ?;", CONNECTION_SYNC );
|
||||
|
||||
/// CLASS INFO
|
||||
prepareStatement( CHARA_CLASS_SEL, "SELECT ClassIdx, Exp, Lvl FROM characlass WHERE CharacterId = ?;",
|
||||
prepareStatement( CHARA_CLASS_SEL, "SELECT ClassIdx, Exp, Lvl, BorrowAction FROM characlass WHERE CharacterId = ?;",
|
||||
CONNECTION_SYNC );
|
||||
prepareStatement( CHARA_CLASS_INS, "INSERT INTO characlass ( CharacterId, ClassIdx, Exp, Lvl ) VALUES( ?,?,?,? );",
|
||||
prepareStatement( CHARA_CLASS_INS, "INSERT INTO characlass ( CharacterId, ClassIdx, Exp, Lvl, BorrowAction ) VALUES( ?,?,?,?,? );",
|
||||
CONNECTION_BOTH );
|
||||
prepareStatement( CHARA_CLASS_UP, "UPDATE characlass SET Exp = ?, Lvl = ? WHERE CharacterId = ? AND ClassIdx = ?;",
|
||||
prepareStatement( CHARA_CLASS_UP, "UPDATE characlass SET Exp = ?, Lvl = ?, BorrowAction = ? WHERE CharacterId = ? AND ClassIdx = ?;",
|
||||
CONNECTION_ASYNC );
|
||||
prepareStatement( CHARA_CLASS_DEL, "DELETE FROM characlass WHERE CharacterId = ?;", CONNECTION_ASYNC );
|
||||
|
||||
|
|
|
@ -563,6 +563,22 @@ void Player::setRewardFlag( Common::UnlockEntry unlockId )
|
|||
Network::Util::Player::sendActorControlSelf( *this, SetRewardFlag, unlock, 1 );
|
||||
}
|
||||
|
||||
void Player::setBorrowAction( uint8_t slot, uint32_t action )
|
||||
{
|
||||
if( slot > Common::ARRSIZE_BORROWACTION )
|
||||
return;
|
||||
|
||||
auto& borrowAction = getBorrowAction();
|
||||
borrowAction[ slot ] = action;
|
||||
}
|
||||
|
||||
Player::BorrowAction& Player::getBorrowAction()
|
||||
{
|
||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||
uint8_t classJobIndex = exdData.getRow< Excel::ClassJob >( static_cast<uint8_t>( getClass() ) )->data().WorkIndex;
|
||||
return m_borrowActions[ classJobIndex ];
|
||||
}
|
||||
|
||||
void Player::learnSong( uint8_t songId, uint32_t itemId )
|
||||
{
|
||||
uint16_t index;
|
||||
|
|
|
@ -38,6 +38,7 @@ namespace Sapphire::Entity
|
|||
|
||||
using ClassList = std::array< uint16_t, Common::ARRSIZE_CLASSJOB >;
|
||||
using ExpList = std::array< uint32_t, Common::ARRSIZE_CLASSJOB >;
|
||||
using BorrowAction = std::array< uint32_t, Common::ARRSIZE_BORROWACTION >;
|
||||
|
||||
struct AchievementData {
|
||||
std::array< uint8_t, 2048 / 8 > unlockList;
|
||||
|
@ -446,6 +447,10 @@ namespace Sapphire::Entity
|
|||
/*! learn an action / update the unlock bitmask. */
|
||||
void setRewardFlag( Common::UnlockEntry unlockId );
|
||||
|
||||
void setBorrowAction( uint8_t slot, uint32_t action );
|
||||
|
||||
BorrowAction& getBorrowAction();
|
||||
|
||||
/*! learn a song / update the unlock bitmask. */
|
||||
void learnSong( uint8_t songId, uint32_t itemId );
|
||||
|
||||
|
@ -966,6 +971,8 @@ namespace Sapphire::Entity
|
|||
|
||||
std::array< Common::HuntingLogEntry, Common::ARRSIZE_MONSTERNOTE > m_huntingLogEntries{};
|
||||
|
||||
std::array< BorrowAction, Common::ARRSIZE_CLASSJOB > m_borrowActions{};
|
||||
|
||||
FriendListIDVec m_friendList{};
|
||||
FriendListDataVec m_friendInviteList{};
|
||||
|
||||
|
|
|
@ -258,7 +258,7 @@ bool Sapphire::Entity::Player::loadAchievements()
|
|||
bool Sapphire::Entity::Player::loadClassData()
|
||||
{
|
||||
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
||||
// ClassIdx, Exp, Lvl
|
||||
// ClassIdx, Exp, Lvl, BorrowAction
|
||||
auto stmt = db.getPreparedStatement( Db::ZoneDbStatements::CHARA_CLASS_SEL );
|
||||
stmt->setUInt64( 1, m_characterId );
|
||||
auto res = db.query( stmt );
|
||||
|
@ -268,9 +268,11 @@ bool Sapphire::Entity::Player::loadClassData()
|
|||
auto index = res->getUInt16( 1 );
|
||||
auto exp = res->getUInt( 2 );
|
||||
auto lvl = res->getUInt8( 3 );
|
||||
auto borrowAction = res->getBlobVector( "BorrowAction" );
|
||||
|
||||
m_classArray[ index ] = lvl;
|
||||
m_expArray[ index ] = exp;
|
||||
memcpy( m_borrowActions[ index ].data(), borrowAction.data(), borrowAction.size() );
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -487,13 +489,19 @@ void Sapphire::Entity::Player::updateDbClass() const
|
|||
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||
uint8_t classJobIndex = exdData.getRow< Excel::ClassJob >( static_cast<uint8_t>( getClass() ) )->data().WorkIndex;
|
||||
auto& borrowAction = m_borrowActions[ classJobIndex ];
|
||||
|
||||
//Exp = ?, Lvl = ? WHERE CharacterId = ? AND ClassIdx = ?
|
||||
//Exp = ?, Lvl = ?, BorrowAction = ? WHERE CharacterId = ? AND ClassIdx = ?
|
||||
auto stmtS = db.getPreparedStatement( Db::CHARA_CLASS_UP );
|
||||
stmtS->setInt( 1, getExp() );
|
||||
stmtS->setInt( 2, getLevel() );
|
||||
stmtS->setUInt64( 3, m_characterId );
|
||||
stmtS->setInt( 4, classJobIndex );
|
||||
|
||||
std::vector< uint8_t > borrowActionVec( borrowAction.size() * 4 );
|
||||
memcpy( borrowActionVec.data(), borrowAction.data(), borrowAction.size() * 4 );
|
||||
stmtS->setBinary( 3, borrowActionVec );
|
||||
|
||||
stmtS->setUInt64( 4, m_characterId );
|
||||
stmtS->setInt( 5, classJobIndex );
|
||||
db.execute( stmtS );
|
||||
}
|
||||
|
||||
|
@ -581,10 +589,14 @@ void Sapphire::Entity::Player::insertDbClass( const uint8_t classJobIndex, uint8
|
|||
{
|
||||
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
||||
auto stmtClass = db.getPreparedStatement( Db::CHARA_CLASS_INS );
|
||||
auto& borrowAction = m_borrowActions[ classJobIndex ];
|
||||
|
||||
stmtClass->setUInt64( 1, m_characterId );
|
||||
stmtClass->setInt( 2, classJobIndex );
|
||||
stmtClass->setInt( 3, 0 );
|
||||
stmtClass->setInt( 4, level );
|
||||
std::vector< uint8_t > borrowActionVec( borrowAction.size() );
|
||||
stmtClass->setBinary( 5, borrowActionVec );
|
||||
db.directExecute( stmtClass );
|
||||
}
|
||||
|
||||
|
|
|
@ -497,6 +497,11 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_
|
|||
Network::Util::Player::sendTitleList( player );
|
||||
break;
|
||||
}
|
||||
case PacketCommand::BORROW_ACTION:
|
||||
{
|
||||
player.setBorrowAction( static_cast< uint8_t >( data.Arg1 ), data.Arg2 );
|
||||
break;
|
||||
}
|
||||
case PacketCommand::SET_HOWTO: // Update howtos seen
|
||||
{
|
||||
player.updateHowtosSeen( data.Arg0 );
|
||||
|
|
|
@ -291,10 +291,12 @@ void Util::Player::sendPlayerSetup( Entity::Player& player )
|
|||
void Util::Player::sendChangeClass( Entity::Player& player )
|
||||
{
|
||||
auto classInfo = makeZonePacket< FFXIVIpcChangeClass >( player.getId() );
|
||||
auto& borrowAction = player.getBorrowAction();
|
||||
classInfo->data().ClassJob = static_cast< uint8_t >( player.getClass() );
|
||||
classInfo->data().Lv = player.getLevel();
|
||||
classInfo->data().Lv1 = player.getLevel();
|
||||
classInfo->data().Login = player.isLogin() ? 1 : 0;
|
||||
memcpy( &classInfo->data().BorrowAction[ 0 ], borrowAction.data(), borrowAction.size() * 4 );
|
||||
server().queueForPlayer( player.getCharacterId(), classInfo );
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue