Core/Achievements: Implement criteria type ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN and criteria requirements ACHIEVEMENT_CRITERIA_REQUIRE_NTH_BIRTHDAY and ACHIEVEMENT_CRITERIA_REQUIRE_KNOWN_TITLE. Fixes anniversary achievements.
By @Schmoozerd
This commit is contained in:
1 parent
a2022d6f6d
commit
f29463cf66
9 files changed
+81
-7
No files matched your search
@@ -97,6 +97,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: // only Children's Week achievements
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN:
|
||||
break;
|
||||
default:
|
||||
if (dataType != ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT)
|
||||
@@ -111,6 +112,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
|
||||
{
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE:
|
||||
case ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT:
|
||||
case ACHIEVEMENT_CRITERIA_REQUIRE_NTH_BIRTHDAY:
|
||||
return true;
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE:
|
||||
if (!creature.id || !sObjectMgr->GetCreatureTemplate(creature.id))
|
||||
@@ -292,6 +294,16 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
case ACHIEVEMENT_CRITERIA_REQUIRE_KNOWN_TITLE:
|
||||
{
|
||||
if (!sCharTitlesStore.LookupEntry(known_title.title_id))
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_requirement` (Entry: %u Type: %u) for requirement ACHIEVEMENT_CRITERIA_REQUIRE_KNOWN_TITLE (%u) have unknown title_id in value1 (%u), ignore.",
|
||||
criteria->ID, criteria->requiredType, dataType, known_title.title_id);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) has data for non-supported data type (%u), ignored.", criteria->ID, criteria->requiredType, dataType);
|
||||
return false;
|
||||
@@ -410,6 +422,26 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID:
|
||||
return source->GetMapId() == map_id.mapId;
|
||||
case ACHIEVEMENT_CRITERIA_REQUIRE_NTH_BIRTHDAY:
|
||||
{
|
||||
time_t birthday_start = time_t(sWorld->getIntConfig(CONFIG_BIRTHDAY_TIME));
|
||||
|
||||
tm birthday_tm = *localtime(&birthday_start);
|
||||
|
||||
// exactly N birthday
|
||||
birthday_tm.tm_year += birthday_login.nth_birthday;
|
||||
|
||||
time_t birthday = mktime(&birthday_tm);
|
||||
time_t now = sWorld->GetGameTime();
|
||||
return now <= birthday + DAY && now >= birthday;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_REQUIRE_KNOWN_TITLE:
|
||||
{
|
||||
if (CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(known_title.title_id))
|
||||
return source && source->HasTitle(titleInfo->bit_index);
|
||||
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1562,6 +1594,20 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
||||
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
|
||||
break;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN:
|
||||
{
|
||||
// This criteria is only called directly after login - with expected miscvalue1 == 1
|
||||
if (!miscValue1)
|
||||
continue;
|
||||
|
||||
// They have no proper requirements in dbc
|
||||
AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);
|
||||
if (!data || !data->Meets(GetPlayer(), unit))
|
||||
continue;
|
||||
|
||||
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
|
||||
break;
|
||||
}
|
||||
// std case: not exist in DBC, not triggered in code as result
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER:
|
||||
@@ -1574,7 +1620,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE:
|
||||
break; // Not implemented yet :(
|
||||
}
|
||||
|
||||
@@ -1717,6 +1762,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
|
||||
return progress->counter >= achievementCriteria->get_killing_blow.killCount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA:
|
||||
return achievementCriteria->win_arena.count && progress->counter >= achievementCriteria->win_arena.count;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN:
|
||||
return true;
|
||||
// handle all statistic-only criteria here
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP:
|
||||
|
||||
@@ -68,10 +68,12 @@ enum AchievementCriteriaDataType
|
||||
ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT = 18, // 0 0 maker instance script call for check current criteria requirements fit
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM = 19, // item_level item_quality for equipped item in slot to check item level and quality
|
||||
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_REQUIRE_NTH_BIRTHDAY = 22, // N login on day of N-th Birthday
|
||||
ACHIEVEMENT_CRITERIA_REQUIRE_KNOWN_TITLE = 23, // title_id known (pvp) title, values from dbc
|
||||
};
|
||||
|
||||
#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 22 // maximum value in AchievementCriteriaDataType enum
|
||||
#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 24 // maximum value in AchievementCriteriaDataType enum
|
||||
|
||||
struct AchievementCriteriaData
|
||||
{
|
||||
@@ -173,6 +175,16 @@ struct AchievementCriteriaData
|
||||
{
|
||||
uint32 mapId;
|
||||
} map_id;
|
||||
// ACHIEVEMENT_CRITERIA_REQUIRE_NTH_BIRTHDAY = 21
|
||||
struct
|
||||
{
|
||||
uint32 nth_birthday;
|
||||
} birthday_login;
|
||||
// ACHIEVEMENT_CRITERIA_REQUIRE_KNOWN_TITLE = 22
|
||||
struct
|
||||
{
|
||||
uint32 title_id;
|
||||
} known_title;
|
||||
// ...
|
||||
struct
|
||||
{
|
||||
|
||||
@@ -174,7 +174,7 @@ enum AchievementCriteriaTypes
|
||||
ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL = 70,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT = 72,
|
||||
/// @todo 73: Achievements 1515, 1241, 1103 (Name: Mal'Ganis)
|
||||
ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE = 74, /// @todo title id is not mentioned in dbc
|
||||
ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN = 74,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS = 75,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL = 76,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL = 77,
|
||||
|
||||
@@ -24303,7 +24303,7 @@ bool Player::isTotalImmune()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Player::HasTitle(uint32 bitIndex)
|
||||
bool Player::HasTitle(uint32 bitIndex) const
|
||||
{
|
||||
if (bitIndex > MAX_TITLE_INDEX)
|
||||
return false;
|
||||
|
||||
@@ -2264,8 +2264,8 @@ class Player : public Unit, public GridObject<Player>
|
||||
void RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry);
|
||||
void CompletedAchievement(AchievementEntry const* entry);
|
||||
|
||||
bool HasTitle(uint32 bitIndex);
|
||||
bool HasTitle(CharTitlesEntry const* title) { return HasTitle(title->bit_index); }
|
||||
bool HasTitle(uint32 bitIndex) const;
|
||||
bool HasTitle(CharTitlesEntry const* title) const { return HasTitle(title->bit_index); }
|
||||
void SetTitle(CharTitlesEntry const* title, bool lost = false);
|
||||
|
||||
//bool isActiveObject() const { return true; }
|
||||
|
||||
@@ -1027,6 +1027,9 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
|
||||
|
||||
m_playerLoading = false;
|
||||
|
||||
// Handle Login-Achievements (should be handled after loading)
|
||||
_player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN, 1);
|
||||
|
||||
sScriptMgr->OnPlayerLogin(pCurrChar);
|
||||
delete holder;
|
||||
}
|
||||
|
||||
@@ -1262,6 +1262,8 @@ void World::LoadConfigSettings(bool reload)
|
||||
|
||||
m_int_configs[CONFIG_PACKET_SPOOF_BANDURATION] = sConfigMgr->GetIntDefault("PacketSpoof.BanDuration", 86400);
|
||||
|
||||
m_int_configs[CONFIG_BIRTHDAY_TIME] = sConfigMgr->GetIntDefault("BirthdayTime", 1222964635);
|
||||
|
||||
// call ScriptMgr if we're reloading the configuration
|
||||
if (reload)
|
||||
sScriptMgr->OnConfigLoad(reload);
|
||||
|
||||
@@ -339,6 +339,7 @@ enum WorldIntConfigs
|
||||
CONFIG_BG_REWARD_WINNER_ARENA_LAST,
|
||||
CONFIG_BG_REWARD_LOSER_HONOR_FIRST,
|
||||
CONFIG_BG_REWARD_LOSER_HONOR_LAST,
|
||||
CONFIG_BIRTHDAY_TIME,
|
||||
INT_CONFIG_VALUE_COUNT
|
||||
};
|
||||
|
||||
|
||||
@@ -1139,6 +1139,15 @@ AccountInstancesPerHour = 5
|
||||
|
||||
Account.PasswordChangeSecurity = 0
|
||||
|
||||
#
|
||||
# BirthdayTime
|
||||
# Description: Set to date of project's birth in UNIX time. By default the date when TrinityCore was started (Thu Oct 2, 2008)
|
||||
# Default: 1222964635
|
||||
#
|
||||
#
|
||||
|
||||
BirthdayTime = 1222964635
|
||||
|
||||
#
|
||||
###################################################################################################
|
||||
|
||||
|
||||
Reference in new issue
Block a user