From d484ed58f70a285f7e506eb366f7a86c941e7fd3 Mon Sep 17 00:00:00 2001 From: Iajret Creature <122297233+AnArgonianLizardThatStealsPRs@users.noreply.github.com> Date: Mon, 13 Nov 2023 21:40:51 +0300 Subject: [PATCH] [MIRROR] Makes achievements_score query database for count [MDB IGNORE] (#602) * Makes achievements_score query database for count (#79597) --------- Co-authored-by: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Co-authored-by: Jordie <4343468+Jordie0608@users.noreply.github.com> --- code/__DEFINES/achievements.dm | 5 -- code/__HELPERS/cmp.dm | 6 -- code/datums/achievements/_achievement_data.dm | 4 +- code/datums/achievements/_awards.dm | 59 +++++++++++++------ 4 files changed, 42 insertions(+), 32 deletions(-) diff --git a/code/__DEFINES/achievements.dm b/code/__DEFINES/achievements.dm index cfe3cd2e456..7af89f2673a 100644 --- a/code/__DEFINES/achievements.dm +++ b/code/__DEFINES/achievements.dm @@ -6,11 +6,6 @@ #define ACHIEVEMENT_DEFAULT "default" #define ACHIEVEMENT_SCORE "score" -///the priority for which awards are orded on [/datum/achievement_data/load_all_achievements()] -#define AWARD_PRIORITY_DEFAULT 100 -///the priority of the achievements score. NO achievement should have a priority equal or lower than this. -#define AWARD_PRIORITY_LAST 0 - /// preferences for the sound played when unlocking an achievement #define CHEEVO_SOUND_TADA "Tada Fanfare" #define CHEEVO_SOUND_JINGLE "Beeps Jingle" diff --git a/code/__HELPERS/cmp.dm b/code/__HELPERS/cmp.dm index e1303882b1a..0210c44ee57 100644 --- a/code/__HELPERS/cmp.dm +++ b/code/__HELPERS/cmp.dm @@ -189,12 +189,6 @@ /proc/cmp_assoc_list_name(list/A, list/B) return sorttext(B["name"], A["name"]) -/// Used by /datum/achievement_data/load_all_achievements() to determine in which order awards have to be loaded. -/proc/cmp_award_priority(type_a, type_b) - var/datum/award/award_a = SSachievements.awards[type_a] - var/datum/award/award_b = SSachievements.awards[type_b] - return award_b?.load_priority - award_a?.load_priority - /// Orders mobs by health /proc/cmp_mob_health(mob/living/mob_a, mob/living/mob_b) return mob_b.health - mob_a.health diff --git a/code/datums/achievements/_achievement_data.dm b/code/datums/achievements/_achievement_data.dm index aa47d8e9fc8..295770b89b5 100644 --- a/code/datums/achievements/_achievement_data.dm +++ b/code/datums/achievements/_achievement_data.dm @@ -45,7 +45,7 @@ kv[key] = value qdel(Query) - for(var/award_type in sortTim(subtypesof(/datum/award), GLOBAL_PROC_REF(cmp_award_priority))) + for(var/award_type in subtypesof(/datum/award)) var/datum/award/award = SSachievements.awards[award_type] if(!award || !award.name) //Skip abstract achievements types continue @@ -116,7 +116,7 @@ "icon_class" = assets.icon_class_name(award.icon), "value" = data[achievement_type], ) - award_data += award.get_ui_data() + award_data += award.get_ui_data(user.ckey) .["achievements"] += list(award_data) for(var/score in SSachievements.scores) diff --git a/code/datums/achievements/_awards.dm b/code/datums/achievements/_awards.dm index 7a7701e0cf1..23ab5e81001 100644 --- a/code/datums/achievements/_awards.dm +++ b/code/datums/achievements/_awards.dm @@ -15,9 +15,6 @@ //Value returned on db connection failure, in case we want to differ 0 and nonexistent later on var/default_value = FALSE - ///Whether the award has to be loaded before or after other awards on [/datum/achievement_data/load_all_achievements()] - var/load_priority = AWARD_PRIORITY_DEFAULT - ///This proc loads the achievement data from the hub. /datum/award/proc/load(key) if(!SSdbcore.Connect()) @@ -109,7 +106,6 @@ /datum/award/achievement/on_unlock(mob/user) . = ..() to_chat(user, span_greenannounce("Achievement unlocked: [name]!")) - user.client.give_award(/datum/award/score/achievements_score, user, 1) var/sound/sound_to_send = LAZYACCESS(GLOB.achievement_sounds, user.client.prefs.read_preference(/datum/preference/choiced/sound_achievement)) if(sound_to_send) SEND_SOUND(user, sound_to_send) @@ -177,20 +173,45 @@ desc = "Don't worry, metagaming is all that matters." icon = "elephant" //Obey the reference database_id = ACHIEVEMENTS_SCORE - load_priority = AWARD_PRIORITY_LAST //See below -/** - * If the raw value is not numerical, it's likely this is the first time the score is being loaded for a ckey. - * So, let's start counting how many achievements have been unlocked so far and return its value instead, - * which is why this award should always be loaded last. - */ +/datum/award/score/achievements_score/get_ui_data(key) + . = ..() + var/datum/db_query/get_unlocked_count = SSdbcore.NewQuery( + "SELECT COUNT(m.achievement_key) FROM [format_table_name("achievements")] AS a JOIN [format_table_name("achievement_metadata")] m ON a.achievement_key = m.achievement_key AND m.achievement_type = 'Achievement' WHERE a.ckey = :ckey", + list("ckey" = key) + ) + if(!get_unlocked_count.Execute(async = TRUE)) + qdel(get_unlocked_count) + .["value"] = default_value + return . + if(get_unlocked_count.NextRow()) + .["value"] = text2num(get_unlocked_count.item[1]) + qdel(get_unlocked_count) + return . + +/datum/award/score/achievements_score/LoadHighScores() + var/datum/db_query/get_unlocked_highscore = SSdbcore.NewQuery( + "SELECT ckey, COUNT(ckey) AS c FROM [format_table_name("achievements")] AS a JOIN [format_table_name("achievement_metadata")] m ON a.achievement_key = m.achievement_key AND m.achievement_type = 'Achievement' GROUP BY ckey ORDER BY c DESC LIMIT 50", + ) + if(!get_unlocked_highscore.Execute(async = TRUE)) + qdel(get_unlocked_highscore) + return + else + while(get_unlocked_highscore.NextRow()) + var/key = get_unlocked_highscore.item[1] + var/score = text2num(get_unlocked_highscore.item[2]) + high_scores[key] = score + qdel(get_unlocked_highscore) + /datum/award/score/achievements_score/on_achievement_data_init(datum/achievement_data/holder, database_value) - if(isnum(database_value)) - return ..() - //We need to keep the value differents so that it's properly saved at the end of the round. - holder.original_cached_data[type] = 0 - var/value = 0 - for(var/award_type in holder.data) - if(ispath(award_type, /datum/award/achievement) && holder.data[award_type]) - value++ - holder.data[type] = value + var/datum/db_query/get_unlocked_load = SSdbcore.NewQuery( + "SELECT COUNT(m.achievement_key) FROM [format_table_name("achievements")] AS a JOIN [format_table_name("achievement_metadata")] m ON a.achievement_key = m.achievement_key AND m.achievement_type = 'Achievement' WHERE a.ckey = :ckey", + list("ckey" = holder.owner_ckey) + ) + if(!get_unlocked_load.Execute(async = TRUE)) + qdel(get_unlocked_load) + return + if(get_unlocked_load.NextRow()) + holder.data[type] = text2num(get_unlocked_load.item[1]) || 0 + holder.original_cached_data[type] = 0 + qdel(get_unlocked_load)