diff --git a/code/datums/wires/collar_bomb.dm b/code/datums/wires/collar_bomb.dm new file mode 100644 index 00000000000..574a3d52dbc --- /dev/null +++ b/code/datums/wires/collar_bomb.dm @@ -0,0 +1,33 @@ +/datum/wires/collar_bomb + proper_name = "Collar Bomb" + randomize = TRUE // Only one wire, no need for blueprints + holder_type = /obj/item/clothing/neck/collar_bomb + wires = list(WIRE_ACTIVATE) + +/datum/wires/collar_bomb/interactable(mob/user) + . = ..() + if(user.get_item_by_slot(ITEM_SLOT_NECK) == holder) + return FALSE + +/datum/wires/collar_bomb/on_pulse(wire, mob/user) + var/obj/item/clothing/neck/collar_bomb/collar = holder + if(collar.active) + return ..() + collar.explosive_countdown(ticks_left = 5) + if(!ishuman(collar.loc)) + return ..() + var/mob/living/carbon/human/brian = collar.loc + if(brian.get_item_by_slot(ITEM_SLOT_NECK) != collar) + return ..() + var/mob/living/triggerer = user + var/obj/item/assembly/assembly + if(isnull(triggerer)) + assembly = assemblies[colors[1]] + if(assembly) + triggerer = get_mob_by_key(assembly.fingerprintslast) + brian.investigate_log("has had their [collar] triggered [triggerer ? "by [user || assembly][assembly ? " last touched by triggerer" : ""]" : ""].", INVESTIGATE_DEATHS) + return ..() + +///I'd rather not get people killed by EMP here. +/datum/wires/collar_bomb/emp_pulse() + return diff --git a/code/game/objects/items/storage/boxes/clothes_boxes.dm b/code/game/objects/items/storage/boxes/clothes_boxes.dm index 18a6ec31d87..ce4dfb6c5e5 100644 --- a/code/game/objects/items/storage/boxes/clothes_boxes.dm +++ b/code/game/objects/items/storage/boxes/clothes_boxes.dm @@ -211,3 +211,11 @@ new /obj/item/clothing/gloves/combat/floortile(src) new /obj/item/clothing/shoes/jackboots/floortile(src) new /obj/item/storage/backpack/floortile(src) + +/obj/item/storage/box/collar_bomb + name = "collar bomb box" + desc = "A small print on the back reads 'For research purposes only. Handle with care. In case of emergency, call the following number:'... the rest is scratched out with a marker..." + +/obj/item/storage/box/collar_bomb/PopulateContents() + var/obj/item/collar_bomb_button/button = new(src) + new /obj/item/clothing/neck/collar_bomb(src, button) diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm index f61aaeb7472..aacf45e239d 100644 --- a/code/game/objects/items/storage/uplink_kits.dm +++ b/code/game/objects/items/storage/uplink_kits.dm @@ -20,6 +20,7 @@ #define KIT_BEES "bee" #define KIT_MR_FREEZE "mr_freeze" #define KIT_TRAITOR_2006 "ancient" +#define KIT_DEAD_MONEY "dead_money" #define KIT_SAM_FISHER "sam_fisher" #define KIT_PROP_HUNT "prop_hunt" @@ -190,6 +191,7 @@ KIT_MAD_SCIENTIST = 2, KIT_BEES = 1, KIT_MR_FREEZE = 2, + KIT_DEAD_MONEY = 2, KIT_TRAITOR_2006 = 1, KIT_SAM_FISHER = 1, KIT_PROP_HUNT = 1 @@ -282,6 +284,17 @@ if(KIT_TRAITOR_2006) //A kit so old, it's probably older than you. //This bundle is filled with the entire uplink contents traitors had access to in 2006, from OpenSS13. Notably the esword was not a choice but existed in code. new /obj/item/storage/toolbox/emergency/old/ancientbundle(src) //Items fit neatly into a classic toolbox just to remind you what the theme is. + if(KIT_DEAD_MONEY) + for(var/i in 1 to 4) + new /obj/item/clothing/neck/collar_bomb(src) // These let you remotely kill people with a signaler, though you have to get them first. + new /obj/item/storage/box/syndie_kit/signaler(src) + new /obj/item/mod/control/pre_equipped/responsory/inquisitory/syndie(src) // basically a snowflake yet better elite modsuit, so like, 8 + 5 tc. + new /obj/item/card/id/advanced/chameleon(src) // 2 tc + new /obj/item/clothing/mask/chameleon(src) + new /obj/item/melee/baton/telescopic/contractor_baton(src) // 7 tc + new /obj/item/jammer(src) // 5 tc + new /obj/item/pinpointer/crew(src) //priceless + if(KIT_SAM_FISHER) new /obj/item/clothing/under/syndicate/combat(src) new /obj/item/clothing/suit/armor/vest/marine/pmc(src) //The armor kit is comparable to the infiltrator, 6 TC @@ -864,5 +877,6 @@ #undef KIT_BEES #undef KIT_MR_FREEZE #undef KIT_TRAITOR_2006 +#undef KIT_DEAD_MONEY #undef KIT_SAM_FISHER #undef KIT_PROP_HUNT diff --git a/code/modules/cargo/markets/market_items/clothing.dm b/code/modules/cargo/markets/market_items/clothing.dm index 8af34e22916..bf705e8b572 100644 --- a/code/modules/cargo/markets/market_items/clothing.dm +++ b/code/modules/cargo/markets/market_items/clothing.dm @@ -93,5 +93,11 @@ stock_max = 3 availability_prob = 40 - - +/datum/market_item/clothing/collar_bomb + name = "Collar Bomb Kit" + desc = "An unpatented and questionably ethical kit consisting of a low-yield explosive collar and a remote to trigger it." + item = /obj/item/storage/box/collar_bomb + price_min = CARGO_CRATE_VALUE * 3.5 + price_max = CARGO_CRATE_VALUE * 4.5 + stock_max = 3 + availability_prob = 60 diff --git a/code/modules/clothing/neck/collar_bomb.dm b/code/modules/clothing/neck/collar_bomb.dm new file mode 100644 index 00000000000..72f5b20320d --- /dev/null +++ b/code/modules/clothing/neck/collar_bomb.dm @@ -0,0 +1,118 @@ +///Special neckwear that kills its wearer if triggered, by either its specific remote or assemblies. +/obj/item/clothing/neck/collar_bomb + name = "collar bomb" + desc = "A cumbersome collar of some sort, filled with just enough explosive to rip one's head off... at least that's what it reads on the front tag." + icon_state = "collar_bomb" + icon = 'icons/obj/clothing/neck.dmi' + inhand_icon_state = "reverse_bear_trap" + lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' + righthand_file = 'icons/mob/inhands/items_righthand.dmi' + clothing_flags = INEDIBLE_CLOTHING + armor_type = /datum/armor/collar_bomb + equip_delay_self = 6 SECONDS + equip_delay_other = 8 SECONDS + ///The button it's associated with + var/obj/item/collar_bomb_button/button + ///Whether the collar countdown has been triggered. + var/active = FALSE + +/datum/armor/collar_bomb + fire = 97 + bomb = 97 + acid = 97 + +/obj/item/clothing/neck/collar_bomb/Initialize(mapload, obj/item/collar_bomb_button/button) + . = ..() + src.button = button + button?.collar = src + set_wires(new /datum/wires/collar_bomb(src)) + +/obj/item/clothing/neck/collar_bomb/Destroy() + button?.collar = null + button = null + return ..() + +/obj/item/clothing/neck/collar_bomb/examine(mob/user) + . = ..() + if(user.get_item_by_slot(ITEM_SLOT_NECK) == src) + return + . += span_tinynotice("It has a [EXAMINE_HINT("wire")] panel that could be interacted with...") + +/obj/item/clothing/neck/collar_bomb/attackby(obj/item/item, mob/user, params) + if(is_wire_tool(item)) + wires.interact(user) + else + return ..() + +/obj/item/clothing/neck/collar_bomb/equipped(mob/user, slot, initial = FALSE) + . = ..() + if(slot == ITEM_SLOT_NECK) + ADD_TRAIT(src, TRAIT_NODROP, INNATE_TRAIT) + +/obj/item/clothing/neck/collar_bomb/dropped(mob/user, silent = FALSE) + . = ..() + REMOVE_TRAIT(src, TRAIT_NODROP, INNATE_TRAIT) + +/obj/item/clothing/neck/collar_bomb/proc/explosive_countdown(ticks_left) + active = TRUE + if(ticks_left > 0) + playsound(src, 'sound/items/timer.ogg', 30, FALSE) + balloon_alert_to_viewers("[ticks_left]") + ticks_left-- + addtimer(CALLBACK(src, PROC_REF(explosive_countdown), ticks_left), 1 SECONDS) + return + + playsound(src, 'sound/effects/snap.ogg', 75, TRUE) + if(!ishuman(loc)) + balloon_alert_to_viewers("dud...") + active = FALSE + return + var/mob/living/carbon/human/brian = loc + if(brian.get_item_by_slot(ITEM_SLOT_NECK) != src) + balloon_alert_to_viewers("dud...") + active = FALSE + return + visible_message(span_warning("[src] goes off, outright decapitating [brian]!"), span_hear("You hear a fleshy boom!")) + playsound(src, SFX_EXPLOSION, 30, TRUE) + brian.apply_damage(200, BRUTE, BODY_ZONE_HEAD) + var/obj/item/bodypart/head/myhead = brian.get_bodypart(BODY_ZONE_HEAD) + myhead?.dismember() + brian.investigate_log("has been decapitated by [src].", INVESTIGATE_DEATHS) + flash_color(brian, flash_color = "#FF0000", flash_time = 1 SECONDS) + qdel(src) + +///The button that detonates the collar. +/obj/item/collar_bomb_button + name = "big yellow button" + desc = "It looks like a big red button, except it's yellow. It comes with a heavy trigger, to avoid accidents." + icon = 'icons/obj/devices/assemblies.dmi' + icon_state = "bigyellow" + inhand_icon_state = "electronic" + lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi' + righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi' + w_class = WEIGHT_CLASS_TINY + ///The collar bomb it's associated with. + var/obj/item/clothing/neck/collar_bomb/collar + +/obj/item/collar_bomb_button/attack_self(mob/user) + . = ..() + if(DOING_INTERACTION_WITH_TARGET(user, src)) + return + balloon_alert_to_viewers("pushing the button...") + if(!do_after(user, 1.2 SECONDS, target = src)) + return + playsound(user, 'sound/machines/click.ogg', 25, TRUE) + if(!collar|| collar.active) + return + collar.explosive_countdown(ticks_left = 5) + if(!ishuman(collar.loc)) + return + var/mob/living/carbon/human/brian = collar.loc + if(brian.get_item_by_slot(ITEM_SLOT_NECK) == collar) + brian.investigate_log("has has their [collar] triggered by [user] via yellow button.", INVESTIGATE_DEATHS) + + +/obj/item/collar_bomb_button/Destroy() + collar?.button = null + collar = null + return ..() diff --git a/code/modules/mod/mod_theme.dm b/code/modules/mod/mod_theme.dm index 509cdfc1ed7..88f697ccd48 100644 --- a/code/modules/mod/mod_theme.dm +++ b/code/modules/mod/mod_theme.dm @@ -1506,6 +1506,19 @@ acid = 90 wound = 10 +/datum/mod_theme/responsory/traitor + name = "dark paladin" + desc = "A high-speed suit stolen by the Gorlex Maradeurs, purposed for less than honest intents." + extended_desc = "A streamlined suit of Nanotrasen Syndicate design, these sleek black suits are only worn by \ + elite emergency response personnel traitors to help save ruin the day. While the slim and nimble design of the suit \ + cuts the ceramics and ablatives in it down, dropping the protection, \ + it keeps the wearer safe from the harsh void of space while sacrificing no speed whatsoever. \ + While wearing it you feel an extreme deference to darkness light." + armor_type = /datum/armor/mod_theme_elite + resistance_flags = FIRE_PROOF|ACID_PROOF + complexity_max = DEFAULT_MAX_COMPLEXITY + 5 + inbuilt_modules = list(/obj/item/mod/module/armor_booster/no_speedbost) + /datum/mod_theme/apocryphal name = "apocryphal" desc = "A high-tech, only technically legal, armored suit created by a collaboration effort between Nanotrasen and Apadyne Technologies." diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm index 0659dd6208b..47f588eb80b 100644 --- a/code/modules/mod/mod_types.dm +++ b/code/modules/mod/mod_types.dm @@ -477,6 +477,25 @@ /obj/item/mod/module/quick_cuff, ) +/obj/item/mod/control/pre_equipped/responsory/inquisitory/syndie + starting_frequency = MODLINK_FREQ_SYNDICATE + req_access = null + applied_cell = /obj/item/stock_parts/cell/super + theme = /datum/mod_theme/responsory/traitor + applied_modules = list( + /obj/item/mod/module/storage/syndicate, + /obj/item/mod/module/emp_shield, + /obj/item/mod/module/magnetic_harness, + /obj/item/mod/module/jetpack, + /obj/item/mod/module/pathfinder, + /obj/item/mod/module/flashlight/darkness, + /obj/item/mod/module/dna_lock, + /obj/item/mod/module/quick_cuff, + /obj/item/mod/module/visor/night, + /obj/item/mod/module/shove_blocker, + /obj/item/mod/module/noslip, + ) + /obj/item/mod/control/pre_equipped/responsory/inquisitory/commander insignia_type = /obj/item/mod/module/insignia/commander additional_module = /obj/item/mod/module/power_kick diff --git a/code/modules/mod/modules/modules_antag.dm b/code/modules/mod/modules/modules_antag.dm index a35e39365b9..2e53e380fd0 100644 --- a/code/modules/mod/modules/modules_antag.dm +++ b/code/modules/mod/modules/modules_antag.dm @@ -29,6 +29,9 @@ /// List of traits added when the mod is activated var/list/traits_to_add = list(TRAIT_HEAD_INJURY_BLOCKED) +/obj/item/mod/module/armor_booster/no_speedbost + speed_added = 0 + /datum/armor/mod_module_armor_boost melee = 25 bullet = 30 @@ -236,6 +239,9 @@ /obj/item/mod/module/insignia/chaplain color = "#f0a00c" +/obj/item/mod/module/insignia/syndie + color = COLOR_SYNDIE_RED + ///Anti Slip - Prevents you from slipping on water. /obj/item/mod/module/noslip name = "MOD anti slip module" diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index 4277734d9e7..59f0055dd87 100644 --- a/code/modules/mod/modules/modules_general.dm +++ b/code/modules/mod/modules/modules_general.dm @@ -436,6 +436,21 @@ if("light_range") set_light_range(clamp(value, min_range, max_range)) +///Like the flashlight module, except the light color is stuck to black and cannot be changed. +/obj/item/mod/module/flashlight/darkness + name = "MOD flashdark module" + desc = "A quirky pair of configurable flashdarks installed on the sides of the helmet, \ + useful for providing darkness at a configurable range." + light_color = COLOR_BLACK + light_system = OVERLAY_LIGHT + light_range = 2 + min_range = 1 + max_range = 3 + +/obj/item/mod/module/flashlight/darkness/get_configuration() + . = ..() + . -= "light_color" + ///Dispenser - Dispenses an item after a time passes. /obj/item/mod/module/dispenser name = "MOD burger dispenser module" diff --git a/icons/mob/clothing/neck.dmi b/icons/mob/clothing/neck.dmi index 5440bf9d99d..7895a3ac7fa 100644 Binary files a/icons/mob/clothing/neck.dmi and b/icons/mob/clothing/neck.dmi differ diff --git a/icons/obj/clothing/neck.dmi b/icons/obj/clothing/neck.dmi index 6027b0022c4..986d9bd9158 100644 Binary files a/icons/obj/clothing/neck.dmi and b/icons/obj/clothing/neck.dmi differ diff --git a/icons/obj/devices/assemblies.dmi b/icons/obj/devices/assemblies.dmi index aa3476eea72..c1b0fd05f13 100644 Binary files a/icons/obj/devices/assemblies.dmi and b/icons/obj/devices/assemblies.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 5a822d8ea49..bfc60442117 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1927,6 +1927,7 @@ #include "code\datums\wires\airlock.dm" #include "code\datums\wires\apc.dm" #include "code\datums\wires\autolathe.dm" +#include "code\datums\wires\collar_bomb.dm" #include "code\datums\wires\conveyor.dm" #include "code\datums\wires\ecto_sniffer.dm" #include "code\datums\wires\emitter.dm" @@ -3819,6 +3820,7 @@ #include "code\modules\clothing\masks\muzzle.dm" #include "code\modules\clothing\masks\surgical.dm" #include "code\modules\clothing\neck\_neck.dm" +#include "code\modules\clothing\neck\collar_bomb.dm" #include "code\modules\clothing\outfits\ert.dm" #include "code\modules\clothing\outfits\event.dm" #include "code\modules\clothing\outfits\plasmaman.dm"