diff --git a/modular_zubbers/code/modules/cargo/packs/goodies.dm b/modular_zubbers/code/modules/cargo/packs/goodies.dm index 0167f0ea206..d39e9326378 100644 --- a/modular_zubbers/code/modules/cargo/packs/goodies.dm +++ b/modular_zubbers/code/modules/cargo/packs/goodies.dm @@ -95,6 +95,12 @@ cost = PAYCHECK_CREW * 12 contains = list(/obj/item/organ/cyberimp/arm/toolkit/rope) +/datum/supply_pack/goody/offstation_deathrattle + name = "Off-Station Deathrattle Kit" + desc = "Going on an adventure far from the comforts of your station? Unsure you'll make it back in one piece? Kahraman Industries and Nanotrasen present the Off-Station Deathrattle implant! This little chip connected to your vitals will send an automatic distress signal in case of your early demise. It will only work outside of Station areas. Warranty is void if death results from falling into pits or diving into lava or plasma lakes." + cost = PAYCHECK_COMMAND * 5 + contains = list(/obj/item/storage/box/offstation_deathrattle) + /datum/supply_pack/goody/pepperball_gun name = "Pepperball Gun Single-Pack" desc = "Contains one pepperball gun, a non-lethal weapon that fires pepper-filled projectiles." diff --git a/modular_zubbers/code/modules/implants/code/implant_deathrattle_offstation.dm b/modular_zubbers/code/modules/implants/code/implant_deathrattle_offstation.dm new file mode 100644 index 00000000000..bbd26141e57 --- /dev/null +++ b/modular_zubbers/code/modules/implants/code/implant_deathrattle_offstation.dm @@ -0,0 +1,151 @@ +/// DEATHRATTLE MEANT FOR MINERS AND SPACETIDERS +/// Sends a message to all players that have a headset with cargo OR medical encryptions when the user dies. On lowpop (less than 10 players), everyone gets the message regardless of the channels they have. Silicons also always get the message because why not. + +GLOBAL_VAR_INIT(offstation_deathrattle_group, null) + +/datum/offstation_deathrattle_group + var/name + var/list/implants = list() + var/list/offstation_traits = list( + ZTRAIT_LAVA_RUINS, + ZTRAIT_ICE_RUINS, + ZTRAIT_ICE_RUINS_UNDERGROUND, + ZTRAIT_MOONSTATION_RUINS, + ) + var/list/deathrattle_sounds = list( + 'sound/items/knell/knell1.ogg', + 'sound/items/knell/knell2.ogg', + 'sound/items/knell/knell3.ogg', + 'sound/items/knell/knell4.ogg', + ) + +/datum/offstation_deathrattle_group/New(name) + if(name) + src.name = name + else + src.name = "off-station group" + +/datum/offstation_deathrattle_group/proc/register(obj/item/implant/deathrattle/implant) + if(implant in implants) + return + + RegisterSignal(implant, COMSIG_IMPLANT_IMPLANTED, PROC_REF(on_implant_implantation)) + RegisterSignal(implant, COMSIG_IMPLANT_REMOVED, PROC_REF(on_implant_removal)) + RegisterSignal(implant, COMSIG_QDELETING, PROC_REF(on_implant_destruction)) + implants += implant + if(implant.imp_in) + on_implant_implantation(implant, implant.imp_in) + +/datum/offstation_deathrattle_group/proc/on_implant_removal(obj/item/implant/implant, mob/living/source, silent = FALSE, special = 0) + UnregisterSignal(source, COMSIG_MOB_STATCHANGE) + +/datum/offstation_deathrattle_group/proc/on_implant_destruction(obj/item/implant/implant) + implants -= implant + +/datum/offstation_deathrattle_group/proc/active_player_count() + var/active_players = 0 + for(var/mob/living/player as anything in GLOB.player_list) + if(!player.client) + continue + if(player.stat == DEAD) + continue + active_players++ + return active_players + +/datum/offstation_deathrattle_group/proc/should_bypass_headset_requirement() + return active_player_count() <= 10 + +/datum/offstation_deathrattle_group/proc/headset_recipient(obj/item/radio/headset/headset) + if(!istype(headset)) + return FALSE + if(!length(headset.channels)) + return FALSE + return (RADIO_CHANNEL_SUPPLY in headset.channels) || (RADIO_CHANNEL_MEDICAL in headset.channels) + +/datum/offstation_deathrattle_group/proc/notify_recipient(mob/living/recipient, victim_name, victim_area, sound) + var/radio_prefix = span_radio("Your headset crackles with a strange, robotic voice...") + var/death_notice = span_robot("[victim_name] has died at [victim_area].") + to_chat(recipient, "[radio_prefix] \"[death_notice]\"") + recipient.playsound_local(get_turf(recipient), sound, vol = 75, vary = FALSE, pressure_affected = FALSE, use_reverb = FALSE) + +/datum/offstation_deathrattle_group/proc/area_auth(mob/living/owner) + if(!istype(owner)) + return FALSE + var/turf/owner_turf = get_turf(owner) + if(!owner_turf) + return FALSE + var/owner_z = owner_turf?.z + if(!owner_z || is_station_level(owner_z)) + return FALSE + // Ignores CentCom & Interlink specifically + if(is_centcom_level(owner_z) || is_away_level(owner_z) || istype(get_area(owner_turf), /area/centcom/interlink)) + return FALSE + if(isspaceturf(owner_turf)) + return TRUE + if(is_mining_level(owner_z) || is_spaceruins_level(owner_z)) + return TRUE + for(var/trait in offstation_traits) + if(SSmapping.level_trait(owner_z, trait)) + return TRUE + return FALSE + +/datum/offstation_deathrattle_group/proc/on_implant_implantation(obj/item/implant/implant, mob/living/target, mob/user, silent = FALSE, force = FALSE) + if(!target && istype(implant, /mob/living)) + target = implant + if(!istype(target)) + return + RegisterSignal(target, COMSIG_MOB_STATCHANGE, PROC_REF(on_user_statchange)) + +/datum/offstation_deathrattle_group/proc/on_user_statchange(mob/living/owner, new_stat) + if(new_stat != DEAD) + return + if(!area_auth(owner)) + return + var/victim_name = owner.mind ? owner.mind.name : owner.real_name + var/victim_area = get_area_name(get_turf(owner)) + var/sound = pick(deathrattle_sounds) + var/bypass_headset_requirement = should_bypass_headset_requirement() + for(var/mob/living/recipient as anything in GLOB.player_list) + if(recipient == owner || recipient.stat == DEAD || !recipient.client) + continue + if(istype(recipient, /mob/living/silicon)) + notify_recipient(recipient, victim_name, victim_area, sound) + continue + var/mob/living/carbon/human/human_recipient = recipient + if(!istype(human_recipient)) + continue + var/obj/item/radio/headset/listener_headset = human_recipient.ears + if(!istype(listener_headset)) + continue + if(!bypass_headset_requirement && !headset_recipient(listener_headset)) + continue + notify_recipient(recipient, victim_name, victim_area, sound) + +/obj/item/implant/deathrattle/offstation + name = "off-station deathrattle implant" + +/obj/item/implant/deathrattle/offstation/Initialize(mapload) + . = ..() + if(!GLOB.offstation_deathrattle_group) + GLOB.offstation_deathrattle_group = new /datum/offstation_deathrattle_group("off-station group") + var/datum/offstation_deathrattle_group/group = GLOB.offstation_deathrattle_group + group.register(src) + +/obj/item/implantcase/deathrattle/offstation + name = "implant case - 'Off-Station Deathrattle'" + desc = "A glass case containing an off-station deathrattle implant." + imp_type = /obj/item/implant/deathrattle/offstation + +/obj/item/storage/box/offstation_deathrattle + name = "off-station deathrattle kit" + desc = "A box containing an implanter and an off-station deathrattle implant, which automatically sends a distress call to the cargo and medical departments in case of premature demise. It will only work outside of Station areas." + icon = 'modular_skyrat/modules/aesthetics/storage/storage.dmi' + icon_state = "box" + +/obj/item/storage/box/offstation_deathrattle/PopulateContents() + new /obj/item/implanter(src) + var/obj/item/implantcase/deathrattle/offstation/case = new(src) + if(!GLOB.offstation_deathrattle_group) + GLOB.offstation_deathrattle_group = new /datum/offstation_deathrattle_group("off-station group") + var/datum/offstation_deathrattle_group/group = GLOB.offstation_deathrattle_group + group.register(case.imp) diff --git a/modular_zubbers/code/modules/mining/equipment/order_mining.dm b/modular_zubbers/code/modules/mining/equipment/order_mining.dm index 41e2d4af91c..ae9fece68e1 100644 --- a/modular_zubbers/code/modules/mining/equipment/order_mining.dm +++ b/modular_zubbers/code/modules/mining/equipment/order_mining.dm @@ -39,6 +39,12 @@ desc = "A modsuit module which provides long range suit sensor broadcasting. Useful in a modsuit as it will cover kheiral cuffs!" cost_per_order = 450 +/datum/orderable_item/mining/offstation_deathrattle + purchase_path = /obj/item/storage/box/offstation_deathrattle + name = "Off-Station Deathrattle Kit" + desc = "Going on an adventure far from the comforts of your station? Unsure you'll make it back in one piece? Kahraman Industries and Nanotrasen present the Off-Station Deathrattle implant! This little chip connected to your vitals will send an automatic distress signal in case of your early demise. It will only work outside of Station areas. Warranty is void if death results from falling into pits or diving into lava or plasma lakes." + cost_per_order = 675 + /// PODS /obj/item/survivalcapsule/plap diff --git a/tgstation.dme b/tgstation.dme index b43676b4d79..56c229f46d0 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -9476,6 +9476,7 @@ #include "modular_zubbers\code\modules\hydroponics\plantgenes\hydroponics.dm" #include "modular_zubbers\code\modules\implants\code\augments_arms.dm" #include "modular_zubbers\code\modules\implants\code\augments_eyes.dm" +#include "modular_zubbers\code\modules\implants\code\implant_deathrattle_offstation.dm" #include "modular_zubbers\code\modules\implants\code\game\objects\items\climbingrope.dm" #include "modular_zubbers\code\modules\item_reskins\plastic.dm" #include "modular_zubbers\code\modules\job_estimation\code\dead.dm"