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 "Common.h"
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
#include "WorldPacket.h"
|
#include "WorldPacket.h"
|
||||||
|
#include "Database/DBCEnums.h"
|
||||||
|
#include "ObjectMgr.h"
|
||||||
|
|
||||||
AchievementMgr::AchievementMgr(Player *player)
|
AchievementMgr::AchievementMgr(Player *player)
|
||||||
{
|
{
|
||||||
|
|
@ -38,6 +40,7 @@ void AchievementMgr::LoadFromDB()
|
||||||
|
|
||||||
void AchievementMgr::SendAchievementEarned(uint32 achievementId)
|
void AchievementMgr::SendAchievementEarned(uint32 achievementId)
|
||||||
{
|
{
|
||||||
|
sLog.outString("AchievementMgr::SendAchievementEarned(%u)", achievementId);
|
||||||
WorldPacket data(SMSG_MESSAGECHAT, 200);
|
WorldPacket data(SMSG_MESSAGECHAT, 200);
|
||||||
data << uint8(CHAT_MSG_ACHIEVEMENT);
|
data << uint8(CHAT_MSG_ACHIEVEMENT);
|
||||||
data << uint32(LANG_UNIVERSAL);
|
data << uint32(LANG_UNIVERSAL);
|
||||||
|
|
@ -60,13 +63,114 @@ void AchievementMgr::SendAchievementEarned(uint32 achievementId)
|
||||||
|
|
||||||
void AchievementMgr::SendCriteriaUpdate(uint32 criteriaId, uint32 counter)
|
void AchievementMgr::SendCriteriaUpdate(uint32 criteriaId, uint32 counter)
|
||||||
{
|
{
|
||||||
|
sLog.outString("AchievementMgr::SendCriteriaUpdate(%u, %u)", criteriaId, counter);
|
||||||
WorldPacket data(SMSG_CRITERIA_UPDATE, 8+4+8);
|
WorldPacket data(SMSG_CRITERIA_UPDATE, 8+4+8);
|
||||||
data << uint32(criteriaId);
|
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.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);
|
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
|
#ifndef __MANGOS_ACHIEVEMENTMGR_H
|
||||||
#define __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
|
class AchievementMgr
|
||||||
{
|
{
|
||||||
|
|
@ -27,13 +34,22 @@ class AchievementMgr
|
||||||
|
|
||||||
void LoadFromDB();
|
void LoadFromDB();
|
||||||
void SaveToDB();
|
void SaveToDB();
|
||||||
void SendAchievementEarned(uint32 achievementId);
|
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1=0, uint32 miscvalue2=0, uint32 time=0);
|
||||||
void SendCriteriaUpdate(uint32 criteriaId, uint32 counter);
|
|
||||||
|
|
||||||
Player* GetPlayer() { return m_player;}
|
Player* GetPlayer() { return m_player;}
|
||||||
|
|
||||||
private:
|
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;
|
Player* m_player;
|
||||||
|
CriteriaProgressMap m_criteriaProgress;
|
||||||
|
CompletedAchievementSet m_completedAchievements;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -805,6 +805,7 @@ void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& /*recvPacket*/)
|
||||||
if (_player->GetMoney() < price)
|
if (_player->GetMoney() < price)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT, slot);
|
||||||
_player->SetByteValue(PLAYER_BYTES_2, 2, slot);
|
_player->SetByteValue(PLAYER_BYTES_2, 2, slot);
|
||||||
_player->ModifyMoney(-int32(price));
|
_player->ModifyMoney(-int32(price));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -744,6 +744,7 @@ class ObjectMgr
|
||||||
bool RemoveVendorItem(uint32 entry,uint32 item);
|
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;
|
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();
|
void LoadAchievementCriteriaList();
|
||||||
|
AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint32 m_auctionid;
|
uint32 m_auctionid;
|
||||||
|
|
@ -810,7 +811,6 @@ class ObjectMgr
|
||||||
|
|
||||||
int DBCLocaleIndex;
|
int DBCLocaleIndex;
|
||||||
|
|
||||||
AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type);
|
|
||||||
private:
|
private:
|
||||||
void LoadScripts(ScriptMapMap& scripts, char const* tablename);
|
void LoadScripts(ScriptMapMap& scripts, char const* tablename);
|
||||||
void ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr);
|
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;
|
UpdateMask Player::updateVisualBits;
|
||||||
|
|
||||||
Player::Player (WorldSession *session): Unit()
|
Player::Player (WorldSession *session): Unit(), m_achievementMgr(this)
|
||||||
{
|
{
|
||||||
m_transport = 0;
|
m_transport = 0;
|
||||||
|
|
||||||
|
|
@ -421,7 +421,6 @@ Player::Player (WorldSession *session): Unit()
|
||||||
m_contestedPvPTimer = 0;
|
m_contestedPvPTimer = 0;
|
||||||
|
|
||||||
m_declinedname = NULL;
|
m_declinedname = NULL;
|
||||||
m_achievementMgr = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Player::~Player ()
|
Player::~Player ()
|
||||||
|
|
@ -468,7 +467,6 @@ Player::~Player ()
|
||||||
itr->second.save->RemovePlayer(this);
|
itr->second.save->RemovePlayer(this);
|
||||||
|
|
||||||
delete m_declinedname;
|
delete m_declinedname;
|
||||||
delete m_achievementMgr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::CleanupsBeforeDelete()
|
void Player::CleanupsBeforeDelete()
|
||||||
|
|
@ -2146,6 +2144,7 @@ void Player::GiveLevel(uint32 level)
|
||||||
Pet* pet = GetPet();
|
Pet* pet = GetPet();
|
||||||
if(pet && pet->getPetType()==SUMMON_PET)
|
if(pet && pet->getPetType()==SUMMON_PET)
|
||||||
pet->GivePetLevel(level);
|
pet->GivePetLevel(level);
|
||||||
|
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::InitTalentForLevel()
|
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_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)))
|
if(!_LoadHomeBind(holder->GetResult(PLAYER_LOGIN_QUERY_LOADHOMEBIND)))
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -15196,7 +15194,7 @@ void Player::SaveToDB()
|
||||||
// save pet (hunter pet level and experience and all type pets health/mana).
|
// save pet (hunter pet level and experience and all type pets health/mana).
|
||||||
if(Pet* pet = GetPet())
|
if(Pet* pet = GetPet())
|
||||||
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
|
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
|
// fast save function for item/money cheating preventing - save only inventory and money state
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#include "WorldSession.h"
|
#include "WorldSession.h"
|
||||||
#include "Pet.h"
|
#include "Pet.h"
|
||||||
#include "Util.h" // for Tokens typedef
|
#include "Util.h" // for Tokens typedef
|
||||||
|
#include "AchievementMgr.h"
|
||||||
|
|
||||||
#include<string>
|
#include<string>
|
||||||
#include<vector>
|
#include<vector>
|
||||||
|
|
@ -2055,7 +2056,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
|
|
||||||
DeclinedName const* GetDeclinedNames() const { return m_declinedname; }
|
DeclinedName const* GetDeclinedNames() const { return m_declinedname; }
|
||||||
|
|
||||||
AchievementMgr *GetAchievementMgr() { return m_achievementMgr; }
|
AchievementMgr& GetAchievementMgr() { return m_achievementMgr; }
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/*********************************************************/
|
/*********************************************************/
|
||||||
|
|
@ -2286,7 +2287,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
WorldLocation m_teleport_dest;
|
WorldLocation m_teleport_dest;
|
||||||
|
|
||||||
DeclinedName *m_declinedname;
|
DeclinedName *m_declinedname;
|
||||||
AchievementMgr *m_achievementMgr;
|
AchievementMgr m_achievementMgr;
|
||||||
private:
|
private:
|
||||||
// internal common parts for CanStore/StoreItem functions
|
// 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;
|
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
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const char Achievementfmt[]="iiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiixxixxxxxxxxxxxxxxxxxxx";
|
const char Achievementfmt[]="niixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiixxixxxxxxxxxxxxxxxxxxx";
|
||||||
const char AchievementCriteriafmt[]="iiiiiiiiixxxxxxxxxxxxxxxxxiixix";
|
const char AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiixix";
|
||||||
const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxxx";
|
const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxxx";
|
||||||
const char AreaTriggerEntryfmt[]="niffffffff";
|
const char AreaTriggerEntryfmt[]="niffffffff";
|
||||||
const char BankBagSlotPricesEntryfmt[]="ni";
|
const char BankBagSlotPricesEntryfmt[]="ni";
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue