[7391] Prevent achievement counter overflow, implement ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE generic support.
Before overflow has been possible at 4294967295 lols for example.
ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE in many cases require check special conditions and targets.
For this allow call it from scripts:
* Add Player::UpdateAchievementCriteria functiona ccessable from scripts
* In emote case it allowed call in form player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote_id, achievement_id, target_unit_ptr);
Author: VladimirMangos
--HG--
branch : trunk
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
DELETE FROM mangos_string WHERE entry = 726;
|
ALTER TABLE db_version CHANGE COLUMN required_7382_01_mangos_creature_template required_7388_01_mangos_mangos_string bit;
|
||||||
|
|
||||||
|
DELETE FROM mangos_string WHERE entry IN (750,751);
|
||||||
INSERT INTO mangos_string VALUES (750,'Not enough players. This game will close in %u mins.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
INSERT INTO mangos_string VALUES (750,'Not enough players. This game will close in %u mins.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
||||||
INSERT INTO mangos_string VALUES (751,'Not enough players. This game will close in %u seconds.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
INSERT INTO mangos_string VALUES (751,'Not enough players. This game will close in %u seconds.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
||||||
|
|||||||
@@ -730,6 +730,31 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
|||||||
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
|
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:
|
||||||
|
{
|
||||||
|
// miscvalue1 = emote
|
||||||
|
// miscvalue2 = achievement->ID for special requirement
|
||||||
|
if(!miscvalue1)
|
||||||
|
continue;
|
||||||
|
if(miscvalue1 != achievementCriteria->do_emote.emoteID)
|
||||||
|
continue;
|
||||||
|
if(achievementCriteria->do_emote.count)
|
||||||
|
{
|
||||||
|
// harcoded case
|
||||||
|
if(achievement->ID==247)
|
||||||
|
{
|
||||||
|
if (!unit || unit->GetTypeId() != TYPEID_PLAYER ||
|
||||||
|
unit->isAlive() || ((Player*)unit)->GetDeathTimer() == 0)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// expected as scripted case
|
||||||
|
else if(!miscvalue2 || !achievement->ID != miscvalue2)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS:
|
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS:
|
||||||
{
|
{
|
||||||
uint32 spellCount = 0;
|
uint32 spellCount = 0;
|
||||||
@@ -798,7 +823,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
|||||||
case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM:
|
case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM:
|
||||||
case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS:
|
case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS:
|
||||||
case ACHIEVEMENT_CRITERIA_TYPE_HK_RACE:
|
case ACHIEVEMENT_CRITERIA_TYPE_HK_RACE:
|
||||||
case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:
|
|
||||||
case ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE:
|
case ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE:
|
||||||
case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
|
case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
|
||||||
case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM:
|
case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM:
|
||||||
@@ -927,6 +951,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
|
|||||||
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
|
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
|
||||||
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT:
|
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT:
|
||||||
return progress->counter >= achievementCriteria->roll_greed_on_loot.count;
|
return progress->counter >= achievementCriteria->roll_greed_on_loot.count;
|
||||||
|
case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:
|
||||||
|
return progress->counter >= achievementCriteria->do_emote.count;
|
||||||
case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD:
|
case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD:
|
||||||
return progress->counter >= achievementCriteria->quest_reward_money.goldInCopper;
|
return progress->counter >= achievementCriteria->quest_reward_money.goldInCopper;
|
||||||
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY:
|
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY:
|
||||||
@@ -1024,8 +1050,12 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry,
|
|||||||
newValue = changeValue;
|
newValue = changeValue;
|
||||||
break;
|
break;
|
||||||
case PROGRESS_ACCUMULATE:
|
case PROGRESS_ACCUMULATE:
|
||||||
newValue = progress->counter + changeValue;
|
{
|
||||||
|
// avoid overflow
|
||||||
|
uint32 max_value = std::numeric_limits<uint32>::max();
|
||||||
|
newValue = max_value - progress->counter > changeValue ? progress->counter + changeValue : max_value;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PROGRESS_HIGHEST:
|
case PROGRESS_HIGHEST:
|
||||||
newValue = progress->counter < changeValue ? changeValue : progress->counter;
|
newValue = progress->counter < changeValue ? changeValue : progress->counter;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -524,8 +524,11 @@ void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data )
|
|||||||
}
|
}
|
||||||
|
|
||||||
EmotesTextEntry const *em = sEmotesTextStore.LookupEntry(text_emote);
|
EmotesTextEntry const *em = sEmotesTextStore.LookupEntry(text_emote);
|
||||||
if (em)
|
if (!em)
|
||||||
{
|
return;
|
||||||
|
|
||||||
|
GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit);
|
||||||
|
|
||||||
uint32 emote_anim = em->textid;
|
uint32 emote_anim = em->textid;
|
||||||
|
|
||||||
WorldPacket data;
|
WorldPacket data;
|
||||||
@@ -548,13 +551,9 @@ void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data )
|
|||||||
data << emoteNum;
|
data << emoteNum;
|
||||||
data << (uint32)namlen;
|
data << (uint32)namlen;
|
||||||
if( namlen > 1 )
|
if( namlen > 1 )
|
||||||
{
|
|
||||||
data.append(nam, namlen);
|
data.append(nam, namlen);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
data << (uint8)0x00;
|
data << (uint8)0x00;
|
||||||
}
|
|
||||||
|
|
||||||
GetPlayer()->SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),true);
|
GetPlayer()->SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),true);
|
||||||
|
|
||||||
@@ -562,7 +561,6 @@ void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data )
|
|||||||
if (pCreature && Script)
|
if (pCreature && Script)
|
||||||
Script->ReceiveEmote(GetPlayer(),pCreature,text_emote);
|
Script->ReceiveEmote(GetPlayer(),pCreature,text_emote);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recv_data )
|
void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recv_data )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20645,3 +20645,8 @@ void Player::HandleFall(MovementInfo const& movementInfo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::UpdateAchievementCriteria( AchievementCriteriaTypes type, uint32 miscvalue1/*=0*/, uint32 miscvalue2/*=0*/, Unit *unit/*=NULL*/, uint32 time/*=0*/ )
|
||||||
|
{
|
||||||
|
GetAchievementMgr().UpdateAchievementCriteria(type, miscvalue1,miscvalue2,unit,time);
|
||||||
|
}
|
||||||
@@ -2181,6 +2181,7 @@ class TRINITY_DLL_SPEC Player : public Unit
|
|||||||
void AddRunePower(uint8 index);
|
void AddRunePower(uint8 index);
|
||||||
void InitRunes();
|
void InitRunes();
|
||||||
AchievementMgr& GetAchievementMgr() { return m_achievementMgr; }
|
AchievementMgr& GetAchievementMgr() { return m_achievementMgr; }
|
||||||
|
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1=0, uint32 miscvalue2=0, Unit *unit=NULL, uint32 time=0);
|
||||||
bool HasTitle(uint32 bitIndex);
|
bool HasTitle(uint32 bitIndex);
|
||||||
bool HasTitle(CharTitlesEntry const* title) { return HasTitle(title->bit_index); }
|
bool HasTitle(CharTitlesEntry const* title) { return HasTitle(title->bit_index); }
|
||||||
void SetTitle(CharTitlesEntry const* title);
|
void SetTitle(CharTitlesEntry const* title);
|
||||||
|
|||||||
@@ -359,7 +359,8 @@ struct AchievementCriteriaEntry
|
|||||||
// TODO: where is the information about the target stored?
|
// TODO: where is the information about the target stored?
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint32 emoteID; // 3
|
uint32 emoteID; // 3 enum TextEmotes
|
||||||
|
uint32 count; // 4 count of emotes, always required special target or requirements
|
||||||
} do_emote;
|
} do_emote;
|
||||||
// ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13
|
// ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13
|
||||||
// ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE = 55
|
// ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE = 55
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "7389"
|
#define REVISION_NR "7391"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|||||||
Reference in New Issue
Block a user