Skip to content

Commit

Permalink
[MIRROR] Makes achievements_score query database for count [MDB IGNOR…
Browse files Browse the repository at this point in the history
…E] (#602)

* Makes achievements_score query database for count (#79597)

---------

Co-authored-by: SkyratBot <[email protected]>
Co-authored-by: Jordie <[email protected]>
  • Loading branch information
3 people authored Nov 13, 2023
1 parent c95932b commit d484ed5
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 32 deletions.
5 changes: 0 additions & 5 deletions code/__DEFINES/achievements.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
6 changes: 0 additions & 6 deletions code/__HELPERS/cmp.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 2 additions & 2 deletions code/datums/achievements/_achievement_data.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
59 changes: 40 additions & 19 deletions code/datums/achievements/_awards.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down Expand Up @@ -109,7 +106,6 @@
/datum/award/achievement/on_unlock(mob/user)
. = ..()
to_chat(user, span_greenannounce("<B>Achievement unlocked: [name]!</B>"))
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)
Expand Down Expand Up @@ -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)

0 comments on commit d484ed5

Please sign in to comment.