diff --git a/code/__DEFINES/medal.dm b/code/__DEFINES/medal.dm
new file mode 100644
index 0000000000..5781e14f57
--- /dev/null
+++ b/code/__DEFINES/medal.dm
@@ -0,0 +1,29 @@
+// Medal names
+#define BOSS_KILL_MEDAL "Killer"
+#define ALL_KILL_MEDAL "Exterminator" //Killing all of x type
+#define BOSS_KILL_MEDAL_CRUSHER "Crusher"
+
+//Defines for boss medals
+#define BOSS_MEDAL_MINER "Blood-drunk Miner"
+#define BOSS_MEDAL_BUBBLEGUM "Bubblegum"
+#define BOSS_MEDAL_COLOSSUS "Colossus"
+#define BOSS_MEDAL_DRAKE "Drake"
+#define BOSS_MEDAL_HIEROPHANT "Hierophant"
+#define BOSS_MEDAL_LEGION "Legion"
+#define BOSS_MEDAL_SWARMER "Swarmer Beacon"
+#define BOSS_MEDAL_TENDRIL "Tendril"
+
+// Score names
+#define HIEROPHANT_SCORE "Hierophants Killed"
+#define BOSS_SCORE "Bosses Killed"
+#define BUBBLEGUM_SCORE "Bubblegum Killed"
+#define COLOSSUS_SCORE "Colossus Killed"
+#define DRAKE_SCORE "Drakes Killed"
+#define LEGION_SCORE "Legion Killed"
+#define SWARMER_BEACON_SCORE "Swarmer Beacons Killed"
+#define TENDRIL_CLEAR_SCORE "Tendrils Killed"
+
+//Misc medals
+#define MEDAL_METEOR "Your Life Before Your Eyes"
+#define MEDAL_PULSE "Jackpot"
+#define MEDAL_TIMEWASTE "Overextended The Joke"
\ No newline at end of file
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index a75b7dd3c0..bee1e19a5b 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -378,20 +378,6 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
#define INCREMENT_TALLY(L, stat) if(L[stat]){L[stat]++}else{L[stat] = 1}
-// Medal names
-#define BOSS_KILL_MEDAL "Killer"
-#define ALL_KILL_MEDAL "Exterminator" //Killing all of x type
-
-// Score names
-#define LEGION_SCORE "Legion Killed"
-#define COLOSSUS_SCORE "Colossus Killed"
-#define BUBBLEGUM_SCORE "Bubblegum Killed"
-#define DRAKE_SCORE "Drakes Killed"
-#define BIRD_SCORE "Hierophants Killed"
-#define SWARMER_BEACON_SCORE "Swarmer Beacons Killed"
-#define BOSS_SCORE "Bosses Killed"
-#define TENDRIL_CLEAR_SCORE "Tendrils Killed"
-
//TODO Move to a pref
#define STATION_GOAL_BUDGET 1
diff --git a/code/controllers/configuration/entries/comms.dm b/code/controllers/configuration/entries/comms.dm
index 289691caad..576e73faaa 100644
--- a/code/controllers/configuration/entries/comms.dm
+++ b/code/controllers/configuration/entries/comms.dm
@@ -20,8 +20,6 @@
/datum/config_entry/string/cross_comms_name
-GLOBAL_VAR_INIT(medals_enabled, TRUE) //will be auto set to false if the game fails contacting the medal hub to prevent unneeded calls.
-
/datum/config_entry/string/medal_hub_address
/datum/config_entry/string/medal_hub_password
diff --git a/code/controllers/subsystem/medals.dm b/code/controllers/subsystem/medals.dm
new file mode 100644
index 0000000000..21366978f6
--- /dev/null
+++ b/code/controllers/subsystem/medals.dm
@@ -0,0 +1,87 @@
+SUBSYSTEM_DEF(medals)
+ name = "Medals"
+ flags = SS_NO_FIRE
+ var/hub_enabled = FALSE
+
+/datum/controller/subsystem/medals/Initialize(timeofday)
+ if(CONFIG_GET(string/medal_hub_address) && CONFIG_GET(string/medal_hub_password))
+ hub_enabled = TRUE
+ ..()
+
+/datum/controller/subsystem/medals/proc/UnlockMedal(medal, client/player)
+ set waitfor = FALSE
+ if(!medal || !hub_enabled)
+ return
+ if(isnull(world.SetMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))))
+ hub_enabled = FALSE
+ log_game("MEDAL ERROR: Could not contact hub to award medal:[medal] player:[player.ckey]")
+ message_admins("Error! Failed to contact hub to award [medal] medal to [player.ckey]!")
+ return
+ to_chat(player, "Achievement unlocked: [medal]!")
+
+
+/datum/controller/subsystem/medals/proc/SetScore(score, client/player, increment, force)
+ set waitfor = FALSE
+ if(!score || !hub_enabled)
+ return
+
+ var/list/oldscore = GetScore(score, player, TRUE)
+ if(increment)
+ if(!oldscore[score])
+ oldscore[score] = 1
+ else
+ oldscore[score] = (text2num(oldscore[score]) + 1)
+ else
+ oldscore[score] = force
+
+ var/newscoreparam = list2params(oldscore)
+
+ if(isnull(world.SetScores(player.ckey, newscoreparam, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))))
+ hub_enabled = FALSE
+ log_game("SCORE ERROR: Could not contact hub to set score. Score:[score] player:[player.ckey]")
+ message_admins("Error! Failed to contact hub to set [score] score for [player.ckey]!")
+
+/datum/controller/subsystem/medals/proc/GetScore(score, client/player, returnlist)
+ if(!score || !hub_enabled)
+ return
+
+ var/scoreget = world.GetScores(player.ckey, score, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
+ if(isnull(scoreget))
+ hub_enabled = FALSE
+ log_game("SCORE ERROR: Could not contact hub to get score. Score:[score] player:[player.ckey]")
+ message_admins("Error! Failed to contact hub to get score: [score] for [player.ckey]!")
+ return
+ . = params2list(scoreget)
+ if(!returnlist)
+ return .[score]
+
+/datum/controller/subsystem/medals/proc/CheckMedal(medal, client/player)
+ if(!medal || !hub_enabled)
+ return
+
+ if(isnull(world.GetMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))))
+ hub_enabled = FALSE
+ log_game("MEDAL ERROR: Could not contact hub to get medal:[medal] player: [player.ckey]")
+ message_admins("Error! Failed to contact hub to get [medal] medal for [player.ckey]!")
+ return
+ to_chat(player, "[medal] is unlocked")
+
+/datum/controller/subsystem/medals/proc/LockMedal(medal, client/player)
+ if(!player || !medal || !hub_enabled)
+ return
+ var/result = world.ClearMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
+ switch(result)
+ if(null)
+ hub_enabled = FALSE
+ log_game("MEDAL ERROR: Could not contact hub to clear medal:[medal] player:[player.ckey]")
+ message_admins("Error! Failed to contact hub to clear [medal] medal for [player.ckey]!")
+ if(TRUE)
+ message_admins("Medal: [medal] removed for [player.ckey]")
+ if(FALSE)
+ message_admins("Medal: [medal] was not found for [player.ckey]. Unable to clear.")
+
+
+/datum/controller/subsystem/medals/proc/ClearScore(client/player)
+ if(isnull(world.SetScores(player.ckey, "", CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))))
+ log_game("MEDAL ERROR: Could not contact hub to clear scores for [player.ckey]!")
+ message_admins("Error! Failed to contact hub to clear scores for [player.ckey]!")
\ No newline at end of file
diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm
index c717b815e9..2326216eff 100644
--- a/code/game/gamemodes/meteor/meteors.dm
+++ b/code/game/gamemodes/meteor/meteors.dm
@@ -164,15 +164,11 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
/obj/effect/meteor/ex_act()
return
-#define METEOR_MEDAL "Your Life Before Your Eyes"
-
/obj/effect/meteor/examine(mob/user)
if(!admin_spawned && isliving(user))
- UnlockMedal(METEOR_MEDAL,user.client)
+ SSmedals.UnlockMedal(MEDAL_METEOR, user.client)
..()
-#undef METEOR_MEDAL
-
/obj/effect/meteor/attackby(obj/item/I, mob/user, params)
if(I.tool_behaviour == TOOL_MINING)
make_debris()
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index 17fea3cbfb..90dc4f4f45 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -67,12 +67,10 @@
return INITIALIZE_HINT_QDEL
Reset()
-#define PULSE_MEDAL "Jackpot"
-
/obj/machinery/computer/arcade/proc/prizevend()
if(prob(0.0001)) //1 in a million
new /obj/item/gun/energy/pulse/prize(src)
- UnlockMedal(PULSE_MEDAL,usr.client)
+ SSmedals.UnlockMedal(MEDAL_PULSE, usr.client)
if(!contents.len)
var/prizeselect = pickweight(prizes)
@@ -82,7 +80,6 @@
visible_message("[src] dispenses [prize]!", "You hear a chime and a clunk.")
prize.forceMove(get_turf(src))
-#undef PULSE_MEDAL
/obj/machinery/computer/arcade/emp_act(severity)
..(severity)
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index e038f1ca38..62530da255 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -923,14 +923,15 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
set category = "Debug"
set name = "Toggle Medal Disable"
set desc = "Toggles the safety lock on trying to contact the medal hub."
- if(!holder)
+
+ if(!check_rights(R_DEBUG))
return
- GLOB.medals_enabled = !GLOB.medals_enabled
+ SSmedals.hub_enabled = !SSmedals.hub_enabled
- message_admins("[key_name_admin(src)] [GLOB.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.")
+ message_admins("[key_name_admin(src)] [SSmedals.hub_enabled ? "disabled" : "enabled"] the medal hub lockout.")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Medal Disable") // If...
- log_admin("[key_name(src)] [GLOB.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.")
+ log_admin("[key_name(src)] [SSmedals.hub_enabled ? "disabled" : "enabled"] the medal hub lockout.")
/client/proc/view_runtimes()
set category = "Debug"
diff --git a/code/modules/awaymissions/super_secret_room.dm b/code/modules/awaymissions/super_secret_room.dm
index 2569f0ca65..65abae44c5 100644
--- a/code/modules/awaymissions/super_secret_room.dm
+++ b/code/modules/awaymissions/super_secret_room.dm
@@ -17,8 +17,6 @@
var/list/json = json_decode(file2text(json_file))
shenanigans = json["phrases"]
-#define TIMEWASTE_MEDAL "Overextended The Joke"
-
/obj/structure/speaking_tile/interact(mob/user)
if(!isliving(user) || speaking)
return
@@ -81,16 +79,15 @@
if(1000)
SpeakPeace(list("The ends exists somewhere beyond meaningful milestones.", "There will be no more messages until then.", "You disgust me."))
if(5643)
- UnlockMedal(TIMEWASTE_MEDAL,user.client)
+ SSmedals.UnlockMedal(MEDAL_TIMEWASTE, user.client)
var/obj/item/reagent_containers/food/drinks/trophy/gold_cup/never_ends = new(get_turf(user))
never_ends.name = "Overextending The Joke: First Place"
never_ends.desc = "And so we are left alone with our regrets."
else
y += 2
-
speaking = FALSE
times_spoken_to++
-#undef TIMEWASTE_MEDAL
+
/obj/structure/speaking_tile/proc/SpeakPeace(list/statements)
for(var/i in 1 to statements.len)
say("[statements[i]]")
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
index 0e67921f3d..8e285c0b4c 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
@@ -1,5 +1,5 @@
#define MINER_DASH_RANGE 4
-#define MEDAL_PREFIX "Blood-drunk Miner"
+
/*
BLOOD-DRUNK MINER
@@ -43,7 +43,7 @@ Difficulty: Medium
wander = FALSE
del_on_death = TRUE
blood_volume = BLOOD_VOLUME_NORMAL
- medal_type = MEDAL_PREFIX
+ medal_type = BOSS_MEDAL_MINER
var/obj/item/melee/transforming/cleaving_saw/miner/miner_saw
var/time_until_next_transform = 0
var/dashing = FALSE
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
index 62b66464eb..e0e7efd11b 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
@@ -1,5 +1,3 @@
-#define MEDAL_PREFIX "Bubblegum"
-
/*
BUBBLEGUM
@@ -48,7 +46,7 @@ Difficulty: Hard
loot = list(/obj/structure/closet/crate/necropolis/bubblegum)
blood_volume = BLOOD_VOLUME_MAXIMUM //BLEED FOR ME
var/charging = FALSE
- medal_type = MEDAL_PREFIX
+ medal_type = BOSS_MEDAL_BUBBLEGUM
score_type = BUBBLEGUM_SCORE
deathmessage = "sinks into a pool of blood, fleeing the battle. You've won, for now... "
death_sound = 'sound/magic/enter_blood.ogg'
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
index 0842329483..1cf031b0cc 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
@@ -1,5 +1,3 @@
-
-#define MEDAL_PREFIX "Colossus"
/*
COLOSSUS
@@ -44,7 +42,7 @@ Difficulty: Very Hard
ranged = 1
pixel_x = -32
del_on_death = 1
- medal_type = MEDAL_PREFIX
+ medal_type = BOSS_MEDAL_COLOSSUS
score_type = COLOSSUS_SCORE
crusher_loot = list(/obj/structure/closet/crate/necropolis/colossus/crusher)
loot = list(/obj/structure/closet/crate/necropolis/colossus)
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm
similarity index 99%
rename from code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm
rename to code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm
index 3efb3e2885..9b8035e790 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm
@@ -1,10 +1,9 @@
-#define MEDAL_PREFIX "Drake"
-
#define DRAKE_SWOOP_HEIGHT 270 //how high up drakes go, in pixels
#define DRAKE_SWOOP_DIRECTION_CHANGE_RANGE 5 //the range our x has to be within to not change the direction we slam from
#define SWOOP_DAMAGEABLE 1
#define SWOOP_INVULNERABLE 2
+
/*
ASH DRAKE
@@ -57,7 +56,7 @@ Difficulty: Medium
butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30)
var/swooping = NONE
var/swoop_cooldown = 0
- medal_type = MEDAL_PREFIX
+ medal_type = BOSS_MEDAL_DRAKE
score_type = DRAKE_SCORE
deathmessage = "collapses into a pile of bones, its flesh sloughing away."
death_sound = 'sound/magic/demon_dies.ogg'
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
index 8dc1780e5e..142883fa02 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
@@ -1,4 +1,3 @@
-#define MEDAL_PREFIX "Hierophant"
/*
The Hierophant
@@ -59,6 +58,11 @@ Difficulty: Hard
loot = list(/obj/item/hierophant_club)
crusher_loot = list(/obj/item/hierophant_club)
wander = FALSE
+ medal_type = BOSS_MEDAL_HIEROPHANT
+ score_type = HIEROPHANT_SCORE
+ del_on_death = TRUE
+ death_sound = 'sound/magic/repulse.ogg'
+
var/burst_range = 3 //range on burst aoe
var/beam_range = 5 //range on cross blast beams
var/chaser_speed = 3 //how fast chasers are currently
@@ -71,10 +75,6 @@ Difficulty: Hard
var/did_reset = TRUE //if we timed out, returned to our beacon, and healed some
var/list/kill_phrases = list("Wsyvgi sj irivkc xettih. Vitemvmrk...", "Irivkc wsyvgi jsyrh. Vitemvmrk...", "Jyip jsyrh. Egxmzexmrk vitemv gcgpiw...", "Kix fiex. Liepmrk...")
var/list/target_phrases = list("Xevkix psgexih.", "Iriqc jsyrh.", "Eguymvih xevkix.")
- medal_type = MEDAL_PREFIX
- score_type = BIRD_SCORE
- del_on_death = TRUE
- death_sound = 'sound/magic/repulse.ogg'
/mob/living/simple_animal/hostile/megafauna/hierophant/Initialize()
. = ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
index afb46a489c..eba26725a6 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
@@ -1,4 +1,3 @@
-#define MEDAL_PREFIX "Legion"
/*
LEGION
@@ -40,7 +39,7 @@ Difficulty: Medium
ranged_cooldown_time = 20
var/size = 5
var/charging = 0
- medal_type = MEDAL_PREFIX
+ medal_type = BOSS_MEDAL_LEGION
score_type = LEGION_SCORE
pixel_y = -90
pixel_x = -75
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
index e34fc76467..5e6211da09 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
@@ -1,6 +1,3 @@
-#define MEDAL_PREFIX "Boss"
-
-
/mob/living/simple_animal/hostile/megafauna
name = "boss of this gym"
desc = "Attack the weak point for massive damage."
@@ -23,6 +20,10 @@
maxbodytemp = INFINITY
aggro_vision_range = 18
idle_vision_range = 5
+ anchored = TRUE
+ mob_size = MOB_SIZE_LARGE
+ layer = LARGE_MOB_LAYER //Looks weird with them slipping under mineral walls and cameras and shit otherwise
+ mouse_opacity = MOUSE_OPACITY_OPAQUE // Easier to click on in melee, they're giant targets anyway
environment_target_typecache = list(
/obj/machinery/door/window,
/obj/structure/window,
@@ -35,16 +36,12 @@
/obj/machinery/field,
/obj/machinery/power/emitter)
var/list/crusher_loot
- var/medal_type = MEDAL_PREFIX
+ var/medal_type
var/score_type = BOSS_SCORE
var/elimination = 0
var/anger_modifier = 0
var/obj/item/device/gps/internal
var/recovery_time = 0
- anchored = TRUE
- mob_size = MOB_SIZE_LARGE
- layer = LARGE_MOB_LAYER //Looks weird with them slipping under mineral walls and cameras and shit otherwise
- mouse_opacity = MOUSE_OPACITY_OPAQUE // Easier to click on in melee, they're giant targets anyway
/mob/living/simple_animal/hostile/megafauna/Initialize(mapload)
. = ..()
@@ -59,13 +56,17 @@
return
else
var/datum/status_effect/crusher_damage/C = has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
- if(C && crusher_loot)
- if(C.total_damage >= maxHealth * 0.6) //if you do at least 60% of its health with the crusher, you'll get the item
- spawn_crusher_loot()
+ var/crusher_kill = FALSE
+ if(C && crusher_loot && C.total_damage >= maxHealth * 0.6)
+ spawn_crusher_loot()
+ crusher_kill = TRUE
if(!admin_spawned)
- SSblackbox.record_feedback("tally", "megafauna_kills", 1, "[initial(name)]")
+ var/tab = "megafauna_kills"
+ if(crusher_kill)
+ tab = "megafauna_kills_crusher"
+ SSblackbox.record_feedback("tally", tab, 1, "[initial(name)]")
if(!elimination) //used so the achievment only occurs for the last legion to die.
- grant_achievement(medal_type,score_type)
+ grant_achievement(medal_type, score_type, crusher_kill)
..()
/mob/living/simple_animal/hostile/megafauna/proc/spawn_crusher_loot()
@@ -123,122 +124,18 @@
/mob/living/simple_animal/hostile/megafauna/proc/SetRecoveryTime(buffer_time)
recovery_time = world.time + buffer_time
-/mob/living/simple_animal/hostile/megafauna/proc/grant_achievement(medaltype,scoretype)
- if(medal_type == "Boss") //Don't award medals if the medal type isn't set
+/mob/living/simple_animal/hostile/megafauna/proc/grant_achievement(medaltype, scoretype, crusher_kill)
+ if(!medal_type || admin_spawned || !SSmedals.hub_enabled) //Don't award medals if the medal type isn't set
return FALSE
- if(admin_spawned)
- return FALSE
-
- if(MedalsAvailable())
- for(var/mob/living/L in view(7,src))
- if(L.stat)
- continue
- if(L.client)
- var/client/C = L.client
- var/suffixm = BOSS_KILL_MEDAL
- UnlockMedal("Boss [suffixm]",C)
- UnlockMedal("[medaltype] [suffixm]",C)
- SetScore(BOSS_SCORE,C,1)
- SetScore(score_type,C,1)
- return TRUE
-
-/proc/UnlockMedal(medal,client/player)
- set waitfor = FALSE
- if(!player || !medal)
- return
- if(MedalsAvailable())
- var/result = world.SetMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
- if(isnull(result))
- GLOB.medals_enabled = FALSE
- log_game("MEDAL ERROR: Could not contact hub to award medal:[medal] player:[player.ckey]")
- message_admins("Error! Failed to contact hub to award [medal] medal to [player.ckey]!")
- else if (result)
- to_chat(player, "Achievement unlocked: [medal]!")
-
-
-/proc/SetScore(score,client/player,increment,force)
- set waitfor = FALSE
- if(!score || !player)
- return
- if(MedalsAvailable())
- var/list/oldscore = GetScore(score,player,1)
- if(increment)
- if(!oldscore[score])
- oldscore[score] = 1
- else
- oldscore[score] = (text2num(oldscore[score]) + 1)
- else
- oldscore[score] = force
-
- var/newscoreparam = list2params(oldscore)
-
- var/result = world.SetScores(player.ckey, newscoreparam, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
-
- if(isnull(result))
- GLOB.medals_enabled = FALSE
- log_game("SCORE ERROR: Could not contact hub to set score. Score:[score] player:[player.ckey]")
- message_admins("Error! Failed to contact hub to set [score] score for [player.ckey]!")
-
-
-/proc/GetScore(score,client/player,returnlist)
-
- if(!score || !player)
- return
- if(MedalsAvailable())
-
- var/scoreget = world.GetScores(player.ckey, score, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
- if(isnull(scoreget))
- GLOB.medals_enabled = FALSE
- log_game("SCORE ERROR: Could not contact hub to get score. Score:[score] player:[player.ckey]")
- message_admins("Error! Failed to contact hub to get score: [score] for [player.ckey]!")
- return
-
- var/list/scoregetlist = params2list(scoreget)
-
- if(returnlist)
- return scoregetlist
- else
- return scoregetlist[score]
-
-
-/proc/CheckMedal(medal,client/player)
-
- if(!player || !medal)
- return
- if(MedalsAvailable())
-
- var/result = world.GetMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
-
- if(isnull(result))
- GLOB.medals_enabled = FALSE
- log_game("MEDAL ERROR: Could not contact hub to get medal:[medal] player:[player.ckey]")
- message_admins("Error! Failed to contact hub to get [medal] medal for [player.ckey]!")
- else if (result)
- to_chat(player, "[medal] is unlocked")
-
-/proc/LockMedal(medal,client/player)
-
- if(!player || !medal)
- return
- if(MedalsAvailable())
-
- var/result = world.ClearMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
-
- if(isnull(result))
- GLOB.medals_enabled = FALSE
- log_game("MEDAL ERROR: Could not contact hub to clear medal:[medal] player:[player.ckey]")
- message_admins("Error! Failed to contact hub to clear [medal] medal for [player.ckey]!")
- else if (result)
- message_admins("Medal: [medal] removed for [player.ckey]")
- else
- message_admins("Medal: [medal] was not found for [player.ckey]. Unable to clear.")
-
-
-/proc/ClearScore(client/player)
- world.SetScores(player.ckey, "", CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
-
-/proc/MedalsAvailable()
- return CONFIG_GET(string/medal_hub_address) && CONFIG_GET(string/medal_hub_password) && GLOB.medals_enabled
-
-#undef MEDAL_PREFIX
+ for(var/mob/living/L in view(7,src))
+ if(L.stat || !L.client)
+ continue
+ var/client/C = L.client
+ SSmedals.UnlockMedal("Boss [BOSS_KILL_MEDAL]", C)
+ SSmedals.UnlockMedal("[medaltype] [BOSS_KILL_MEDAL]", C)
+ if(crusher_kill && istype(L.get_active_held_item(), /obj/item/twohanded/required/kinetic_crusher))
+ SSmedals.UnlockMedal("[medaltype] [BOSS_KILL_MEDAL_CRUSHER]", C)
+ SSmedals.SetScore(BOSS_SCORE, C, 1)
+ SSmedals.SetScore(score_type, C, 1)
+ return TRUE
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm
index 6a7af7910e..3d435de4e2 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm
@@ -45,9 +45,8 @@
/mob/living/simple_animal/hostile/spawner/lavaland/Destroy()
QDEL_NULL(emitted_light)
QDEL_NULL(gps)
- . = ..()
+ return ..()
-#define MEDAL_PREFIX "Tendril"
/mob/living/simple_animal/hostile/spawner/lavaland/death()
var/last_tendril = TRUE
for(var/mob/living/simple_animal/hostile/spawner/lavaland/other in GLOB.mob_living_list)
@@ -55,18 +54,13 @@
last_tendril = FALSE
break
if(last_tendril && !admin_spawned)
- if(MedalsAvailable())
+ if(SSmedals.hub_enabled)
for(var/mob/living/L in view(7,src))
- if(L.stat)
+ if(L.stat || !L.client)
continue
- if(L.client)
- var/client/C = L.client
- var/suffixm = ALL_KILL_MEDAL
- var/prefix = MEDAL_PREFIX
- UnlockMedal("[prefix] [suffixm]",C)
- SetScore(TENDRIL_CLEAR_SCORE,C,1)
+ SSmedals.UnlockMedal("[BOSS_MEDAL_TENDRIL] [ALL_KILL_MEDAL]", L.client)
+ SSmedals.SetScore(TENDRIL_CLEAR_SCORE, L.client, 1)
..()
-#undef MEDAL_PREFIX
/obj/effect/collapse
name = "collapsing necropolis tendril"
diff --git a/tgstation.dme b/tgstation.dme
index 2534f97c3e..92ab64b374 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -54,6 +54,7 @@
#include "code\__DEFINES\maps.dm"
#include "code\__DEFINES\maths.dm"
#include "code\__DEFINES\MC.dm"
+#include "code\__DEFINES\medal.dm"
#include "code\__DEFINES\menu.dm"
#include "code\__DEFINES\misc.dm"
#include "code\__DEFINES\mobs.dm"
@@ -253,6 +254,7 @@
#include "code\controllers\subsystem\lighting.dm"
#include "code\controllers\subsystem\machines.dm"
#include "code\controllers\subsystem\mapping.dm"
+#include "code\controllers\subsystem\medals.dm"
#include "code\controllers\subsystem\minimap.dm"
#include "code\controllers\subsystem\mobs.dm"
#include "code\controllers\subsystem\npcpool.dm"
@@ -2027,8 +2029,12 @@
#include "code\modules\mob\living\simple_animal\hostile\megafauna\blood_drunk_miner.dm"
#include "code\modules\mob\living\simple_animal\hostile\megafauna\bubblegum.dm"
#include "code\modules\mob\living\simple_animal\hostile\megafauna\colossus.dm"
+<<<<<<< HEAD
#include "code\modules\mob\living\simple_animal\hostile\megafauna\dragon.dm"
#include "code\modules\mob\living\simple_animal\hostile\megafauna\dragon_vore.dm"
+=======
+#include "code\modules\mob\living\simple_animal\hostile\megafauna\drake.dm"
+>>>>>>> a2ccca5... All medal methods are handled on SSmedals as opposed to global procs and also have proper defines. Killing with a crusher grants special medals. (#35673)
#include "code\modules\mob\living\simple_animal\hostile\megafauna\hierophant.dm"
#include "code\modules\mob\living\simple_animal\hostile\megafauna\legion.dm"
#include "code\modules\mob\living\simple_animal\hostile\megafauna\megafauna.dm"