From c2ca32592c03659d5824bf30379566470d428b14 Mon Sep 17 00:00:00 2001 From: Mordred Date: Thu, 28 Mar 2019 22:58:40 +0100 Subject: [PATCH] Hunting log now implemented for classes. GC still to come --- src/common/Network/CommonActorControl.h | 5 ++ src/world/Actor/Player.cpp | 63 +++++++++++++++++++++++++ src/world/Actor/Player.h | 7 ++- src/world/Actor/PlayerSql.cpp | 23 +++++++++ 4 files changed, 97 insertions(+), 1 deletion(-) diff --git a/src/common/Network/CommonActorControl.h b/src/common/Network/CommonActorControl.h index e204e931..d104732b 100644 --- a/src/common/Network/CommonActorControl.h +++ b/src/common/Network/CommonActorControl.h @@ -199,6 +199,11 @@ enum ActorControlType : uint16_t GilTrailMsg = 0x211, + HuntingLogRankUnlock = 0x21D, + HuntingLogEntryUpdate = 0x21E, + HuntingLogSectionFinish = 0x21F, + HuntingLogRankFinish = 0x220, + SetMaxGearSets = 0x230, SetCharaGearParamUI = 0x260, diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index 2654df97..eb08142a 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -1134,6 +1134,11 @@ void Sapphire::Entity::Player::onMobKill( uint16_t nameId ) { auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >(); pScriptMgr->onBNpcKill( *getAsPlayer(), nameId ); + + if( isActionLearned( static_cast< uint8_t >( Common::UnlockEntry::HuntingLog ) ) ) + { + updateHuntingLog( nameId ); + } } void Sapphire::Entity::Player::freePlayerSpawnId( uint32_t actorId ) @@ -2029,3 +2034,61 @@ void Sapphire::Entity::Player::sendHuntingLog() queuePacket( huntPacket ); } } + +void Sapphire::Entity::Player::updateHuntingLog( uint16_t id ) +{ + std::vector< uint32_t > rankRewards{ 2500, 10000, 20000, 30000, 40000 }; + const auto maxRank = 4; + auto pExdData = m_pFw->get< Data::ExdDataGenerated >(); + + auto& logEntry = m_huntingLogEntries[ static_cast< uint8_t >( getClass() ) - 1 ]; + + bool logChanged = false; + + bool allSectionsComplete = true; + for( int i = 1; i <= 10; ++i ) + { + bool sectionComplete = true; + bool sectionChanged = false; + uint32_t monsterNoteId = static_cast< uint32_t >( ( static_cast< uint8_t >( getClass() ) ) * 10000 + logEntry.rank * 10 + i ); + auto note = pExdData->get< Sapphire::Data::MonsterNote >( monsterNoteId ); + for( auto x = 0; x < 4; ++x ) + { + Logger::debug( "checking monsterNoteId#{}, monsternoteTarget#{}", monsterNoteId, note->monsterNoteTarget[ x ] ); + auto note1 = pExdData->get< Sapphire::Data::MonsterNoteTarget >( note->monsterNoteTarget[ x ] ); + if( note1->bNpcName == id && logEntry.entries[ i - 1 ][ x ] < note->count[ x ] ) + { + logEntry.entries[ i - 1 ][ x ]++; + queuePacket( makeActorControl143( getId(), HuntingLogEntryUpdate, monsterNoteId, x, logEntry.entries[ i - 1 ][ x ] ) ); + Logger::debug( "Kill counts!" ); + logChanged = true; + sectionChanged = true; + } + if( logEntry.entries[ i - 1 ][ x ] != note->count[ x ] ) + sectionComplete = false; + } + if( logChanged && sectionComplete && sectionChanged ) + { + queuePacket( makeActorControl143( getId(), HuntingLogSectionFinish, monsterNoteId, i, 0 ) ); + gainExp( note->reward ); + } + if( !sectionComplete ) + { + allSectionsComplete = false; + } + } + if( logChanged && allSectionsComplete ) + { + queuePacket( makeActorControl143( getId(), HuntingLogRankFinish, 4, 0, 0 ) ); + gainExp( rankRewards[ logEntry.rank ] ); + if( logEntry.rank < 4 ) + { + logEntry.rank++; + memset( logEntry.entries, 0, 40 ); + queuePacket( makeActorControl143( getId(), HuntingLogRankUnlock, + static_cast< uint8_t >( getClass() ), logEntry.rank + 1, 0 ) ); + } + } + sendHuntingLog(); +} + diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index 007a2bae..3a7e6795 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -966,6 +966,12 @@ namespace Sapphire::Entity Common::HuntingLogEntry& getHuntingLogEntry( uint8_t index ); + void sendHuntingLog(); + + void updateDbMonsterNote(); + + void updateHuntingLog( uint16_t id ); + ////////////////////////////////////////////////////////////////////////////////////////////////////// uint64_t m_lastMoveTime; @@ -1100,7 +1106,6 @@ namespace Sapphire::Entity std::array< Common::HuntingLogEntry, 12 > m_huntingLogEntries; - void sendHuntingLog(); }; } diff --git a/src/world/Actor/PlayerSql.cpp b/src/world/Actor/PlayerSql.cpp index 1d23d0ff..1fe30904 100644 --- a/src/world/Actor/PlayerSql.cpp +++ b/src/world/Actor/PlayerSql.cpp @@ -494,6 +494,9 @@ void Sapphire::Entity::Player::updateSql() ////// Class updateDbClass(); + ////// MonterNote + updateDbMonsterNote(); + } void Sapphire::Entity::Player::updateDbClass() const @@ -511,6 +514,26 @@ void Sapphire::Entity::Player::updateDbClass() const pDb->execute( stmtS ); } +void Sapphire::Entity::Player::updateDbMonsterNote() +{ + auto pDb = m_pFw->get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); + // Category_0-11 + auto stmt = pDb->getPreparedStatement( Db::CHARA_MONSTERNOTE_UP ); + //std::array< std::vector< uint8_t >, 12 > vectors; + std::vector< uint8_t > vector( 41 ); + for( std::size_t i = 0; i < m_huntingLogEntries.size(); ++i ) + { + vector[ 0 ] = m_huntingLogEntries[ i ].rank; + + memcpy( &vector[ 1 ], + reinterpret_cast< uint8_t* >( m_huntingLogEntries[ i ].entries ), + 40 ); + stmt->setBinary( i + 1, vector ); + } + stmt->setInt( 13, m_id ); + pDb->execute( stmt ); +} + void Sapphire::Entity::Player::insertDbClass( const uint8_t classJobIndex ) const { auto pDb = m_pFw->get< Db::DbWorkerPool< Db::ZoneDbConnection > >();