1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-01 08:27:46 +00:00

Merge pull request #843 from hkAlice/over-achievers

[3.x] better comments on achievement usage; get level from player object for classjob achievements;
This commit is contained in:
Adam 2023-01-21 11:42:31 +11:00 committed by GitHub
commit e768442f00
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 3 deletions

View file

@ -20,12 +20,42 @@ namespace Sapphire::World::Manager
bool cacheAchievements(); bool cacheAchievements();
/// <summary>
/// progress an achievement by its given properties
/// each type has a specific logic for progress, attention should be given to the type being passed
/// optional parameter for overriding the amount to increment a given progress by
///
/// example usage for Achievement::Type::General:
///
/// To Crush Your Enemies I
/// Defeat 100 enemies.
///
/// type (col[7]): 1 -> Common::Achievement::Type::General
/// subtype (col[8]): 11 -> Common::Achievement::GeneralSubtype::EnemyDefeatCount
///
/// progressAchievementByType< Common::Achievement::Type::General >( player, GeneralSubtype::EnemyDefeatCount );
///
/// example usage for Achievement::Type::ClassJob:
///
/// progressAchievementByType< Common::Achievement::Type::Classjob >( player, static_cast< uint32_t >( player.getClass() ) );
///
/// </summary>
/// <typeparam name="AchievementType"></typeparam>
/// <param name="player"></param>
/// <param name="argument"></param>
/// <param name="progressCount"></param>
template < auto AchievementType > template < auto AchievementType >
void progressAchievementByType( Entity::Player& player, int32_t argument, uint32_t progressCount = 1 ) void progressAchievementByType( Entity::Player& player, int32_t argument, uint32_t progressCount = 1 )
{ {
progressAchievement< decltype( AchievementType ), AchievementType >( player, argument, progressCount ); progressAchievement< decltype( AchievementType ), AchievementType >( player, argument, progressCount );
} }
/// <summary>
/// check if player has an achievement by its given id
/// </summary>
/// <param name="player"></param>
/// <param name="achievementId"></param>
/// <returns>true/false</returns>
bool hasAchievementUnlocked( Entity::Player& player, uint32_t achievementId ); bool hasAchievementUnlocked( Entity::Player& player, uint32_t achievementId );
void unlockAchievement( Entity::Player& player, uint32_t achievementId ); void unlockAchievement( Entity::Player& player, uint32_t achievementId );
@ -50,8 +80,19 @@ namespace Sapphire::World::Manager
const std::vector< uint32_t >& getAchievementIdByType( Common::Achievement::Type type ) const; const std::vector< uint32_t >& getAchievementIdByType( Common::Achievement::Type type ) const;
const std::vector< uint32_t >& getAchievementIdByType( uint32_t type ) const; const std::vector< uint32_t >& getAchievementIdByType( uint32_t type ) const;
/// <summary>
/// get a key for merged achievements (type:subtype) that have progress data
/// </summary>
/// <param name="achvType"></param>
/// <param name="argument"></param>
/// <returns>data key for given type:subtype</returns>
Common::AchievementDataKey getKeyFromType( Common::Achievement::Type achvType, int32_t argument ); Common::AchievementDataKey getKeyFromType( Common::Achievement::Type achvType, int32_t argument );
/// <summary>
/// parse and unlock achievements linked to a given achievement Id
/// </summary>
/// <param name="player"></param>
/// <param name="achievementId"></param>
void handleLinkedAchievementsForId( Entity::Player& player, uint32_t achievementId ); void handleLinkedAchievementsForId( Entity::Player& player, uint32_t achievementId );
template< typename AchievementTypeT, AchievementTypeT achievementType > template< typename AchievementTypeT, AchievementTypeT achievementType >
@ -90,7 +131,7 @@ namespace Sapphire::World::Manager
} }
template<> template<>
inline void AchievementMgr::progressAchievement< Common::Achievement::Type, Common::Achievement::Type::Classjob >( Entity::Player& player, int32_t classJob, uint32_t level ) inline void AchievementMgr::progressAchievement< Common::Achievement::Type, Common::Achievement::Type::Classjob >( Entity::Player& player, int32_t classJob, uint32_t unused )
{ {
auto& achvDataList = player.getAchievementDataList(); auto& achvDataList = player.getAchievementDataList();
@ -99,6 +140,8 @@ namespace Sapphire::World::Manager
if( !achvDataList.count( dataKey.u32 ) ) if( !achvDataList.count( dataKey.u32 ) )
achvDataList[ dataKey.u32 ] = 0; achvDataList[ dataKey.u32 ] = 0;
auto level = player.getLevelForClass( static_cast< Common::ClassJob >( classJob ) );
achvDataList[ dataKey.u32 ] = level; achvDataList[ dataKey.u32 ] = level;
const auto achvIdList = getAchievementIdByType( dataKey.u32 ); const auto achvIdList = getAchievementIdByType( dataKey.u32 );

View file

@ -175,7 +175,7 @@ void PlayerMgr::onLevelUp( Entity::Player& player )
player.getLevel(), player.getLevel() - 1 ), true ); player.getLevel(), player.getLevel() - 1 ), true );
auto& achvMgr = Common::Service< World::Manager::AchievementMgr >::ref(); auto& achvMgr = Common::Service< World::Manager::AchievementMgr >::ref();
achvMgr.progressAchievementByType< Common::Achievement::Type::Classjob >( player, static_cast< uint8_t >( player.getClass() ), player.getLevel() ); achvMgr.progressAchievementByType< Common::Achievement::Type::Classjob >( player, static_cast< uint32_t >( player.getClass() ) );
} }
void PlayerMgr::onSetLevelForClass( Entity::Player& player, Common::ClassJob classJob ) void PlayerMgr::onSetLevelForClass( Entity::Player& player, Common::ClassJob classJob )
@ -186,7 +186,7 @@ void PlayerMgr::onSetLevelForClass( Entity::Player& player, Common::ClassJob cla
server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), Network::ActorControl::ClassJobUpdate, server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), Network::ActorControl::ClassJobUpdate,
static_cast< uint8_t >( classJob ), player.getLevelForClass( classJob ) ) ); static_cast< uint8_t >( classJob ), player.getLevelForClass( classJob ) ) );
achvMgr.progressAchievementByType< Common::Achievement::Type::Classjob >( player, static_cast< uint8_t >( classJob ), player.getLevel() ); achvMgr.progressAchievementByType< Common::Achievement::Type::Classjob >( player, static_cast< uint32_t >( classJob ) );
} }