diff --git a/code/datums/uplink/stealthy_and_inconspicuous_weapons.dm b/code/datums/uplink/stealthy_and_inconspicuous_weapons.dm
index 4a288bb2d4a..f75a8dfe963 100644
--- a/code/datums/uplink/stealthy_and_inconspicuous_weapons.dm
+++ b/code/datums/uplink/stealthy_and_inconspicuous_weapons.dm
@@ -33,6 +33,12 @@
item_cost = 20
path = /obj/item/pen/reagent/sleepy
+/datum/uplink_item/item/stealthy_weapons/fakescalp
+ name = "Injection Scalpel"
+ desc = "This 'scalpel' will inject a chemical of choice into the bloodstream of an unsuspecting patient, either it be a surgery or assault. WARNING: Not for use as a scalpel, chemicals not included."
+ item_cost = 15
+ path = /obj/item/material/knife/reagent/fakescalp
+
/datum/uplink_item/item/stealthy_weapons/syringegun
name = "Disguised Syringe Gun"
desc = "A syringe gun disguised as an electronic cigarette with 4 darts included in the box. Chemicals not included!"
diff --git a/code/game/antagonist/station/traitor.dm b/code/game/antagonist/station/traitor.dm
index a2b275bee43..a4e1dfc50fb 100644
--- a/code/game/antagonist/station/traitor.dm
+++ b/code/game/antagonist/station/traitor.dm
@@ -1,5 +1,12 @@
GLOBAL_DATUM_INIT(traitors, /datum/antagonist/traitor, new)
+/proc/istraitor(mob/player)
+ if(!GLOB.traitors || !player.mind)
+ return FALSE
+ if(player.mind in GLOB.traitors.current_antagonists)
+ return TRUE
+ return FALSE
+
// Inherits most of its vars from the base datum.
/datum/antagonist/traitor
id = MODE_TRAITOR
diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm
index 72c612256e5..bbe89c601b5 100644
--- a/code/game/machinery/alarm.dm
+++ b/code/game/machinery/alarm.dm
@@ -228,7 +228,8 @@
req_access.Cut()
to_chat(user, SPAN_NOTICE("You short out \the [src]'s scanner circuit, removing the access requirements!"))
sparks(2, 1, src)
- return 1
+ emagged = TRUE
+ return TRUE
return
/obj/machinery/alarm/proc/handle_heating_cooling(var/datum/gas_mixture/environment)
diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm
index 8c62130d77c..4233b47e367 100644
--- a/code/game/objects/items/weapons/grenades/grenade.dm
+++ b/code/game/objects/items/weapons/grenades/grenade.dm
@@ -9,11 +9,21 @@
throw_range = 20
obj_flags = OBJ_FLAG_CONDUCTIBLE
slot_flags = SLOT_BELT
+ var/emagged = FALSE
var/active = 0
var/det_time = 50
var/fail_det_time = 5 // If you are clumsy and fail, you get this time.
var/arm_sound = 'sound/weapons/armbomb.ogg'
+/obj/item/grenade/emag_act(remaining_charges, mob/user, emag_source)
+ . = ..()
+ if(!emagged)
+ to_chat(user, SPAN_NOTICE("You short out \the [src]'s timer, it is now permanently set for instant detonation!"))
+ sparks(2, 1, src)
+ det_time = 1
+ emagged = TRUE
+ return TRUE
+
/obj/item/grenade/proc/clown_check(var/mob/living/user)
if((MUTATION_CLUMSY in user.mutations) && prob(50))
to_chat(user, "Huh? How does this thing work?")
@@ -62,22 +72,25 @@
/obj/item/grenade/attackby(obj/item/W as obj, mob/user as mob)
if(isScrewdriver(W))
- switch(det_time)
- if (1)
- det_time = 10
- to_chat(user, "You set the [name] for 1 second detonation time.")
- if (10)
- det_time = 30
- to_chat(user, "You set the [name] for 3 second detonation time.")
- if (30)
- det_time = 50
- to_chat(user, "You set the [name] for 5 second detonation time.")
- if (50)
- det_time = 1
- to_chat(user, "You set the [name] for instant detonation.")
- add_fingerprint(user)
+ if(!emagged)
+ switch(det_time)
+ if (1)
+ det_time = 10
+ to_chat(user, SPAN_NOTICE("You set the [name] for 1 second detonation time."))
+ if (10)
+ det_time = 30
+ to_chat(user, SPAN_NOTICE("You set the [name] for 3 second detonation time."))
+ if (30)
+ det_time = 50
+ to_chat(user, SPAN_NOTICE("You set the [name] for 5 second detonation time."))
+ if (50)
+ det_time = 1
+ to_chat(user, SPAN_NOTICE("You set the [name] for instant detonation."))
+ else
+ to_chat(user, SPAN_WARNING("\The [src] refuses the change!"))
+ add_fingerprint(user)
..()
/obj/item/grenade/attack_hand()
walk(src, null, null)
- ..()
\ No newline at end of file
+ ..()
diff --git a/code/game/objects/items/weapons/material/knives.dm b/code/game/objects/items/weapons/material/knives.dm
index 75d36b03958..3b2726ce800 100644
--- a/code/game/objects/items/weapons/material/knives.dm
+++ b/code/game/objects/items/weapons/material/knives.dm
@@ -110,3 +110,49 @@
name = "lightweight utility knife"
desc = "A lightweight utility knife made out of a steel alloy."
icon_state = "titanium"
+
+//Reagent Knives
+
+/obj/item/material/knife/reagent
+ atom_flags = ATOM_FLAG_OPEN_CONTAINER
+ var/amount_to_transfer = 1 // the amount of chems to transfer between attacks
+ var/volume = 30
+ origin_tech = list(TECH_MATERIAL = 2, TECH_ESOTERIC = 5)
+
+/obj/item/material/knife/reagent/New()
+ ..()
+ create_reagents(volume)
+
+/obj/item/material/knife/reagent/attack(mob/living/M, mob/user, var/target_zone)
+ if(!istype(M))
+ return
+
+ . = ..()
+
+ var/allow = M.can_inject(user, target_zone)
+ if(user.a_intent == I_HURT) //prevents it from injecting reagents WITHOUT attacking (reagents get injected but no harm is done to the target)
+ if(allow == INJECTION_PORT) //this is a knife meant for combat, we are not gonna inject
+ return
+ if(reagents.total_volume)
+ if(M.reagents)
+ var/should_admin_log = reagents.should_admin_log()
+ var/contained_reagents = reagents.get_reagents()
+ var/trans = reagents.trans_to_mob(M, 1, CHEM_BLOOD) //we transfer only 1 unit because slashing doesnt generally make you stay in the wound long
+ if(should_admin_log)
+ admin_inject_log(user, M, src, contained_reagents, trans)
+
+
+/obj/item/material/knife/reagent/fakescalp
+ name = "scalpel"
+ desc = "A tiny and extremely sharp steel cutting tool used for surgery, dissection, autopsy, and very precise cuts. The cornerstone of any surgical procedure."
+ icon = 'icons/obj/surgery.dmi'
+ icon_state = "scalpel"
+ max_force = 7 //already kills people with chems, why make it op?
+ applies_material_colour = 0 //does not rename it to "steel scalpel" so we can hide it :)))))))
+ applies_material_name = 0 //does not recolor it, makes it indistinguishable from a real scalpel.
+ origin_tech = list(TECH_MATERIAL = 2, TECH_ESOTERIC = 5)
+
+/obj/item/material/knife/reagent/fakescalp/examine(mob/user, distance)
+ . = ..()
+ if(istraitor(user) || user.skill_check(SKILL_MEDICAL, SKILL_TRAINED) || user.skill_check(SKILL_DEVICES, SKILL_TRAINED))
+ to_chat(user, "That doesn't look like a normal scalpel.")
diff --git a/code/modules/modular_computers/computers/subtypes/preset_pda.dm b/code/modules/modular_computers/computers/subtypes/preset_pda.dm
index 376540adabd..b5a08268a3c 100644
--- a/code/modules/modular_computers/computers/subtypes/preset_pda.dm
+++ b/code/modules/modular_computers/computers/subtypes/preset_pda.dm
@@ -18,8 +18,7 @@
hard_drive.store_file(new /datum/computer_file/program/wordprocessor())
hard_drive.store_file(new /datum/computer_file/program/records())
hard_drive.store_file(new /datum/computer_file/program/newscast())
- if(prob(50)) //harmless tax software
- hard_drive.store_file(new /datum/computer_file/program/uplink())
+ hard_drive.store_file(new /datum/computer_file/program/uplink()) //this shit was long overdue, its now for everyone, DEATH TO METAGAME
var/datum/extension/interactive/ntos/os = get_extension(src, /datum/extension/interactive/ntos)
if(os)
os.set_autorun("emailc")
@@ -86,4 +85,4 @@
/obj/item/modular_computer/pda/captain/install_default_hardware()
..()
- scanner = new /obj/item/stock_parts/computer/scanner/paper(src)
\ No newline at end of file
+ scanner = new /obj/item/stock_parts/computer/scanner/paper(src)
diff --git a/code/modules/overmap/ships/computers/helm.dm b/code/modules/overmap/ships/computers/helm.dm
index 8a84c785f4f..57077c7e07c 100644
--- a/code/modules/overmap/ships/computers/helm.dm
+++ b/code/modules/overmap/ships/computers/helm.dm
@@ -256,7 +256,8 @@ LEGACY_RECORD_STRUCTURE(all_waypoints, waypoint)
req_access.Cut()
to_chat(user, SPAN_NOTICE("You short out \the [src]'s internal circuitry, removing the access requirements!"))
sparks(2, 1, src)
- return 1
+ emagged = TRUE
+ return TRUE
return
/**