2018-03-06 22:22:19 +01:00
|
|
|
#include <Network/PacketDef/Zone/ServerZoneDef.h>
|
2021-11-27 00:53:57 +01:00
|
|
|
#include <Exd/ExdData.h>
|
2020-03-01 01:00:57 +11:00
|
|
|
#include <Service.h>
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
#include "Manager/QuestMgr.h"
|
2023-02-16 22:16:01 +01:00
|
|
|
#include "Manager/MapMgr.h"
|
2021-08-30 10:16:05 +02:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
#include "Player.h"
|
2017-08-08 13:53:47 +02:00
|
|
|
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
using namespace Sapphire::Common;
|
|
|
|
using namespace Sapphire::Network::Packets;
|
|
|
|
using namespace Sapphire::Network::Packets::WorldPackets::Server;
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2021-12-21 01:05:08 +01:00
|
|
|
void Sapphire::Entity::Player::finishQuest( uint16_t questId, uint32_t optionalChoice )
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
removeQuest( questId );
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
auto& questMgr = Common::Service< World::Manager::QuestMgr >::ref();
|
2021-12-21 01:05:08 +01:00
|
|
|
|
2023-01-23 20:16:08 -03:00
|
|
|
updateQuestsCompleted( questId );
|
|
|
|
|
2021-12-21 01:05:08 +01:00
|
|
|
//@todo should probably be changed to a bool function in case reward can not be obtained as quests will not complete in that case
|
|
|
|
questMgr.onCompleteQuest( *this, questId, optionalChoice );
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
void Sapphire::Entity::Player::unfinishQuest( uint16_t questId )
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
removeQuestsCompleted( questId );
|
|
|
|
auto& questMgr = Common::Service< World::Manager::QuestMgr >::ref();
|
|
|
|
questMgr.sendQuestsInfo( *this );
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
void Sapphire::Entity::Player::removeQuest( uint16_t questId )
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
int8_t idx = getQuestIndex( questId );
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
if( idx == -1 )
|
2018-08-29 21:40:59 +02:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
Logger::error( "QuestId#{0} not found in active quest list!", questId );
|
|
|
|
return;
|
2018-08-29 21:40:59 +02:00
|
|
|
}
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
auto& questMgr = Common::Service< World::Manager::QuestMgr >::ref();
|
2023-02-16 22:16:01 +01:00
|
|
|
auto& mapMgr = Common::Service< World::Manager::MapMgr >::ref();
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
m_quests[ idx ] = World::Quest();
|
|
|
|
removeQuestTracking( idx );
|
|
|
|
deleteDbQuest( questId );
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2023-02-16 22:16:01 +01:00
|
|
|
mapMgr.updateQuests( *this );
|
2021-11-27 00:53:57 +01:00
|
|
|
questMgr.onRemoveQuest( *this, idx );
|
2017-08-08 13:53:47 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
void Sapphire::Entity::Player::removeQuestTracking( int8_t idx )
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
for( int32_t ii = 0; ii < 5; ii++ )
|
2018-08-29 21:40:59 +02:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
if( m_questTracking[ ii ] == idx )
|
|
|
|
m_questTracking[ ii ] = -1;
|
2018-08-29 21:40:59 +02:00
|
|
|
}
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
bool Sapphire::Entity::Player::hasQuest( uint32_t questId )
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
return ( getQuestIndex( static_cast< uint16_t >( questId ) ) > -1 );
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
int8_t Sapphire::Entity::Player::getQuestIndex( uint16_t questId )
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
for( size_t pos = 0; pos < 30; ++pos )
|
2018-08-29 21:40:59 +02:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
if( m_quests[ pos ].getId() == questId )
|
|
|
|
return static_cast< int8_t >( pos );
|
2018-08-29 21:40:59 +02:00
|
|
|
}
|
2021-11-27 00:53:57 +01:00
|
|
|
return -1;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
2018-07-09 21:53:23 +01:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
void Sapphire::Entity::Player::updateQuest( const World::Quest& quest )
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
auto& questMgr = Common::Service< World::Manager::QuestMgr >::ref();
|
2023-02-16 22:16:01 +01:00
|
|
|
auto& mapMgr = Common::Service< World::Manager::MapMgr >::ref();
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
if( hasQuest( quest.getId() ) )
|
2018-08-29 21:40:59 +02:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
uint8_t index = getQuestIndex( quest.getId() );
|
|
|
|
m_quests[ index ] = quest;
|
2023-02-16 22:16:01 +01:00
|
|
|
mapMgr.updateQuests( *this );
|
2021-11-27 00:53:57 +01:00
|
|
|
questMgr.onUpdateQuest( *this, index );
|
2018-08-29 21:40:59 +02:00
|
|
|
}
|
2022-01-16 22:22:27 +01:00
|
|
|
else if( quest.getSeq() != 0 )
|
2021-11-27 00:53:57 +01:00
|
|
|
addQuest( quest );
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
bool Sapphire::Entity::Player::addQuest( const World::Quest& quest )
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
int8_t idx = getFreeQuestSlot();
|
2019-03-17 22:25:52 +01:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
if( idx == -1 )
|
2018-08-29 21:40:59 +02:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
Logger::error( "No free slot for additional quests" );
|
|
|
|
return false;
|
2018-08-29 21:40:59 +02:00
|
|
|
}
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
auto& questMgr = Common::Service< World::Manager::QuestMgr >::ref();
|
2023-02-16 22:16:01 +01:00
|
|
|
auto& mapMgr = Common::Service< World::Manager::MapMgr >::ref();
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
m_quests[ idx ] = quest;
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
insertDbQuest( quest, idx );
|
|
|
|
addQuestTracking( idx );
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2023-02-16 22:16:01 +01:00
|
|
|
mapMgr.updateQuests( *this );
|
2021-11-27 00:53:57 +01:00
|
|
|
questMgr.onUpdateQuest( *this, idx );
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
return true;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-20 15:25:57 +01:00
|
|
|
std::optional< Sapphire::World::Quest > Sapphire::Entity::Player::getQuest( uint32_t questId )
|
|
|
|
{
|
|
|
|
if( !hasQuest( questId ) )
|
|
|
|
return std::nullopt;
|
|
|
|
|
|
|
|
auto idx = getQuestIndex( questId );
|
|
|
|
|
|
|
|
auto quest = getQuestByIndex( idx );
|
|
|
|
return { quest };
|
|
|
|
}
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
int8_t Sapphire::Entity::Player::getFreeQuestSlot()
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2023-01-17 08:28:06 +01:00
|
|
|
int8_t result = -1;
|
2021-11-27 00:53:57 +01:00
|
|
|
for( int8_t idx = 0; idx < 30; idx++ )
|
|
|
|
if( m_quests[ idx ].getId() == 0 )
|
2018-08-29 21:40:59 +02:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
result = idx;
|
|
|
|
break;
|
2018-08-29 21:40:59 +02:00
|
|
|
}
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
return result;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
void Sapphire::Entity::Player::addQuestTracking( uint8_t idx )
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
for( int32_t ii = 0; ii < 5; ii++ )
|
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
if( m_questTracking[ ii ] == -1 )
|
2018-08-29 21:40:59 +02:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
m_questTracking[ ii ] = idx;
|
|
|
|
break;
|
2018-08-29 21:40:59 +02:00
|
|
|
}
|
|
|
|
}
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
void Sapphire::Entity::Player::updateQuestsCompleted( uint32_t questId )
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
uint8_t index = questId / 8;
|
2018-08-29 21:40:59 +02:00
|
|
|
uint8_t bitIndex = ( questId ) % 8;
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
uint8_t value = 0x80 >> bitIndex;
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
m_questCompleteFlags[ index ] |= value;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2022-02-17 04:26:19 +01:00
|
|
|
bool Sapphire::Entity::Player::isQuestCompleted( uint32_t questId )
|
|
|
|
{
|
|
|
|
uint8_t index = questId / 8;
|
|
|
|
uint8_t bitIndex = ( questId ) % 8;
|
|
|
|
|
|
|
|
uint8_t value = 0x80 >> bitIndex;
|
|
|
|
|
|
|
|
return m_questCompleteFlags[ index ] & value;
|
|
|
|
}
|
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
void Sapphire::Entity::Player::removeQuestsCompleted( uint32_t questId )
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
uint8_t index = questId / 8;
|
2018-08-29 21:40:59 +02:00
|
|
|
uint8_t bitIndex = ( questId ) % 8;
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
uint8_t value = 0x80 >> bitIndex;
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
m_questCompleteFlags[ index ] ^= value;
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2023-02-16 22:16:01 +01:00
|
|
|
Common::Service< World::Manager::MapMgr >::ref().updateQuests( *this );
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
Sapphire::World::Quest& Sapphire::Entity::Player::getQuestByIndex( uint16_t index )
|
|
|
|
{
|
|
|
|
return m_quests[ index ];
|
|
|
|
}
|
|
|
|
|
|
|
|
std::array< Sapphire::World::Quest, 30 >& Sapphire::Entity::Player::getQuestArrayRef()
|
|
|
|
{
|
|
|
|
return m_quests;
|
|
|
|
}
|
|
|
|
|
|
|
|
int16_t Sapphire::Entity::Player::getQuestTracking( uint8_t index ) const
|
|
|
|
{
|
|
|
|
if( index < 0 || index >= 5 )
|
|
|
|
return -1;
|
|
|
|
return m_questTracking[ index ];
|
|
|
|
}
|
|
|
|
|
|
|
|
Sapphire::Entity::Player::QuestComplete& Sapphire::Entity::Player::getQuestCompleteFlags()
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
return m_questCompleteFlags;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|