mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 22:37:03 +00:00
Further work on the achievement system
Implemented ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT Fixed SMSG_CRITERIA_UPDATE structure Implemented parts of ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL - there are still some unknown additional conditions for this criteria type Fixed sAchievementStore lookup errors caused by an invalid DBCfmt
This commit is contained in:
parent
6496f7499e
commit
deccb566ae
7 changed files with 138 additions and 18 deletions
|
|
@ -20,6 +20,8 @@
|
|||
#include "Common.h"
|
||||
#include "Player.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Database/DBCEnums.h"
|
||||
#include "ObjectMgr.h"
|
||||
|
||||
AchievementMgr::AchievementMgr(Player *player)
|
||||
{
|
||||
|
|
@ -38,6 +40,7 @@ void AchievementMgr::LoadFromDB()
|
|||
|
||||
void AchievementMgr::SendAchievementEarned(uint32 achievementId)
|
||||
{
|
||||
sLog.outString("AchievementMgr::SendAchievementEarned(%u)", achievementId);
|
||||
WorldPacket data(SMSG_MESSAGECHAT, 200);
|
||||
data << uint8(CHAT_MSG_ACHIEVEMENT);
|
||||
data << uint32(LANG_UNIVERSAL);
|
||||
|
|
@ -60,13 +63,114 @@ void AchievementMgr::SendAchievementEarned(uint32 achievementId)
|
|||
|
||||
void AchievementMgr::SendCriteriaUpdate(uint32 criteriaId, uint32 counter)
|
||||
{
|
||||
sLog.outString("AchievementMgr::SendCriteriaUpdate(%u, %u)", criteriaId, counter);
|
||||
WorldPacket data(SMSG_CRITERIA_UPDATE, 8+4+8);
|
||||
data << uint32(criteriaId);
|
||||
data << uint8(counter);
|
||||
data << uint8(counter);// 2 times?
|
||||
|
||||
// the counter is packed like a packed Guid
|
||||
data.appendPackGUID(counter);
|
||||
|
||||
data.append(GetPlayer()->GetPackGUID());
|
||||
data << uint64(0x0000000); // unknown, same as in SMSG_EARNED_ACHIEVEMENT, static for every player?
|
||||
data << uint32(0); // unknown, 0
|
||||
/*
|
||||
data << uint32(counter);
|
||||
data << uint32(counter+1);//timer1
|
||||
data << uint32(counter+2);//timer2
|
||||
*/
|
||||
data << uint32(0);
|
||||
data << uint32(0);
|
||||
data << uint32(0);
|
||||
data << uint32(0);
|
||||
GetPlayer()->SendMessageToSet(&data, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* this function will be called whenever the user might have done a criteria relevant action
|
||||
*/
|
||||
void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1, uint32 miscvalue2, uint32 time)
|
||||
{
|
||||
sLog.outString("AchievementMgr::UpdateAchievementCriteria(%u, %u, %u, %u)", type, miscvalue1, miscvalue2, time);
|
||||
AchievementCriteriaEntryList const& achievementCriteriaList = objmgr.GetAchievementCriteriaByType(type);
|
||||
for(AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i!=achievementCriteriaList.end(); ++i)
|
||||
{
|
||||
AchievementCriteriaEntry const *achievementCriteria = (*i);
|
||||
switch (type)
|
||||
{
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT:
|
||||
SetCriteriaProgress(achievementCriteria, miscvalue1);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
if(IsCompletedCriteria(achievementCriteria))
|
||||
CompletedCriteria(achievementCriteria);
|
||||
}
|
||||
}
|
||||
|
||||
bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria)
|
||||
{
|
||||
AchievementEntry const* achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement);
|
||||
if(!achievement)
|
||||
return false;
|
||||
// counter can never complete
|
||||
if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
|
||||
return false;
|
||||
|
||||
switch(achievementCriteria->requiredType)
|
||||
{
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
|
||||
return m_criteriaProgress[achievementCriteria->ID] >= achievementCriteria->reach_level.level;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT:
|
||||
return m_criteriaProgress[achievementCriteria->ID] >= achievementCriteria->buy_bank_slot.numberOfSlots;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AchievementMgr::CompletedCriteria(AchievementCriteriaEntry const* criteria)
|
||||
{
|
||||
AchievementEntry const* achievement = sAchievementStore.LookupEntry(criteria->referredAchievement);
|
||||
if(!achievement)
|
||||
return;
|
||||
// counter can never complete
|
||||
if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
|
||||
return;
|
||||
|
||||
if(criteria->completionFlag & ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL)
|
||||
{
|
||||
CompletedAchievement(achievement);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if there are also other critiera which have to be fulfilled for that achievement
|
||||
for (uint32 entryId = 0; entryId<sAchievementCriteriaStore.GetNumRows(); entryId++)
|
||||
{
|
||||
AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId);
|
||||
if(!criteria || criteria->referredAchievement!= achievement->ID)
|
||||
continue;
|
||||
|
||||
// found an outstanding criteria, return
|
||||
if(!IsCompletedCriteria(criteria))
|
||||
return;
|
||||
}
|
||||
CompletedAchievement(achievement);
|
||||
}
|
||||
|
||||
void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 newValue)
|
||||
{
|
||||
sLog.outString("AchievementMgr::SetCriteriaProgress(%u, %u)", entry->ID, newValue);
|
||||
m_criteriaProgress[entry->ID] = newValue;
|
||||
SendCriteriaUpdate(entry->ID, newValue);
|
||||
}
|
||||
|
||||
void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
|
||||
{
|
||||
sLog.outString("AchievementMgr::CompletedAchievement(%u)", achievement->ID);
|
||||
if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER || m_completedAchievements.find(achievement->ID)!=m_completedAchievements.end())
|
||||
return;
|
||||
|
||||
SendAchievementEarned(achievement->ID);
|
||||
m_completedAchievements.insert(achievement->ID);
|
||||
// TODO: reward titles and items
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,14 @@
|
|||
#ifndef __MANGOS_ACHIEVEMENTMGR_H
|
||||
#define __MANGOS_ACHIEVEMENTMGR_H
|
||||
|
||||
#include "Player.h"
|
||||
#include "Common.h"
|
||||
#include "Database/DBCEnums.h"
|
||||
#include "Database/DBCStores.h"
|
||||
|
||||
typedef HM_NAMESPACE::hash_map<uint32, uint32> CriteriaProgressMap;
|
||||
typedef std::set<uint32> CompletedAchievementSet;
|
||||
|
||||
class Player;
|
||||
|
||||
class AchievementMgr
|
||||
{
|
||||
|
|
@ -27,13 +34,22 @@ class AchievementMgr
|
|||
|
||||
void LoadFromDB();
|
||||
void SaveToDB();
|
||||
void SendAchievementEarned(uint32 achievementId);
|
||||
void SendCriteriaUpdate(uint32 criteriaId, uint32 counter);
|
||||
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1=0, uint32 miscvalue2=0, uint32 time=0);
|
||||
|
||||
Player* GetPlayer() { return m_player;}
|
||||
|
||||
private:
|
||||
void SendAchievementEarned(uint32 achievementId);
|
||||
void SendCriteriaUpdate(uint32 criteriaId, uint32 counter);
|
||||
void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 newValue);
|
||||
void CompletedCriteria(AchievementCriteriaEntry const* entry);
|
||||
void CompletedAchievement(AchievementEntry const* entry);
|
||||
bool IsCompletedCriteria(AchievementCriteriaEntry const* entry);
|
||||
|
||||
Player* m_player;
|
||||
CriteriaProgressMap m_criteriaProgress;
|
||||
CompletedAchievementSet m_completedAchievements;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -805,6 +805,7 @@ void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& /*recvPacket*/)
|
|||
if (_player->GetMoney() < price)
|
||||
return;
|
||||
|
||||
_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT, slot);
|
||||
_player->SetByteValue(PLAYER_BYTES_2, 2, slot);
|
||||
_player->ModifyMoney(-int32(price));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -744,6 +744,7 @@ class ObjectMgr
|
|||
bool RemoveVendorItem(uint32 entry,uint32 item);
|
||||
bool IsVendorItemValid( uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL, std::set<uint32>* skip_vendors = NULL ) const;
|
||||
void LoadAchievementCriteriaList();
|
||||
AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type);
|
||||
|
||||
protected:
|
||||
uint32 m_auctionid;
|
||||
|
|
@ -810,7 +811,6 @@ class ObjectMgr
|
|||
|
||||
int DBCLocaleIndex;
|
||||
|
||||
AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type);
|
||||
private:
|
||||
void LoadScripts(ScriptMapMap& scripts, char const* tablename);
|
||||
void ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr);
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ const int32 Player::ReputationRank_Length[MAX_REPUTATION_RANK] = {36000, 3000, 3
|
|||
|
||||
UpdateMask Player::updateVisualBits;
|
||||
|
||||
Player::Player (WorldSession *session): Unit()
|
||||
Player::Player (WorldSession *session): Unit(), m_achievementMgr(this)
|
||||
{
|
||||
m_transport = 0;
|
||||
|
||||
|
|
@ -421,7 +421,6 @@ Player::Player (WorldSession *session): Unit()
|
|||
m_contestedPvPTimer = 0;
|
||||
|
||||
m_declinedname = NULL;
|
||||
m_achievementMgr = NULL;
|
||||
}
|
||||
|
||||
Player::~Player ()
|
||||
|
|
@ -468,7 +467,6 @@ Player::~Player ()
|
|||
itr->second.save->RemovePlayer(this);
|
||||
|
||||
delete m_declinedname;
|
||||
delete m_achievementMgr;
|
||||
}
|
||||
|
||||
void Player::CleanupsBeforeDelete()
|
||||
|
|
@ -2146,6 +2144,7 @@ void Player::GiveLevel(uint32 level)
|
|||
Pet* pet = GetPet();
|
||||
if(pet && pet->getPetType()==SUMMON_PET)
|
||||
pet->GivePetLevel(level);
|
||||
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL, level);
|
||||
}
|
||||
|
||||
void Player::InitTalentForLevel()
|
||||
|
|
@ -13974,8 +13973,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
|||
|
||||
m_social = sSocialMgr.LoadFromDB(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSOCIALLIST), GetGUIDLow());
|
||||
|
||||
m_achievementMgr = new AchievementMgr(this);
|
||||
m_achievementMgr->LoadFromDB();
|
||||
m_achievementMgr.LoadFromDB();
|
||||
|
||||
if(!_LoadHomeBind(holder->GetResult(PLAYER_LOGIN_QUERY_LOADHOMEBIND)))
|
||||
return false;
|
||||
|
|
@ -15196,7 +15194,7 @@ void Player::SaveToDB()
|
|||
// save pet (hunter pet level and experience and all type pets health/mana).
|
||||
if(Pet* pet = GetPet())
|
||||
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
|
||||
m_achievementMgr->SaveToDB();
|
||||
m_achievementMgr.SaveToDB();
|
||||
}
|
||||
|
||||
// fast save function for item/money cheating preventing - save only inventory and money state
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "WorldSession.h"
|
||||
#include "Pet.h"
|
||||
#include "Util.h" // for Tokens typedef
|
||||
#include "AchievementMgr.h"
|
||||
|
||||
#include<string>
|
||||
#include<vector>
|
||||
|
|
@ -2055,7 +2056,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
|
||||
DeclinedName const* GetDeclinedNames() const { return m_declinedname; }
|
||||
|
||||
AchievementMgr *GetAchievementMgr() { return m_achievementMgr; }
|
||||
AchievementMgr& GetAchievementMgr() { return m_achievementMgr; }
|
||||
protected:
|
||||
|
||||
/*********************************************************/
|
||||
|
|
@ -2286,7 +2287,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
WorldLocation m_teleport_dest;
|
||||
|
||||
DeclinedName *m_declinedname;
|
||||
AchievementMgr *m_achievementMgr;
|
||||
AchievementMgr m_achievementMgr;
|
||||
private:
|
||||
// internal common parts for CanStore/StoreItem functions
|
||||
uint8 _CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountVec& dest, ItemPrototype const *pProto, uint32& count, bool swap, Item *pSrcItem ) const;
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
const char Achievementfmt[]="iiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiixxixxxxxxxxxxxxxxxxxxx";
|
||||
const char AchievementCriteriafmt[]="iiiiiiiiixxxxxxxxxxxxxxxxxiixix";
|
||||
const char Achievementfmt[]="niixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiixxixxxxxxxxxxxxxxxxxxx";
|
||||
const char AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiixix";
|
||||
const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxxx";
|
||||
const char AreaTriggerEntryfmt[]="niffffffff";
|
||||
const char BankBagSlotPricesEntryfmt[]="ni";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue