mirror of
https://github.com/liyunfan1223/azerothcore-wotlk.git
synced 2026-08-08 07:48:02 +00:00
fix(Core/Achievements): new achievement criteria type ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_TEAMS_SCORES (#7756)
- Closes #7613
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1630947176293030300');
|
||||||
|
|
||||||
|
UPDATE `achievement_criteria_data` SET `type`=24, `value1`=1600 WHERE `criteria_id` IN (611,1235,1238);
|
||||||
|
UPDATE `achievement_criteria_data` SET `type`=24, `value1`=3 WHERE `criteria_id`=1236;
|
||||||
@@ -248,6 +248,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE:
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE:
|
||||||
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_TEAMS_SCORES:
|
||||||
return true; // not check correctness node indexes
|
return true; // not check correctness node indexes
|
||||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM:
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM:
|
||||||
if (equipped_item.item_quality >= MAX_ITEM_QUALITY)
|
if (equipped_item.item_quality >= MAX_ITEM_QUALITY)
|
||||||
@@ -341,11 +342,11 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un
|
|||||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA:
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA:
|
||||||
return source->HasAuraEffect(aura.spell_id, aura.effect_idx);
|
return source->HasAuraEffect(aura.spell_id, aura.effect_idx);
|
||||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA:
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA:
|
||||||
{
|
{
|
||||||
uint32 zone_id, area_id;
|
uint32 zone_id, area_id;
|
||||||
source->GetZoneAndAreaId(zone_id, area_id);
|
source->GetZoneAndAreaId(zone_id, area_id);
|
||||||
return area.id == zone_id || area.id == area_id;
|
return area.id == zone_id || area.id == area_id;
|
||||||
}
|
}
|
||||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA:
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA:
|
||||||
return target && target->HasAuraEffect(aura.spell_id, aura.effect_idx);
|
return target && target->HasAuraEffect(aura.spell_id, aura.effect_idx);
|
||||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE:
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE:
|
||||||
@@ -361,89 +362,107 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un
|
|||||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT:
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT:
|
||||||
return sScriptMgr->OnCriteriaCheck(ScriptId, const_cast<Player*>(source), const_cast<Unit*>(target), criteria_id);
|
return sScriptMgr->OnCriteriaCheck(ScriptId, const_cast<Player*>(source), const_cast<Unit*>(target), criteria_id);
|
||||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY:
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY:
|
||||||
{
|
{
|
||||||
if (source->GetMap()->IsRaid())
|
if (source->GetMap()->IsRaid())
|
||||||
if (source->GetMap()->Is25ManRaid() != ((difficulty.difficulty & RAID_DIFFICULTY_MASK_25MAN) != 0))
|
if (source->GetMap()->Is25ManRaid() != ((difficulty.difficulty & RAID_DIFFICULTY_MASK_25MAN) != 0))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(criteria_id);
|
AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(criteria_id);
|
||||||
uint8 spawnMode = source->GetMap()->GetSpawnMode();
|
uint8 spawnMode = source->GetMap()->GetSpawnMode();
|
||||||
// Dungeons completed on heroic mode count towards both in general achievement, but not in statistics.
|
// Dungeons completed on heroic mode count towards both in general achievement, but not in statistics.
|
||||||
return sAchievementMgr->IsStatisticCriteria(criteria) ? spawnMode == difficulty.difficulty : spawnMode >= difficulty.difficulty;
|
return sAchievementMgr->IsStatisticCriteria(criteria) ? spawnMode == difficulty.difficulty : spawnMode >= difficulty.difficulty;
|
||||||
}
|
}
|
||||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT:
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT:
|
||||||
return source->GetMap()->GetPlayersCountExceptGMs() <= map_players.maxcount;
|
return source->GetMap()->GetPlayersCountExceptGMs() <= map_players.maxcount;
|
||||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM:
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM:
|
||||||
{
|
{
|
||||||
if (!target || target->GetTypeId() != TYPEID_PLAYER)
|
if (!target || target->GetTypeId() != TYPEID_PLAYER)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// DB data compatibility...
|
// DB data compatibility...
|
||||||
uint32 teamOld = target->ToPlayer()->GetTeamId() == TEAM_ALLIANCE ? ALLIANCE : HORDE;
|
uint32 teamOld = target->ToPlayer()->GetTeamId() == TEAM_ALLIANCE ? ALLIANCE : HORDE;
|
||||||
return teamOld == team.team;
|
return teamOld == team.team;
|
||||||
}
|
}
|
||||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_DRUNK:
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_DRUNK:
|
||||||
return Player::GetDrunkenstateByValue(source->GetDrunkValue()) >= DrunkenState(drunk.state);
|
return Player::GetDrunkenstateByValue(source->GetDrunkValue()) >= DrunkenState(drunk.state);
|
||||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY:
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY:
|
||||||
return IsHolidayActive(HolidayIds(holiday.id));
|
return IsHolidayActive(HolidayIds(holiday.id));
|
||||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE:
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE:
|
||||||
{
|
{
|
||||||
Battleground* bg = source->GetBattleground();
|
Battleground* bg = source->GetBattleground();
|
||||||
if (!bg)
|
if (!bg)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint32 score = bg->GetTeamScore(source->GetTeamId() == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE);
|
uint32 score = bg->GetTeamScore(source->GetTeamId() == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE);
|
||||||
return score >= bg_loss_team_score.min_score && score <= bg_loss_team_score.max_score;
|
return score >= bg_loss_team_score.min_score && score <= bg_loss_team_score.max_score;
|
||||||
}
|
}
|
||||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT:
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT:
|
||||||
|
{
|
||||||
|
if (!source->IsInWorld())
|
||||||
|
return false;
|
||||||
|
Map* map = source->GetMap();
|
||||||
|
if (!map->IsDungeon())
|
||||||
{
|
{
|
||||||
if (!source->IsInWorld())
|
LOG_ERROR("sql.sql", "Achievement system call ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT (%u) for achievement criteria %u for non-dungeon/non-raid map %u",
|
||||||
return false;
|
ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT, criteria_id, map->GetId());
|
||||||
Map* map = source->GetMap();
|
return false;
|
||||||
if (!map->IsDungeon())
|
|
||||||
{
|
|
||||||
LOG_ERROR("sql.sql", "Achievement system call ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT (%u) for achievement criteria %u for non-dungeon/non-raid map %u",
|
|
||||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT, criteria_id, map->GetId());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
InstanceScript* instance = map->ToInstanceMap()->GetInstanceScript();
|
|
||||||
if (!instance)
|
|
||||||
{
|
|
||||||
LOG_ERROR("sql.sql", "Achievement system call ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT (%u) for achievement criteria %u for map %u but map does not have a instance script",
|
|
||||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT, criteria_id, map->GetId());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return instance->CheckAchievementCriteriaMeet(criteria_id, source, target, miscvalue1);
|
|
||||||
}
|
}
|
||||||
|
InstanceScript* instance = map->ToInstanceMap()->GetInstanceScript();
|
||||||
|
if (!instance)
|
||||||
|
{
|
||||||
|
LOG_ERROR("sql.sql", "Achievement system call ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT (%u) for achievement criteria %u for map %u but map does not have a instance script",
|
||||||
|
ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT, criteria_id, map->GetId());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return instance->CheckAchievementCriteriaMeet(criteria_id, source, target, miscvalue1);
|
||||||
|
}
|
||||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM:
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM:
|
||||||
{
|
{
|
||||||
ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(miscvalue1);
|
ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(miscvalue1);
|
||||||
if (!pProto)
|
if (!pProto)
|
||||||
return false;
|
return false;
|
||||||
return pProto->ItemLevel >= equipped_item.item_level && pProto->Quality >= equipped_item.item_quality;
|
return pProto->ItemLevel >= equipped_item.item_level && pProto->Quality >= equipped_item.item_quality;
|
||||||
}
|
}
|
||||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID:
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID:
|
||||||
return source->GetMapId() == map_id.mapId;
|
return source->GetMapId() == map_id.mapId;
|
||||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_NTH_BIRTHDAY:
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_NTH_BIRTHDAY:
|
||||||
{
|
{
|
||||||
time_t birthday_start = time_t(sWorld->getIntConfig(CONFIG_BIRTHDAY_TIME));
|
time_t birthday_start = time_t(sWorld->getIntConfig(CONFIG_BIRTHDAY_TIME));
|
||||||
tm birthday_tm;
|
tm birthday_tm;
|
||||||
localtime_r(&birthday_start, &birthday_tm);
|
localtime_r(&birthday_start, &birthday_tm);
|
||||||
|
|
||||||
// exactly N birthday
|
// exactly N birthday
|
||||||
birthday_tm.tm_year += birthday_login.nth_birthday;
|
birthday_tm.tm_year += birthday_login.nth_birthday;
|
||||||
|
|
||||||
time_t birthday = mktime(&birthday_tm);
|
time_t birthday = mktime(&birthday_tm);
|
||||||
time_t now = sWorld->GetGameTime();
|
time_t now = sWorld->GetGameTime();
|
||||||
return now <= birthday + DAY && now >= birthday;
|
return now <= birthday + DAY && now >= birthday;
|
||||||
}
|
}
|
||||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_KNOWN_TITLE:
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_KNOWN_TITLE:
|
||||||
{
|
{
|
||||||
if (CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(known_title.title_id))
|
if (CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(known_title.title_id))
|
||||||
return source && source->HasTitle(titleInfo->bit_index);
|
return source && source->HasTitle(titleInfo->bit_index);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_TEAMS_SCORES:
|
||||||
|
{
|
||||||
|
Battleground* bg = source->GetBattleground();
|
||||||
|
if (!bg)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TeamId winnerTeam = bg->GetWinner();
|
||||||
|
if (winnerTeam == TEAM_NEUTRAL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 winnnerScore = bg->GetTeamScore(winnerTeam);
|
||||||
|
uint32 loserScore = bg->GetTeamScore(TeamId(!uint32(winnerTeam)));
|
||||||
|
return source->GetTeamId() == winnerTeam && winnnerScore == teams_scores.winner_score && loserScore == teams_scores.loser_score;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,9 +55,10 @@ enum AchievementCriteriaDataType
|
|||||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID = 20, // map_id 0 player must be on map with id in map_id
|
ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID = 20, // map_id 0 player must be on map with id in map_id
|
||||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE = 21, // class_id race_id
|
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE = 21, // class_id race_id
|
||||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_NTH_BIRTHDAY = 22, // N login on day of N-th Birthday
|
ACHIEVEMENT_CRITERIA_DATA_TYPE_NTH_BIRTHDAY = 22, // N login on day of N-th Birthday
|
||||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_KNOWN_TITLE = 23 // title_id known (pvp) title, values from dbc
|
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_KNOWN_TITLE = 23, // title_id known (pvp) title, values from dbc
|
||||||
|
ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_TEAMS_SCORES = 24, // winner_score loser score player's team win bg and their teams have exact scores
|
||||||
};
|
};
|
||||||
#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 24 // maximum value in AchievementCriteriaDataType enum
|
#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 25 // maximum value in AchievementCriteriaDataType enum
|
||||||
|
|
||||||
enum AchievementCommonCategories
|
enum AchievementCommonCategories
|
||||||
{
|
{
|
||||||
@@ -156,7 +157,7 @@ struct AchievementCriteriaData
|
|||||||
uint32 min_score;
|
uint32 min_score;
|
||||||
uint32 max_score;
|
uint32 max_score;
|
||||||
} bg_loss_team_score;
|
} bg_loss_team_score;
|
||||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT = 18 (no data)
|
// ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT = 18 (no data)
|
||||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM = 19
|
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM = 19
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@@ -168,16 +169,22 @@ struct AchievementCriteriaData
|
|||||||
{
|
{
|
||||||
uint32 mapId;
|
uint32 mapId;
|
||||||
} map_id;
|
} map_id;
|
||||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_NTH_BIRTHDAY = 21
|
// ACHIEVEMENT_CRITERIA_DATA_TYPE_NTH_BIRTHDAY = 22
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint32 nth_birthday;
|
uint32 nth_birthday;
|
||||||
} birthday_login;
|
} birthday_login;
|
||||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_KNOWN_TITLE = 22
|
// ACHIEVEMENT_CRITERIA_DATA_TYPE_KNOWN_TITLE = 23
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint32 title_id;
|
uint32 title_id;
|
||||||
} known_title;
|
} known_title;
|
||||||
|
// ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_TEAMS_SCORES = 24
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 winner_score;
|
||||||
|
uint32 loser_score;
|
||||||
|
} teams_scores;
|
||||||
// ...
|
// ...
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user