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:
Discover- committed 2014-02-05 09:34:12 +01:00
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:
+14 -2
View File
@@ -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
{
+1 -1
View File
@@ -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,
+1 -1
View File
@@ -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;
+2 -2
View File
@@ -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;
}
+2
View File
@@ -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);
+1
View File
@@ -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
#
###################################################################################################