diff --git a/code/__DEFINES/achievements.dm b/code/__DEFINES/achievements.dm
index 3873b1af7b2..b610eb50cc1 100644
--- a/code/__DEFINES/achievements.dm
+++ b/code/__DEFINES/achievements.dm
@@ -1,3 +1,5 @@
+// Keep the identifiers here below 32 characters, you can put the full display name in the actual achievement datum
+
#define ACHIEVEMENT_DEFAULT "default"
#define ACHIEVEMENT_SCORE "score"
@@ -10,6 +12,13 @@
#define MEDAL_THANKSALOT "The Best Driver"
#define MEDAL_HELBITALJANKEN "Hel-bent on Winning"
#define MEDAL_MATERIALCRAFT "Getting an Upgrade"
+#define MEDAL_DISKPLEASE "Disk, Please!"
+#define MEDAL_GAMER "I'm Not Important"
+#define MEDAL_VENDORSQUISH "Teenage Anarchist"
+#define MEDAL_SWIRLIE "Bowl-d"
+#define MEDAL_SELFOUCH "Hands???"
+#define MEDAL_SANDMAN "Mister Sandman"
+#define MEDAL_CLEANBOSS "Cleanboss"
//Boss medals
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index 99194a4f52a..20c3a3c39ee 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -65,6 +65,9 @@
M.lastattacker = user.real_name
M.lastattackerckey = user.ckey
+ if(force && M == user && user.client)
+ user.client.give_award(/datum/award/achievement/misc/selfouch, user)
+
user.do_attack_animation(M)
M.attacked_by(src, user)
diff --git a/code/datums/achievements/misc_achievements.dm b/code/datums/achievements/misc_achievements.dm
index 51e72555d16..a4f65925d27 100644
--- a/code/datums/achievements/misc_achievements.dm
+++ b/code/datums/achievements/misc_achievements.dm
@@ -35,8 +35,43 @@
name = "Helbitaljanken"
desc = "You janked hard"
database_id = MEDAL_HELBITALJANKEN
-
+
/datum/award/achievement/misc/getting_an_upgrade
name = "Getting an upgrade"
desc = "Make your first unique material item!"
database_id = MEDAL_MATERIALCRAFT
+
+/datum/award/achievement/misc/rocket_holdup
+ name = "Disk, Please!"
+ desc = "Is the man currently pointing a loaded rocket launcher at your head point blank really dumb enough to pull the trigger? Do you really want to find out?"
+ database_id = MEDAL_DISKPLEASE
+
+/datum/award/achievement/misc/gamer
+ name = "My Watchlist Status is Not Important"
+ desc = "You may be under the impression that violent video games are a harmless pastime, but the security and medical personnel swarming your location with batons and knockout gas look like they disagree."
+ database_id = MEDAL_GAMER
+
+/datum/award/achievement/misc/vendor_squish
+ name = "I Was a Teenage Anarchist"
+ desc = "You were doing a great job sticking it to the system until that vending machine decided to fight back."
+ database_id = MEDAL_VENDORSQUISH
+
+/datum/award/achievement/misc/swirlie
+ name = "A Bowl-d New World"
+ desc = "There's a lot of grisly ways to kick it on the Spinward Periphery, but drowning to death in a toilet probably wasn't what you had in mind. Probably."
+ database_id = MEDAL_SWIRLIE
+
+/datum/award/achievement/misc/selfouch
+ name = "How Do I Switch Hands???"
+ desc = "If you saw someone casually club themselves upside the head with a toolbox anywhere in the galaxy but here, you'd probably be pretty concerned for them."
+ database_id = MEDAL_SELFOUCH
+
+/datum/award/achievement/misc/sandman
+ name = "Mister Sandman"
+ desc = "Mechanically speaking, there's no real benefit to being unconscious during surgery. Weird how insistent this doctor is about using the N2O anyway though, huh?"
+ database_id = MEDAL_SANDMAN
+
+/datum/award/achievement/misc/cleanboss
+ name = "One Lean, Mean, Cleaning Machine"
+ desc = "How does it feel to know that your workplace values a mop bucket on wheels more than you?" // i can do better than this give me time
+ database_id = MEDAL_CLEANBOSS
diff --git a/code/datums/components/gunpoint.dm b/code/datums/components/gunpoint.dm
index 165df2ef9ae..31a01809204 100644
--- a/code/datums/components/gunpoint.dm
+++ b/code/datums/components/gunpoint.dm
@@ -26,7 +26,7 @@
target = targ
weapon = wep
RegisterSignal(targ, list(COMSIG_MOB_ATTACK_HAND, COMSIG_MOB_ITEM_ATTACK, COMSIG_MOVABLE_MOVED, COMSIG_MOB_FIRED_GUN), .proc/trigger_reaction)
-
+
RegisterSignal(weapon, list(COMSIG_ITEM_DROPPED, COMSIG_ITEM_EQUIPPED), .proc/cancel)
shooter.visible_message("[shooter] aims [weapon] point blank at [target]!", \
@@ -36,11 +36,9 @@
shooter.apply_status_effect(STATUS_EFFECT_HOLDUP)
target.apply_status_effect(STATUS_EFFECT_HELDUP)
- /*
if(target.job == "Captain" && target.stat == CONSCIOUS && is_nuclear_operative(shooter))
if(istype(weapon, /obj/item/gun/ballistic/rocketlauncher) && weapon.chambered)
shooter.client.give_award(/datum/award/achievement/misc/rocket_holdup, shooter)
- */
target.do_alert_animation(target)
target.playsound_local(target.loc, 'sound/machines/chime.ogg', 50, TRUE)
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index e8bd40f8960..3268f5d9763 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -506,6 +506,8 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list(
gamers[gamer] = -1
+ gamer.client.give_award(/datum/award/achievement/misc/gamer, gamer) // PSYCH REPORT NOTE: patient kept rambling about how they did it for an "achievement", recommend continued holding for observation
+
if(!isnull(GLOB.data_core.general))
for(var/datum/data/record/R in GLOB.data_core.general)
if(R.fields["name"] == gamer.name)
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index 9db8b147083..9ca3810c6c1 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -39,6 +39,7 @@
if(open)
GM.visible_message("[user] starts to give [GM] a swirlie!", "[user] starts to give you a swirlie...")
swirlie = GM
+ var/was_alive = (swirlie.stat != DEAD)
if(do_after(user, 30, 0, target = src))
GM.visible_message("[user] gives [GM] a swirlie!", "[user] gives you a swirlie!", "You hear a toilet flushing.")
if(iscarbon(GM))
@@ -47,6 +48,8 @@
C.adjustOxyLoss(5)
else
GM.adjustOxyLoss(5)
+ if(was_alive && swirlie.stat == DEAD && swirlie.client)
+ swirlie.client.give_award(/datum/award/achievement/misc/swirlie, swirlie) // just like space high school all over again!
swirlie = null
else
playsound(src.loc, 'sound/effects/bang.ogg', 25, TRUE)
diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
index a38a6efc903..1ea96fed27f 100644
--- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
@@ -50,6 +50,8 @@
var/list/prefixes
var/list/suffixes
+ var/ascended = FALSE // if we have all the top titles, grant achievements to living mobs that gaze upon our cleanbot god
+
/mob/living/simple_animal/bot/cleanbot/proc/deputize(obj/item/W, mob/user)
if(in_range(src, user))
@@ -64,6 +66,8 @@
/mob/living/simple_animal/bot/cleanbot/proc/update_titles()
var/working_title = ""
+ ascended = TRUE
+
for(var/pref in prefixes)
for(var/title in pref)
if(title in stolen_valor)
@@ -71,6 +75,8 @@
if(title in officers)
commissioned = TRUE
break
+ else
+ ascended = FALSE // we didn't have the first entry in the list if we got here, so we're not achievement worthy yet
working_title += chosen_name
@@ -79,6 +85,8 @@
if(title in stolen_valor)
working_title += " " + suf[title]
break
+ else
+ ascended = FALSE
name = working_title
@@ -87,6 +95,9 @@
if(weapon)
. += " Is that \a [weapon] taped to it...?"
+ if(ascended && user.stat == CONSCIOUS && user.client)
+ user.client.give_award(/datum/award/achievement/misc/cleanboss, user)
+
/mob/living/simple_animal/bot/cleanbot/Initialize()
. = ..()
diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm
index ab5b6be6ba6..caeadcf1ebd 100644
--- a/code/modules/surgery/surgery_step.dm
+++ b/code/modules/surgery/surgery_step.dm
@@ -86,6 +86,8 @@
if(iscyborg(user))//any immunities to surgery slowdown should go in this check.
modded_time = time
+ var/was_sleeping = (target.stat != DEAD && target.IsSleeping())
+
if(do_after(user, modded_time, target = target))
var/chem_check_result = chem_check(target)
@@ -104,6 +106,9 @@
if(surgery.status > surgery.steps.len)
surgery.complete()
+ if(target.stat == DEAD && was_sleeping && user.client)
+ user.client.give_award(/datum/award/achievement/misc/sandman, user)
+
surgery.step_in_progress = FALSE
return advance
diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm
index be0e8e98c38..ee176efa608 100644
--- a/code/modules/vending/_vending.dm
+++ b/code/modules/vending/_vending.dm
@@ -474,6 +474,7 @@ GLOBAL_LIST_EMPTY(vending_products)
if(in_range(fatty, src))
for(var/mob/living/L in get_turf(fatty))
+ var/was_alive = (L.stat != DEAD)
var/mob/living/carbon/C = L
if(istype(C))
@@ -531,6 +532,9 @@ GLOBAL_LIST_EMPTY(vending_products)
if(crit_case)
L.apply_damage(squish_damage, forced=TRUE)
+ if(was_alive && L.stat == DEAD && L.client)
+ L.client.give_award(/datum/award/achievement/misc/vendor_squish, L) // good job losing a fight with an inanimate object idiot
+
L.Paralyze(60)
L.emote("scream")
playsound(L, 'sound/effects/blobattack.ogg', 40, TRUE)