diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm
index 271f448d95a..c8c69880bef 100644
--- a/code/_globalvars/lists/objects.dm
+++ b/code/_globalvars/lists/objects.dm
@@ -39,7 +39,7 @@ GLOBAL_LIST_EMPTY(ladders)
GLOBAL_LIST_EMPTY(trophy_cases)
GLOBAL_LIST_EMPTY(experiment_handlers)
///This is a global list of all signs you can change an existing sign or new sign backing to, when using a pen on them.
-GLOBAL_LIST_EMPTY(editable_sign_types)
+GLOBAL_LIST_INIT(editable_sign_types, populate_editable_sign_types())
GLOBAL_LIST_EMPTY(wire_color_directory)
GLOBAL_LIST_EMPTY(wire_name_directory)
diff --git a/code/datums/station_traits/negative_traits.dm b/code/datums/station_traits/negative_traits.dm
index cda36ef5970..614d203507c 100644
--- a/code/datums/station_traits/negative_traits.dm
+++ b/code/datums/station_traits/negative_traits.dm
@@ -134,3 +134,87 @@
/// The bot's language holder - so we can randomize and change their language
var/datum/language_holder/bot_languages = found_bot.get_language_holder()
bot_languages.selected_language = bot_languages.get_random_spoken_language()
+
+/datum/station_trait/revenge_of_pun_pun
+ name = "Revenge of Pun Pun"
+ trait_type = STATION_TRAIT_NEGATIVE
+ weight = 2
+ var/static/list/weapon_types
+
+/datum/station_trait/revenge_of_pun_pun/New()
+ if(!weapon_types)
+ weapon_types = list(
+ /obj/item/chair = 20,
+ /obj/item/tailclub = 10,
+ /obj/item/melee/baseball_bat = 10,
+ /obj/item/melee/chainofcommand/tailwhip = 10,
+ /obj/item/melee/chainofcommand/tailwhip/kitty = 10,
+ /obj/item/reagent_containers/food/drinks/bottle = 20,
+ /obj/item/reagent_containers/food/drinks/bottle/kong = 5,
+ /obj/item/switchblade/extended = 10,
+ /obj/item/sign/random = 10,
+ /obj/item/gun/ballistic/automatic/pistol = 1,
+ )
+
+ RegisterSignal(SSatoms, COMSIG_SUBSYSTEM_POST_INITIALIZE, .proc/arm_monke)
+
+/datum/station_trait/revenge_of_pun_pun/proc/arm_monke()
+ SIGNAL_HANDLER
+ var/mob/living/carbon/human/species/monkey/punpun/punpun = locate()
+ if(!punpun)
+ return
+ var/weapon_type = pickweight(weapon_types)
+ var/obj/item/weapon = new weapon_type
+ if(!punpun.put_in_l_hand(weapon) && !punpun.put_in_r_hand(weapon))
+ // Guess they did all this with whatever they have in their hands already
+ qdel(weapon)
+ weapon = punpun.get_active_held_item() || punpun.get_inactive_held_item()
+
+ weapon?.add_mob_blood(punpun)
+ punpun.add_mob_blood(punpun)
+
+ new /datum/ai_controller/monkey/angry(punpun)
+
+ var/area/place = get_area(punpun)
+
+ var/list/area_open_turfs = list()
+ for(var/turf/location in place)
+ if(location.density)
+ continue
+ area_open_turfs += location
+
+ punpun.forceMove(pick(area_open_turfs))
+
+ for(var/i in 1 to rand(10, 40))
+ new /obj/effect/decal/cleanable/blood(pick(area_open_turfs))
+
+ var/list/blood_path = list()
+ for(var/i in 1 to 10) // Only 10 attempts
+ var/turf/destination = pick(area_open_turfs)
+ var/turf/next_step = get_step_to(punpun, destination)
+ for(var/k in 1 to 30) // Max 30 steps
+ if(!next_step)
+ break
+ blood_path += next_step
+ next_step = get_step_to(next_step, destination)
+ if(length(blood_path))
+ break
+ if(!length(blood_path))
+ CRASH("Unable to make a path from punpun")
+
+ var/turf/last_location
+ for(var/turf/location as anything in blood_path)
+ last_location = location
+
+ if(prob(80))
+ new /obj/effect/decal/cleanable/blood(location)
+
+ if(prob(50))
+ var/static/blood_types = list(
+ /obj/effect/decal/cleanable/blood/splatter,
+ /obj/effect/decal/cleanable/blood/gibs,
+ )
+ var/blood_type = pick(blood_types)
+ new blood_type(get_turf(pick(orange(location, 2))))
+
+ new /obj/effect/decal/cleanable/blood/gibs/torso(last_location)
diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm
index f3d032c8b16..33827bfd5ff 100644
--- a/code/game/objects/items/weaponry.dm
+++ b/code/game/objects/items/weaponry.dm
@@ -370,11 +370,19 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
attack_verb_continuous = list("stubs", "pokes")
attack_verb_simple = list("stub", "poke")
resistance_flags = FIRE_PROOF
- var/extended = 0
+ var/extended = FALSE
+
+/obj/item/switchblade/Initialize()
+ . = ..()
+ set_extended(extended)
/obj/item/switchblade/attack_self(mob/user)
extended = !extended
playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, TRUE)
+ set_extended(!extended)
+
+/obj/item/switchblade/proc/set_extended(new_extended)
+ extended = new_extended
if(extended)
force = 20
w_class = WEIGHT_CLASS_NORMAL
@@ -398,6 +406,9 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
user.visible_message("[user] is slitting [user.p_their()] own throat with [src]! It looks like [user.p_theyre()] trying to commit suicide!")
return (BRUTELOSS)
+/obj/item/switchblade/extended
+ extended = TRUE
+
/obj/item/phone
name = "red phone"
desc = "Should anything ever go wrong..."
diff --git a/code/game/objects/structures/signs/_signs.dm b/code/game/objects/structures/signs/_signs.dm
index e3e39ed2904..dacc3b1b53f 100644
--- a/code/game/objects/structures/signs/_signs.dm
+++ b/code/game/objects/structures/signs/_signs.dm
@@ -59,12 +59,14 @@
* The first time a pen is used on any sign, this populates GLOBAL_LIST_EMPTY(editable_sign_types), creating a global list of all the signs that you can set a sign backing to with a pen.
*/
/proc/populate_editable_sign_types()
+ var/list/output = list()
for(var/s in subtypesof(/obj/structure/sign))
var/obj/structure/sign/potential_sign = s
if(!initial(potential_sign.is_editable))
continue
- GLOB.editable_sign_types[initial(potential_sign.sign_change_name)] = potential_sign
- GLOB.editable_sign_types = sortList(GLOB.editable_sign_types) //Alphabetizes the results.
+ output[initial(potential_sign.sign_change_name)] = potential_sign
+ output = sortList(output) //Alphabetizes the results.
+ return output
/obj/structure/sign/wrench_act(mob/living/user, obj/item/wrench/I)
. = ..()
@@ -130,9 +132,7 @@
/obj/structure/sign/attackby(obj/item/I, mob/user, params)
if(is_editable && istype(I, /obj/item/pen))
if(!length(GLOB.editable_sign_types))
- populate_editable_sign_types()
- if(!length(GLOB.editable_sign_types))
- CRASH("GLOB.editable_sign_types failed to populate")
+ CRASH("GLOB.editable_sign_types failed to populate")
var/choice = input(user, "Select a sign type.", "Sign Customization") as null|anything in GLOB.editable_sign_types
if(!choice)
return
@@ -160,9 +160,7 @@
/obj/item/sign/attackby(obj/item/I, mob/user, params)
if(is_editable && istype(I, /obj/item/pen))
if(!length(GLOB.editable_sign_types))
- populate_editable_sign_types()
- if(!length(GLOB.editable_sign_types))
- CRASH("GLOB.editable_sign_types failed to populate")
+ CRASH("GLOB.editable_sign_types failed to populate")
var/choice = input(user, "Select a sign type.", "Sign Customization") as null|anything in GLOB.editable_sign_types
if(!choice)
return
@@ -174,18 +172,20 @@
user.visible_message("You begin changing [src].")
if(!do_after(user, 4 SECONDS, target = src))
return
- var/obj/structure/sign/sign_type = GLOB.editable_sign_types[choice]
- name = initial(sign_type.name)
- if(sign_type != /obj/structure/sign/blank)
- desc = "[initial(sign_type.desc)] It can be placed on a wall."
- else
- desc = initial(desc) //If you're changing it to a blank sign, just use obj/item/sign's description.
- icon_state = initial(sign_type.icon_state)
- sign_path = sign_type
+ set_sign_type(GLOB.editable_sign_types[choice])
user.visible_message("You finish changing the sign.")
return
return ..()
+/obj/item/sign/proc/set_sign_type(obj/structure/sign/fake_type)
+ name = initial(fake_type.name)
+ if(fake_type != /obj/structure/sign/blank)
+ desc = "[initial(fake_type.desc)] It can be placed on a wall."
+ else
+ desc = initial(desc)
+ icon_state = initial(fake_type.icon_state)
+ sign_path = fake_type
+
/obj/item/sign/afterattack(atom/target, mob/user, proximity)
. = ..()
if(!iswallturf(target) || !proximity)
@@ -210,6 +210,10 @@
placed_sign.setDir(dir)
qdel(src)
+/obj/item/sign/random/Initialize()
+ . = ..()
+ set_sign_type(GLOB.editable_sign_types[pick(GLOB.editable_sign_types)])
+
/obj/structure/sign/nanotrasen
name = "\improper Nanotrasen logo sign"
sign_change_name = "Corporate Logo - Nanotrasen"