diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index ef3da7d5b8d..c822a5c4a94 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -389,6 +389,8 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) explanation_text = "Steal [steal_target]. One was last seen in [get_location()]. " if(length(O.protected_jobs)) explanation_text += "It may also be in the possession of the [english_list(O.protected_jobs, and_text = " or ")]." + if(istype(O, /datum/theft_objective/supermatter_sliver)) + give_supermatter_kit() return explanation_text = "Free Objective." @@ -410,6 +412,8 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) else steal_target = new new_target explanation_text = "Steal [steal_target.name]." + if(istype(steal_target, /datum/theft_objective/supermatter_sliver)) + give_supermatter_kit() return steal_target /datum/objective/steal/check_completion() @@ -427,6 +431,22 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) if(I.type in steal_target.altitems) return steal_target.check_special_completion(I) +/datum/objective/steal/proc/give_supermatter_kit() + var/mob/living/carbon/human/mob = owner.current + var/T = new /obj/item/storage/box/syndie_kit/supermatter + var/list/slots = list ( + "backpack" = slot_in_backpack, + "left pocket" = slot_l_store, + "right pocket" = slot_r_store, + "left hand" = slot_l_hand, + "right hand" = slot_r_hand, + ) + var/where = mob.equip_in_one_of_slots(T, slots) + if(where) + to_chat(mob, "

[where] is a box containing items and instructions to help you obtain a sliver of the supermatter.
") + else + to_chat(mob, "Unfortunately, you weren't able to get a supermatter sliver stealing kit. This is very bad and you should adminhelp immediately (press F1).") + mob.update_icons() /datum/objective/steal/exchange martyr_compatible = 0 diff --git a/code/game/gamemodes/steal_items.dm b/code/game/gamemodes/steal_items.dm index 7e15147e885..3bae32f168a 100644 --- a/code/game/gamemodes/steal_items.dm +++ b/code/game/gamemodes/steal_items.dm @@ -138,6 +138,12 @@ protected_jobs = list("Head Of Security", "Warden") location_override = "the Warden's Office" +/datum/theft_objective/supermatter_sliver + name = "a supermatter shard" + typepath = /obj/item/nuke_core/supermatter_sliver + protected_jobs = list("Chief Engineer", "Engineer", "Atmospheric Technician") //Unlike other steal objectives, all jobs in the department have easy access, and would not be noticed at all stealing this + location_override = "Engineering. You can use the box and instructions provided to harvest the sliver." + /datum/theft_objective/number var/min=0 var/max=0 diff --git a/code/game/objects/items/theft_items.dm b/code/game/objects/items/theft_items.dm new file mode 100644 index 00000000000..ad0106f0840 --- /dev/null +++ b/code/game/objects/items/theft_items.dm @@ -0,0 +1,291 @@ +//Items for nuke theft, supermatter theft traitor objective + + +// STEALING THE NUKE, this is disabled currently, as I don't think we need an objective to steal the nuclear device. The items work fine, just you wont be able to screw the nuke, get the core, nor does it have a core in it + +//the nuke core - objective item +/obj/item/nuke_core + name = "plutonium core" + desc = "Extremely radioactive. Wear goggles." + icon = 'icons/obj/nuke_tools.dmi' + icon_state = "plutonium_core" + item_state = "plutoniumcore" + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF + var/pulse = 0 + var/cooldown = 0 + var/pulseicon = "plutonium_core_pulse" + +/obj/item/nuke_core/Initialize() + . = ..() + START_PROCESSING(SSobj, src) + +/obj/item/nuke_core/Destroy() + STOP_PROCESSING(SSobj, src) + return ..() + +/obj/item/nuke_core/attackby(obj/item/nuke_core_container/container, mob/user) + if(istype(container)) + container.load(src, user) + else + return ..() + +/obj/item/nuke_core/process() + if(cooldown < world.time - 60) + cooldown = world.time + flick(pulseicon, src) + radiation_pulse(src, 400, 2) + +/obj/item/nuke_core/suicide_act(mob/user) + user.visible_message("[user] is rubbing [src] against [user.p_them()]self! It looks like [user.p_theyre()] trying to commit suicide!") + return TOXLOSS + +//nuke core box, for carrying the core +/obj/item/nuke_core_container + name = "nuke core container" + desc = "Solid container for radioactive objects." + icon = 'icons/obj/nuke_tools.dmi' + icon_state = "core_container_empty" + item_state = "metal" + var/obj/item/nuke_core/core + +/obj/item/nuke_core_container/Destroy() + QDEL_NULL(core) + return ..() + +/obj/item/nuke_core_container/proc/load(obj/item/nuke_core/ncore, mob/user) + if(core || !istype(ncore)) + return FALSE + ncore.forceMove(src) + core = ncore + icon_state = "core_container_loaded" + to_chat(user, "Container is sealing...") + addtimer(CALLBACK(src, .proc/seal), 50) + return TRUE + +/obj/item/nuke_core_container/proc/seal() + if(istype(core)) + STOP_PROCESSING(SSobj, core) + icon_state = "core_container_sealed" + playsound(src, 'sound/items/deconstruct.ogg', 60, TRUE) + if(ismob(loc)) + to_chat(loc, "[src] is permanently sealed, [core]'s radiation is contained.") + +/obj/item/nuke_core_container/attackby(obj/item/nuke_core/core, mob/user) + if(istype(core)) + if(!user.drop_item()) + to_chat(user, "The [core] is stuck to your hand!") + return + else + load(core, user) + else + return ..() + +//snowflake screwdriver, works as a key to start nuke theft, traitor only +/obj/item/screwdriver/nuke + name = "screwdriver" + desc = "A screwdriver with an ultra thin tip that's carefully designed to boost screwing speed." + icon = 'icons/obj/nuke_tools.dmi' + icon_state = "screwdriver_nuke" + item_state = "screwdriver_nuke" + toolspeed = 0.5 + random_color = FALSE + +/obj/item/paper/guides/antag/nuke_instructions + info = "How to break into a Nanotrasen self-destruct terminal and remove its plutonium core:
\ + " + +// STEALING SUPERMATTER. This works, and is active + +/obj/item/paper/guides/antag/supermatter_sliver + info = "How to safely extract a supermatter sliver:
\ + " + +/obj/item/nuke_core/supermatter_sliver + name = "supermatter sliver" + desc = "A tiny, highly volatile sliver of a supermatter crystal. Do not handle without protection!" + icon_state = "supermatter_sliver" + pulseicon = "supermatter_sliver_pulse" + + +/obj/item/nuke_core/supermatter_sliver/attack_tk(mob/user) // no TK dusting memes + return + + +/obj/item/nuke_core/supermatter_sliver/can_be_pulled(user) // no drag memes + return FALSE + +/obj/item/nuke_core/supermatter_sliver/attackby(obj/item/W, mob/living/user, params) + if(istype(W, /obj/item/hemostat/supermatter)) + var/obj/item/hemostat/supermatter/tongs = W + if (tongs.sliver) + to_chat(user, "\The [tongs] is already holding a supermatter sliver!") + return FALSE + forceMove(tongs) + tongs.sliver = src + tongs.icon_state = "supermatter_tongs_loaded" + tongs.item_state = "supermatter_tongs_loaded" + to_chat(user, "You carefully pick up [src] with [tongs].") + else if(istype(W, /obj/item/scalpel/supermatter) || istype(W, /obj/item/nuke_core_container/supermatter/)) // we don't want it to dust + return + else + to_chat(user, "As it touches \the [src], both \the [src] and \the [W] burst into dust!") + radiation_pulse(user, 100) + playsound(src, 'sound/effects/supermatter.ogg', 50, TRUE) + qdel(W) + qdel(src) + +/obj/item/nuke_core/supermatter_sliver/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) + if(!isliving(hit_atom)) + return ..() + var/mob/living/victim = hit_atom + if(victim.incorporeal_move || victim.status_flags & GODMODE) //try to keep this in sync with supermatter's consume fail conditions + return ..() + if(throwingdatum?.thrower) + var/mob/user = throwingdatum.thrower + add_attack_logs(user, victim, "[victim] consumed by [src] thrown by [user] ") + message_admins("[src] has consumed [key_name_admin(victim)] [ADMIN_JMP(src)], thrown by [key_name_admin(user)].") + investigate_log("has consumed [key_name(victim)], thrown by [key_name(user)]", "supermatter") + else + message_admins("[src] has consumed [key_name_admin(victim)] [ADMIN_JMP(src)] via throw impact.") + investigate_log("has consumed [key_name(victim)] via throw impact.", "supermatter") + victim.visible_message("As [victim] is hit by [src], both flash into dust and silence fills the room...",\ + "You're hit by [src] and everything suddenly goes silent.\n[src] flashes into dust, and soon as you can register this, you do as well.",\ + "Everything suddenly goes silent.") + victim.dust() + radiation_pulse(src, 500, 2) + playsound(src, 'sound/effects/supermatter.ogg', 50, TRUE) + qdel(src) + +/obj/item/nuke_core/supermatter_sliver/pickup(mob/living/user) + ..() + if(!isliving(user) || user.status_flags & GODMODE) //try to keep this in sync with supermatter's consume fail conditions + return FALSE + user.visible_message("[user] reaches out and tries to pick up [src]. [user.p_their()] body starts to glow and bursts into flames before flashing into dust!",\ + "You reach for [src] with your hands. That was dumb.",\ + "Everything suddenly goes silent.") + radiation_pulse(user, 500, 2) + playsound(src, 'sound/effects/supermatter.ogg', 50, TRUE) + user.dust() + +/obj/item/nuke_core_container/supermatter + name = "supermatter bin" + desc = "A tiny receptacle that releases an inert hyper-noblium mix upon sealing, allowing a sliver of a supermatter crystal to be safely stored." + var/obj/item/nuke_core/supermatter_sliver/sliver + +/obj/item/nuke_core_container/supermatter/Destroy() + QDEL_NULL(sliver) + return ..() + +/obj/item/nuke_core_container/supermatter/load(obj/item/hemostat/supermatter/T, mob/user) + if(!istype(T) || !T.sliver) + return FALSE + T.sliver.forceMove(src) + sliver = T.sliver + T.sliver = null + T.icon_state = "supermatter_tongs" + T.item_state = "supermatter_tongs" + icon_state = "supermatter_container_loaded" + to_chat(user, "Container is sealing...") + addtimer(CALLBACK(src, .proc/seal), 50) + return TRUE + +/obj/item/nuke_core_container/supermatter/seal() + if(istype(sliver)) + STOP_PROCESSING(SSobj, sliver) + icon_state = "supermatter_container_sealed" + playsound(src, 'sound/items/Deconstruct.ogg', 60, TRUE) + if(ismob(loc)) + to_chat(loc, "[src] is permanently sealed, [sliver] is safely contained.") + +/obj/item/nuke_core_container/supermatter/attackby(obj/item/hemostat/supermatter/tongs, mob/user) + if(istype(tongs)) + //try to load shard into core + load(tongs, user) + else + return ..() + +/obj/item/scalpel/supermatter + name = "supermatter scalpel" + desc = "A scalpel with a fragile tip of condensed hyper-noblium gas, searingly cold to the touch, that can safely shave a sliver off a supermatter crystal." + icon = 'icons/obj/nuke_tools.dmi' + icon_state = "supermatter_scalpel" + toolspeed = 0.5 + damtype = BURN + usesound = 'sound/weapons/bladeslice.ogg' + var/usesLeft + +/obj/item/scalpel/supermatter/Initialize() + . = ..() + usesLeft = rand(2, 4) + +/obj/item/hemostat/supermatter + name = "supermatter extraction tongs" + desc = "A pair of tongs made from condensed hyper-noblium gas, searingly cold to the touch, that can safely grip a supermatter sliver." + icon = 'icons/obj/nuke_tools.dmi' + icon_state = "supermatter_tongs" + lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' + righthand_file = 'icons/mob/inhands/items_righthand.dmi' + item_state = "supermatter_tongs" + toolspeed = 0.75 + damtype = BURN + var/obj/item/nuke_core/supermatter_sliver/sliver + +/obj/item/hemostat/supermatter/Destroy() + QDEL_NULL(sliver) + return ..() + +/obj/item/hemostat/supermatter/afterattack(atom/O, mob/user, proximity) + . = ..() + if(!sliver) + return + if(proximity && ismovable(O) && O != sliver) + Consume(O, user) + +/obj/item/hemostat/supermatter/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) // no instakill supermatter javelins + if(sliver) + sliver.forceMove(loc) + visible_message("\The [sliver] falls out of \the [src] as it hits the ground.") + sliver = null + icon_state = "supermatter_tongs" + item_state = "supermatter_tongs" + return ..() + +/obj/item/hemostat/supermatter/proc/Consume(atom/movable/AM, mob/living/user) + if(ismob(AM)) + if(!isliving(AM)) + return + var/mob/living/victim = AM + if(victim.incorporeal_move || victim.status_flags & GODMODE) //try to keep this in sync with supermatter's consume fail conditions + return + victim.dust() + message_admins("[src] has consumed [key_name_admin(victim)] [ADMIN_JMP(src)].") + investigate_log("has irradiated [key_name(victim)].", "supermatter") + else if(istype(AM, /obj/singularity)) + return + else + investigate_log("has consumed [AM].", "supermatter") + qdel(AM) + if (user) + add_attack_logs(user, AM, "[AM] and [user] consumed by melee attack with [src] by [user]") + user.visible_message("As [user] touches [AM] with \the [src], both flash into dust and silence fills the room...",\ + "You touch [AM] with [src], and everything suddenly goes silent.\n[AM] and [sliver] flash into dust, and soon as you can register this, you do as well.",\ + "Everything suddenly goes silent.") + user.dust() + radiation_pulse(src, 500, 2) + playsound(src, 'sound/effects/supermatter.ogg', 50, TRUE) + QDEL_NULL(sliver) diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index 2747be43612..0acf6713001 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -309,3 +309,24 @@ To apply, hold the injector a short distance away from the outer thigh before ap new /obj/item/reagent_containers/syringe/capulettium_plus(src) new /obj/item/reagent_containers/syringe/sarin(src) new /obj/item/reagent_containers/syringe/pancuronium(src) + +/obj/item/storage/box/syndie_kit/nuke + name = "box" //Bit of stealth, since you spawn with it + desc = "It's just an ordinary box." + icon_state = "box" + +/obj/item/storage/box/syndie_kit/nuke/populate_contents() + new /obj/item/screwdriver/nuke(src) + new /obj/item/nuke_core_container(src) + new /obj/item/paper/guides/antag/nuke_instructions(src) + +/obj/item/storage/box/syndie_kit/supermatter + name = "box" + desc = "It's just an ordinary box." + icon_state = "box" + +/obj/item/storage/box/syndie_kit/supermatter/populate_contents() + new /obj/item/scalpel/supermatter(src) + new /obj/item/hemostat/supermatter(src) + new /obj/item/nuke_core_container/supermatter(src) + new /obj/item/paper/guides/antag/supermatter_sliver(src) diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index aa4ae90d380..60117f93806 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -709,7 +709,20 @@ return if(moveable && default_unfasten_wrench(user, I, time = 20)) return - if(user.drop_item()) + if(istype(I, /obj/item/scalpel/supermatter)) + var/obj/item/scalpel/supermatter/scalpel = I + to_chat(user, "You carefully begin to scrape \the [src] with \the [I]...") + if(I.use_tool(src, user, 100, volume=100)) + if (scalpel.usesLeft) + to_chat(user, "You extract a sliver from \the [src]. \The [src] begins to react violently!") + new /obj/item/nuke_core/supermatter_sliver(drop_location()) + matter_power += 800 + scalpel.usesLeft-- + if (!scalpel.usesLeft) + to_chat(user, "A tiny piece of \the [I] falls off, rendering it useless!") + else + to_chat(user, "You fail to extract a sliver from \The [src]! \the [I] isn't sharp enough anymore.") + else if(user.drop_item()) user.visible_message("As [user] touches [src] with \a [I], silence fills the room...",\ "You touch [src] with [I], and everything suddenly goes silent.\n[I] flashes into dust as you flinch away from [src].",\ "Everything suddenly goes silent.") diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index c3dd016de8c..82868525246 100644 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index 0e85c1c84d1..5130da0766c 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/obj/nuke_tools.dmi b/icons/obj/nuke_tools.dmi new file mode 100644 index 00000000000..06f1bdf225d Binary files /dev/null and b/icons/obj/nuke_tools.dmi differ diff --git a/paradise.dme b/paradise.dme index f787871e9b9..995e72d1b6d 100644 --- a/paradise.dme +++ b/paradise.dme @@ -848,6 +848,7 @@ #include "code\game\objects\items\mixing_bowl.dm" #include "code\game\objects\items\random_items.dm" #include "code\game\objects\items\shooting_range.dm" +#include "code\game\objects\items\theft_items.dm" #include "code\game\objects\items\toys.dm" #include "code\game\objects\items\trash.dm" #include "code\game\objects\items\devices\aicard.dm"