From 14d337787b75592bbebda2d22ee5f48caa2e30ed Mon Sep 17 00:00:00 2001 From: Emmett Gaines Date: Sat, 8 May 2021 01:00:59 -0400 Subject: [PATCH] Gives the monkey a gun (#58565) This adds a rare-ish negative station trait that gives Pun Pun a weapon, fills their heart with anger, and bloodies up the location they spawn in. (Yes the weapon is even more rarely a gun) A request for one of the weapons to be a sign meant that a random sign type was added here as well. --- code/_globalvars/lists/objects.dm | 2 +- code/datums/station_traits/negative_traits.dm | 84 +++++++++++++++++++ code/game/objects/items/weaponry.dm | 13 ++- code/game/objects/structures/signs/_signs.dm | 36 ++++---- 4 files changed, 117 insertions(+), 18 deletions(-) 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"