The code phrases were:[phrases] \
The code responses were:[responses]
"
- to_chat(world, text)
- return TRUE
+ return text.Join("")
diff --git a/code/game/gamemodes/vampire/vampire_gamemode.dm b/code/game/gamemodes/vampire/vampire_gamemode.dm
index 688d8c7da8b0..306ef74cb9a7 100644
--- a/code/game/gamemodes/vampire/vampire_gamemode.dm
+++ b/code/game/gamemodes/vampire/vampire_gamemode.dm
@@ -51,7 +51,7 @@
if(!length(vampires))
return
- var/text = "The vampires were:"
+ var/list/text = list("The vampires were:")
for(var/datum/mind/vampire in vampires)
var/traitorwin = TRUE
var/datum/antagonist/vampire/V = vampire.has_antag_datum(/datum/antagonist/vampire)
@@ -101,14 +101,13 @@
else
text += " The [special_role_text] has failed!"
SSblackbox.record_feedback("tally", "vampire_success", 1, "FAIL")
- to_chat(world, text)
- return TRUE
+ return text.Join("")
/datum/game_mode/proc/auto_declare_completion_enthralled()
if(!length(vampire_enthralled))
return
- var/text = "The Enthralled were:"
+ var/list/text = list("The Enthralled were:")
for(var/datum/mind/mind in vampire_enthralled)
text += " [mind.get_display_key()] was [mind.name] ("
if(mind.current)
@@ -121,6 +120,5 @@
else
text += "body destroyed"
text += ")"
- to_chat(world, text)
- return TRUE
+ return text.Join("")
diff --git a/code/game/gamemodes/wizard/godhand.dm b/code/game/gamemodes/wizard/godhand.dm
index edfe5d8f41b3..0f0dfbe4f5df 100644
--- a/code/game/gamemodes/wizard/godhand.dm
+++ b/code/game/gamemodes/wizard/godhand.dm
@@ -23,10 +23,7 @@
attached_spell.UnregisterSignal(attached_spell.action.owner, COMSIG_MOB_WILLINGLY_DROP)
return ..()
-/obj/item/melee/touch_attack/customised_abstract_text()
- if(!ishuman(loc))
- return
- var/mob/living/carbon/human/owner = loc
+/obj/item/melee/touch_attack/customised_abstract_text(mob/living/carbon/owner)
return "[owner.p_their(TRUE)] [owner.l_hand == src ? "left hand" : "right hand"] is burning in magic fire."
/obj/item/melee/touch_attack/attack(mob/target, mob/living/carbon/user)
diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm
index 4a1816392faf..db77680783e3 100644
--- a/code/game/gamemodes/wizard/wizard.dm
+++ b/code/game/gamemodes/wizard/wizard.dm
@@ -191,8 +191,8 @@
return 1
/datum/game_mode/proc/auto_declare_completion_wizard()
- if(wizards.len)
- var/text = " the wizards/witches were:"
+ if(length(wizards))
+ var/list/text = list(" the wizards/witches were:")
for(var/datum/mind/wizard in wizards)
@@ -236,8 +236,7 @@
i++
text += " "
- to_chat(world, text)
- return 1
+ return text.Join("")
//OTHER PROCS
diff --git a/code/game/jobs/departments.dm b/code/game/jobs/departments.dm
index 43a562d559b7..898b771f4699 100644
--- a/code/game/jobs/departments.dm
+++ b/code/game/jobs/departments.dm
@@ -127,7 +127,6 @@
"Chaplain",
"Clown",
"Mime",
- "Barber",
"Magistrate",
"Nanotrasen Representative",
"Blueshield",
diff --git a/code/game/jobs/job/supervisor.dm b/code/game/jobs/job/supervisor.dm
index ca6eac1b5d9c..47b012eecffc 100644
--- a/code/game/jobs/job/supervisor.dm
+++ b/code/game/jobs/job/supervisor.dm
@@ -275,7 +275,7 @@
suit = /obj/item/clothing/suit/storage/iaa/blackjacket
shoes = /obj/item/clothing/shoes/brown
l_ear = /obj/item/radio/headset/headset_iaa/alt
- glasses = /obj/item/clothing/glasses/hud/security/sunglasses/read_only
+ glasses = /obj/item/clothing/glasses/hud/security/sunglasses
id = /obj/item/card/id/internalaffairsagent
l_pocket = /obj/item/laser_pointer
r_pocket = /obj/item/clothing/accessory/lawyers_badge
diff --git a/code/game/jobs/job/support.dm b/code/game/jobs/job/support.dm
index 5a4f493570bb..58eec484c1cf 100644
--- a/code/game/jobs/job/support.dm
+++ b/code/game/jobs/job/support.dm
@@ -467,34 +467,6 @@
continue
H.add_language(la)
-/datum/job/barber
- title = "Barber"
- flag = JOB_BARBER
- department_flag = JOBCAT_SUPPORT
- total_positions = 1
- spawn_positions = 1
- job_department_flags = DEP_FLAG_SERVICE
- supervisors = "the head of personnel"
- department_head = list("Head of Personnel")
- selection_color = "#dddddd"
- alt_titles = list("Hair Stylist","Beautician")
- access = list(ACCESS_MAINT_TUNNELS)
- minimal_access = list(ACCESS_MAINT_TUNNELS)
- outfit = /datum/outfit/job/barber
-
-/datum/outfit/job/barber
- name = "Barber"
- jobtype = /datum/job/barber
-
- uniform = /obj/item/clothing/under/rank/civilian/barber
- shoes = /obj/item/clothing/shoes/black
- l_ear = /obj/item/radio/headset/headset_service
- id = /obj/item/card/id/barber
- backpack_contents = list(
- /obj/item/storage/box/lip_stick = 1,
- /obj/item/storage/box/barber = 1
- )
-
/datum/job/explorer
title = "Explorer"
flag = JOB_EXPLORER
diff --git a/code/game/jobs/job_globals.dm b/code/game/jobs/job_globals.dm
index e14c0197223b..5f922af3975b 100644
--- a/code/game/jobs/job_globals.dm
+++ b/code/game/jobs/job_globals.dm
@@ -67,7 +67,6 @@ GLOBAL_LIST_INIT(support_positions, list(
"Chaplain",
"Clown",
"Mime",
- "Barber",
"Explorer"
))
diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/game/machinery/computer/HolodeckControl.dm
index 1acf00f7525a..c1b66de25f8b 100644
--- a/code/game/machinery/computer/HolodeckControl.dm
+++ b/code/game/machinery/computer/HolodeckControl.dm
@@ -357,6 +357,7 @@
/obj/item/holo/esword
name = "holographic energy sword"
desc = "This looks like a real energy sword!"
+ icon = 'icons/obj/energy_melee.dmi'
lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons_righthand.dmi'
icon_state = "sword0"
diff --git a/code/game/machinery/computer/arcade_games/recruiter.dm b/code/game/machinery/computer/arcade_games/recruiter.dm
index 4000e067527e..cdfd12c76ae8 100644
--- a/code/game/machinery/computer/arcade_games/recruiter.dm
+++ b/code/game/machinery/computer/arcade_games/recruiter.dm
@@ -39,7 +39,7 @@
var/list/incorrect_planets = list("Eath", "Marks", "Lunao", "Jabon 4", "Old Canaan", "Mauna-P",
"Daohmai", "Gomhes", "Zrerrballak", "Xarqis", "Soorlm", "Urum", "Baron 1", "Kelunte", "Daltedt")
- var/list/jobs = list("Assistant", "Clown", "Chef", "Janitor", "Bartender", "Barber", "Botanist", "Explorer", "Quartermaster",
+ var/list/jobs = list("Assistant", "Clown", "Chef", "Janitor", "Bartender", "Botanist", "Explorer", "Quartermaster",
"Station Engineer", "Atmospheric Technician", "Medical Doctor", "Coroner", "Geneticist", "Chaplain", "Librarian",
"Security Officer", "Detective", "Scientist", "Roboticist", "Shaft Miner", "Cargo Technician", "Internal Affairs Agent")
/// Jobs that NT stations dont offer/mispelled
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 8188c3743ab5..2799378e89d7 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -776,6 +776,8 @@ GLOBAL_LIST_EMPTY(airlock_emissive_underlays)
if((istype(living_mover) && HAS_TRAIT(living_mover, TRAIT_CONTORTED_BODY) && IS_HORIZONTAL(living_mover))) // We really dont want people to get shocked on a door they're passing through
if(density && !do_mob(living_mover, living_mover, 2 SECONDS, requires_upright = FALSE))
return FALSE
+ if(!IS_HORIZONTAL(living_mover) || locked) // Checking if the user has gotten up or the airlock was bolted after we tried to crawl underneath
+ return FALSE
living_mover.forceMove(get_turf(src))
return TRUE
if(isElectrified() && density && isitem(mover) && !on_spark_cooldown)
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index d138477758e4..cb6bba8b720c 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -233,7 +233,7 @@ GLOBAL_LIST_EMPTY(holopads)
callnames -= get_area(src)
var/list/sorted_callnames = sortAtom(callnames)
dialling_input = TRUE
- var/result = input(usr, "Choose an area to call", "Holocall") as null|anything in sorted_callnames
+ var/result = tgui_input_list(usr, "Choose an area to call", "Holocall", sorted_callnames)
dialling_input = FALSE
if(QDELETED(usr) || !result || outgoing_call)
return
diff --git a/code/game/machinery/tcomms/nttc.dm b/code/game/machinery/tcomms/nttc.dm
index a375e56cdefc..e73cbd943e16 100644
--- a/code/game/machinery/tcomms/nttc.dm
+++ b/code/game/machinery/tcomms/nttc.dm
@@ -112,7 +112,6 @@
"Shaft Miner" = "supradio",
"Spelunker" = "supradio",
// Service
- "Barber" = "srvradio",
"Bartender" = "srvradio",
"Beautician" = "srvradio",
"Botanical Researcher" = "srvradio",
diff --git a/code/game/machinery/vendors/contraband_vendors.dm b/code/game/machinery/vendors/contraband_vendors.dm
index 72b5ebd56377..be658bffa8e8 100644
--- a/code/game/machinery/vendors/contraband_vendors.dm
+++ b/code/game/machinery/vendors/contraband_vendors.dm
@@ -21,7 +21,7 @@
/obj/item/healthanalyzer = 1)
contraband = list(/obj/item/reagent_containers/syringe/antiviral = 4,
- /obj/item/reagent_containers/food/pill/tox = 1)
+ /obj/item/reagent_containers/pill/tox = 1)
/obj/machinery/economy/vending/syndicigs
name = "\improper Suspicious Cigarette Machine"
diff --git a/code/game/machinery/vendors/departmental_vendors.dm b/code/game/machinery/vendors/departmental_vendors.dm
index 8dc59113a032..15dc44926ef7 100644
--- a/code/game/machinery/vendors/departmental_vendors.dm
+++ b/code/game/machinery/vendors/departmental_vendors.dm
@@ -250,8 +250,8 @@
products = list(/obj/item/reagent_containers/hypospray/autoinjector/epinephrine = 4,
/obj/item/stack/medical/bruise_pack/advanced = 2,
/obj/item/stack/medical/ointment/advanced = 2,
- /obj/item/reagent_containers/food/pill/patch/styptic = 3,
- /obj/item/reagent_containers/food/pill/patch/silver_sulf = 3,
+ /obj/item/reagent_containers/patch/styptic = 3,
+ /obj/item/reagent_containers/patch/silver_sulf = 3,
/obj/item/reagent_containers/applicator/brute = 2,
/obj/item/reagent_containers/applicator/burn = 2,
/obj/item/stack/medical/bruise_pack = 2,
@@ -268,9 +268,9 @@
/obj/item/reagent_containers/syringe/antiviral = 3,
/obj/item/reagent_containers/syringe/calomel = 3,
/obj/item/reagent_containers/syringe/heparin = 3,
- /obj/item/reagent_containers/food/pill/salbutamol = 5,
- /obj/item/reagent_containers/food/pill/mannitol = 5,
- /obj/item/reagent_containers/food/pill/mutadone = 5,
+ /obj/item/reagent_containers/pill/salbutamol = 5,
+ /obj/item/reagent_containers/pill/mannitol = 5,
+ /obj/item/reagent_containers/pill/mutadone = 5,
/obj/item/reagent_containers/glass/beaker = 3,
/obj/item/reagent_containers/dropper = 3,
/obj/item/reagent_containers/hypospray/safety = 2,
diff --git a/code/game/machinery/vendors/generic_vendors.dm b/code/game/machinery/vendors/generic_vendors.dm
index 46ef25ca4a38..e87c805fb81f 100644
--- a/code/game/machinery/vendors/generic_vendors.dm
+++ b/code/game/machinery/vendors/generic_vendors.dm
@@ -1191,7 +1191,7 @@
/obj/item/storage/fancy/cigarettes/cigpack_random = 6,
/obj/item/storage/fancy/cigarettes/cigpack_robustgold = 1,
/obj/item/clothing/mask/cigarette/cigar/havana = 2,
- /obj/item/reagent_containers/food/pill/patch/nicotine = 10,
+ /obj/item/reagent_containers/patch/nicotine = 10,
/obj/item/storage/box/matches = 10,
/obj/item/lighter/random = 4,
/obj/item/lighter/zippo = 2)
@@ -1204,7 +1204,7 @@
/obj/item/storage/fancy/cigarettes/cigpack_midori = 60,
/obj/item/storage/fancy/cigarettes/cigpack_random = 80,
/obj/item/storage/fancy/cigarettes/cigpack_robustgold = 120,
- /obj/item/reagent_containers/food/pill/patch/nicotine = 70,
+ /obj/item/reagent_containers/patch/nicotine = 70,
/obj/item/storage/box/matches = 20,
/obj/item/lighter/random = 40,
/obj/item/lighter/zippo = 80,
@@ -1281,7 +1281,7 @@
/obj/item/healthanalyzer = 1)
contraband = list(/obj/item/reagent_containers/syringe/antiviral = 4,
- /obj/item/reagent_containers/food/pill/tox = 1)
+ /obj/item/reagent_containers/pill/tox = 1)
armor = list(MELEE = 50, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 0, RAD = 0, FIRE = 100, ACID = 70)
//this shouldn't be priced
diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm
index e89056171f35..3b5bb6c80dd3 100644
--- a/code/game/objects/effects/landmarks.dm
+++ b/code/game/objects/effects/landmarks.dm
@@ -107,7 +107,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/awaystart) //Without this away mission
/obj/effect/landmark/spawner/rev
name = "revenantspawn"
icon_state = "Rev"
-
+
/obj/effect/landmark/spawner/bubblegum_arena
name = "bubblegum_arena_human"
icon_state = "Explorer"
@@ -279,10 +279,6 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/awaystart) //Without this away mission
name = "Blueshield"
icon_state = "BS"
-/obj/effect/landmark/start/barber
- name = "Barber"
- icon_state = "Barber"
-
/obj/effect/landmark/start/bartender
name = "Bartender"
icon_state = "Bartender"
diff --git a/code/game/objects/effects/spawners/random_spawners.dm b/code/game/objects/effects/spawners/random_spawners.dm
index e109701cc947..850e12c3ef50 100644
--- a/code/game/objects/effects/spawners/random_spawners.dm
+++ b/code/game/objects/effects/spawners/random_spawners.dm
@@ -275,7 +275,7 @@
// Loot schema: space gear, basic armor, basic ammo (10mm, rcd), drugs, more dangerous/useful gimmick items, lower-value minerals
result = list(/datum/nothing = 27,
/obj/item/storage/box/syndie_kit/space = 1,
- /obj/item/storage/box/syndie_kit/modsuit = 1,
+ /obj/item/mod/control/pre_equipped/traitor = 1,
/obj/item/clothing/shoes/magboots/syndie = 1,
/obj/item/clothing/suit/armor/vest/combat = 1,
/obj/item/ammo_box/magazine/m10mm = 1,
@@ -309,7 +309,7 @@
result = list(/datum/nothing = 25,
/obj/item/jammer = 1,
/obj/item/storage/firstaid/regular = 1,
- /obj/item/storage/box/syndie_kit/bonerepair = 1,
+ /obj/item/reagent_containers/hypospray/autoinjector/nanocalcium = 1,
/obj/item/gun/projectile/automatic/pistol = 1,
/obj/item/stock_parts/cell/bluespace = 1,
/obj/item/card/emag = 1,
@@ -353,7 +353,7 @@
/obj/item/chameleon = 1,
/obj/item/reagent_containers/hypospray/autoinjector/stimulants = 1,
/obj/item/grenade/plastic/c4/x4 = 1,
- /obj/item/storage/box/syndie_kit/modsuit/elite = 1)// Adding this as it is something an explorer can use to explore space better, that isn't a high powered murder weapon.
+ /obj/item/mod/control/pre_equipped/traitor_elite = 1)// Adding this as it is something an explorer can use to explore space better, that isn't a high powered murder weapon.
// Layout-affecting spawns
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 2f3140a86f49..61f4e4b8656c 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -154,7 +154,7 @@ GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons
in_storage = TRUE
// this proc is used to add text for items with ABSTRACT flag after default examine text
-/obj/item/proc/customised_abstract_text()
+/obj/item/proc/customised_abstract_text(mob/living/carbon/owner)
return
/obj/item/proc/determine_move_resist()
diff --git a/code/game/objects/items/contraband.dm b/code/game/objects/items/contraband.dm
index ad6d886cd374..3af05bb9a1cc 100644
--- a/code/game/objects/items/contraband.dm
+++ b/code/game/objects/items/contraband.dm
@@ -8,8 +8,8 @@
/obj/item/storage/pill_bottle/happy/populate_contents()
for(var/i in 1 to 5)
- new /obj/item/reagent_containers/food/pill/happy(src)
- new /obj/item/reagent_containers/food/pill/happy/happiness(src)
+ new /obj/item/reagent_containers/pill/happy(src)
+ new /obj/item/reagent_containers/pill/happy/happiness(src)
/obj/item/storage/pill_bottle/zoom
name = "Zoom pills"
@@ -18,13 +18,13 @@
/obj/item/storage/pill_bottle/zoom/populate_contents()
for(var/i in 1 to 7)
- new /obj/item/reagent_containers/food/pill/zoom(src)
+ new /obj/item/reagent_containers/pill/zoom(src)
-/obj/item/reagent_containers/food/pill/random_drugs
+/obj/item/reagent_containers/pill/random_drugs
name = "pill"
desc = "A cocktail of illicit designer drugs, who knows what might be in here."
-/obj/item/reagent_containers/food/pill/random_drugs/Initialize(mapload)
+/obj/item/reagent_containers/pill/random_drugs/Initialize(mapload)
. = ..()
icon_state = "pill" + pick("2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20")
@@ -48,4 +48,4 @@
/obj/item/storage/pill_bottle/random_drug_bottle/Initialize(mapload)
. = ..()
for(var/i in 1 to 5)
- new /obj/item/reagent_containers/food/pill/random_drugs(src)
+ new /obj/item/reagent_containers/pill/random_drugs(src)
diff --git a/code/game/objects/items/his_grace.dm b/code/game/objects/items/his_grace.dm
index 74731a1f18d6..7766452893d1 100644
--- a/code/game/objects/items/his_grace.dm
+++ b/code/game/objects/items/his_grace.dm
@@ -1,9 +1,9 @@
-//His Grace is a very special weapon granted only to traitor chaplains.
-//When awakened, He thirsts for blood and begins ticking a "bloodthirst" counter.
-//The wielder of His Grace is immune to stuns and gradually heals.
-//If the wielder fails to feed His Grace in time, He will devour them and become incredibly aggressive.
-//Leaving His Grace alone for some time will reset His thirst and put Him to sleep.
-//Using His Grace effectively requires extreme speed and care.
+// His Grace is a very special weapon granted only to traitor chaplains.
+// When awakened, He thirsts for blood and begins ticking a "bloodthirst" counter.
+// The wielder of His Grace is immune to stuns and gradually heals.
+// If the wielder fails to feed His Grace in time, He will devour them and become incredibly aggressive.
+// Leaving His Grace alone for some time will reset His thirst and put Him to sleep.
+// Using His Grace effectively requires extreme speed and care.
/obj/item/his_grace
name = "artistic toolbox"
@@ -19,13 +19,16 @@
hitsound = 'sound/weapons/smash.ogg'
drop_sound = 'sound/items/handling/toolbox_drop.ogg'
pickup_sound = 'sound/items/handling/toolbox_pickup.ogg'
+
+ /// Is our little toolbox awake?
var/awakened = FALSE
+ /// How hungry is His Grace?
var/bloodthirst = HIS_GRACE_SATIATED
var/prev_bloodthirst = HIS_GRACE_SATIATED
var/force_bonus = 0
var/ascended = FALSE
+ var/victims = 0
var/victims_needed = 25
- var/ascend_bonus = 15
/obj/item/his_grace/Initialize(mapload)
. = ..()
@@ -69,22 +72,24 @@
/obj/item/his_grace/examine(mob/user)
. = ..()
- if(awakened)
- switch(bloodthirst)
- if(HIS_GRACE_SATIATED to HIS_GRACE_PECKISH)
- . += "[src] isn't very hungry. Not yet."
- if(HIS_GRACE_PECKISH to HIS_GRACE_HUNGRY)
- . += "[src] would like a snack."
- if(HIS_GRACE_HUNGRY to HIS_GRACE_FAMISHED)
- . += "[src] is quite hungry now."
- if(HIS_GRACE_FAMISHED to HIS_GRACE_STARVING)
- . += "[src] is openly salivating at the sight of you. Be careful."
- if(HIS_GRACE_STARVING to HIS_GRACE_CONSUME_OWNER)
- . += "You walk a fine line. [src] is very close to devouring you."
- if(HIS_GRACE_CONSUME_OWNER to HIS_GRACE_FALL_ASLEEP)
- . += "[src] is shaking violently and staring directly at you."
- else
+
+ if(!awakened)
. += "[src] is latched closed."
+ return
+
+ switch(bloodthirst)
+ if(HIS_GRACE_SATIATED to HIS_GRACE_PECKISH)
+ . += "[src] isn't very hungry. Not yet."
+ if(HIS_GRACE_PECKISH to HIS_GRACE_HUNGRY)
+ . += "[src] would like a snack."
+ if(HIS_GRACE_HUNGRY to HIS_GRACE_FAMISHED)
+ . += "[src] is quite hungry now."
+ if(HIS_GRACE_FAMISHED to HIS_GRACE_STARVING)
+ . += "[src] is openly salivating at the sight of you. Be careful."
+ if(HIS_GRACE_STARVING to HIS_GRACE_CONSUME_OWNER)
+ . += "You walk a fine line. [src] is very close to devouring you."
+ if(HIS_GRACE_CONSUME_OWNER to HIS_GRACE_FALL_ASLEEP)
+ . += "[src] is shaking violently and staring directly at you."
/obj/item/his_grace/relaymove(mob/living/user, direction) //Allows changelings, etc. to climb out of Him after they revive, provided He isn't active
if(!awakened)
@@ -95,29 +100,37 @@
if(!bloodthirst)
drowse()
return
- if(bloodthirst < HIS_GRACE_CONSUME_OWNER && !ascended)
- adjust_bloodthirst(0.5 + FLOOR(length(contents) * 0.25, 1))
+ if(bloodthirst < HIS_GRACE_CONSUME_OWNER)
+ adjust_bloodthirst(0.5 + round(length(contents) * (1 / 6), 1))
else
adjust_bloodthirst(0.5) //don't cool off rapidly once we're at the point where His Grace consumes all.
- var/mob/living/master = get_atom_on_turf(src, /mob/living)
- var/list/held_items = list()
- if(istype(master))
- held_items += master.l_hand
- held_items += master.r_hand
- if(istype(master) && (src in held_items))
- switch(bloodthirst)
- if(HIS_GRACE_CONSUME_OWNER to HIS_GRACE_FALL_ASLEEP)
- master.visible_message("[src] turns on [master]!", "[src] turns on you!")
- do_attack_animation(master, null, src)
- master.emote("scream")
- master.remove_status_effect(STATUS_EFFECT_HISGRACE)
- flags &= ~NODROP
- master.Weaken(6 SECONDS)
- master.adjustBruteLoss(1000)
- playsound(master, 'sound/effects/splat.ogg', 100, FALSE)
- else
- master.apply_status_effect(STATUS_EFFECT_HISGRACE)
+
+ var/mob/living/carbon/human/master = get_atom_on_turf(src, /mob/living/carbon/human) // Only humans may wield Him
+ if(!master || !istype(master))
+ go_rabid()
+ return
+
+ if(!(src in list(master.l_hand, master.r_hand)))
+ go_rabid()
+ return
+
+ if(bloodthirst <= HIS_GRACE_CONSUME_OWNER || ascended)
+ master.apply_status_effect(STATUS_EFFECT_HISGRACE)
return
+
+ // They didn't sacrifice enough people, so this is where we go ham
+ master.visible_message("[src] turns on [master]!",
+ "[src] turns on you!")
+ do_attack_animation(master, used_item = src)
+ master.emote("scream")
+ master.remove_status_effect(STATUS_EFFECT_HISGRACE)
+ flags &= ~NODROP
+ master.Weaken(6 SECONDS)
+ master.adjustBruteLoss(1000)
+ playsound(master, 'sound/effects/splat.ogg', 100, FALSE)
+ go_rabid()
+
+/obj/item/his_grace/proc/go_rabid() // She Caerbannog on my rabid till I-
forceMove(get_turf(src)) //no you can't put His Grace in a locker you just have to deal with Him
if(bloodthirst < HIS_GRACE_CONSUME_OWNER)
return
@@ -182,30 +195,38 @@
/obj/item/his_grace/proc/consume(mob/living/meal) //Here's your dinner, Mr. Grace.
if(!meal)
return
- var/victims = 0
+
meal.visible_message("[src] swings open and devours [meal]!", "[src] consumes you!")
meal.adjustBruteLoss(300)
playsound(meal, 'sound/misc/desceration-02.ogg', 75, TRUE)
playsound(src, 'sound/items/eatfood.ogg', 100, TRUE)
meal.forceMove(src)
- force_bonus += HIS_GRACE_FORCE_BONUS
+
+ force_bonus += (ascended ? ASCEND_BONUS : HIS_GRACE_FORCE_BONUS)
+
prev_bloodthirst = bloodthirst
- if(prev_bloodthirst < HIS_GRACE_CONSUME_OWNER)
- bloodthirst = max(length(contents), 1) //Never fully sated, and His hunger will only grow.
+ if(ascended) // Otherwise there might be fractions where His Grace is droppable while ascended
+ bloodthirst = prev_bloodthirst
+ else if(prev_bloodthirst < HIS_GRACE_CONSUME_OWNER)
+ bloodthirst = length(contents) //Never fully sated, and His hunger will only grow.
else
bloodthirst = HIS_GRACE_CONSUME_OWNER
- for(var/mob/living/C in contents)
- if(C.mind)
- victims++
+
+ if(meal.mind)
+ victims++
if(victims >= victims_needed)
ascend()
update_stats()
/obj/item/his_grace/proc/adjust_bloodthirst(amt)
prev_bloodthirst = bloodthirst
- if(prev_bloodthirst < HIS_GRACE_CONSUME_OWNER && !ascended)
+ if(ascended)
+ bloodthirst = HIS_GRACE_CONSUME_OWNER // As to maximize their healing buff
+ update_stats()
+ return
+ if(prev_bloodthirst < HIS_GRACE_CONSUME_OWNER)
bloodthirst = clamp(bloodthirst + amt, HIS_GRACE_SATIATED, HIS_GRACE_CONSUME_OWNER)
- else if(!ascended)
+ else
bloodthirst = clamp(bloodthirst + amt, HIS_GRACE_CONSUME_OWNER, HIS_GRACE_FALL_ASLEEP)
update_stats()
@@ -250,7 +271,6 @@
/obj/item/his_grace/proc/ascend()
if(ascended)
return
- force_bonus += ascend_bonus
desc = "A legendary toolbox and a distant artifact from The Age of Three Powers. On its three latches engraved are the words \"The Sun\", \"The Moon\", and \"The Stars\". The entire toolbox has the words \"The World\" engraved into its sides."
icon_state = "his_grace_ascended"
item_state = "toolbox_gold"
diff --git a/code/game/objects/items/random_items.dm b/code/game/objects/items/random_items.dm
index 874ab450ce7e..bbb75fa65f9b 100644
--- a/code/game/objects/items/random_items.dm
+++ b/code/game/objects/items/random_items.dm
@@ -61,7 +61,7 @@
var/possible_meds = is_rare ? possible_meds_rare : possible_meds_standard
var/datum/reagent/R = pick(possible_meds)
- var/obj/item/reagent_containers/food/pill/P = new(src)
+ var/obj/item/reagent_containers/pill/P = new(src)
if(is_rare)
P.reagents.add_reagent(R, 10)
diff --git a/code/game/objects/items/stacks/nanopaste.dm b/code/game/objects/items/stacks/nanopaste.dm
index d0fce583b732..e296d1666010 100644
--- a/code/game/objects/items/stacks/nanopaste.dm
+++ b/code/game/objects/items/stacks/nanopaste.dm
@@ -25,45 +25,47 @@
if(ishuman(M)) //Repairing robotic limbs and IPCs
var/mob/living/carbon/human/H = M
- var/obj/item/organ/external/S = H.get_organ(user.zone_selected)
+ var/obj/item/organ/external/external_limb = H.get_organ(user.zone_selected)
- if(S && S.is_robotic())
- if(S.get_damage())
- use(1)
- var/remheal = 15
- var/nremheal = 0
- S.heal_damage(robo_repair = 1) //should in, theory, heal the robotic organs in just the targeted area with it being S instead of E
- var/childlist
- if(!isnull(S.children))
- childlist = S.children.Copy()
- var/parenthealed = FALSE
- while(remheal > 0)
- var/obj/item/organ/external/E
- if(S.get_damage())
- E = S
- else if(LAZYLEN(childlist))
- E = pick_n_take(childlist)
- if(!E.get_damage() || !E.is_robotic())
- continue
- else if(S.parent && !parenthealed)
- E = S.parent
- parenthealed = TRUE
- if(!E.get_damage() || !E.is_robotic())
- break
- else
- break
- nremheal = max(remheal - E.get_damage(), 0)
- E.heal_damage(remheal, 0, 0, 1) //Healing Brute
- E.heal_damage(0, remheal, 0, 1) //Healing Burn
- remheal = nremheal
- user.visible_message("\The [user] applies some nanite paste at \the [M]'s [E.name] with \the [src].")
- if(H.bleed_rate && ismachineperson(H))
- H.bleed_rate = 0
- else
- to_chat(user, "Nothing to fix here.")
+ if(external_limb && external_limb.is_robotic())
+ robotic_limb_repair(user, external_limb, H)
else
to_chat(user, "[src] won't work on that.")
+/obj/item/stack/nanopaste/proc/robotic_limb_repair(mob/user, obj/item/organ/external/external_limb, mob/living/carbon/human/H)
+ if(!external_limb.get_damage())
+ to_chat(user, "Nothing to fix here.")
+ return
+ use(1)
+ var/remaining_heal = 15
+ var/new_remaining_heal = 0
+ external_limb.heal_damage(robo_repair = TRUE) //should in, theory, heal the robotic organs in just the targeted area with it being external_limb instead of other_external_limb
+ var/list/childlist
+ if(!isnull(external_limb.children))
+ childlist = external_limb.children.Copy()
+ var/parenthealed = FALSE
+ while(remaining_heal > 0)
+ var/obj/item/organ/external/other_external_limb
+ if(external_limb.get_damage())
+ other_external_limb = external_limb
+ else if(LAZYLEN(childlist))
+ other_external_limb = pick_n_take(childlist)
+ if(!other_external_limb.get_damage() || !other_external_limb.is_robotic())
+ continue
+ else if(external_limb.parent && !parenthealed)
+ other_external_limb = external_limb.parent
+ parenthealed = TRUE
+ if(!other_external_limb.get_damage() || !other_external_limb.is_robotic())
+ break
+ else
+ break
+ new_remaining_heal = max(remaining_heal - other_external_limb.get_damage(), 0)
+ other_external_limb.heal_damage(remaining_heal, remaining_heal, FALSE, TRUE)
+ remaining_heal = new_remaining_heal
+ user.visible_message("[user] applies some nanite paste at [H]'s [other_external_limb.name] with [src].")
+ if(H.bleed_rate && ismachineperson(H))
+ H.bleed_rate = 0
+
/obj/item/stack/nanopaste/cyborg
energy_type = /datum/robot_energy_storage/medical/nanopaste
is_cyborg = TRUE
diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index 8225956d0e2a..11a50e1c59bb 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -282,6 +282,7 @@ GLOBAL_LIST_INIT(cloth_recipes, list (
null,
new /datum/stack_recipe_list("cloth bags", list(
new /datum/stack_recipe("backpack", /obj/item/storage/backpack, 4),
+ new /datum/stack_recipe("satchel", /obj/item/storage/backpack/satchel_norm, 4),
new /datum/stack_recipe("dufflebag", /obj/item/storage/backpack/duffel, 6),
null,
new /datum/stack_recipe("plant bag", /obj/item/storage/bag/plants, 4),
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index eebe95f2bef6..929a7aaf76d0 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -176,6 +176,7 @@
/obj/item/toy/sword
name = "toy sword"
desc = "A cheap, plastic replica of an energy sword. Realistic sounds! Ages 8 and up."
+ icon = 'icons/obj/energy_melee.dmi'
lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons_righthand.dmi'
icon_state = "sword0"
diff --git a/code/game/objects/items/weapons/RSF.dm b/code/game/objects/items/weapons/RSF.dm
index f3c9a997ea03..66951e2e044d 100644
--- a/code/game/objects/items/weapons/RSF.dm
+++ b/code/game/objects/items/weapons/RSF.dm
@@ -25,7 +25,7 @@
var/static/list/rsf_items = list("Drinking Glass" = /obj/item/reagent_containers/food/drinks/drinkingglass,
"Paper" = /obj/item/paper,
"Pen" = /obj/item/pen,
- "Dice Pack" = /obj/item/storage/pill_bottle/dice,
+ "Dice Pack" = /obj/item/storage/bag/dice,
"Cigarette" = /obj/item/clothing/mask/cigarette,
"Newdles" = /obj/item/reagent_containers/food/snacks/chinese/newdles,
"Donut" = /obj/item/reagent_containers/food/snacks/donut,
diff --git a/code/game/objects/items/weapons/batons.dm b/code/game/objects/items/weapons/batons.dm
index 8dd0921cbed6..63220202163a 100644
--- a/code/game/objects/items/weapons/batons.dm
+++ b/code/game/objects/items/weapons/batons.dm
@@ -8,6 +8,7 @@
/obj/item/melee/classic_baton
name = "police baton"
desc = "A wooden truncheon for beating criminal scum."
+ icon = 'icons/obj/baton.dmi'
icon_state = "baton"
item_state = "classic_baton"
slot_flags = SLOT_FLAG_BELT
diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm
index 5c1f5881cd10..7afd3326575b 100644
--- a/code/game/objects/items/weapons/cards_ids.dm
+++ b/code/game/objects/items/weapons/cards_ids.dm
@@ -446,7 +446,6 @@
"assistant",
"clown",
"mime",
- "barber",
"botanist",
"librarian",
"chaplain",
@@ -938,12 +937,6 @@
desc = "..."
access = list(ACCESS_MIME, ACCESS_THEATRE, ACCESS_MAINT_TUNNELS)
-/obj/item/card/id/barber
- name = "Barber ID"
- registered_name = "Barber"
- icon_state = "barber"
- access = list(ACCESS_MAINT_TUNNELS)
-
/obj/item/card/id/botanist
name = "Botanist ID"
registered_name = "Botanist"
@@ -1109,7 +1102,7 @@
override_name = 1
/proc/get_station_card_skins()
- return list("data","id","gold","silver","security","detective","warden","internalaffairsagent","medical","coroner","chemist","virologist","paramedic","psychiatrist","geneticist","research","roboticist","quartermaster","cargo","shaftminer","engineering","atmostech","captain","HoP","HoS","CMO","RD","CE","assistant","clown","mime","barber","botanist","librarian","chaplain","bartender","chef","janitor","rainbow","prisoner","explorer")
+ return list("data","id","gold","silver","security","detective","warden","internalaffairsagent","medical","coroner","chemist","virologist","paramedic","psychiatrist","geneticist","research","roboticist","quartermaster","cargo","shaftminer","engineering","atmostech","captain","HoP","HoS","CMO","RD","CE","assistant","clown","mime","botanist","librarian","chaplain","bartender","chef","janitor","rainbow","prisoner","explorer")
/proc/get_centcom_card_skins()
return list("centcom","blueshield","magistrate","ntrep","ERT_leader","ERT_empty","ERT_security","ERT_engineering","ERT_medical","ERT_janitorial","ERT_paranormal","deathsquad","commander","syndie","TDred","TDgreen")
diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm
index daf394f72404..1f740ef64b37 100644
--- a/code/game/objects/items/weapons/defib.dm
+++ b/code/game/objects/items/weapons/defib.dm
@@ -90,8 +90,8 @@
cell = locate(/obj/item/stock_parts/cell) in contents
update_icon(UPDATE_OVERLAYS)
-/obj/item/defibrillator/ui_action_click()
- toggle_paddles()
+/obj/item/defibrillator/ui_action_click(mob/user)
+ toggle_paddles(user)
/obj/item/defibrillator/CtrlClick(mob/user)
if(ishuman(user) && Adjacent(user))
@@ -251,7 +251,7 @@
/obj/item/defibrillator/compact/advanced/attackby(obj/item/W, mob/user, params)
if(W == paddles)
- toggle_paddles()
+ toggle_paddles(user)
update_icon(UPDATE_OVERLAYS)
/obj/item/defibrillator/compact/advanced/loaded/Initialize(mapload)
diff --git a/code/game/objects/items/weapons/dice.dm b/code/game/objects/items/weapons/dice.dm
index 7b3db4429a69..8ee1908cd781 100644
--- a/code/game/objects/items/weapons/dice.dm
+++ b/code/game/objects/items/weapons/dice.dm
@@ -1,13 +1,15 @@
-/obj/item/storage/pill_bottle/dice //But why is this a pill bottle
+/obj/item/storage/bag/dice //Thankfully no longer a pill bottle.
name = "bag of dice"
desc = "Contains all the luck you'll ever need."
icon = 'icons/obj/dice.dmi'
icon_state = "dicebag"
- can_hold = list(/obj/item/dice)
- allow_wrap = FALSE
use_sound = "rustle"
+ storage_slots = 50
+ max_combined_w_class = 50
+ can_hold = list(/obj/item/dice)
+ resistance_flags = FLAMMABLE
-/obj/item/storage/pill_bottle/dice/populate_contents()
+/obj/item/storage/bag/dice/populate_contents()
var/special_die = pick("1","2","fudge","00","100")
if(special_die == "1")
new /obj/item/dice/d1(src)
@@ -26,7 +28,7 @@
if(special_die == "100")
new /obj/item/dice/d100(src)
-/obj/item/storage/pill_bottle/dice/suicide_act(mob/user)
+/obj/item/storage/bag/dice/suicide_act(mob/user)
user.visible_message("[user] is gambling with death! It looks like [user.p_theyre()] trying to commit suicide!")
return (OXYLOSS)
@@ -248,7 +250,7 @@
/obj/item/chameleon_counterfeiter,
/obj/item/clothing/shoes/chameleon/noslip,
/obj/item/pinpointer/advpinpointer,
- /obj/item/storage/box/syndie_kit/bonerepair,
+ /obj/item/reagent_containers/hypospray/autoinjector/nanocalcium,
/obj/item/storage/backpack/duffel/syndie/med/surgery,
/obj/item/storage/toolbox/syndicate,
/obj/item/storage/backpack/clown/syndie,
@@ -258,7 +260,7 @@
/obj/item/clothing/glasses/chameleon/thermal,
/obj/item/borg/upgrade/modkit/indoors,
/obj/item/storage/box/syndie_kit/chameleon,
- /obj/item/storage/box/syndie_kit/modsuit,
+ /obj/item/mod/control/pre_equipped/traitor,
/obj/item/implanter/storage,
/obj/item/toy/syndicateballoon)
var/selected_item = pick(traitor_items)
diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm
index f5edbe4b71a2..4117a9491054 100644
--- a/code/game/objects/items/weapons/handcuffs.dm
+++ b/code/game/objects/items/weapons/handcuffs.dm
@@ -1,13 +1,13 @@
/obj/item/restraints
name = "bugged restraints" //This item existed before this pr, but had no name or such. Better warn people if it exists
desc = "Should not exist. Report me to a(n) coder/admin!"
+ icon = 'icons/obj/restraints.dmi'
var/cuffed_state = "handcuff"
/obj/item/restraints/handcuffs
name = "handcuffs"
desc = "Use this to keep prisoners in line."
gender = PLURAL
- icon = 'icons/obj/items.dmi'
icon_state = "handcuff"
belt_icon = "handcuffs"
flags = CONDUCT
diff --git a/code/game/objects/items/weapons/holy_weapons.dm b/code/game/objects/items/weapons/holy_weapons.dm
index 2b41c2b9f00b..2d7130f1ca04 100644
--- a/code/game/objects/items/weapons/holy_weapons.dm
+++ b/code/game/objects/items/weapons/holy_weapons.dm
@@ -122,10 +122,7 @@
damtype = BURN
attack_verb = list("punched", "cross countered", "pummeled")
-/obj/item/nullrod/godhand/customised_abstract_text()
- if(!ishuman(loc))
- return
- var/mob/living/carbon/human/owner = loc
+/obj/item/nullrod/godhand/customised_abstract_text(mob/living/carbon/owner)
return "[owner.p_their(TRUE)] [owner.l_hand == src ? "left hand" : "right hand"] is burning in holy fire."
/obj/item/nullrod/staff
@@ -211,6 +208,7 @@
/obj/item/nullrod/claymore/saber
name = "light energy blade"
hitsound = 'sound/weapons/blade1.ogg'
+ icon = 'icons/obj/energy_melee.dmi'
icon_state = "swordblue"
item_state = "swordblue"
desc = "If you strike me down, I shall become more robust than you can possibly imagine."
@@ -437,10 +435,7 @@
w_class = WEIGHT_CLASS_HUGE
sharp = TRUE
-/obj/item/nullrod/armblade/customised_abstract_text()
- if(!ishuman(loc))
- return
- var/mob/living/carbon/human/owner = loc
+/obj/item/nullrod/armblade/customised_abstract_text(mob/living/carbon/owner)
return "[owner.p_their(TRUE)] [owner.l_hand == src ? "left arm" : "right arm"] has been turned into a grotesque meat-blade."
/obj/item/nullrod/armblade/mining
diff --git a/code/game/objects/items/weapons/legcuffs.dm b/code/game/objects/items/weapons/legcuffs.dm
index 05228fd9a068..d3a3350cf9fb 100644
--- a/code/game/objects/items/weapons/legcuffs.dm
+++ b/code/game/objects/items/weapons/legcuffs.dm
@@ -2,7 +2,6 @@
name = "leg cuffs"
desc = "Use this to keep prisoners in line."
gender = PLURAL
- icon = 'icons/obj/items.dmi'
icon_state = "handcuff"
cuffed_state = "legcuff"
flags = CONDUCT
@@ -154,7 +153,7 @@
/obj/item/restraints/legcuffs/beartrap/energy
name = "energy snare"
armed = TRUE
- icon_state = "e_snare"
+ icon_state = "e_snare1"
trap_damage = 0
flags = DROPDEL
breakouttime = 6 SECONDS
diff --git a/code/game/objects/items/weapons/lighters.dm b/code/game/objects/items/weapons/lighters.dm
index b0f10f0da9da..bf720995b07b 100644
--- a/code/game/objects/items/weapons/lighters.dm
+++ b/code/game/objects/items/weapons/lighters.dm
@@ -2,7 +2,7 @@
/obj/item/lighter
name = "cheap lighter"
desc = "A cheap-as-free lighter."
- icon = 'icons/obj/items.dmi'
+ icon = 'icons/obj/lighter.dmi'
lefthand_file = 'icons/mob/inhands/lighter_lefthand.dmi'
righthand_file = 'icons/mob/inhands/lighter_righthand.dmi'
icon_state = "lighter-g"
diff --git a/code/game/objects/items/weapons/melee/energy_melee_weapons.dm b/code/game/objects/items/weapons/melee/energy_melee_weapons.dm
index bd9fbd120e13..92768750e7e7 100644
--- a/code/game/objects/items/weapons/melee/energy_melee_weapons.dm
+++ b/code/game/objects/items/weapons/melee/energy_melee_weapons.dm
@@ -1,4 +1,5 @@
/obj/item/melee/energy
+ icon = 'icons/obj/energy_melee.dmi'
var/active = FALSE
var/force_on = 30 //force when active
var/throwforce_on = 20
diff --git a/code/game/objects/items/weapons/paint_bucket.dm b/code/game/objects/items/weapons/paint_bucket.dm
index bcc8493f11ef..85435b23f144 100644
--- a/code/game/objects/items/weapons/paint_bucket.dm
+++ b/code/game/objects/items/weapons/paint_bucket.dm
@@ -3,7 +3,7 @@
/obj/item/reagent_containers/glass/paint
desc = "It's a paint bucket."
name = "paint bucket"
- icon = 'icons/obj/items.dmi'
+ icon = 'icons/obj/paint.dmi'
icon_state = "paint_neutral"
item_state = "paintcan"
materials = list(MAT_METAL = 400)
diff --git a/code/game/objects/items/weapons/scissors.dm b/code/game/objects/items/weapons/scissors.dm
index afc917a9667a..abd1ca581ad6 100644
--- a/code/game/objects/items/weapons/scissors.dm
+++ b/code/game/objects/items/weapons/scissors.dm
@@ -12,7 +12,7 @@
/obj/item/scissors/barber
name = "Barber's Scissors"
- desc = "A pair of scissors used by the barber."
+ desc = "A pair of scissors used by a barber."
icon_state = "bscissor"
item_state = "scissor"
attack_verb = list("beautifully sliced", "artistically cut", "smoothly stabbed", "quickly jabbed")
@@ -49,38 +49,3 @@
H.update_hair()
H.update_fhair()
user.visible_message("[user] finishes cutting [M]'s hair!")
-
-/obj/item/scissors/safety //Totally safe, I assure you.
- desc = "The blades of the scissors appear to be made of some sort of ultra-strong metal alloy."
- force = 18 //same as e-daggers
- var/is_cutting = 0 //to prevent spam clicking this for huge accumulation of losebreath.
-
-/obj/item/scissors/safety/attack(mob/living/carbon/M as mob, mob/user as mob)
- if(user.a_intent != INTENT_HELP)
- ..()
- return
- if(!(M in view(1)))
- ..()
- return
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
-
- if(!is_cutting)
- is_cutting = 1
- user.visible_message("[user] starts cutting [M]'s hair!", "You start cutting [M]'s hair!")
- playsound(loc, 'sound/goonstation/misc/scissor.ogg', 100, 1)
- if(do_after(user, 50 * toolspeed, target = H))
- playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
- user.visible_message("[user] abruptly stops cutting [M]'s hair and slices [M.p_their()] throat!", "You stop cutting [M]'s hair and slice [M.p_their()] throat!") //Just a little off the top.
- H.AdjustLoseBreath(20 SECONDS) //30 Oxy damage over time
- H.apply_damage(18, BRUTE, "head", sharp =1, used_weapon = "scissors")
- var/turf/location = get_turf(src)
- H.add_splatter_floor(location)
- H.bloody_hands(H)
- H.bloody_body(H)
- var/mob/living/carbon/human/U = user
- U.bloody_hands(H)
- U.bloody_body(H)
- is_cutting = 0
- return
- is_cutting = 0
diff --git a/code/game/objects/items/weapons/shields.dm b/code/game/objects/items/weapons/shields.dm
index f871e1f96d15..e8659695765a 100644
--- a/code/game/objects/items/weapons/shields.dm
+++ b/code/game/objects/items/weapons/shields.dm
@@ -1,5 +1,6 @@
/obj/item/shield
name = "shield"
+ icon = 'icons/obj/shield.dmi'
lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons_righthand.dmi'
armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 0, BOMB = 30, RAD = 0, FIRE = 80, ACID = 70)
diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm
index 6fed959f886f..fbcd813e5044 100644
--- a/code/game/objects/items/weapons/storage/bags.dm
+++ b/code/game/objects/items/weapons/storage/bags.dm
@@ -520,7 +520,10 @@
storage_slots = 50
max_combined_w_class = 200
w_class = WEIGHT_CLASS_TINY
- can_hold = list(/obj/item/reagent_containers/food/pill,/obj/item/reagent_containers/glass/beaker,/obj/item/reagent_containers/glass/bottle)
+ can_hold = list(/obj/item/reagent_containers/pill,
+ /obj/item/reagent_containers/patch,
+ /obj/item/reagent_containers/glass/beaker,
+ /obj/item/reagent_containers/glass/bottle)
resistance_flags = FLAMMABLE
/*
* Biowaste bag (mostly for xenobiologists)
diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm
index 1e2dc9bff031..e71d266c3d27 100644
--- a/code/game/objects/items/weapons/storage/belt.dm
+++ b/code/game/objects/items/weapons/storage/belt.dm
@@ -175,7 +175,7 @@
/obj/item/reagent_containers/dropper,
/obj/item/reagent_containers/glass/beaker,
/obj/item/reagent_containers/glass/bottle,
- /obj/item/reagent_containers/food/pill,
+ /obj/item/reagent_containers/pill,
/obj/item/reagent_containers/syringe,
/obj/item/lighter/zippo,
/obj/item/storage/fancy/cigarettes,
@@ -227,13 +227,13 @@
update_icon()
/obj/item/storage/belt/medical/response_team/populate_contents()
- new /obj/item/reagent_containers/food/pill/salbutamol(src)
- new /obj/item/reagent_containers/food/pill/salbutamol(src)
- new /obj/item/reagent_containers/food/pill/charcoal(src)
- new /obj/item/reagent_containers/food/pill/charcoal(src)
- new /obj/item/reagent_containers/food/pill/salicylic(src)
- new /obj/item/reagent_containers/food/pill/salicylic(src)
- new /obj/item/reagent_containers/food/pill/salicylic(src)
+ new /obj/item/reagent_containers/pill/salbutamol(src)
+ new /obj/item/reagent_containers/pill/salbutamol(src)
+ new /obj/item/reagent_containers/pill/charcoal(src)
+ new /obj/item/reagent_containers/pill/charcoal(src)
+ new /obj/item/reagent_containers/pill/salicylic(src)
+ new /obj/item/reagent_containers/pill/salicylic(src)
+ new /obj/item/reagent_containers/pill/salicylic(src)
update_icon()
/obj/item/storage/belt/botany
@@ -926,7 +926,7 @@
/obj/item/storage/bag/ore,
/obj/item/survivalcapsule,
/obj/item/t_scanner/adv_mining_scanner,
- /obj/item/reagent_containers/food/pill,
+ /obj/item/reagent_containers/pill,
/obj/item/storage/pill_bottle,
/obj/item/stack/ore,
/obj/item/reagent_containers/food/drinks,
diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm
index 4397e08b6617..52e11f4a208f 100644
--- a/code/game/objects/items/weapons/storage/boxes.dm
+++ b/code/game/objects/items/weapons/storage/boxes.dm
@@ -92,7 +92,7 @@
new /obj/item/tank/internals/emergency_oxygen/engi/syndi(src)
new /obj/item/crowbar/small(src)
new /obj/item/reagent_containers/hypospray/autoinjector/epinephrine(src)
- new /obj/item/reagent_containers/food/pill/initropidril(src)
+ new /obj/item/reagent_containers/pill/initropidril(src)
new /obj/item/flashlight/flare/glowstick/red(src)
/obj/item/storage/box/gloves
@@ -839,7 +839,7 @@
new /obj/item/flashlight/flare(src)
new /obj/item/kitchen/knife/combat(src)
new /obj/item/radio/centcom(src)
- new /obj/item/reagent_containers/food/pill/patch/synthflesh(src)
+ new /obj/item/reagent_containers/patch/synthflesh(src)
new /obj/item/reagent_containers/hypospray/autoinjector/epinephrine(src)
/obj/item/storage/box/deathsquad
@@ -850,7 +850,7 @@
new /obj/item/flashlight/flare(src)
new /obj/item/crowbar/small(src)
new /obj/item/kitchen/knife/combat(src)
- new /obj/item/reagent_containers/food/pill/patch/synthflesh(src)
+ new /obj/item/reagent_containers/patch/synthflesh(src)
new /obj/item/reagent_containers/hypospray/autoinjector/survival(src)
new /obj/item/ammo_box/a357(src)
new /obj/item/ammo_box/a357(src)
@@ -867,8 +867,8 @@
new /obj/item/flashlight/flare(src)
new /obj/item/crowbar/red(src)
new /obj/item/kitchen/knife/combat(src)
- new /obj/item/reagent_containers/food/pill/patch/synthflesh(src)
- new /obj/item/reagent_containers/food/pill/patch/synthflesh(src)
+ new /obj/item/reagent_containers/patch/synthflesh(src)
+ new /obj/item/reagent_containers/patch/synthflesh(src)
/obj/item/storage/box/clown
name = "clown box"
diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm
index 23cb103c9f6e..92d06d52b92b 100644
--- a/code/game/objects/items/weapons/storage/firstaid.dm
+++ b/code/game/objects/items/weapons/storage/firstaid.dm
@@ -38,10 +38,10 @@
/obj/item/storage/firstaid/fire/populate_contents()
new /obj/item/reagent_containers/applicator/burn(src)
- new /obj/item/reagent_containers/food/pill/patch/silver_sulf/small(src)
+ new /obj/item/reagent_containers/patch/silver_sulf/small(src)
new /obj/item/healthanalyzer(src)
new /obj/item/reagent_containers/hypospray/autoinjector/epinephrine(src)
- new /obj/item/reagent_containers/food/pill/salicylic(src)
+ new /obj/item/reagent_containers/pill/salicylic(src)
/obj/item/storage/firstaid/fire/empty/populate_contents()
return
@@ -51,11 +51,11 @@
icon_state = "firstaid"
/obj/item/storage/firstaid/regular/populate_contents()
- new /obj/item/reagent_containers/food/pill/patch/styptic(src)
- new /obj/item/reagent_containers/food/pill/patch/styptic(src)
- new /obj/item/reagent_containers/food/pill/salicylic(src)
- new /obj/item/reagent_containers/food/pill/patch/silver_sulf(src)
- new /obj/item/reagent_containers/food/pill/patch/silver_sulf(src)
+ new /obj/item/reagent_containers/patch/styptic(src)
+ new /obj/item/reagent_containers/patch/styptic(src)
+ new /obj/item/reagent_containers/pill/salicylic(src)
+ new /obj/item/reagent_containers/patch/silver_sulf(src)
+ new /obj/item/reagent_containers/patch/silver_sulf(src)
new /obj/item/healthanalyzer(src)
new /obj/item/reagent_containers/hypospray/autoinjector/epinephrine(src)
@@ -69,9 +69,9 @@
/obj/item/storage/firstaid/doctor/populate_contents()
new /obj/item/reagent_containers/applicator/brute(src)
new /obj/item/reagent_containers/applicator/burn(src)
- new /obj/item/reagent_containers/food/pill/patch/styptic(src)
- new /obj/item/reagent_containers/food/pill/patch/silver_sulf(src)
- new /obj/item/reagent_containers/food/pill/salicylic(src)
+ new /obj/item/reagent_containers/patch/styptic(src)
+ new /obj/item/reagent_containers/patch/silver_sulf(src)
+ new /obj/item/reagent_containers/pill/salicylic(src)
new /obj/item/healthanalyzer/advanced(src)
new /obj/item/reagent_containers/hypospray/autoinjector/epinephrine(src)
@@ -89,7 +89,7 @@
/obj/item/storage/firstaid/toxin/populate_contents()
for(var/I in 1 to 3)
new /obj/item/reagent_containers/syringe/charcoal(src)
- new /obj/item/reagent_containers/food/pill/charcoal(src)
+ new /obj/item/reagent_containers/pill/charcoal(src)
new /obj/item/healthanalyzer(src)
/obj/item/storage/firstaid/toxin/empty/populate_contents()
@@ -103,10 +103,10 @@
med_bot_skin = "o2"
/obj/item/storage/firstaid/o2/populate_contents()
- new /obj/item/reagent_containers/food/pill/salbutamol(src)
- new /obj/item/reagent_containers/food/pill/salbutamol(src)
- new /obj/item/reagent_containers/food/pill/salbutamol(src)
- new /obj/item/reagent_containers/food/pill/salbutamol(src)
+ new /obj/item/reagent_containers/pill/salbutamol(src)
+ new /obj/item/reagent_containers/pill/salbutamol(src)
+ new /obj/item/reagent_containers/pill/salbutamol(src)
+ new /obj/item/reagent_containers/pill/salbutamol(src)
new /obj/item/healthanalyzer(src)
/obj/item/storage/firstaid/o2/empty/populate_contents()
@@ -125,7 +125,7 @@
/obj/item/storage/firstaid/brute/populate_contents()
new /obj/item/reagent_containers/applicator/brute(src)
- new /obj/item/reagent_containers/food/pill/patch/styptic/small(src)
+ new /obj/item/reagent_containers/patch/styptic/small(src)
new /obj/item/healthanalyzer(src)
new /obj/item/reagent_containers/hypospray/autoinjector/epinephrine(src)
new /obj/item/stack/medical/bruise_pack(src)
@@ -257,8 +257,8 @@
belt_icon = "pill_bottle"
use_sound = "pillbottle"
w_class = WEIGHT_CLASS_SMALL
- can_hold = list(/obj/item/reagent_containers/food/pill)
- cant_hold = list(/obj/item/reagent_containers/food/pill/patch)
+ can_hold = list(/obj/item/reagent_containers/pill)
+ cant_hold = list(/obj/item/reagent_containers/patch)
allow_quick_gather = TRUE
use_to_pickup = TRUE
storage_slots = 50
@@ -295,7 +295,7 @@
to_chat(user, "You are already applying meds.")
return
applying_meds = TRUE
- for(var/obj/item/reagent_containers/food/pill/P in contents)
+ for(var/obj/item/reagent_containers/pill/P in contents)
if(P.attack(M, user))
applying_meds = FALSE
else
@@ -309,31 +309,31 @@
/obj/item/storage/pill_bottle/ert_red/populate_contents()
for(var/I in 1 to 6)
- new /obj/item/reagent_containers/food/pill/pentetic(src)
- new /obj/item/reagent_containers/food/pill/ironsaline(src)
- new /obj/item/reagent_containers/food/pill/salicylic(src)
- new /obj/item/reagent_containers/food/pill/mannitol(src)
+ new /obj/item/reagent_containers/pill/pentetic(src)
+ new /obj/item/reagent_containers/pill/ironsaline(src)
+ new /obj/item/reagent_containers/pill/salicylic(src)
+ new /obj/item/reagent_containers/pill/mannitol(src)
/obj/item/storage/pill_bottle/ert_amber
wrapper_color = COLOR_ORANGE
/obj/item/storage/pill_bottle/ert_amber/populate_contents()
for(var/I in 1 to 6)
- new /obj/item/reagent_containers/food/pill/salbutamol(src)
- new /obj/item/reagent_containers/food/pill/charcoal(src)
- new /obj/item/reagent_containers/food/pill/salicylic(src)
+ new /obj/item/reagent_containers/pill/salbutamol(src)
+ new /obj/item/reagent_containers/pill/charcoal(src)
+ new /obj/item/reagent_containers/pill/salicylic(src)
/obj/item/storage/pill_bottle/ert_gamma
wrapper_color = COLOR_YELLOW_GRAY
/obj/item/storage/pill_bottle/ert_gamma/populate_contents()
for(var/I in 1 to 6)
- new /obj/item/reagent_containers/food/pill/pentetic(src)
- new /obj/item/reagent_containers/food/pill/ironsaline(src)
- new /obj/item/reagent_containers/food/pill/hydrocodone(src)
- new /obj/item/reagent_containers/food/pill/mannitol(src)
- new /obj/item/reagent_containers/food/pill/lazarus_reagent(src)
- new /obj/item/reagent_containers/food/pill/rezadone(src)
+ new /obj/item/reagent_containers/pill/pentetic(src)
+ new /obj/item/reagent_containers/pill/ironsaline(src)
+ new /obj/item/reagent_containers/pill/hydrocodone(src)
+ new /obj/item/reagent_containers/pill/mannitol(src)
+ new /obj/item/reagent_containers/pill/lazarus_reagent(src)
+ new /obj/item/reagent_containers/pill/rezadone(src)
/obj/item/storage/pill_bottle/MouseDrop(obj/over_object) // Best utilized if you're a cantankerous doctor with a Vicodin habit.
if(iscarbon(over_object))
@@ -344,7 +344,7 @@
return
C.visible_message("[C] [rapid_intake_message]")
if(do_mob(C, C, 100)) // 10 seconds
- for(var/obj/item/reagent_containers/food/pill/P in contents)
+ for(var/obj/item/reagent_containers/pill/P in contents)
P.attack(C, C)
C.visible_message("[C] [rapid_post_instake_message]")
return
@@ -363,7 +363,7 @@
icon_state = "patch_pack"
belt_icon = "patch_pack"
use_sound = "patchpack"
- can_hold = list(/obj/item/reagent_containers/food/pill/patch)
+ can_hold = list(/obj/item/reagent_containers/patch)
cant_hold = list()
rapid_intake_message = "flips the lid of the patch pack open and begins rapidly stamping patches on themselves!"
rapid_post_instake_message = "stamps the entire contents of the patch pack all over their entire body!"
@@ -376,7 +376,7 @@
/obj/item/storage/pill_bottle/charcoal/populate_contents()
for(var/I in 1 to 7)
- new /obj/item/reagent_containers/food/pill/charcoal(src)
+ new /obj/item/reagent_containers/pill/charcoal(src)
/obj/item/storage/pill_bottle/painkillers
name = "Pill Bottle (Salicylic Acid)"
@@ -385,15 +385,15 @@
/obj/item/storage/pill_bottle/painkillers/populate_contents()
for(var/I in 1 to 8)
- new /obj/item/reagent_containers/food/pill/salicylic(src)
+ new /obj/item/reagent_containers/pill/salicylic(src)
/obj/item/storage/pill_bottle/fakedeath
allow_wrap = FALSE
/obj/item/storage/pill_bottle/fakedeath/populate_contents()
- new /obj/item/reagent_containers/food/pill/fakedeath(src)
- new /obj/item/reagent_containers/food/pill/fakedeath(src)
- new /obj/item/reagent_containers/food/pill/fakedeath(src)
+ new /obj/item/reagent_containers/pill/fakedeath(src)
+ new /obj/item/reagent_containers/pill/fakedeath(src)
+ new /obj/item/reagent_containers/pill/fakedeath(src)
/obj/item/storage/pill_bottle/patch_pack/ert
name = "ert red patch pack"
@@ -402,9 +402,9 @@
/obj/item/storage/pill_bottle/patch_pack/ert/populate_contents()
for(var/I in 1 to 5)
- new /obj/item/reagent_containers/food/pill/patch/perfluorodecalin(src)
- new /obj/item/reagent_containers/food/pill/patch/silver_sulf(src)
- new /obj/item/reagent_containers/food/pill/patch/styptic(src)
+ new /obj/item/reagent_containers/patch/perfluorodecalin(src)
+ new /obj/item/reagent_containers/patch/silver_sulf(src)
+ new /obj/item/reagent_containers/patch/styptic(src)
/obj/item/storage/pill_bottle/patch_pack/ert/gamma
name = "ert gamma patch pack"
@@ -418,5 +418,5 @@
/obj/item/storage/pill_bottle/patch_pack/ert_amber/populate_contents()
for(var/I in 1 to 5)
- new /obj/item/reagent_containers/food/pill/patch/silver_sulf/small(src)
- new /obj/item/reagent_containers/food/pill/patch/styptic/small(src)
+ new /obj/item/reagent_containers/patch/silver_sulf/small(src)
+ new /obj/item/reagent_containers/patch/styptic/small(src)
diff --git a/code/game/objects/items/weapons/storage/garment.dm b/code/game/objects/items/weapons/storage/garment.dm
index 5a3bec68e747..d3c5ea44ef64 100644
--- a/code/game/objects/items/weapons/storage/garment.dm
+++ b/code/game/objects/items/weapons/storage/garment.dm
@@ -183,7 +183,7 @@
new /obj/item/clothing/shoes/jackboots/jacksandals(src)
new /obj/item/clothing/mask/gas/sechailer(src)
new /obj/item/clothing/glasses/sunglasses(src)
- new /obj/item/clothing/glasses/hud/security/sunglasses/read_only(src)
+ new /obj/item/clothing/glasses/hud/security/sunglasses(src)
new /obj/item/clothing/glasses/hud/health/sunglasses(src)
new /obj/item/clothing/glasses/hud/skills/sunglasses(src)
new /obj/item/clothing/accessory/blue(src)
diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm
index 6562a14ea26d..4b81c4ad8183 100644
--- a/code/game/objects/items/weapons/storage/uplink_kits.dm
+++ b/code/game/objects/items/weapons/storage/uplink_kits.dm
@@ -132,14 +132,14 @@
/obj/item/gun/projectile/automatic/pistol, // 4TC
/obj/item/ammo_box/magazine/m10mm/fire, // 2TC
/obj/item/ammo_box/magazine/m10mm/fire, // 2TC
- /obj/item/storage/box/syndie_kit/modsuit, // 6TC
+ /obj/item/mod/control/pre_equipped/traitor, // 6TC
/obj/item/clothing/gloves/combat, // 0TC
/obj/item/card/id/syndicate, // 2TC
/obj/item/clothing/shoes/chameleon/noslip, // 2TC
/obj/item/encryptionkey/syndicate) // 2TC
var/static/list/metroid = list( // 21 + modules + laser gun
- /obj/item/storage/box/syndie_kit/modsuit/elite, // 9TC
+ /obj/item/mod/control/pre_equipped/traitor_elite, // 9TC
/obj/item/mod/module/visor/thermal, // 3 TC
/obj/item/mod/module/stealth, //0 TC but strong
/obj/item/mod/module/power_kick, //0 TC but funny
@@ -169,24 +169,6 @@
new /obj/item/clothing/mask/gas/syndicate(src)
new /obj/item/tank/internals/emergency_oxygen/engi/syndi(src)
-/obj/item/storage/box/syndie_kit/modsuit
- name = "Boxed Blood Red MODsuit"
- can_hold = list(/obj/item/tank/internals/emergency_oxygen/engi/syndi, /obj/item/clothing/mask/gas/syndicate)
- max_w_class = WEIGHT_CLASS_NORMAL
-
-/obj/item/storage/box/syndie_kit/modsuit/populate_contents()
- new /obj/item/mod/control/pre_equipped/traitor(src)
- new /obj/item/clothing/mask/gas/syndicate(src)
- new /obj/item/tank/internals/emergency_oxygen/engi/syndi(src)
-
-/obj/item/storage/box/syndie_kit/modsuit/elite //I have been informed this is a good idea.
- name = "Boxed Elite MODsuit"
-
-/obj/item/storage/box/syndie_kit/modsuit/elite/populate_contents()
- new /obj/item/mod/control/pre_equipped/traitor_elite(src)
- new /obj/item/clothing/mask/gas/syndicate(src)
- new /obj/item/tank/internals/emergency_oxygen/engi/syndi(src)
-
/obj/item/storage/box/syndie_kit/conversion
name = "box (CK)"
@@ -282,6 +264,9 @@
new /obj/item/spellbook/oneuse/mime/greaterwall(src)
new /obj/item/spellbook/oneuse/mime/fingergun(src)
+/obj/item/storage/box/syndie_kit/combat_baking
+ name = "combat bakery kit"
+
/obj/item/storage/box/syndie_kit/combat_baking/populate_contents()
new /obj/item/reagent_containers/food/snacks/baguette/combat(src)
for(var/i in 1 to 2)
@@ -325,25 +310,6 @@
new/obj/item/cardboard_cutout/adaptive(src)
new/obj/item/toy/crayon/spraycan(src)
-/obj/item/storage/box/syndie_kit/bonerepair
- name = "emergency nanite kit"
- desc = "A box containing one prototype nanite repair system."
-
-/obj/item/storage/box/syndie_kit/bonerepair/populate_contents()
- new /obj/item/reagent_containers/hypospray/autoinjector/nanocalcium(src)
- var/obj/item/paper/P = new /obj/item/paper(src)
- P.name = "Prototype nanite repair guide"
- P.desc = "For when you want to safely get off Mr Bones' Wild Ride."
- P.info = {"
-
Prototype Emergency Repair Nanites
-
-Usage:
-
-This is a highly experimental prototype chemical designed to repair damaged bones, organs, and treat interenal bleeding of soldiers in the field, use only as a last resort. The autoinjector contains prototype nanites bearing a classifed payload. The nanites will simultaneously shut down body systems whilst aiding in repair.
Warning: Side effects can cause temporary paralysis, loss of co-ordination and sickness. Do not use with any kind of stimulant or drugs. Serious damage can occur!
-
-To apply, hold the injector a short distance away from the outer thigh before applying firmly to the skin surface. The process of repairing should begin after a short time, during which you are advised to remain still.
After use you are advised to see a doctor at the next available opportunity. Mild scarring and tissue damage may occur after use. This is a prototype. We are not liable for any bone spurs, cancers, extra limbs, or creation of new viruses from use of the product.
- "}
-
/obj/item/storage/box/syndie_kit/safecracking
name = "Safe-cracking Kit"
desc = "Everything you need to quietly open a mechanical combination safe."
diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm
index 23742229ad17..511765091187 100644
--- a/code/game/objects/items/weapons/stunbaton.dm
+++ b/code/game/objects/items/weapons/stunbaton.dm
@@ -1,6 +1,7 @@
/obj/item/melee/baton
name = "stunbaton"
desc = "A stun baton for incapacitating people with."
+ icon = 'icons/obj/baton.dmi'
icon_state = "stunbaton"
var/base_icon = "stunbaton"
item_state = null
@@ -251,15 +252,13 @@
L.SetStuttering(4 SECONDS)
ADD_TRAIT(L, TRAIT_WAS_BATONNED, user_UID) // so one person cannot hit the same person with two separate batons
- L.apply_status_effect(STATUS_EFFECT_DELAYED, 2 SECONDS, CALLBACK(L, TYPE_PROC_REF(/mob/living, KnockDown), knockdown_duration), COMSIG_LIVING_CLEAR_STUNS)
addtimer(CALLBACK(src, PROC_REF(baton_delay), L, user_UID), 2 SECONDS)
SEND_SIGNAL(L, COMSIG_LIVING_MINOR_SHOCK, 33)
L.lastattacker = user.real_name
L.lastattackerckey = user.ckey
- L.visible_message("[user] has stunned [L] with [src]!",
- "[L == user ? "You stun yourself" : "[user] has stunned you"] with [src]!")
+ L.visible_message("[src] stuns [L]!")
add_attack_logs(user, L, "stunned")
playsound(src, 'sound/weapons/egloves.ogg', 50, TRUE, -1)
deductcharge(hitcost)
diff --git a/code/game/objects/items/weapons/tanks/watertank.dm b/code/game/objects/items/weapons/tanks/watertank.dm
index a613ef07428b..e456bfa2f73a 100644
--- a/code/game/objects/items/weapons/tanks/watertank.dm
+++ b/code/game/objects/items/weapons/tanks/watertank.dm
@@ -75,9 +75,9 @@
QDEL_NULL(noz)
return ..()
-/obj/item/watertank/attack_hand(mob/user as mob)
- if(src.loc == user)
- ui_action_click()
+/obj/item/watertank/attack_hand(mob/user)
+ if(loc == user)
+ toggle_mister(user)
return
..()
diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm
index f4e1ffcc2b8b..1660d8a80136 100644
--- a/code/game/objects/items/weapons/twohanded.dm
+++ b/code/game/objects/items/weapons/twohanded.dm
@@ -96,6 +96,7 @@
/obj/item/dualsaber
name = "double-bladed energy sword"
desc = "Handle with care."
+ icon = 'icons/obj/energy_melee.dmi'
lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons_righthand.dmi'
icon_state = "dualsaber0"
@@ -229,9 +230,13 @@
//spears
/obj/item/spear
- icon_state = "spearglass0"
name = "spear"
desc = "A haphazardly-constructed yet still deadly weapon of ancient design."
+ icon = 'icons/obj/spear.dmi'
+ base_icon_state = "spearglass"
+ icon_state = "spearglass0"
+ lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/weapons_righthand.dmi'
force = 10
w_class = WEIGHT_CLASS_BULKY
slot_flags = SLOT_FLAG_BACK
@@ -249,9 +254,6 @@
max_integrity = 200
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 50, ACID = 30)
needs_permit = TRUE
- lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons_righthand.dmi'
- base_icon_state = "spearglass"
/obj/item/spear/Initialize(mapload)
. = ..()
@@ -749,10 +751,7 @@
STOP_PROCESSING(SSobj, src)
return ..()
-/obj/item/pyro_claws/customised_abstract_text()
- if(!ishuman(loc))
- return
- var/mob/living/carbon/human/owner = loc
+/obj/item/pyro_claws/customised_abstract_text(mob/living/carbon/owner)
return "[owner.p_they(TRUE)] [owner.p_have(FALSE)] energy claws extending [owner.p_their(FALSE)] wrists."
/obj/item/pyro_claws/process()
diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm
index 6667e4ad4dab..e7ccfb48c2b6 100644
--- a/code/game/objects/items/weapons/weaponry.dm
+++ b/code/game/objects/items/weapons/weaponry.dm
@@ -4,7 +4,7 @@
/obj/item/banhammer
desc = "A banhammer"
name = "banhammer"
- icon = 'icons/obj/items.dmi'
+ icon = 'icons/obj/toy.dmi'
icon_state = "toyhammer"
slot_flags = SLOT_FLAG_BELT
throwforce = 0
diff --git a/code/game/objects/mail.dm b/code/game/objects/mail.dm
index 993a07b82e4e..13f6601ecb7f 100644
--- a/code/game/objects/mail.dm
+++ b/code/game/objects/mail.dm
@@ -155,7 +155,7 @@
/obj/item/toy/figure/crew/janitor,
/obj/item/toy/figure/crew/librarian,
/obj/item/storage/box/scratch_cards)
- job_list = list("Bartender", "Chef", "Botanist", "Janitor", "Barber", "Librarian", "Barber")
+ job_list = list("Bartender", "Chef", "Botanist", "Janitor", "Librarian")
/obj/item/envelope/circuses
icon_state = "mail_serv"
@@ -181,7 +181,7 @@
/obj/item/storage/fancy/cigarettes/cigpack_robustgold,
/obj/item/poster/random_official,
/obj/item/book/manual/wiki/sop_command,
- /obj/item/reagent_containers/food/pill/patch/synthflesh,
+ /obj/item/reagent_containers/patch/synthflesh,
/obj/item/paper_bin/nanotrasen,
/obj/item/reagent_containers/food/snacks/spesslaw,
/obj/item/clothing/head/collectable/petehat,
diff --git a/code/game/objects/structures/barsign.dm b/code/game/objects/structures/barsign.dm
index fdab17f2d501..039698d630ab 100644
--- a/code/game/objects/structures/barsign.dm
+++ b/code/game/objects/structures/barsign.dm
@@ -142,7 +142,7 @@
req_access = list(ACCESS_SYNDICATE)
/obj/structure/sign/barsign/proc/pick_sign()
- var/picked_name = input("Available Signage", "Bar Sign") as null|anything in barsigns
+ var/picked_name = tgui_input_list(usr, "Available Signage", "Bar Sign", barsigns)
if(!picked_name)
return
set_sign(picked_name)
diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm
index a8b7a6ca9073..afef1b023e01 100644
--- a/code/game/objects/structures/bedsheet_bin.dm
+++ b/code/game/objects/structures/bedsheet_bin.dm
@@ -7,7 +7,7 @@ LINEN BINS
/obj/item/bedsheet
name = "bedsheet"
desc = "A surprisingly soft linen bedsheet."
- icon = 'icons/obj/items.dmi'
+ icon = 'icons/obj/bedsheet.dmi'
icon_state = "sheet"
item_state = "bedsheet"
lefthand_file = 'icons/mob/inhands/bedsheet_lefthand.dmi'
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index ffd73efa8836..bb2e6da5fef2 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -388,6 +388,7 @@
return ..()
+
/obj/structure/closet/bluespace
name = "bluespace closet"
desc = "A storage unit that moves and stores through the fourth dimension."
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical_lockers.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical_lockers.dm
index 65b4cb3b9084..7ef37f41ed32 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/medical_lockers.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/medical_lockers.dm
@@ -97,25 +97,25 @@
// Why the hell is this in the closets folder?
/obj/item/storage/pill_bottle/psychiatrist/populate_contents()
- new /obj/item/reagent_containers/food/pill/haloperidol(src)
- new /obj/item/reagent_containers/food/pill/haloperidol(src)
- new /obj/item/reagent_containers/food/pill/haloperidol(src)
- new /obj/item/reagent_containers/food/pill/methamphetamine(src)
- new /obj/item/reagent_containers/food/pill/methamphetamine(src)
- new /obj/item/reagent_containers/food/pill/methamphetamine(src)
- new /obj/item/reagent_containers/food/pill/happy_psych(src)
- new /obj/item/reagent_containers/food/pill/happy_psych(src)
- new /obj/item/reagent_containers/food/pill/happy_psych(src)
- new /obj/item/reagent_containers/food/pill/patch/nicotine(src)
- new /obj/item/reagent_containers/food/pill/patch/nicotine(src)
- new /obj/item/reagent_containers/food/pill/patch/nicotine(src)
- new /obj/item/reagent_containers/food/pill/hydrocodone(src)
- new /obj/item/reagent_containers/food/pill/hydrocodone(src)
- new /obj/item/reagent_containers/food/pill/mannitol(src)
- new /obj/item/reagent_containers/food/pill/mannitol(src)
- new /obj/item/reagent_containers/food/pill/mannitol(src)
- new /obj/item/reagent_containers/food/pill/mannitol(src)
- new /obj/item/reagent_containers/food/pill/mannitol(src)
+ new /obj/item/reagent_containers/pill/haloperidol(src)
+ new /obj/item/reagent_containers/pill/haloperidol(src)
+ new /obj/item/reagent_containers/pill/haloperidol(src)
+ new /obj/item/reagent_containers/pill/methamphetamine(src)
+ new /obj/item/reagent_containers/pill/methamphetamine(src)
+ new /obj/item/reagent_containers/pill/methamphetamine(src)
+ new /obj/item/reagent_containers/pill/happy_psych(src)
+ new /obj/item/reagent_containers/pill/happy_psych(src)
+ new /obj/item/reagent_containers/pill/happy_psych(src)
+ new /obj/item/reagent_containers/patch/nicotine(src)
+ new /obj/item/reagent_containers/patch/nicotine(src)
+ new /obj/item/reagent_containers/patch/nicotine(src)
+ new /obj/item/reagent_containers/pill/hydrocodone(src)
+ new /obj/item/reagent_containers/pill/hydrocodone(src)
+ new /obj/item/reagent_containers/pill/mannitol(src)
+ new /obj/item/reagent_containers/pill/mannitol(src)
+ new /obj/item/reagent_containers/pill/mannitol(src)
+ new /obj/item/reagent_containers/pill/mannitol(src)
+ new /obj/item/reagent_containers/pill/mannitol(src)
/obj/structure/closet/secure_closet/psychiatrist
name = "psychiatrist's locker"
diff --git a/code/game/objects/structures/reflector.dm b/code/game/objects/structures/reflector.dm
index 7177cc6937ba..9d58f51557ba 100644
--- a/code/game/objects/structures/reflector.dm
+++ b/code/game/objects/structures/reflector.dm
@@ -7,6 +7,8 @@
density = TRUE
layer = 3
var/finished = FALSE
+ var/obj/item/stack/sheet/build_stack_type
+ var/build_stack_amount
/obj/structure/reflector/bullet_act(obj/item/projectile/P)
@@ -47,7 +49,7 @@
return
else
S.use(5)
- new /obj/structure/reflector/single (src.loc)
+ new /obj/structure/reflector/single(loc)
qdel(src)
if(istype(W,/obj/item/stack/sheet/rglass))
if(S.get_amount() < 10)
@@ -55,12 +57,12 @@
return
else
S.use(10)
- new /obj/structure/reflector/double (src.loc)
+ new /obj/structure/reflector/double(loc)
qdel(src)
if(istype(W, /obj/item/stack/sheet/mineral/diamond))
if(S.get_amount() >= 1)
S.use(1)
- new /obj/structure/reflector/box (src.loc)
+ new /obj/structure/reflector/box(loc)
qdel(src)
return
return ..()
@@ -77,7 +79,9 @@
return
playsound(user, 'sound/items/Ratchet.ogg', 50, 1)
TOOL_DISMANTLE_SUCCESS_MESSAGE
- new /obj/item/stack/sheet/metal(src.loc, 5)
+ new /obj/item/stack/sheet/metal(loc, 5)
+ if(build_stack_type)
+ new build_stack_type(loc, build_stack_amount)
qdel(src)
/obj/structure/reflector/welder_act(mob/user, obj/item/I)
@@ -120,6 +124,8 @@
icon_state = "reflector"
desc = "A double sided angled mirror for reflecting lasers. This one does so at a 90 degree angle."
finished = TRUE
+ build_stack_type = /obj/item/stack/sheet/glass
+ build_stack_amount = 5
var/static/list/rotations = list("[NORTH]" = list("[SOUTH]" = WEST, "[EAST]" = NORTH),
"[EAST]" = list("[SOUTH]" = EAST, "[WEST]" = NORTH),
"[SOUTH]" = list("[NORTH]" = EAST, "[WEST]" = SOUTH),
@@ -137,6 +143,8 @@
icon_state = "reflector_double"
desc = "A double sided angled mirror for reflecting lasers. This one does so at a 90 degree angle."
finished = TRUE
+ build_stack_type = /obj/item/stack/sheet/rglass
+ build_stack_amount = 10
var/static/list/double_rotations = list("[NORTH]" = list("[NORTH]" = WEST, "[EAST]" = SOUTH, "[SOUTH]" = EAST, "[WEST]" = NORTH),
"[EAST]" = list("[NORTH]" = EAST, "[WEST]" = SOUTH, "[SOUTH]" = WEST, "[EAST]" = NORTH),
"[SOUTH]" = list("[NORTH]" = EAST, "[WEST]" = SOUTH, "[SOUTH]" = WEST, "[EAST]" = NORTH),
@@ -154,6 +162,8 @@
icon_state = "reflector_box"
desc = "A box with an internal set of mirrors that reflects all laser fire in a single direction."
finished = TRUE
+ build_stack_type = /obj/item/stack/sheet/mineral/diamond
+ build_stack_amount = 1
var/static/list/box_rotations = list("[NORTH]" = list("[SOUTH]" = NORTH, "[EAST]" = NORTH, "[WEST]" = NORTH, "[NORTH]" = NORTH),
"[EAST]" = list("[SOUTH]" = EAST, "[EAST]" = EAST, "[WEST]" = EAST, "[NORTH]" = EAST),
"[SOUTH]" = list("[SOUTH]" = SOUTH, "[EAST]" = SOUTH, "[WEST]" = SOUTH, "[NORTH]" = SOUTH),
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index 5c1c3f7074fa..fce002c46a56 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -401,7 +401,6 @@
return 1
-
/obj/structure/table/water_act(volume, temperature, source, method)
. = ..()
if(HAS_TRAIT(src, TRAIT_OIL_SLICKED))
@@ -409,7 +408,6 @@
remove_atom_colour(FIXED_COLOUR_PRIORITY)
REMOVE_TRAIT(src, TRAIT_OIL_SLICKED, "potion")
-
/*
* Glass Tables
*/
diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm
index af6bead91896..825e9c771e96 100644
--- a/code/game/verbs/ooc.dm
+++ b/code/game/verbs/ooc.dm
@@ -215,6 +215,10 @@ GLOBAL_VAR_INIT(admin_ooc_colour, "#b82e00")
log_looc(msg, src)
mob.create_log(LOOC_LOG, msg)
+ if(isliving(mob))
+ for(var/mob/M in viewers(7, mob))
+ if(M.client?.prefs.toggles2 & PREFTOGGLE_2_RUNECHAT)
+ M.create_chat_message(mob, msg, FALSE, symbol = RUNECHAT_SYMBOL_LOOC)
var/mob/source = mob.get_looc_source()
var/list/heard = get_mobs_in_view(7, source)
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 3e00f46a0433..9bb9212f81d2 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -537,7 +537,7 @@ GLOBAL_LIST_INIT(view_runtimes_verbs, list(
var/turf/epicenter = mob.loc
var/list/choices = list("Small Bomb", "Medium Bomb", "Big Bomb", "Custom Bomb")
- var/choice = input("What size explosion would you like to produce?") as null|anything in choices
+ var/choice = tgui_input_list(src, "What size explosion would you like to produce?", "Drop Bomb", choices)
switch(choice)
if(null)
return 0
diff --git a/code/modules/admin/misc_admin_procs.dm b/code/modules/admin/misc_admin_procs.dm
index 1c4f6058ba41..f6ccc2931ab3 100644
--- a/code/modules/admin/misc_admin_procs.dm
+++ b/code/modules/admin/misc_admin_procs.dm
@@ -118,6 +118,8 @@ GLOBAL_VAR_INIT(nologevent, 0)
body += "Related accounts by IP: [jointext(M.client.related_accounts_ip, " - ")]
"
if(M.ckey)
+ body += "Enabled AntagHUD: [M.has_ahudded() ? "TRUE" : "false"] "
+ body += "Roundstart observer: [M.is_roundstart_observer() ? "true" : "false"] "
body += "Kick | "
body += "Ban | "
body += "Jobban | "
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index de30a0f3c0cb..605b1575d281 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -291,10 +291,10 @@
var/action=""
if(GLOB.configuration.general.allow_antag_hud)
+ GLOB.antag_hud_users.Cut()
for(var/mob/dead/observer/g in get_ghosts())
if(g.antagHUD)
g.antagHUD = FALSE // Disable it on those that have it enabled
- g.has_enabled_antagHUD = FALSE // We'll allow them to respawn
to_chat(g, "The Administrators have disabled AntagHUD ")
GLOB.configuration.general.allow_antag_hud = FALSE
to_chat(src, "AntagHUD usage has been disabled")
@@ -332,7 +332,7 @@
to_chat(g, "The administrator has placed restrictions on joining the round if you use AntagHUD")
to_chat(g, "Your AntagHUD has been disabled, you may choose to re-enabled it but will be under restrictions ")
g.antagHUD = FALSE
- g.has_enabled_antagHUD = FALSE
+ GLOB.antag_hud_users -= g.ckey
action = "placed restrictions"
GLOB.configuration.general.restrict_antag_hud_rejoin = TRUE
to_chat(src, "AntagHUD restrictions have been enabled")
diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm
index 4acb46abaa35..11b4ebbe98ef 100644
--- a/code/modules/antagonists/changeling/powers/mutations.dm
+++ b/code/modules/antagonists/changeling/powers/mutations.dm
@@ -161,10 +161,7 @@
var/obj/machinery/computer/C = target
C.attack_alien(user) //muh copypasta
-/obj/item/melee/arm_blade/customised_abstract_text()
- if(!ishuman(loc))
- return
- var/mob/living/carbon/human/owner = loc
+/obj/item/melee/arm_blade/customised_abstract_text(mob/living/carbon/owner)
return "[owner.p_their(TRUE)] [owner.l_hand == src ? "left arm" : "right arm"] has been turned into a grotesque meat-blade."
/***************************************\
@@ -209,10 +206,7 @@
throw_speed = 0
var/datum/action/changeling/weapon/parent_action
-/obj/item/gun/magic/tentacle/customised_abstract_text()
- if(!ishuman(loc))
- return
- var/mob/living/carbon/human/owner = loc
+/obj/item/gun/magic/tentacle/customised_abstract_text(mob/living/carbon/owner)
return "[owner.p_their(TRUE)] [owner.l_hand == src ? "left arm" : "right arm"] has been turned into a grotesque tentacle."
/obj/item/gun/magic/tentacle/Initialize(mapload, silent, new_parent_action)
diff --git a/code/modules/antagonists/vampire/vampire_powers/hemomancer_powers.dm b/code/modules/antagonists/vampire/vampire_powers/hemomancer_powers.dm
index 3e7121129e12..2fb0c1cbb32f 100644
--- a/code/modules/antagonists/vampire/vampire_powers/hemomancer_powers.dm
+++ b/code/modules/antagonists/vampire/vampire_powers/hemomancer_powers.dm
@@ -68,10 +68,7 @@
parent_spell = null
return ..()
-/obj/item/vamp_claws/customised_abstract_text()
- if(!ishuman(loc))
- return
- var/mob/living/carbon/human/owner = loc
+/obj/item/vamp_claws/customised_abstract_text(mob/living/carbon/owner)
return "[owner.p_they(TRUE)] [owner.p_have(FALSE)] bloodied claws extending from [owner.p_their(FALSE)] wrists."
/obj/item/vamp_claws/afterattack(atom/target, mob/user, proximity)
diff --git a/code/modules/atmospherics/machinery/portable/portable_pump.dm b/code/modules/atmospherics/machinery/portable/portable_pump.dm
index 9ec0f1461fd1..b4601e55aeac 100644
--- a/code/modules/atmospherics/machinery/portable/portable_pump.dm
+++ b/code/modules/atmospherics/machinery/portable/portable_pump.dm
@@ -167,10 +167,7 @@
return TRUE
if("remove_tank")
- if(holding_tank)
- on = FALSE
- holding_tank.forceMove(get_turf(src))
- holding_tank = null
+ replace_tank(ui.user, TRUE)
update_icon()
return TRUE
diff --git a/code/modules/atmospherics/machinery/portable/scrubber.dm b/code/modules/atmospherics/machinery/portable/scrubber.dm
index 9a798b8ef064..8b7a38cca7c0 100644
--- a/code/modules/atmospherics/machinery/portable/scrubber.dm
+++ b/code/modules/atmospherics/machinery/portable/scrubber.dm
@@ -151,9 +151,7 @@
return TRUE
if("remove_tank")
- if(holding_tank)
- holding_tank.forceMove(get_turf(src))
- holding_tank = null
+ replace_tank(ui.user, TRUE)
update_icon()
return TRUE
diff --git a/code/modules/awaymissions/mob_spawn.dm b/code/modules/awaymissions/mob_spawn.dm
index 1679d57f145c..ed30ed2b5ff7 100644
--- a/code/modules/awaymissions/mob_spawn.dm
+++ b/code/modules/awaymissions/mob_spawn.dm
@@ -82,9 +82,14 @@
if(jobban_isbanned(user, banType) || jobban_isbanned(user, ROLE_SYNDICATE))
to_chat(user, "You are jobanned!")
return FALSE
- if(cannotPossess(user))
- to_chat(user, "Upon using the antagHUD you forfeited the ability to join the round.")
+ if(!HAS_TRAIT(user, TRAIT_RESPAWNABLE))
+ to_chat(user, "You currently do not have respawnability!")
return FALSE
+ if(isobserver(user))
+ var/mob/dead/observer/O = user
+ if(!O.check_ahud_rejoin_eligibility())
+ to_chat(user, "Upon using the antagHUD you forfeited the ability to join the round.")
+ return FALSE
if(time_check(user))
return FALSE
return TRUE
@@ -570,7 +575,7 @@
shoes = /obj/item/clothing/shoes/workboots
l_ear = /obj/item/radio/headset/headset_cargo/mining
id = /obj/item/card/id/shaftminer
- l_pocket = /obj/item/reagent_containers/food/pill/patch/styptic
+ l_pocket = /obj/item/reagent_containers/patch/styptic
r_pocket = /obj/item/flashlight/seclite
//Scientist corpse.
diff --git a/code/modules/client/preference/loadout/loadout_shoes.dm b/code/modules/client/preference/loadout/loadout_shoes.dm
index 4fbd21d4e34f..6181e2120a7b 100644
--- a/code/modules/client/preference/loadout/loadout_shoes.dm
+++ b/code/modules/client/preference/loadout/loadout_shoes.dm
@@ -75,3 +75,31 @@
/datum/gear/shoes/whiteshoes
display_name = "White shoes"
path = /obj/item/clothing/shoes/white
+
+/datum/gear/shoes/leathershoes
+ display_name = "Leather shoes"
+ path = /obj/item/clothing/shoes/leather
+
+/datum/gear/shoes/redshoes
+ display_name = "Red shoes"
+ path = /obj/item/clothing/shoes/red
+
+/datum/gear/shoes/orangeshoes
+ display_name = "Orange shoes"
+ path = /obj/item/clothing/shoes/orange
+
+/datum/gear/shoes/yellowshoes
+ display_name = "Yellow shoes"
+ path = /obj/item/clothing/shoes/yellow
+
+/datum/gear/shoes/greenshoes
+ display_name = "Green shoes"
+ path = /obj/item/clothing/shoes/green
+
+/datum/gear/shoes/blueshoes
+ display_name = "Blue shoes"
+ path = /obj/item/clothing/shoes/blue
+
+/datum/gear/shoes/purpleshoes
+ display_name = "Purple shoes"
+ path = /obj/item/clothing/shoes/purple
diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm
index d044e9391162..1e31735ae2ea 100644
--- a/code/modules/clothing/chameleon.dm
+++ b/code/modules/clothing/chameleon.dm
@@ -329,6 +329,7 @@
prescription_upgradable = TRUE
/obj/item/clothing/glasses/hud/security/chameleon
+ examine_extensions = list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SECURITY_WRITE)
flash_protect = FLASH_PROTECTION_FLASH
var/datum/action/item_action/chameleon/change/chameleon_action
diff --git a/code/modules/clothing/glasses/hudglasses.dm b/code/modules/clothing/glasses/hudglasses.dm
index 34ac0fa8fce2..784eb833ba3c 100644
--- a/code/modules/clothing/glasses/hudglasses.dm
+++ b/code/modules/clothing/glasses/hudglasses.dm
@@ -41,7 +41,7 @@
icon_state = "healthhud"
origin_tech = "magnets=3;biotech=2"
hud_types = DATA_HUD_MEDICAL_ADVANCED
- examine_extensions = list(EXAMINE_HUD_MEDICAL)
+ examine_extensions = list(EXAMINE_HUD_MEDICAL_READ)
sprite_sheets = list(
"Vox" = 'icons/mob/clothing/species/vox/eyes.dmi',
@@ -105,7 +105,7 @@
origin_tech = "magnets=3;combat=2"
var/global/list/jobs[0]
hud_types = DATA_HUD_SECURITY_ADVANCED
- examine_extensions = list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SECURITY_WRITE)
+ examine_extensions = list(EXAMINE_HUD_SECURITY_READ)
sprite_sheets = list(
"Vox" = 'icons/mob/clothing/species/vox/eyes.dmi',
@@ -131,9 +131,6 @@
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE //don't render darkness while wearing these
-/obj/item/clothing/glasses/hud/security/sunglasses/read_only
- examine_extensions = list(EXAMINE_HUD_SECURITY_READ)
-
/obj/item/clothing/glasses/hud/security/sunglasses
name = "HUDSunglasses"
desc = "Sunglasses with a HUD."
diff --git a/code/modules/clothing/suits/job_suits.dm b/code/modules/clothing/suits/job_suits.dm
index 53b42f0e0b77..0984dc2c3478 100644
--- a/code/modules/clothing/suits/job_suits.dm
+++ b/code/modules/clothing/suits/job_suits.dm
@@ -348,5 +348,5 @@
desc = "A tweed mantle, worn by the Research Director. Smells like science."
icon_state = "rdmantle"
item_state = "rdmantle"
- allowed = list(/obj/item/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/reagent_containers/applicator, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/food/pill, /obj/item/storage/pill_bottle, /obj/item/paper)
+ allowed = list(/obj/item/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/reagent_containers/applicator, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper)
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 50, ACID = 50)
diff --git a/code/modules/clothing/suits/labcoat.dm b/code/modules/clothing/suits/labcoat.dm
index e6c574897b07..4c535d35c151 100644
--- a/code/modules/clothing/suits/labcoat.dm
+++ b/code/modules/clothing/suits/labcoat.dm
@@ -7,7 +7,7 @@
suit_adjusted = 1
blood_overlay_type = "coat"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
- allowed = list(/obj/item/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/reagent_containers/applicator, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/food/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/robotanalyzer)
+ allowed = list(/obj/item/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/reagent_containers/applicator, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/robotanalyzer)
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 50, ACID = 50)
species_exception = list(/datum/species/golem)
sprite_sheets = list(
diff --git a/code/modules/food_and_drinks/food_base.dm b/code/modules/food_and_drinks/food_base.dm
index b2dafb1a3d84..51bca61fe51c 100644
--- a/code/modules/food_and_drinks/food_base.dm
+++ b/code/modules/food_and_drinks/food_base.dm
@@ -4,22 +4,22 @@
/obj/item/reagent_containers/food
possible_transfer_amounts = null
visible_transfer_rate = FALSE
- volume = 50 //Sets the default container amount for all food items.
- var/filling_color = "#FFFFFF" //Used by sandwiches.
- var/junkiness = 0 //for junk food. used to lower human satiety.
+ volume = 50
+ /// Used by sandwiches
+ var/filling_color = "#FFFFFF"
+ /// Used by junk food to lower satiety
+ var/junkiness = 0
var/bitesize = 2
var/consume_sound = 'sound/items/eatfood.ogg'
- var/apply_type = REAGENT_INGEST
- var/apply_method = "swallow"
- var/transfer_efficiency = 1.0
- var/instant_application = 0 //if we want to bypass the forcedfeed delay
- var/can_taste = TRUE//whether you can taste eating from this
- var/antable = TRUE // Will ants come near it?
- /// location checked every 5 minutes. If its the same place, the food has a chance to spawn ants
+ /// Will ants infest it?
+ var/antable = TRUE
+ /// Location checked every 5 minutes. If its the same place, the food has a chance to spawn ants
var/ant_location
+ /// Things that suppress food from being infested by ants when on the same turf
+ var/static/list/ant_suppressors
/// Time we last checked for ants
var/last_ant_time = 0
- ///Name of the food to show up in kitchen machines (microwaves, ovens, etc)
+ /// Name of the food to show up in kitchen machines (microwaves, ovens, etc)
var/ingredient_name
var/ingredient_name_plural
resistance_flags = FLAMMABLE
@@ -27,10 +27,18 @@
/obj/item/reagent_containers/food/Initialize(mapload)
. = ..()
- if(antable)
- START_PROCESSING(SSobj, src)
- ant_location = get_turf(src)
- last_ant_time = world.time
+ if(!antable)
+ return
+
+ if(!ant_suppressors)
+ ant_suppressors = typecacheof(list(
+ /obj/structure/table,
+ /obj/structure/rack,
+ /obj/structure/closet
+ ))
+ START_PROCESSING(SSobj, src)
+ ant_location = get_turf(src)
+ last_ant_time = world.time
/obj/item/reagent_containers/food/Destroy()
ant_location = null
@@ -46,18 +54,26 @@
/obj/item/reagent_containers/food/proc/check_for_ants()
last_ant_time = world.time
- var/turf/T = get_turf(src)
- if(!isturf(loc))
+
+ // Are we unshielded from the fury of space ants?
+ if(!prob(15)) // Ants are often not the smartest
return
- if((locate(/obj/structure/table) in T) || (locate(/obj/structure/rack) in T))
+ if(!isturf(loc)) // Being inside something protects the food
return
- if(ant_location == T) //It must have been on the same floor since at least the last check_for_ants()
- if(prob(15))
- if(!locate(/obj/effect/decal/cleanable/ants) in T)
- new /obj/effect/decal/cleanable/ants(T)
- antable = FALSE
- desc += " It appears to be infested with ants. Yuck!"
- reagents.add_reagent("ants", 1) // Don't eat things with ants in it you weirdo.
- else
+ var/turf/T = get_turf(src)
+
+ if(T != ant_location) // Moving the food before a full ant swarm can arrive to the location also helps
ant_location = T
+ return
+
+ for(var/obj/structure/S in T) // Check if some object on our turf protects the food from ants
+ if(is_type_in_typecache(S, ant_suppressors))
+ return
+
+ // Dinner time!
+ if(!locate(/obj/effect/decal/cleanable/ants) in T)
+ new /obj/effect/decal/cleanable/ants(T)
+ antable = FALSE
+ desc += " It appears to be infested with ants. Yuck!"
+ reagents.add_reagent("ants", 1) // Don't eat things with ants in it you weirdo.
diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
index bcfb364c33c2..7ac0273ec5cb 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
@@ -578,7 +578,8 @@
/obj/item/reagent_containers/iv_bag,
/obj/item/reagent_containers/applicator,
/obj/item/storage/pill_bottle,
- /obj/item/reagent_containers/food/pill,
+ /obj/item/reagent_containers/pill,
+ /obj/item/reagent_containers/patch,
/obj/item/stack/medical
))
@@ -618,7 +619,8 @@
/obj/item/reagent_containers/iv_bag,
/obj/item/reagent_containers/applicator,
/obj/item/storage/pill_bottle,
- /obj/item/reagent_containers/food/pill,
+ /obj/item/reagent_containers/pill,
+ /obj/item/reagent_containers/patch,
/obj/item/stack/medical
))
@@ -652,8 +654,8 @@
/obj/machinery/smartfridge/secure/chemistry/preloaded/Initialize(mapload)
starting_items = list(
- /obj/item/reagent_containers/food/pill/epinephrine = 12,
- /obj/item/reagent_containers/food/pill/charcoal = 5,
+ /obj/item/reagent_containers/pill/epinephrine = 12,
+ /obj/item/reagent_containers/pill/charcoal = 5,
/obj/item/reagent_containers/glass/bottle/epinephrine = 1,
/obj/item/reagent_containers/glass/bottle/charcoal = 1,
)
diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm
index 9190650405ff..ccf5a753bb56 100644
--- a/code/modules/hydroponics/growninedible.dm
+++ b/code/modules/hydroponics/growninedible.dm
@@ -8,8 +8,8 @@
resistance_flags = FLAMMABLE
var/obj/item/seeds/seed = null // type path, gets converted to item on New(). It's safe to assume it's always a seed item.
-/obj/item/grown/New(newloc, obj/item/seeds/new_seed = null)
- ..()
+/obj/item/grown/Initialize(mapload, newloc, obj/item/seeds/new_seed = null)
+ . = ..()
create_reagents(50)
if(new_seed)
diff --git a/code/modules/mining/equipment/mining_tools.dm b/code/modules/mining/equipment/mining_tools.dm
index d7b8b2ec423f..6ee74a27e432 100644
--- a/code/modules/mining/equipment/mining_tools.dm
+++ b/code/modules/mining/equipment/mining_tools.dm
@@ -1,7 +1,7 @@
/*****************Pickaxes & Drills & Shovels****************/
/obj/item/pickaxe
name = "pickaxe"
- icon = 'icons/obj/items.dmi'
+ icon = 'icons/obj/mining_tool.dmi'
icon_state = "pickaxe"
flags = CONDUCT
slot_flags = SLOT_FLAG_BELT
@@ -124,7 +124,7 @@
/obj/item/shovel
name = "shovel"
desc = "A large tool for digging and moving dirt."
- icon = 'icons/obj/items.dmi'
+ icon = 'icons/obj/mining_tool.dmi'
icon_state = "shovel"
flags = CONDUCT
slot_flags = SLOT_FLAG_BELT
diff --git a/code/modules/mining/equipment/resonator.dm b/code/modules/mining/equipment/resonator.dm
index 59092349bfc1..01632b004861 100644
--- a/code/modules/mining/equipment/resonator.dm
+++ b/code/modules/mining/equipment/resonator.dm
@@ -1,7 +1,7 @@
/**********************Resonator**********************/
/obj/item/resonator
name = "resonator"
- icon = 'icons/obj/items.dmi'
+ icon = 'icons/obj/mining_tool.dmi'
icon_state = "resonator"
item_state = "resonator"
origin_tech = "magnets=3;engineering=3"
diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm
index afb885b7c271..b7f65bf4fdc6 100644
--- a/code/modules/mining/equipment/survival_pod.dm
+++ b/code/modules/mining/equipment/survival_pod.dm
@@ -228,7 +228,7 @@
var/obj/item/reagent_containers/food/snacks/warmdonkpocket_weak/W = new(src)
load(W)
if(prob(50))
- var/obj/item/storage/pill_bottle/dice/D = new(src)
+ var/obj/item/storage/bag/dice/D = new(src)
load(D)
else
var/obj/item/instrument/guitar/G = new(src)
diff --git a/code/modules/mining/lavaland/loot/colossus_loot.dm b/code/modules/mining/lavaland/loot/colossus_loot.dm
index d4126deb2be9..9fdd6258241e 100644
--- a/code/modules/mining/lavaland/loot/colossus_loot.dm
+++ b/code/modules/mining/lavaland/loot/colossus_loot.dm
@@ -221,7 +221,7 @@
if(ready_to_deploy)
if(!istype(user)) // No revs allowed
return
- if(cannotPossess(user))
+ if(!user.check_ahud_rejoin_eligibility())
to_chat(user, "Upon using the antagHUD you forfeited the ability to join the round.")
return
var/be_helper = alert("Become a Lightgeist? (Warning, You can no longer be cloned!)",,"Yes","No")
diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm
index 8c7316313e0f..0616f5e8d72f 100644
--- a/code/modules/mining/machine_vending.dm
+++ b/code/modules/mining/machine_vending.dm
@@ -374,7 +374,7 @@
/obj/item/mining_voucher
name = "mining voucher"
desc = "A token to redeem a piece of equipment. Use it on a mining equipment vendor."
- icon = 'icons/obj/items.dmi'
+ icon = 'icons/obj/mining_tool.dmi'
icon_state = "mining_voucher"
w_class = WEIGHT_CLASS_TINY
diff --git a/code/modules/mob/dead/observer/observer_base.dm b/code/modules/mob/dead/observer/observer_base.dm
index 3250aa20176f..91200ba4e13c 100644
--- a/code/modules/mob/dead/observer/observer_base.dm
+++ b/code/modules/mob/dead/observer/observer_base.dm
@@ -828,3 +828,17 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/datum/spawners_menu/menu = new /datum/spawners_menu(src)
menu.ui_interact(src)
+
+/**
+ * Check if a player has antag-hudded, and if so, if they can rejoin.
+ * Returns TRUE if the player can rejoin, and FALSE if the player is ineligible to rejoin.
+ * If allow_roundstart_observers is FALSE (TRUE by default), then any observers who were able to ahud due to joining roundstart will be excluded as well.
+ */
+/mob/dead/observer/proc/check_ahud_rejoin_eligibility(allow_roundstart_observers = TRUE)
+ if(!GLOB.configuration.general.restrict_antag_hud_rejoin || !has_ahudded())
+ return TRUE
+
+ if(is_roundstart_observer())
+ return allow_roundstart_observers
+ return FALSE
+
diff --git a/code/modules/mob/living/carbon/brain/robotic_brain.dm b/code/modules/mob/living/carbon/brain/robotic_brain.dm
index f22a6012d786..c4fb75669173 100644
--- a/code/modules/mob/living/carbon/brain/robotic_brain.dm
+++ b/code/modules/mob/living/carbon/brain/robotic_brain.dm
@@ -62,7 +62,7 @@
to_chat(O, "\A [src] has been activated. (Teleport | Sign Up)")
/obj/item/mmi/robotic_brain/proc/check_observer(mob/dead/observer/O)
- if(cannotPossess(O))
+ if(!O.check_ahud_rejoin_eligibility())
return FALSE
if(jobban_isbanned(O, "Cyborg") || jobban_isbanned(O, "nonhumandept"))
return FALSE
@@ -121,6 +121,10 @@
to_chat(brainmob, "Remember, the purpose of your existence is to serve [imprinted_master]'s every word, unless lawed or placed into a mech in the future.")
brainmob.mind.assigned_role = "Positronic Brain"
+ if(brainmob.has_ahudded())
+ log_admin("[key_name(brainmob)] has joined as a robot brain, after having toggled antag hud.")
+ message_admins("[key_name(brainmob)] has joined as a robot brain, after having toggled antag hud.")
+
visible_message("[src] chimes quietly.")
become_occupied(occupied_icon)
@@ -155,7 +159,7 @@
if(!check_observer(O))
to_chat(O, "You cannot be \a [src].")
return
- if(cannotPossess(O))
+ if(!O.check_ahud_rejoin_eligibility())
to_chat(O, "Upon using the antagHUD you forfeited the ability to join the round.")
return
if(jobban_isbanned(O, "Cyborg") || jobban_isbanned(O, "nonhumandept"))
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 59d13f73faa3..1f4afda83b90 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -520,7 +520,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
var/failed = 0
if(istype(I, /obj/item/implant))
continue
- if(istype(I, /obj/item/reagent_containers/food/pill/patch))
+ if(istype(I, /obj/item/reagent_containers/patch))
continue
if(I.flags & ABSTRACT)
continue
@@ -1138,87 +1138,133 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
return shock_reduction
/mob/living/carbon/proc/can_eat(flags = 255)
- return 1
+ return TRUE
+
+/mob/living/carbon/proc/eat(obj/item/reagent_containers/to_eat, mob/user, bitesize_override)
+ if(ispill(to_eat) || ispatch(to_eat))
+ return consume_patch_or_pill(to_eat, user)
+
+ if(!isfood(to_eat)) // We first have to know if it's either a pill or a patch, only then can we check if it's a food item
+ return FALSE
-/mob/living/carbon/proc/eat(obj/item/reagent_containers/food/toEat, mob/user, bitesize_override)
- if(!istype(toEat))
- return 0
+ var/obj/item/reagent_containers/food/food = to_eat // It's not a patch or a pill so it must be food
var/fullness = nutrition + 10
- if(istype(toEat, /obj/item/reagent_containers/food/snacks))
+ if(istype(food, /obj/item/reagent_containers/food/snacks))
for(var/datum/reagent/consumable/C in reagents.reagent_list) //we add the nutrition value of what we're currently digesting
fullness += C.nutriment_factor * C.volume / (C.metabolization_rate * metabolism_efficiency)
+
if(user == src)
- if(istype(toEat, /obj/item/reagent_containers/food/drinks))
- if(!selfDrink(toEat))
- return 0
+ if(istype(food, /obj/item/reagent_containers/food/drinks))
+ if(!selfDrink(food))
+ return FALSE
else
- if(!selfFeed(toEat, fullness))
- return 0
+ if(!selfFeed(food, fullness))
+ return FALSE
else
- if(!forceFed(toEat, user, fullness))
- return 0
- consume(toEat, bitesize_override, can_taste_container = toEat.can_taste)
+ if(!forceFed(food, user, fullness))
+ return FALSE
+
+ consume(food, bitesize_override)
SSticker.score.score_food_eaten++
- return 1
+ return TRUE
-/mob/living/carbon/proc/selfFeed(obj/item/reagent_containers/food/toEat, fullness)
- if(ispill(toEat))
- to_chat(src, "You [toEat.apply_method] [toEat].")
+/mob/living/carbon/proc/selfFeed(obj/item/reagent_containers/food/to_eat, fullness)
+ if(ispill(to_eat))
+ to_chat(src, "You swallow [to_eat].")
+ else if(ispatch(to_eat))
+ to_chat(src, "You apply [to_eat].")
else
- if(toEat.junkiness && satiety < -150 && nutrition > NUTRITION_LEVEL_STARVING + 50)
+ if(to_eat.junkiness && satiety < -150 && nutrition > NUTRITION_LEVEL_STARVING + 50)
to_chat(src, "You don't feel like eating any more junk food at the moment.")
- return 0
+ return FALSE
if(fullness <= 50)
- to_chat(src, "You hungrily chew out a piece of [toEat] and gobble it!")
+ to_chat(src, "You hungrily chew out a piece of [to_eat] and gobble it!")
else if(fullness > 50 && fullness < 150)
- to_chat(src, "You hungrily begin to eat [toEat].")
+ to_chat(src, "You hungrily begin to eat [to_eat].")
else if(fullness > 150 && fullness < 500)
- to_chat(src, "You take a bite of [toEat].")
+ to_chat(src, "You take a bite of [to_eat].")
else if(fullness > 500 && fullness < 600)
- to_chat(src, "You unwillingly chew a bit of [toEat].")
+ to_chat(src, "You unwillingly chew a bit of [to_eat].")
else if(fullness > (600 * (1 + overeatduration / 2000))) // The more you eat - the more you can eat
- to_chat(src, "You cannot force any more of [toEat] to go down your throat.")
- return 0
- return 1
+ to_chat(src, "You cannot force any more of [to_eat] to go down your throat.")
+ return FALSE
+ return TRUE
/mob/living/carbon/proc/selfDrink(obj/item/reagent_containers/food/drinks/toDrink, mob/user)
- return 1
+ return TRUE
-/mob/living/carbon/proc/forceFed(obj/item/reagent_containers/food/toEat, mob/user, fullness)
- if(ispill(toEat) || fullness <= (600 * (1 + overeatduration / 1000)))
- if(!toEat.instant_application)
- visible_message("[user] attempts to force [src] to [toEat.apply_method] [toEat].")
- else
- visible_message("[user] cannot force anymore of [toEat] down [src]'s throat.")
- return 0
- if(!toEat.instant_application)
- if(!do_mob(user, src))
- return 0
- forceFedAttackLog(toEat, user)
- visible_message("[user] forces [src] to [toEat.apply_method] [toEat].")
- return 1
+/mob/living/carbon/proc/forceFed(obj/item/reagent_containers/to_eat, mob/user, fullness)
+ if(fullness > (600 * (1 + overeatduration / 1000)))
+ visible_message("[user] cannot force anymore of [to_eat] down [src]'s throat.")
+ return FALSE
-/mob/living/carbon/proc/forceFedAttackLog(obj/item/reagent_containers/food/toEat, mob/user)
- add_attack_logs(user, src, "Fed [toEat]. Reagents: [toEat.reagents.log_list(toEat)]", toEat.reagents.harmless_helper() ? ATKLOG_ALMOSTALL : null)
+ visible_message("[user] attempts to force [src] to swallow [to_eat].")
+ if(!do_after(user, 3 SECONDS, TRUE, src))
+ return FALSE
+ forceFedAttackLog(to_eat, user)
+ visible_message("[user] forces [src] to swallow [to_eat].")
+ return TRUE
+/mob/living/carbon/proc/forceFedAttackLog(obj/item/reagent_containers/to_eat, mob/user)
+ add_attack_logs(user, src, "Fed [to_eat]. Reagents: [to_eat.reagents.log_list(to_eat)]", to_eat.reagents.harmless_helper() ? ATKLOG_ALMOSTALL : null)
/*TO DO - If/when stomach organs are introduced, override this at the human level sending the item to the stomach
so that different stomachs can handle things in different ways VB*/
-/mob/living/carbon/proc/consume(obj/item/reagent_containers/food/toEat, bitesize_override, can_taste_container = TRUE)
- var/this_bite = bitesize_override ? bitesize_override : toEat.bitesize
- if(!toEat.reagents)
+/mob/living/carbon/proc/consume(obj/item/reagent_containers/food/to_eat, bitesize_override)
+ var/this_bite = bitesize_override ? bitesize_override : to_eat.bitesize
+ if(!to_eat.reagents)
return
if(satiety > -200)
- satiety -= toEat.junkiness
- if(toEat.consume_sound)
- playsound(loc, toEat.consume_sound, rand(10,50), 1)
- if(toEat.reagents.total_volume)
- if(can_taste_container)
- taste(toEat.reagents)
- var/fraction = min(this_bite/toEat.reagents.total_volume, 1)
+ satiety -= to_eat.junkiness
+ if(to_eat.consume_sound)
+ playsound(loc, to_eat.consume_sound, rand(10, 50), TRUE)
+ if(to_eat.reagents.total_volume)
+ taste(to_eat.reagents)
+ var/fraction = min(this_bite / to_eat.reagents.total_volume, 1)
if(fraction)
- toEat.reagents.reaction(src, toEat.apply_type, fraction)
- toEat.reagents.trans_to(src, this_bite*toEat.transfer_efficiency)
+ to_eat.reagents.reaction(src, REAGENT_INGEST, fraction)
+ to_eat.reagents.trans_to(src, this_bite)
+
+/mob/living/carbon/proc/consume_patch_or_pill(obj/item/reagent_containers/medicine, user) // medicine = patch or pill
+ // The reason why this is bundled up is to avoid 2 procs that will be practically identical
+ if(!medicine.reagents.total_volume)
+ return TRUE // Doesn't have reagents, would be fine to use up
+
+ if(!dna.species.dietflags) // You will not feed the IPC
+ to_chat(user, "You cannot feed [src] [medicine]!")
+ return FALSE
+
+ var/apply_method = "swallow"
+ var/reagent_application = REAGENT_INGEST
+ var/requires_mouth = TRUE
+ var/instant = FALSE
+ var/efficiency = 1
+
+ if(ispatch(medicine))
+ apply_method = "apply"
+ reagent_application = REAGENT_TOUCH
+ requires_mouth = FALSE
+ efficiency = 0.5 // Patches aren't that good at transporting reagents into the bloodstream
+ var/obj/item/reagent_containers/patch/patch = medicine
+ if(patch.instant_application)
+ instant = TRUE
+
+ if(user != src && !instant)
+ if(requires_mouth && !get_organ("head"))
+ to_chat(user, "You cannot feed [src] [medicine]!")
+ return FALSE
+ visible_message("[user] attempts to force [src] to [apply_method] [medicine].")
+ if(!do_after(user, 3 SECONDS, TRUE, src, TRUE))
+ return FALSE
+ forceFedAttackLog(medicine, user)
+ visible_message("[user] forces [src] to [apply_method] [medicine].")
+ else
+ to_chat(user, "You [apply_method] [medicine].")
+
+ var/fraction = min(1 / medicine.reagents.total_volume, 1)
+ medicine.reagents.reaction(src, reagent_application, fraction)
+ medicine.reagents.trans_to(src, medicine.reagents.total_volume * efficiency)
+ return TRUE
/mob/living/carbon/get_access()
. = ..()
diff --git a/code/modules/mob/living/carbon/carbon_life.dm b/code/modules/mob/living/carbon/carbon_life.dm
index fc7df749d7df..176ac3043106 100644
--- a/code/modules/mob/living/carbon/carbon_life.dm
+++ b/code/modules/mob/living/carbon/carbon_life.dm
@@ -364,7 +364,7 @@
var/applied_amount = 0.35 * multiple_patch_multiplier
for(var/patch in processing_patches)
- var/obj/item/reagent_containers/food/pill/patch/P = patch
+ var/obj/item/reagent_containers/patch/P = patch
if(P.reagents && P.reagents.total_volume)
var/fractional_applied_amount = applied_amount / P.reagents.total_volume
diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm
index 4889521c7d96..af45e81a29f9 100644
--- a/code/modules/mob/living/carbon/examine.dm
+++ b/code/modules/mob/living/carbon/examine.dm
@@ -176,7 +176,7 @@
msg += "[p_they(TRUE)] [p_are()] [bicon(legcuffed)] legcuffed!\n"
for(var/obj/item/abstract_item in abstract_items)
- var/text = abstract_item.customised_abstract_text()
+ var/text = abstract_item.customised_abstract_text(src)
if(!text)
continue
msg += "[text]\n"
@@ -314,15 +314,23 @@
if(CIH?.examine_extensions)
have_hudtypes += CIH.examine_extensions
+ var/user_accesses = M.get_access()
+ var/secwrite = has_access(null, list(ACCESS_SECURITY, ACCESS_FORENSICS_LOCKERS), user_accesses) // same as obj/machinery/computer/secure_data/req_one_access
+ var/medwrite = has_access(null, list(ACCESS_MEDICAL, ACCESS_FORENSICS_LOCKERS), user_accesses) // same access as obj/machinery/computer/med_data/req_one_access
+ if(secwrite)
+ have_hudtypes += EXAMINE_HUD_SECURITY_WRITE
+ if(medwrite)
+ have_hudtypes += EXAMINE_HUD_MEDICAL_WRITE
+
return (hudtype in have_hudtypes)
else if(isrobot(M) || isAI(M)) //Stand-in/Stopgap to prevent pAIs from freely altering records, pending a more advanced Records system
- return (hudtype in list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SECURITY_WRITE, EXAMINE_HUD_MEDICAL))
+ return (hudtype in list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SECURITY_WRITE, EXAMINE_HUD_MEDICAL_READ, EXAMINE_HUD_MEDICAL_WRITE))
else if(isobserver(M))
var/mob/dead/observer/O = M
if(DATA_HUD_SECURITY_ADVANCED in O.data_hud_seen)
- return (hudtype in list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SKILLS))
+ return (hudtype in list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_MEDICAL_READ, EXAMINE_HUD_SKILLS))
return FALSE
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 74113625e2ea..ddd10970e26c 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -71,7 +71,9 @@
var/check_mutations=0 // Check mutations on next life tick
var/heartbeat = 0
- var/receiving_cpr = FALSE
+
+ /// UID of the person who is giving this mob CPR.
+ var/receiving_cpr_from
var/fire_dmi = 'icons/mob/OnFire.dmi'
var/fire_sprite = "Standing"
diff --git a/code/modules/mob/living/carbon/human/human_examine.dm b/code/modules/mob/living/carbon/human/human_examine.dm
index e6ff0fde85ba..61a9b1f54463 100644
--- a/code/modules/mob/living/carbon/human/human_examine.dm
+++ b/code/modules/mob/living/carbon/human/human_examine.dm
@@ -180,30 +180,6 @@
msg += "[p_they(TRUE)] [p_are()] mostly desiccated now, with only [isslimeperson(src) ? "congealed slime" : "bones"] remaining of what used to be a person.\n"
// only humans get employment records
- if(hasHUD(user, EXAMINE_HUD_SECURITY_READ))
- var/perpname = get_visible_name(TRUE)
- var/criminal = "None"
- var/commentLatest = "ERROR: Unable to locate a data core entry for this person." //If there is no datacore present, give this
-
- if(perpname)
- for(var/datum/data/record/E in GLOB.data_core.general)
- if(E.fields["name"] == perpname)
- for(var/datum/data/record/R in GLOB.data_core.security)
- if(R.fields["id"] == E.fields["id"])
- criminal = R.fields["criminal"]
- if(LAZYLEN(R.fields["comments"])) //if the commentlist is present
- var/list/comments = R.fields["comments"]
- commentLatest = LAZYACCESS(comments, comments.len) //get the latest entry from the comment log
- if(islist(commentLatest))
- commentLatest = "[commentLatest["header"]]: [commentLatest["text"]]"
- else
- commentLatest = "No entries." //If present but without entries (=target is recognized crew)
-
- var/criminal_status = hasHUD(user, EXAMINE_HUD_SECURITY_WRITE) ? "\[[criminal]\]" : "\[[criminal]\]"
- msg += "Criminal status: [criminal_status]\n"
- msg += "Security records:\[View comment log\]\[Add comment\]\n"
- msg += "Latest entry: [commentLatest]\n"
-
if(hasHUD(user, EXAMINE_HUD_SKILLS))
var/perpname = get_visible_name(TRUE)
var/skills
@@ -220,18 +196,47 @@
msg += "Employment records: [copytext_preserve_html(skills, 1, char_limit-3)]...More...\n"
- if(hasHUD(user,EXAMINE_HUD_MEDICAL))
+ if(hasHUD(user, EXAMINE_HUD_MEDICAL_READ))
var/perpname = get_visible_name(TRUE)
var/medical = "None"
+ var/mental = "None"
for(var/datum/data/record/E in GLOB.data_core.general)
if(E.fields["name"] == perpname)
for(var/datum/data/record/R in GLOB.data_core.general)
if(R.fields["id"] == E.fields["id"])
medical = R.fields["p_stat"]
+ mental = R.fields["m_stat"]
- msg += "Physical status:\[[medical]\]\n"
- msg += "Medical records:\[View\]\[Add comment\]\n"
+ var/medical_status = hasHUD(user, EXAMINE_HUD_MEDICAL_WRITE) ? "\[[medical]\]" : "\[[medical]\]"
+ var/mental_status = hasHUD(user, EXAMINE_HUD_MEDICAL_WRITE) ? "\[[mental]\]" : "\[[mental]\]"
+ msg += "Physical status: [medical_status]\n"
+ msg += "Mental Status: [mental_status]\n"
+ msg += "Medical records:\[View\]\[Add comment\]\n"
+
+ if(hasHUD(user, EXAMINE_HUD_SECURITY_READ))
+ var/perpname = get_visible_name(TRUE)
+ var/criminal = "None"
+ var/commentLatest = "ERROR: Unable to locate a data core entry for this person." //If there is no datacore present, give this
+
+ if(perpname)
+ for(var/datum/data/record/E in GLOB.data_core.general)
+ if(E.fields["name"] == perpname)
+ for(var/datum/data/record/R in GLOB.data_core.security)
+ if(R.fields["id"] == E.fields["id"])
+ criminal = R.fields["criminal"]
+ if(LAZYLEN(R.fields["comments"])) //if the commentlist is present
+ var/list/comments = R.fields["comments"]
+ commentLatest = LAZYACCESS(comments, comments.len) //get the latest entry from the comment log
+ if(islist(commentLatest))
+ commentLatest = "[commentLatest["header"]]: [commentLatest["text"]]"
+ else
+ commentLatest = "No entries." //If present but without entries (=target is recognized crew)
+
+ var/criminal_status = hasHUD(user, EXAMINE_HUD_SECURITY_WRITE) ? "\[[criminal]\]" : "\[[criminal]\]"
+ msg += "Criminal status: [criminal_status]\n"
+ msg += "Security records:\[View comment log\]\[Add comment\]\n"
+ msg += "Latest entry: [commentLatest]\n"
return msg
diff --git a/code/modules/mob/living/carbon/human/human_mob.dm b/code/modules/mob/living/carbon/human/human_mob.dm
index 307f1e578b1a..645fffbefcb4 100644
--- a/code/modules/mob/living/carbon/human/human_mob.dm
+++ b/code/modules/mob/living/carbon/human/human_mob.dm
@@ -770,10 +770,10 @@
add_comment(usr, "security", sanitized)
if(href_list["medical"])
- if(hasHUD(usr, EXAMINE_HUD_MEDICAL))
+ if(hasHUD(usr, EXAMINE_HUD_MEDICAL_WRITE))
if(usr.incapacitated())
return
- var/modified = 0
+ var/modified = FALSE
var/perpname = get_visible_name(TRUE)
for(var/datum/data/record/E in GLOB.data_core.general)
@@ -782,21 +782,39 @@
if(R.fields["id"] == E.fields["id"])
var/setmedical = input(usr, "Specify a new medical status for this person.", "Medical HUD", R.fields["p_stat"]) in list("*SSD*", "*Deceased*", "Physically Unfit", "Active", "Disabled", "Cancel")
- if(hasHUD(usr, EXAMINE_HUD_MEDICAL))
+ if(hasHUD(usr, EXAMINE_HUD_MEDICAL_WRITE))
if(setmedical != "Cancel")
R.fields["p_stat"] = setmedical
- modified = 1
+ modified = TRUE
if(GLOB.PDA_Manifest.len)
GLOB.PDA_Manifest.Cut()
- spawn()
- sec_hud_set_security_status()
+ if(!modified)
+ to_chat(usr, "Unable to locate a data core entry for this person.")
+
+ if(href_list["mental"])
+ if(hasHUD(usr, EXAMINE_HUD_MEDICAL_WRITE))
+ if(usr.incapacitated())
+ return
+ var/modified = FALSE
+ var/perpname = get_visible_name(TRUE)
+
+ for(var/datum/data/record/E in GLOB.data_core.general)
+ if(E.fields["name"] == perpname)
+ for(var/datum/data/record/R in GLOB.data_core.general)
+ if(R.fields["id"] == E.fields["id"])
+ var/setmental = input(usr, "Specify a new mental status for this person.", "Medical HUD", R.fields["m_stat"]) in list("*Insane*", "*Unstable*", "*Watch*", "Stable", "Cancel")
+
+ if(hasHUD(usr, EXAMINE_HUD_MEDICAL_WRITE))
+ if(setmental != "Cancel")
+ R.fields["m_stat"] = setmental
+ modified = TRUE
if(!modified)
to_chat(usr, "Unable to locate a data core entry for this person.")
if(href_list["medrecord"])
- if(hasHUD(usr, EXAMINE_HUD_MEDICAL))
+ if(hasHUD(usr, EXAMINE_HUD_MEDICAL_READ))
if(usr.incapacitated())
return
var/read = 0
@@ -806,7 +824,7 @@
if(E.fields["name"] == perpname)
for(var/datum/data/record/R in GLOB.data_core.medical)
if(R.fields["id"] == E.fields["id"])
- if(hasHUD(usr, EXAMINE_HUD_MEDICAL))
+ if(hasHUD(usr, EXAMINE_HUD_MEDICAL_READ))
to_chat(usr, "Name: [R.fields["name"]] Blood Type: [R.fields["b_type"]]")
to_chat(usr, "DNA: [R.fields["b_dna"]]")
to_chat(usr, "Minor Disabilities: [R.fields["mi_dis"]]")
@@ -821,7 +839,7 @@
to_chat(usr, "Unable to locate a data core entry for this person.")
if(href_list["medrecordComment"])
- if(hasHUD(usr, EXAMINE_HUD_MEDICAL))
+ if(hasHUD(usr, EXAMINE_HUD_MEDICAL_READ))
if(usr.incapacitated())
return
var/perpname = get_visible_name(TRUE)
@@ -831,7 +849,7 @@
if(E.fields["name"] == perpname)
for(var/datum/data/record/R in GLOB.data_core.medical)
if(R.fields["id"] == E.fields["id"])
- if(hasHUD(usr, EXAMINE_HUD_MEDICAL))
+ if(hasHUD(usr, EXAMINE_HUD_MEDICAL_READ))
read = TRUE
if(LAZYLEN(R.fields["comments"]))
for(var/c in R.fields["comments"])
@@ -844,11 +862,11 @@
to_chat(usr, "Unable to locate a data core entry for this person.")
if(href_list["medrecordadd"])
- if(usr.incapacitated() || !hasHUD(usr, EXAMINE_HUD_MEDICAL))
+ if(usr.incapacitated() || !hasHUD(usr, EXAMINE_HUD_MEDICAL_WRITE))
return
var/raw_input = input("Add Comment:", "Medical records", null, null) as message
var/sanitized = copytext(trim(sanitize(raw_input)), 1, MAX_MESSAGE_LEN)
- if(!sanitized || usr.stat || usr.restrained() || !hasHUD(usr, EXAMINE_HUD_MEDICAL))
+ if(!sanitized || usr.stat || usr.restrained() || !hasHUD(usr, EXAMINE_HUD_MEDICAL_WRITE))
return
add_comment(usr, "medical", sanitized)
@@ -1660,7 +1678,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
if(H == src)
to_chat(src, "You cannot perform CPR on yourself!")
return
- if(H.receiving_cpr) // To prevent spam stacking
+ if(!isnull(H.receiving_cpr_from)) // To prevent spam stacking
to_chat(src, "They are already receiving CPR!")
return
if(!can_use_hands() || !has_both_hands())
@@ -1670,7 +1688,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
to_chat(src, "You can't perform effective CPR with your hands full!")
return
- H.receiving_cpr = TRUE
+ H.receiving_cpr_from = UID()
var/cpr_modifier = get_cpr_mod(H)
if(H.stat == DEAD || HAS_TRAIT(H, TRAIT_FAKEDEATH))
if(ismachineperson(H) && do_mob(src, H, 4 SECONDS)) // hehe
@@ -1680,12 +1698,12 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
)
playsound(H, 'sound/weapons/ringslam.ogg', 50, TRUE)
adjustBruteLossByPart(2, "head")
- H.receiving_cpr = FALSE
+ H.receiving_cpr_from = null
return
if(!H.is_revivable())
to_chat(src, "[H] is already too far gone for CPR...")
- H.receiving_cpr = FALSE
+ H.receiving_cpr_from = null
return
visible_message("[src] is trying to perform CPR on [H]'s lifeless body!", "You start trying to perform CPR on [H]'s lifeless body!")
@@ -1722,7 +1740,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
else
visible_message("[src] stops giving [H] CPR.", "You stop giving [H] CPR.")
- H.receiving_cpr = FALSE
+ H.receiving_cpr_from = null
return
visible_message("[src] is trying to perform CPR on [H.name]!", "You try to perform CPR on [H.name]!")
@@ -1741,7 +1759,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
to_chat(H, "You feel a breath of fresh air enter your lungs. It feels good.")
add_attack_logs(src, H, "CPRed", ATKLOG_ALL)
- H.receiving_cpr = FALSE
+ H.receiving_cpr_from = null
visible_message("[src] stops performing CPR on [H].", "You stop performing CPR on [H].")
to_chat(src, "You need to stay still while performing CPR!")
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index 06b880e98c89..a299c6fae879 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -114,6 +114,10 @@
var/datum/data/pda/app/messenger/M = pda.find_program(/datum/data/pda/app/messenger)
M.toff = TRUE
+ if(has_ahudded())
+ message_admins("[key_name(src)] has joined as a pAI, having previously enabled antag hud.")
+ log_admin("[key_name(src)] has joined as a pAI, having previously enabled antag hud.")
+
// Software modules. No these var names have nothing to do with photoshop
for(var/PS in subtypesof(/datum/pai_software))
var/datum/pai_software/PSD = new PS(src)
diff --git a/code/modules/mob/living/silicon/pai/recruit.dm b/code/modules/mob/living/silicon/pai/recruit.dm
index 79b4fa8cd5e0..409468696c26 100644
--- a/code/modules/mob/living/silicon/pai/recruit.dm
+++ b/code/modules/mob/living/silicon/pai/recruit.dm
@@ -355,7 +355,7 @@ GLOBAL_DATUM_INIT(paiController, /datum/paiController, new) // Global handler fo
return 0
if(!player_old_enough_antag(O.client,ROLE_PAI))
return 0
- if(cannotPossess(O))
+ if(!O.check_ahud_rejoin_eligibility())
return 0
if(!HAS_TRAIT(O, TRAIT_RESPAWNABLE))
return 0
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm
index 250c2a5a2c89..412423c92869 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm
@@ -121,7 +121,7 @@
var/joinedasobserver = FALSE
if(isobserver(src))
var/mob/dead/observer/G = src
- if(cannotPossess(G))
+ if(!G.check_ahud_rejoin_eligibility())
to_chat(usr, "Upon using the antagHUD you forfeited the ability to join the round.")
return
if(G.started_as_observer == TRUE)
diff --git a/code/modules/mob/living/silicon/robot/drone/maint_drone.dm b/code/modules/mob/living/silicon/robot/drone/maint_drone.dm
index b5b2ca28e597..aed0e9b16b45 100644
--- a/code/modules/mob/living/silicon/robot/drone/maint_drone.dm
+++ b/code/modules/mob/living/silicon/robot/drone/maint_drone.dm
@@ -291,7 +291,7 @@
/mob/living/silicon/robot/drone/proc/request_player()
for(var/mob/dead/observer/O in GLOB.player_list)
- if(cannotPossess(O))
+ if(!O.check_ahud_rejoin_eligibility())
continue
if(jobban_isbanned(O, "nonhumandept") || jobban_isbanned(O, "Drone"))
continue
diff --git a/code/modules/mob/living/simple_animal/hostile/headslug.dm b/code/modules/mob/living/simple_animal/hostile/headslug.dm
index 49b3bb92f87e..1fd512d6d577 100644
--- a/code/modules/mob/living/simple_animal/hostile/headslug.dm
+++ b/code/modules/mob/living/simple_animal/hostile/headslug.dm
@@ -108,6 +108,10 @@
M.key = origin.key
M.revive() // better make sure some weird shit doesn't happen, because it has in the pas
M.forceMove(get_turf(owner)) // So that they are not stuck inside
+ if(!ishuman(owner))
+ owner.gib()
+ return
+
owner.apply_damage(300, BRUTE, BODY_ZONE_CHEST)
owner.bleed(BLOOD_VOLUME_NORMAL)
var/obj/item/organ/external/chest = owner.get_organ(BODY_ZONE_CHEST)
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_ghost_interaction.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_ghost_interaction.dm
index b7340a936e02..bbf76c1d31dc 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_ghost_interaction.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_ghost_interaction.dm
@@ -16,8 +16,10 @@
humanize_prompt += " Role: [spider_role_summary]"
if(user.ckey in GLOB.ts_ckey_blacklist)
error_on_humanize = "You are not able to control any terror spider this round."
- else if(cannotPossess(user))
- error_on_humanize = "You have enabled antag HUD and are unable to re-enter the round."
+ else if(isobserver(user))
+ var/mob/dead/observer/O = user
+ if(!O.check_ahud_rejoin_eligibility())
+ error_on_humanize = "You have enabled antag HUD and are unable to re-enter the round."
else if(!ai_playercontrol_allowtype)
error_on_humanize = "This specific type of terror spider is not player-controllable."
else if(degenerate)
diff --git a/code/modules/mob/mob_misc_procs.dm b/code/modules/mob/mob_misc_procs.dm
index eefdb926c3b7..a374e36223c0 100644
--- a/code/modules/mob/mob_misc_procs.dm
+++ b/code/modules/mob/mob_misc_procs.dm
@@ -137,13 +137,6 @@
return 1
-/proc/cannotPossess(A)
- var/mob/dead/observer/G = A
- if(G.has_enabled_antagHUD && GLOB.configuration.general.restrict_antag_hud_rejoin)
- return 1
- return 0
-
-
/proc/iscuffed(A)
if(iscarbon(A))
var/mob/living/carbon/C = A
@@ -808,6 +801,12 @@ GLOBAL_LIST_INIT(intents, list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM
/mob/proc/attempt_listen_to_deadsay()
+/mob/proc/is_roundstart_observer()
+ return (ckey in GLOB.roundstart_observer_keys)
+
+/mob/proc/has_ahudded()
+ return (ckey in GLOB.antag_hud_users)
+
/// Proc to PROPERLY set mob invisibility, huds gotta get set too!
/mob/proc/set_invisible(invis_value)
if(invis_value)
diff --git a/code/modules/mob/mob_vars.dm b/code/modules/mob/mob_vars.dm
index f66f9da307a4..a4b9e8281baa 100644
--- a/code/modules/mob/mob_vars.dm
+++ b/code/modules/mob/mob_vars.dm
@@ -122,8 +122,6 @@
var/move_on_shuttle = TRUE // Can move on the shuttle.
- /// Whether antagHUD has been enabled previously.
- var/has_enabled_antagHUD = FALSE
var/antagHUD = FALSE // Whether AntagHUD is active right now
var/can_change_intents = TRUE //all mobs can change intents by default.
///Override for sound_environments. If this is set the user will always hear a specific type of reverb (Instead of the area defined reverb)
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index 54955dc07493..7541cf6a4d8a 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -189,8 +189,9 @@
src << browse(null, "window=playersetup")
spawning = TRUE
stop_sound_channel(CHANNEL_LOBBYMUSIC)
-
-
+ if(SSticker.current_state < GAME_STATE_PLAYING)
+ GLOB.roundstart_observer_keys |= ckey
+ to_chat(src, "As you observed before the round started, you can freely toggle antag-hud without losing respawnability.")
observer.started_as_observer = 1
close_spawn_windows()
var/obj/O = locate("landmark*Observer-Start")
diff --git a/code/modules/mod/mod_theme.dm b/code/modules/mod/mod_theme.dm
index 0cb1688f77d4..3d50e73e1273 100644
--- a/code/modules/mod/mod_theme.dm
+++ b/code/modules/mod/mod_theme.dm
@@ -1064,6 +1064,7 @@
siemens_coefficient = 0
slowdown_inactive = 0.5
slowdown_active = 0
+ complexity_max = DEFAULT_MAX_COMPLEXITY + 5
allowed_suit_storage = list(
/obj/item/ammo_box,
/obj/item/ammo_casing,
diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm
index bf9c6d79a422..be9d2a4c26a4 100644
--- a/code/modules/mod/mod_types.dm
+++ b/code/modules/mod/mod_types.dm
@@ -226,6 +226,11 @@
/obj/item/mod/module/jetpack,
)
+/obj/item/mod/control/pre_equipped/traitor/Initialize(mapload)
+ . = ..()
+ new /obj/item/clothing/mask/gas/syndicate(bag)
+ new /obj/item/tank/internals/emergency_oxygen/engi/syndi(bag)
+
/obj/item/mod/control/pre_equipped/traitor_elite
theme = /datum/mod_theme/elite
applied_cell = /obj/item/stock_parts/cell/bluespace
@@ -242,6 +247,11 @@
/obj/item/mod/module/jetpack/advanced,
)
+/obj/item/mod/control/pre_equipped/traitor_elite/Initialize(mapload)
+ . = ..()
+ new /obj/item/clothing/mask/gas/syndicate(bag)
+ new /obj/item/tank/internals/emergency_oxygen/engi/syndi(bag)
+
/obj/item/mod/control/pre_equipped/nuclear
theme = /datum/mod_theme/syndicate
applied_cell = /obj/item/stock_parts/cell/hyper
@@ -292,7 +302,7 @@
/obj/item/mod/control/pre_equipped/responsory
theme = /datum/mod_theme/responsory
- applied_cell = /obj/item/stock_parts/cell/hyper
+ applied_cell = /obj/item/stock_parts/cell/bluespace
req_access = list(ACCESS_CENT_GENERAL)
applied_modules = list(
/obj/item/mod/module/storage/syndicate, //Yes yes syndicate tech in ert but they need the storage
@@ -326,7 +336,7 @@
/obj/item/mod/control/pre_equipped/responsory/engineer
insignia_type = /obj/item/mod/module/insignia/engineer
- additional_module = /obj/item/mod/module/anomaly_locked/kinesis/prebuilt //This can only end well.
+ additional_module = list(/obj/item/mod/module/anomaly_locked/kinesis/prebuilt, /obj/item/mod/module/firefighting_tank) //This can only end well.
/obj/item/mod/control/pre_equipped/responsory/medic
insignia_type = /obj/item/mod/module/insignia/medic
diff --git a/code/modules/ninja/energy_katana.dm b/code/modules/ninja/energy_katana.dm
index 218c5432c670..340f054f0ccf 100644
--- a/code/modules/ninja/energy_katana.dm
+++ b/code/modules/ninja/energy_katana.dm
@@ -1,6 +1,7 @@
/obj/item/katana/energy
name = "energy katana"
desc = "A katana infused with a strong energy"
+ icon = 'icons/obj/energy_melee.dmi'
icon_state = "energy_katana"
item_state = "energy_katana"
force = 40
diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm
index f9061deae8c0..3ab6c5a21849 100644
--- a/code/modules/paperwork/paper.dm
+++ b/code/modules/paperwork/paper.dm
@@ -98,8 +98,14 @@
if(is_pen(user.get_active_hand()))
rename(user)
- else
- return ..()
+ return
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ var/obj/item/I = H.is_in_hands(/obj/item/paper)
+ if(I)
+ ProcFoldPlane(H, I)
+ return
+ return ..()
/obj/item/paper/proc/rename(mob/user)
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm
index 45ec3a502140..16999baf0edd 100644
--- a/code/modules/paperwork/paperplane.dm
+++ b/code/modules/paperwork/paperplane.dm
@@ -108,20 +108,6 @@
E.take_damage(8, 1)
H.emote("scream")
-/obj/item/paper/AltClick(mob/user, obj/item/I)
- if(in_range(user, src) && !user.incapacitated())
- if(is_pen(user.get_active_hand()))
- rename()
- return
-
- if(ishuman(user))
- var/mob/living/carbon/human/H = user
- I = H.is_in_hands(/obj/item/paper)
- if(I)
- ProcFoldPlane(H, I)
- else
- ..()
-
/obj/item/paper/proc/ProcFoldPlane(mob/living/carbon/user, obj/item/I)
if(istype(user))
if((!in_range(src, user)) || user.stat || user.restrained())
diff --git a/code/modules/power/generators/thermo_electric_generator.dm b/code/modules/power/generators/thermo_electric_generator.dm
index e052cf96bdc6..4f0a5a811a28 100644
--- a/code/modules/power/generators/thermo_electric_generator.dm
+++ b/code/modules/power/generators/thermo_electric_generator.dm
@@ -193,13 +193,10 @@
. = TRUE
if(!default_unfasten_wrench(user, I, 0))
return
- anchored = !anchored
if(!anchored)
disconnect()
- power_change()
else
connect()
- to_chat(user, "You [anchored ? "secure" : "unsecure"] the bolts holding [src] to the floor.")
/obj/machinery/power/teg/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
diff --git a/code/modules/projectiles/guns/energy/special_eguns.dm b/code/modules/projectiles/guns/energy/special_eguns.dm
index b43f8efb62d6..cced4f362f0d 100644
--- a/code/modules/projectiles/guns/energy/special_eguns.dm
+++ b/code/modules/projectiles/guns/energy/special_eguns.dm
@@ -545,7 +545,6 @@
origin_tech = "combat=4;materials=4;powerstorage=3;magnets=2"
ammo_type = list(/obj/item/ammo_casing/energy/temp)
- selfcharge = TRUE
// Measured in Kelvin
var/temperature = T20C
@@ -553,8 +552,8 @@
var/min_temp = 0
var/max_temp = 500
- /// How fast the gun recharges
- var/recharge_multiplier = 1
+ /// How fast the gun changes temperature
+ var/temperature_multiplier = 10
/obj/item/gun/energy/temperature/Initialize(mapload, ...)
. = ..()
@@ -594,20 +593,20 @@
/obj/item/gun/energy/temperature/emag_act(mob/user)
if(!emagged)
emagged = TRUE
- to_chat(user, "You remove the gun's temperature cap! Targets hit by searing beams will burst into flames!")
+ to_chat(user, "You remove the gun's temperature cap! Targets hit by searing beams will burst into flames!")
desc += " Its temperature cap has been removed."
max_temp = 1000
- recharge_multiplier = 5 //so emagged temp guns adjust their temperature much more quickly
+ temperature_multiplier *= 5 //so emagged temp guns adjust their temperature much more quickly
/obj/item/gun/energy/temperature/process()
..()
if(target_temperature != temperature)
var/difference = abs(target_temperature - temperature)
- if(difference >= (10 * recharge_multiplier))
+ if(difference >= temperature_multiplier)
if(target_temperature < temperature)
- temperature -= (10 * recharge_multiplier)
+ temperature -= temperature_multiplier
else
- temperature += (10 * recharge_multiplier)
+ temperature += temperature_multiplier
else
temperature = target_temperature
update_icon()
diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm
index 3d5d5cdfdb2b..a839563d6ac1 100644
--- a/code/modules/reagents/chemistry/machinery/chem_master.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_master.dm
@@ -461,7 +461,7 @@
to_chat(usr, "Not enough reagents to create these pills!")
return
- var/obj/item/reagent_containers/food/pill/P = new(loc)
+ var/obj/item/reagent_containers/pill/P = new(loc)
P.name = "[answer] pill"
P.pixel_x = rand(-7, 7) // Random position
P.pixel_y = rand(-7, 7)
@@ -495,7 +495,7 @@
to_chat(usr, "Not enough reagents to create these patches!")
return
- var/obj/item/reagent_containers/food/pill/patch/P = new(loc)
+ var/obj/item/reagent_containers/patch/P = new(loc)
P.name = "[answer] patch"
P.pixel_x = rand(-7, 7) // random position
P.pixel_y = rand(-7, 7)
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index e45e71c20a6f..72996bda5f3a 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -202,7 +202,7 @@
/obj/item/reagent_containers/hypospray/autoinjector/nanocalcium
name = "protoype nanite autoinjector"
- desc = "After a short period of time the nanites will slow the body's systems and assist with body repair. Nanomachines son."
+ desc = "A highly experimental prototype chemical designed to fully mend limbs and organs of soldiers in the field, shuts down body systems whilst aiding in repair. WARNING: Side effects can cause temporary paralysis, loss of co-ordination and sickness. Do not use with any kind of stimulant or drugs. Serious damage can occur!"
icon_state = "bonepen"
amount_per_transfer_from_this = 30
volume = 30
diff --git a/code/modules/reagents/reagent_containers/patch.dm b/code/modules/reagents/reagent_containers/patch.dm
index 968a8ab5aa5a..6b2167e056b9 100644
--- a/code/modules/reagents/reagent_containers/patch.dm
+++ b/code/modules/reagents/reagent_containers/patch.dm
@@ -1,4 +1,4 @@
-/obj/item/reagent_containers/food/pill/patch
+/obj/item/reagent_containers/patch
name = "chemical patch"
desc = "A chemical patch for touch based applications."
icon = 'icons/obj/chemical.dmi'
@@ -6,17 +6,20 @@
item_state = "bandaid"
possible_transfer_amounts = null
volume = 30
- apply_type = REAGENT_TOUCH
- apply_method = "apply"
- transfer_efficiency = 0.5 //patches aren't as effective at getting chemicals into the bloodstream.
temperature_min = 270
temperature_max = 350
+ var/instant_application = FALSE
var/needs_to_apply_reagents = TRUE
-/obj/item/reagent_containers/food/pill/patch/attack(mob/living/carbon/M, mob/user, def_zone)
+/obj/item/reagent_containers/patch/attack(mob/living/carbon/M, mob/user, def_zone)
+ return apply(M, user)
+
+/obj/item/reagent_containers/patch/attack_self(mob/user)
+ return apply(user, user)
+
+/obj/item/reagent_containers/patch/proc/apply(mob/living/carbon/M, mob/user)
if(!istype(M))
return FALSE
- bitesize = 0
if(M.eat(src, user))
if(user.get_active_hand() == src)
user.drop_item() // Only drop if they're holding the patch directly
@@ -25,50 +28,47 @@
return TRUE
return FALSE
-/obj/item/reagent_containers/food/pill/patch/afterattack(obj/target, mob/user , proximity)
- return // thanks inheritance again
-
-/obj/item/reagent_containers/food/pill/patch/styptic
+/obj/item/reagent_containers/patch/styptic
name = "brute patch"
desc = "Helps with brute injuries."
icon_state = "bandaid_brute"
- instant_application = 1
+ instant_application = TRUE
list_reagents = list("styptic_powder" = 30)
-/obj/item/reagent_containers/food/pill/patch/styptic/small
+/obj/item/reagent_containers/patch/styptic/small
name = "brute mini-patch"
list_reagents = list("styptic_powder" = 15)
-/obj/item/reagent_containers/food/pill/patch/silver_sulf
+/obj/item/reagent_containers/patch/silver_sulf
name = "burn patch"
desc = "Helps with burn injuries."
icon_state = "bandaid_burn"
- instant_application = 1
+ instant_application = TRUE
list_reagents = list("silver_sulfadiazine" = 30)
-/obj/item/reagent_containers/food/pill/patch/silver_sulf/small
+/obj/item/reagent_containers/patch/silver_sulf/small
name = "burn mini-patch"
list_reagents = list("silver_sulfadiazine" = 15)
-/obj/item/reagent_containers/food/pill/patch/synthflesh
+/obj/item/reagent_containers/patch/synthflesh
name = "synthflesh patch"
desc = "Helps with brute and burn injuries."
icon_state = "bandaid_med"
- instant_application = 1
+ instant_application = TRUE
list_reagents = list("synthflesh" = 10)
-/obj/item/reagent_containers/food/pill/patch/nicotine
+/obj/item/reagent_containers/patch/nicotine
name = "nicotine patch"
desc = "Helps temporarily curb the cravings of nicotine dependency."
list_reagents = list("nicotine" = 10)
-/obj/item/reagent_containers/food/pill/patch/jestosterone
+/obj/item/reagent_containers/patch/jestosterone
name = "jestosterone patch"
desc = "Helps with brute injuries if the affected person is a clown, otherwise inflicts various annoying effects."
icon_state = "bandaid_clown"
list_reagents = list("jestosterone" = 20)
-/obj/item/reagent_containers/food/pill/patch/perfluorodecalin
+/obj/item/reagent_containers/patch/perfluorodecalin
name = "perfluorodecalin patch"
desc = "Incredibly potent respiratory aid drug, may cause shortness of breath if used in large amounts."
icon_state = "bandaid_med"
diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm
index 0bbe6956b928..f8d257e73092 100644
--- a/code/modules/reagents/reagent_containers/pill.dm
+++ b/code/modules/reagents/reagent_containers/pill.dm
@@ -3,7 +3,7 @@
*
* A swallowable pill. Can be dissolved in reagent containers.
*/
-/obj/item/reagent_containers/food/pill
+/obj/item/reagent_containers/pill
name = "pill"
desc = "A pill."
icon = 'icons/obj/chemical.dmi'
@@ -13,31 +13,27 @@
possible_transfer_amounts = null
volume = 100
has_lid = FALSE
- consume_sound = null
- can_taste = FALSE
- antable = FALSE
-/obj/item/reagent_containers/food/pill/Initialize(mapload)
+/obj/item/reagent_containers/pill/Initialize(mapload)
. = ..()
if(!icon_state)
icon_state = "pill[rand(1, 20)]"
-/obj/item/reagent_containers/food/pill/proc/apply(mob/living/carbon/M, mob/user, def_zone)
+/obj/item/reagent_containers/pill/proc/apply(mob/living/carbon/M, mob/user, def_zone)
if(!istype(M))
return FALSE
- bitesize = reagents.total_volume
if(M.eat(src, user))
qdel(src)
return TRUE
return FALSE
-/obj/item/reagent_containers/food/pill/attack(mob/living/carbon/M, mob/user, def_zone)
+/obj/item/reagent_containers/pill/attack(mob/living/carbon/M, mob/user, def_zone)
return apply(M, user)
-/obj/item/reagent_containers/food/pill/attack_self(mob/user)
+/obj/item/reagent_containers/pill/attack_self(mob/user)
return apply(user, user)
-/obj/item/reagent_containers/food/pill/afterattack(obj/target, mob/user, proximity)
+/obj/item/reagent_containers/pill/afterattack(obj/target, mob/user, proximity)
if(!proximity || !target.is_refillable())
return
if(target.reagents.holder_full())
@@ -51,138 +47,138 @@
qdel(src)
// Basic set of pills below
-/obj/item/reagent_containers/food/pill/tox
+/obj/item/reagent_containers/pill/tox
name = "\improper Toxin pill"
desc = "Highly toxic."
icon_state = "pill21"
list_reagents = list("toxin" = 50)
-/obj/item/reagent_containers/food/pill/initropidril
+/obj/item/reagent_containers/pill/initropidril
name = "\improper Initropidril pill"
desc = "Don't swallow this."
icon_state = "pill21"
list_reagents = list("initropidril" = 50)
-/obj/item/reagent_containers/food/pill/fakedeath
+/obj/item/reagent_containers/pill/fakedeath
name = "fake death pill"
desc = "Swallow then rest to appear dead, stand up to wake up. Also mutes the user's voice."
icon_state = "pill4"
list_reagents = list("capulettium_plus" = 50)
-/obj/item/reagent_containers/food/pill/adminordrazine
+/obj/item/reagent_containers/pill/adminordrazine
name = "\improper Adminordrazine pill"
desc = "It's magic. We don't have to explain it."
icon_state = "pill16"
list_reagents = list("adminordrazine" = 50)
-/obj/item/reagent_containers/food/pill/morphine
+/obj/item/reagent_containers/pill/morphine
name = "\improper Morphine pill"
desc = "Commonly used to treat insomnia."
icon_state = "pill8"
list_reagents = list("morphine" = 30)
-/obj/item/reagent_containers/food/pill/methamphetamine
+/obj/item/reagent_containers/pill/methamphetamine
name = "\improper Methamphetamine pill"
desc = "Helps improve the ability to concentrate."
icon_state = "pill8"
list_reagents = list("methamphetamine" = 5)
-/obj/item/reagent_containers/food/pill/haloperidol
+/obj/item/reagent_containers/pill/haloperidol
name = "\improper Haloperidol pill"
desc = "Haloperidol is an anti-psychotic used to treat psychiatric problems."
icon_state = "pill8"
list_reagents = list("haloperidol" = 15)
-/obj/item/reagent_containers/food/pill/happy_psych
+/obj/item/reagent_containers/pill/happy_psych
name = "mood stabilizer pill"
desc = "Used to temporarily alleviate anxiety and depression. Take only as prescribed."
icon_state = "pill_happy"
list_reagents = list("happiness" = 15, "mannitol" = 5)
-/obj/item/reagent_containers/food/pill/happy
+/obj/item/reagent_containers/pill/happy
name = "happy pill"
desc = "They have little happy faces on them and smell like marker pens."
icon_state = "pill_happy"
list_reagents = list("space_drugs" = 15, "sugar" = 15)
-/obj/item/reagent_containers/food/pill/happy/happiness
+/obj/item/reagent_containers/pill/happy/happiness
name = "fun pill"
desc = "Makes you feel real good!"
list_reagents = list("happiness" = 15)
-/obj/item/reagent_containers/food/pill/zoom
+/obj/item/reagent_containers/pill/zoom
name = "zoom pill"
desc = "Zoooom!"
icon_state = "pill18"
list_reagents = list("synaptizine" = 5, "methamphetamine" = 5)
-/obj/item/reagent_containers/food/pill/charcoal
+/obj/item/reagent_containers/pill/charcoal
name = "\improper Charcoal pill"
desc = "Neutralizes many common toxins."
icon_state = "pill17"
list_reagents = list("charcoal" = 50)
-/obj/item/reagent_containers/food/pill/epinephrine
+/obj/item/reagent_containers/pill/epinephrine
name = "\improper Epinephrine pill"
desc = "Used to provide shots of adrenaline."
icon_state = "pill6"
list_reagents = list("epinephrine" = 50)
-/obj/item/reagent_containers/food/pill/salicylic
+/obj/item/reagent_containers/pill/salicylic
name = "\improper Salicylic Acid pill"
desc = "Commonly used to treat moderate pain and fevers."
icon_state = "pill4"
list_reagents = list("sal_acid" = 20)
-/obj/item/reagent_containers/food/pill/salbutamol
+/obj/item/reagent_containers/pill/salbutamol
name = "\improper Salbutamol pill"
desc = "Used to treat respiratory distress."
icon_state = "pill8"
list_reagents = list("salbutamol" = 20)
-/obj/item/reagent_containers/food/pill/hydrocodone
+/obj/item/reagent_containers/pill/hydrocodone
name = "\improper Hydrocodone pill"
desc = "Used to treat extreme pain."
icon_state = "pill6"
list_reagents = list("hydrocodone" = 15)
-/obj/item/reagent_containers/food/pill/calomel
+/obj/item/reagent_containers/pill/calomel
name = "\improper Calomel pill"
desc = "Can be used to purge impurities, but is highly toxic itself."
icon_state = "pill3"
list_reagents = list("calomel" = 15)
-/obj/item/reagent_containers/food/pill/mutadone
+/obj/item/reagent_containers/pill/mutadone
name = "\improper Mutadone pill"
desc = "Used to cure genetic abnormalities."
icon_state = "pill13"
list_reagents = list("mutadone" = 1)
-/obj/item/reagent_containers/food/pill/mannitol
+/obj/item/reagent_containers/pill/mannitol
name = "\improper Mannitol pill"
desc = "Used to treat cranial swelling."
icon_state = "pill19"
list_reagents = list("mannitol" = 10)
-/obj/item/reagent_containers/food/pill/pentetic
+/obj/item/reagent_containers/pill/pentetic
name ="\improper Pentetic pill"
desc = "Used to purge substances and radiation."
icon_state = "pill7"
list_reagents = list("pen_acid" = 5)
-/obj/item/reagent_containers/food/pill/ironsaline
+/obj/item/reagent_containers/pill/ironsaline
name = "\improper Iron saline pill"
desc = "Used to help with blood loss."
icon_state = "pill2"
list_reagents = list("iron" = 10, "salglu_solution" = 10)
-/obj/item/reagent_containers/food/pill/lazarus_reagent
+/obj/item/reagent_containers/pill/lazarus_reagent
name = "\improper Lazarus Reagent pill"
desc = "Miraculous drug used for revival. Use with caution. Improper use may cause bodies to violently blow apart."
icon_state = "pill9"
list_reagents = list("lazarus_reagent" = 1)
-/obj/item/reagent_containers/food/pill/rezadone
+/obj/item/reagent_containers/pill/rezadone
name = "\improper Rezadone pill"
desc = "Used to rapidly repair cellular defects within a subject's cell structure."
icon_state = "pill10"
diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm
index 8351a0948f60..a82989c14039 100644
--- a/code/modules/research/designs/medical_designs.dm
+++ b/code/modules/research/designs/medical_designs.dm
@@ -540,6 +540,39 @@
build_path = /obj/item/organ/internal/cyberimp/brain/wire_interface
category = list("Medical")
+/datum/design/raiden_implant
+ name = "Reactive Repair Implant"
+ desc = "This implant reworks the IPC frame, in order to incorporate materials that return to their original shape after being damaged. Requires power to function."
+ id = "ci-raiden_implant"
+ req_tech = list("materials" = 5, "programming" = 5, "biotech" = 5, "magnets" = 5, "engineering" = 5)
+ build_type = PROTOLATHE | MECHFAB
+ construction_time = 60
+ materials = list(MAT_METAL = 12500, MAT_SILVER = 12000, MAT_GOLD = 2500, MAT_PLASMA = 5000)
+ build_path = /obj/item/organ/internal/cyberimp/chest/ipc_repair
+ category = list("Medical")
+
+/datum/design/monsoon_implant
+ name = "Magnetic Joints Implant"
+ desc = "This implant modifies IPC joints to use magnets, allowing easy re-attachment and fluid movement."
+ id = "ci-monsoon_implant"
+ req_tech = list("materials" = 5, "programming" = 5, "biotech" = 5, "magnets" = 5, "engineering" = 5)
+ build_type = PROTOLATHE | MECHFAB
+ construction_time = 60
+ materials = list(MAT_METAL = 12500, MAT_SILVER = 12000, MAT_GOLD = 2500, MAT_PLASMA = 5000)
+ build_path = /obj/item/organ/internal/cyberimp/chest/ipc_joints/magnetic_joints
+ category = list("Medical")
+
+/datum/design/sundown_implant
+ name = "Sealed Joints Implant"
+ desc = "This implant seals and reinforces IPC joints, securing the limbs better, though prone to locking up."
+ id = "ci-sundown_implant"
+ req_tech = list("materials" = 5, "programming" = 5, "biotech" = 5, "engineering" = 5, "combat" = 5)
+ build_type = PROTOLATHE | MECHFAB
+ construction_time = 60
+ materials = list(MAT_METAL = 12500, MAT_SILVER = 12000, MAT_GOLD = 2500, MAT_PLASMA = 5000)
+ build_path = /obj/item/organ/internal/cyberimp/chest/ipc_joints/sealed
+ category = list("Medical")
+
/////////////////////////////////////////
////////////Regular Implants/////////////
/////////////////////////////////////////
diff --git a/code/modules/response_team/ert.dm b/code/modules/response_team/ert.dm
index 55e6ab2a0862..47b6a68617c0 100644
--- a/code/modules/response_team/ert.dm
+++ b/code/modules/response_team/ert.dm
@@ -48,12 +48,14 @@ GLOBAL_LIST_EMPTY(ert_request_messages)
to_chat(src, "This role is not yet available to you. You need to wait another [player_age_check] days.")
return FALSE
- if(cannotPossess(src))
+ return TRUE
+
+/mob/dead/observer/JoinResponseTeam()
+ . = ..()
+ if(!check_ahud_rejoin_eligibility())
to_chat(src, "Upon using the antagHUD you forfeited the ability to join the round.")
return FALSE
- return TRUE
-
/proc/trigger_armed_response_team(datum/response_team/response_team_type, commander_slots, security_slots, medical_slots, engineering_slots, janitor_slots, paranormal_slots, cyborg_slots, cyborg_security)
GLOB.response_team_members = list()
GLOB.active_team = response_team_type
diff --git a/code/modules/response_team/ert_outfits.dm b/code/modules/response_team/ert_outfits.dm
index 24163420fd9c..cd26c0b1817d 100644
--- a/code/modules/response_team/ert_outfits.dm
+++ b/code/modules/response_team/ert_outfits.dm
@@ -223,7 +223,7 @@
name = "RT Engineer (Amber)"
shoes = /obj/item/clothing/shoes/magboots
suit = /obj/item/clothing/suit/space/hardsuit/ert/engineer
- suit_store = /obj/item/tank/internals/emergency_oxygen/engi
+ suit_store = /obj/item/tank/internals/emergency_oxygen/double
glasses = /obj/item/clothing/glasses/meson/engine
mask = /obj/item/clothing/mask/gas
l_pocket = /obj/item/gun/energy/gun/mini
@@ -251,7 +251,7 @@
name = "RT Engineer (Red)"
shoes = /obj/item/clothing/shoes/magboots/advance
suit = /obj/item/clothing/suit/space/hardsuit/ert/engineer/gamma
- suit_store = /obj/item/tank/internals/emergency_oxygen/engi
+ suit_store = /obj/item/tank/internals/emergency_oxygen/double
glasses = /obj/item/clothing/glasses/meson/engine
mask = /obj/item/clothing/mask/gas
l_pocket = /obj/item/t_scanner
@@ -261,7 +261,7 @@
/obj/item/rcd/preloaded = 1,
/obj/item/rcd_ammo = 3,
/obj/item/gun/energy/gun = 1,
- /obj/item/rpd = 1
+ /obj/item/rpd/bluespace = 1
)
cybernetic_implants = list(
@@ -279,6 +279,7 @@
name = "RT Engineer (Gamma)"
shoes = /obj/item/clothing/shoes/magboots/elite
back = /obj/item/mod/control/pre_equipped/responsory/engineer
+ suit_store = /obj/item/tank/internals/emergency_oxygen/double
glasses = /obj/item/clothing/glasses/meson/night
mask = /obj/item/clothing/mask/gas/sechailer/swat
l_pocket = /obj/item/t_scanner
@@ -288,7 +289,7 @@
/obj/item/rcd/combat = 1,
/obj/item/rcd_ammo/large = 3,
/obj/item/gun/energy/gun/blueshield/pdw9 = 1,
- /obj/item/rpd = 1
+ /obj/item/rpd/bluespace = 1
)
cybernetic_implants = list(
diff --git a/code/modules/ruins/spaceruin_code/voyager.dm b/code/modules/ruins/spaceruin_code/voyager.dm
index ac4c8c81b841..48850bbf4c4f 100644
--- a/code/modules/ruins/spaceruin_code/voyager.dm
+++ b/code/modules/ruins/spaceruin_code/voyager.dm
@@ -1,8 +1,8 @@
/obj/item/golden_record
name = "Golden Record"
desc = "A relic of the past, you don't know what lies inside, but you remember someone talking about it arriving in 250356 years"
- icon = 'icons/obj/space/voyager.dmi'
- icon_state = "golden_record_new" //credits to mcramon for brand new sprite
+ icon = 'icons/obj/ruin_objects.dmi'
+ icon_state = "golden_record" //credits to mcramon for brand new sprite
drop_sound = 'sound/items/handling/disk_drop.ogg'
pickup_sound = 'sound/items/handling/disk_pickup.ogg'
throw_speed = 1
diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm
index 9e2f6c23a8f3..6e081554cae5 100644
--- a/code/modules/shuttle/supply.dm
+++ b/code/modules/shuttle/supply.dm
@@ -35,7 +35,8 @@
/obj/item/warp_cube,
/obj/machinery/quantumpad,
/obj/structure/extraction_point,
- /obj/item/envelope)
+ /obj/item/envelope,
+ /obj/item/paicard)
if(A)
if(is_type_in_list(A, blacklist))
return TRUE
diff --git a/code/modules/surgery/dental_implant.dm b/code/modules/surgery/dental_implant.dm
index 47b09e448b6c..93eeeed91e9e 100644
--- a/code/modules/surgery/dental_implant.dm
+++ b/code/modules/surgery/dental_implant.dm
@@ -12,7 +12,7 @@
/datum/surgery_step/insert_pill
name = "insert pill"
- allowed_tools = list(/obj/item/reagent_containers/food/pill = 100)
+ allowed_tools = list(/obj/item/reagent_containers/pill = 100)
time = 1.6 SECONDS
/datum/surgery_step/insert_pill/begin_step(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -22,12 +22,12 @@
)
return ..()
-/datum/surgery_step/insert_pill/end_step(mob/living/user, mob/living/carbon/target, target_zone, obj/item/reagent_containers/food/pill/tool, datum/surgery/surgery)
+/datum/surgery_step/insert_pill/end_step(mob/living/user, mob/living/carbon/target, target_zone, obj/item/reagent_containers/pill/tool, datum/surgery/surgery)
if(!istype(tool))
return SURGERY_STEP_INCOMPLETE
var/dental_implants = 0
- for(var/obj/item/reagent_containers/food/pill in target.contents) // Can't give them more than 4 dental implants.
+ for(var/obj/item/reagent_containers/pill in target.contents) // Can't give them more than 4 dental implants.
dental_implants++
if(dental_implants >= 4)
user.visible_message("[user] pulls \the [tool] back out of [target]'s [parse_zone(target_zone)]!", "You pull \the [tool] back out of [target]'s [parse_zone(target_zone)], there wans't enough room...")
diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm
index 7105e36a56d2..b60d8eab24c7 100644
--- a/code/modules/surgery/organs/augments_arms.dm
+++ b/code/modules/surgery/organs/augments_arms.dm
@@ -497,10 +497,7 @@
var/disabled = FALSE
var/force_when_disabled = 5 //still basically a metal pipe, just hard to move
-/obj/item/shield/v1_arm/customised_abstract_text()
- if(!ishuman(loc))
- return
- var/mob/living/carbon/human/owner = loc
+/obj/item/shield/v1_arm/customised_abstract_text(mob/living/carbon/owner)
return "[owner.p_their(TRUE)] [owner.l_hand == src ? "left arm" : "right arm"] is covered in metal."
/obj/item/shield/v1_arm/emp_act(severity)
diff --git a/code/modules/surgery/organs/augments_eyes.dm b/code/modules/surgery/organs/augments_eyes.dm
index 17daa66b9aa3..3637f1f4f83d 100644
--- a/code/modules/surgery/organs/augments_eyes.dm
+++ b/code/modules/surgery/organs/augments_eyes.dm
@@ -43,7 +43,7 @@
origin_tech = "materials=4;programming=4;biotech=4"
aug_message = "You suddenly see health bars floating above people's heads..."
HUD_type = DATA_HUD_MEDICAL_ADVANCED
- examine_extensions = list(EXAMINE_HUD_MEDICAL)
+ examine_extensions = list(EXAMINE_HUD_MEDICAL_READ)
/obj/item/organ/internal/cyberimp/eyes/hud/diagnostic
name = "Diagnostic HUD implant"
@@ -60,4 +60,4 @@
origin_tech = "materials=4;programming=4;biotech=3;combat=3"
aug_message = "Job indicator icons pop up in your vision. That is not a certified surgeon..."
HUD_type = DATA_HUD_SECURITY_ADVANCED
- examine_extensions = list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SECURITY_WRITE)
+ examine_extensions = list(EXAMINE_HUD_SECURITY_READ)
diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm
index af1503c93aa8..43d40ddec061 100644
--- a/code/modules/surgery/organs/augments_internal.dm
+++ b/code/modules/surgery/organs/augments_internal.dm
@@ -317,7 +317,6 @@
/obj/item/organ/internal/cyberimp/chest/nutriment
name = "Nutriment pump implant"
desc = "This implant will synthesize a small amount of nutriment and pumps it directly into your bloodstream when you are starving."
- icon_state = "chest_implant"
implant_color = "#00AA00"
var/hunger_threshold = NUTRITION_LEVEL_STARVING
var/synthesizing = 0
@@ -367,7 +366,6 @@
/obj/item/organ/internal/cyberimp/chest/nutriment/plus
name = "Nutriment pump implant PLUS"
desc = "This implant will synthesize a small amount of nutriment and pumps it directly into your bloodstream when you are hungry."
- icon_state = "chest_implant"
implant_color = "#006607"
hunger_threshold = NUTRITION_LEVEL_HUNGRY
poison_amount = 10
@@ -384,7 +382,6 @@
/obj/item/organ/internal/cyberimp/chest/reviver
name = "Reviver implant"
desc = "This implant will attempt to heal you out of critical condition. For the faint of heart!"
- icon_state = "chest_implant"
implant_color = "#AD0000"
origin_tech = "materials=5;programming=4;biotech=4"
slot = "heartdrive"
@@ -457,6 +454,87 @@
if(H.stat == CONSCIOUS)
to_chat(H, "You feel your heart beating again!")
+/obj/item/organ/internal/cyberimp/chest/ipc_repair
+ name = "Reactive Repair Implant"
+ desc = "This implant reworks the IPC frame, in order to incorporate materials that return to their original shape after being damaged. Requires power to function."
+ implant_color = "#0ac0d8"
+ origin_tech = "materials=4;programming=4;biotech=4;magnets=4;engineering=4"
+ slot = "stomach" //Can't have a nutriment pump with it.
+ requires_machine_person = TRUE
+
+/obj/item/organ/internal/cyberimp/chest/ipc_repair/on_life()
+ if(crit_fail)
+ return
+ if(owner.maxHealth == owner.health)
+ owner.adjust_nutrition(-0.5)
+ return //Passive damage scanning
+
+ owner.adjustBruteLoss(-0.5, robotic = TRUE)
+ owner.adjustFireLoss(-0.5, robotic = TRUE)
+ owner.adjust_nutrition(-4) //Very power inefficent. Hope you got an APC nearby.
+
+/obj/item/organ/internal/cyberimp/chest/ipc_repair/emp_act(severity)
+ if(!owner || emp_proof || crit_fail)
+ return
+ crit_fail = TRUE
+ addtimer(VARSET_CALLBACK(src, crit_fail, FALSE), 30 SECONDS / severity)
+
+/obj/item/organ/internal/cyberimp/chest/ipc_joints
+ name = "IPC ER-OR Joint Implant"
+ desc = "This is a basetype. Notify a coder!"
+ implant_color = "#eeff00"
+ origin_tech = "materials=5;programming=4;biotech=4"
+ slot = "joints"
+ requires_machine_person = TRUE
+
+/obj/item/organ/internal/cyberimp/chest/ipc_joints/magnetic_joints
+ name = "Magnetic Joints Implant"
+ desc = "This implant modifies IPC joints to use magnets, allowing easy re-attachment and fluid movement."
+ implant_color = "#670db1"
+ origin_tech = "materials=4;programming=4;biotech=4;magnets=4;engineering=4"
+
+/obj/item/organ/internal/cyberimp/chest/ipc_joints/magnetic_joints/emp_act(severity)
+ if(!owner || emp_proof)
+ return
+ if(ishuman(owner))
+ var/mob/living/carbon/human/H = owner
+ to_chat(H, "Your magnetic joints lose power!")
+ for(var/obj/item/organ/external/E in H.bodyparts)
+ if(E.body_part != UPPER_TORSO && E.body_part != LOWER_TORSO)
+ E.droplimb(TRUE) //lego disasemble sound
+
+/obj/item/organ/internal/cyberimp/chest/ipc_joints/magnetic_joints/insert(mob/living/carbon/M, special = FALSE)
+ ADD_TRAIT(M, TRAIT_IPC_JOINTS_MAG, "ipc_joint[UID()]")
+ return ..()
+
+/obj/item/organ/internal/cyberimp/chest/ipc_joints/magnetic_joints/remove(mob/living/carbon/M, special = FALSE)
+ REMOVE_TRAIT(M, TRAIT_IPC_JOINTS_MAG, "ipc_joint[UID()]")
+ return ..()
+
+/obj/item/organ/internal/cyberimp/chest/ipc_joints/sealed
+ name = "Sealed Joints Implant"
+ desc = "This implant seals and reinforces IPC joints, securing the limbs better for industrial work, though prone to locking up."
+ implant_color = "#b10d0d"
+ origin_tech = "materials=4;programming=4;biotech=4;engineering=4;combat=4;"
+
+/obj/item/organ/internal/cyberimp/chest/ipc_joints/sealed/emp_act(severity)
+ if(!owner || emp_proof)
+ return
+ var/weaken_time = (10 + (severity - 1 ? 0 : 10)) SECONDS
+ owner.Weaken(weaken_time) //Pop it and lock it
+ to_chat(owner, "Your body seizes up!")
+ return weaken_time
+
+/obj/item/organ/internal/cyberimp/chest/ipc_joints/sealed/insert(mob/living/carbon/M, special = FALSE)
+ ADD_TRAIT(M, TRAIT_IPC_JOINTS_SEALED, "ipc_joint[UID()]")
+ owner.physiology.stamina_mod *= 1.15 //15% more stamina damage, representing extra friction in limbs. I guess.
+ return ..()
+
+/obj/item/organ/internal/cyberimp/chest/ipc_joints/sealed/remove(mob/living/carbon/M, special = FALSE)
+ REMOVE_TRAIT(M, TRAIT_IPC_JOINTS_SEALED, "ipc_joint[UID()]")
+ owner.physiology.stamina_mod /= 1.15
+ return ..()
+
//BOX O' IMPLANTS
/obj/item/storage/box/cyber_implants
diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ.dm
index 710177e61cec..2b000ee96042 100644
--- a/code/modules/surgery/organs/organ.dm
+++ b/code/modules/surgery/organs/organ.dm
@@ -30,6 +30,8 @@
var/emp_proof = FALSE //is the organ immune to EMPs?
var/hidden_pain = FALSE //will it skip pain messages?
var/requires_robotic_bodypart = FALSE
+ /// When this variable is true, it can only be installed on the machine person species.
+ var/requires_machine_person = FALSE
///Should this organ be destroyed on removal?
var/destroy_on_removal = FALSE
@@ -54,17 +56,14 @@
..(holder)
if(!max_damage)
max_damage = min_broken_damage * 2
- if(istype(holder))
+ if(ishuman(holder))
if(holder.dna)
dna = holder.dna.Clone()
+ if(!blood_DNA)
+ blood_DNA = list()
+ blood_DNA[dna.unique_enzymes] = dna.blood_type
else
stack_trace("[holder] spawned without a proper DNA.")
- var/mob/living/carbon/human/H = holder
- if(istype(H))
- if(dna)
- if(!blood_DNA)
- blood_DNA = list()
- blood_DNA[dna.unique_enzymes] = dna.blood_type
else
dna = new /datum/dna(null)
if(species_override)
diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm
index f4bc08df16ea..4a913730ba9d 100644
--- a/code/modules/surgery/organs/organ_external.dm
+++ b/code/modules/surgery/organs/organ_external.dm
@@ -164,6 +164,27 @@
if(!HAS_TRAIT(owner, TRAIT_IB_IMMUNE))
limb_flags &= ~CANNOT_INT_BLEED
+/obj/item/organ/external/attack(mob/M, mob/living/user)
+ if(!ishuman(M))
+ return ..()
+ var/mob/living/carbon/human/C = M
+ if(is_robotic() && HAS_TRAIT(C, TRAIT_IPC_JOINTS_MAG) && isnull(C.bodyparts_by_name[limb_name]))
+ user.unEquip(src)
+ replaced(C)
+ C.update_body()
+ C.updatehealth()
+ C.UpdateDamageIcon()
+ if(limb_name == BODY_ZONE_HEAD)
+ var/obj/item/organ/external/head/H = C.get_organ(BODY_ZONE_HEAD)
+ var/datum/robolimb/robohead = GLOB.all_robolimbs[H.model]
+ if(robohead.is_monitor) //Ensures that if an IPC gets a head that's got a human hair wig attached to their body, the hair won't wipe.
+ H.h_style = "Bald"
+ H.f_style = "Shaved"
+ C.m_styles["head"] = "None"
+ user.visible_message(
+ "[user] has attached [C]'s [src] to the [amputation_point].",
+ "You have attached [C]'s [src] to the [amputation_point].")
+ return TRUE
/obj/item/organ/external/replaced(mob/living/carbon/human/target)
owner = target
loc = null
@@ -198,6 +219,7 @@
****************************************************/
/obj/item/organ/external/receive_damage(brute, burn, sharp, used_weapon = null, list/forbidden_limbs = list(), ignore_resists = FALSE, updating_health = TRUE)
+ var/max_limb_damage = max_damage - (HAS_TRAIT(owner, TRAIT_IPC_JOINTS_MAG) ? max_damage * 0.25 : 0)
if(tough && !ignore_resists)
brute = max(0, brute - 5)
burn = max(0, burn - 4)
@@ -226,7 +248,7 @@
// Probability of taking internal damage from sufficient force, while otherwise healthy
#define LIMB_DMG_PROB 5
// High brute damage or sharp objects may damage internal organs
- if(internal_organs && (brute_dam >= max_damage || (((sharp && brute >= LIMB_SHARP_THRESH_INT_DMG) || brute >= LIMB_THRESH_INT_DMG) && prob(LIMB_DMG_PROB))))
+ if(internal_organs && (brute_dam >= max_limb_damage || (((sharp && brute >= LIMB_SHARP_THRESH_INT_DMG) || brute >= LIMB_THRESH_INT_DMG) && prob(LIMB_DMG_PROB))))
// Damage an internal organ
if(internal_organs && internal_organs.len)
var/obj/item/organ/internal/I = pick(internal_organs)
@@ -244,14 +266,14 @@
add_autopsy_data(null, brute + burn)
// Make sure we don't exceed the maximum damage a limb can take before dismembering
- if((brute_dam + burn_dam + brute + burn) < max_damage)
+ if((brute_dam + burn_dam + brute + burn) < max_limb_damage)
brute_dam += brute
burn_dam += burn
check_for_internal_bleeding(brute)
else
//If we can't inflict the full amount of damage, spread the damage in other ways
//How much damage can we actually cause?
- var/can_inflict = max_damage - (brute_dam + burn_dam)
+ var/can_inflict = max_limb_damage - (brute_dam + burn_dam)
if(can_inflict)
if(brute > 0)
//Inflict all burte damage we can
@@ -285,7 +307,7 @@
var/obj/item/organ/external/target = pick(possible_points)
target.receive_damage(brute, burn, sharp, used_weapon, forbidden_limbs + src, ignore_resists = TRUE) //If the damage was reduced before, don't reduce it again
- if(dismember_at_max_damage && body_part != UPPER_TORSO && body_part != LOWER_TORSO) // We've ensured all damage to the mob is retained, now let's drop it, if necessary.
+ if(dismember_at_max_damage && body_part != UPPER_TORSO && body_part != LOWER_TORSO && !HAS_TRAIT(owner, TRAIT_IPC_JOINTS_SEALED)) // We've ensured all damage to the mob is retained, now let's drop it, if necessary.
droplimb(1) //Clean loss, just drop the limb and be done
var/mob/living/carbon/owner_old = owner //Need to update health, but need a reference in case the below check cuts off a limb.
diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm
index 3fa25913f8e0..f4a897775589 100644
--- a/code/modules/surgery/organs_internal.dm
+++ b/code/modules/surgery/organs_internal.dm
@@ -396,6 +396,10 @@
to_chat(user, "[I] is an organ that requires a robotic interface! [target]'s [parse_zone(target_zone)] does not have one.")
return SURGERY_BEGINSTEP_SKIP
+ if(I.requires_machine_person && !ismachineperson(target))
+ to_chat(user, "[I] is an organ that requires an IPC interface! [target]'s [parse_zone(target_zone)] does not have one.")
+ return SURGERY_BEGINSTEP_SKIP
+
if(target_zone != I.parent_organ || target.get_organ_slot(I.slot))
to_chat(user, "There is no room for [I] in [target]'s [parse_zone(target_zone)]!")
return SURGERY_BEGINSTEP_SKIP
@@ -427,7 +431,10 @@
if(!istype(tool))
return SURGERY_STEP_INCOMPLETE
if(I.requires_robotic_bodypart)
- to_chat(user, "[I] is an organ that requires a robotic interface[target].")
+ to_chat(user, "[I] requires a robotic interface.")
+ return SURGERY_STEP_INCOMPLETE
+ if(I.requires_machine_person && !ismachineperson(target))
+ to_chat(user, "[I] requires an IPC interface!")
return SURGERY_STEP_INCOMPLETE
if(!user.drop_item())
to_chat(user, "[I] is stuck to your hand, you can't put it in [target]!")
diff --git a/code/modules/tgui/modules/destination_tagger.dm b/code/modules/tgui/modules/destination_tagger.dm
index dea53ca53c17..cdd2487681c6 100644
--- a/code/modules/tgui/modules/destination_tagger.dm
+++ b/code/modules/tgui/modules/destination_tagger.dm
@@ -5,8 +5,9 @@
/datum/ui_module/destination_tagger/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
- ui = new(user, src, ui_key, "DestinationTagger", name, 395, 350, master_ui, state)
+ ui = new(user, src, ui_key, "DestinationTagger", name, 400, 350, master_ui, state)
ui.open()
+ ui.set_autoupdate(FALSE)
/datum/ui_module/destination_tagger/ui_data(mob/user)
var/list/data = list()
@@ -35,7 +36,7 @@
my_tag = destination_id
playsound(host, 'sound/machines/terminal_select.ogg', 15, TRUE)
-
+ . = TRUE
// Handle setting tags (and flushing for drones)
if(istype(host, /obj/item/destTagger))
var/obj/item/destTagger/O = host
diff --git a/code/modules/tgui/modules/ghost_hud_panel.dm b/code/modules/tgui/modules/ghost_hud_panel.dm
index 54a52787f8b4..344948764459 100644
--- a/code/modules/tgui/modules/ghost_hud_panel.dm
+++ b/code/modules/tgui/modules/ghost_hud_panel.dm
@@ -62,14 +62,22 @@ GLOBAL_DATUM_INIT(ghost_hud_panel, /datum/ui_module/ghost_hud_panel, new)
to_chat(ghost, "You have been banned from using this feature.")
return FALSE
// Check if this is the first time they're turning on Antag HUD.
- if(!check_rights(R_ADMIN | R_MOD, FALSE) && !ghost.has_enabled_antagHUD && GLOB.configuration.general.restrict_antag_hud_rejoin)
+ if(!check_rights(R_ADMIN | R_MOD, FALSE) && !ghost.is_roundstart_observer() && GLOB.configuration.general.restrict_antag_hud_rejoin && !ghost.has_ahudded())
var/response = alert(ghost, "If you turn this on, you will not be able to take any part in the round.", "Are you sure you want to enable antag HUD?", "Yes", "No")
if(response == "No")
return FALSE
- ghost.has_enabled_antagHUD = TRUE
ghost.can_reenter_corpse = FALSE
REMOVE_TRAIT(ghost, TRAIT_RESPAWNABLE, GHOSTED)
+ log_admin("[key_name(ghost)] has enabled antaghud as an observer and forfeited respawnability.")
+ message_admins("[key_name(ghost)] has enabled antaghud as an observer and forfeited respawnability.")
+
+
+ else if(ghost.is_roundstart_observer() && !ghost.has_ahudded())
+ log_admin("[key_name(ghost)] has enabled antaghud for the first time as a roundstart observer, keeping respawnability.")
+
+ GLOB.antag_hud_users |= ghost.ckey
+
ghost.antagHUD = TRUE
for(var/datum/atom_hud/antag/H in GLOB.huds)
diff --git a/code/modules/tgui/modules/law_manager.dm b/code/modules/tgui/modules/law_manager.dm
index 25c7758c844e..667c0a57b109 100644
--- a/code/modules/tgui/modules/law_manager.dm
+++ b/code/modules/tgui/modules/law_manager.dm
@@ -125,12 +125,17 @@
owner.statelaws(ALs)
if("transfer_laws")
- if(is_malf(usr))
- var/datum/ai_laws/ALs = locate(params["transfer_laws"]) in (is_admin(usr) ? admin_laws : player_laws)
- if(ALs)
- log_and_message_admins("has transfered the [ALs.name] laws to [owner].")
- ALs.sync(owner, 0)
- current_view = 0
+ if(!is_malf(usr))
+ return
+ var/admin_overwrite = is_admin(usr)
+ var/datum/ai_laws/ALs = locate(params["transfer_laws"]) in (admin_overwrite ? admin_laws : player_laws)
+ if(!ALs)
+ return
+ if(admin_overwrite && alert("Do you want to overwrite [owner]'s zeroth law? If the chosen lawset has no zeroth law while [owner] has one, it will get removed!", "Load Lawset", "Yes", "No") != "Yes")
+ admin_overwrite = FALSE
+ log_and_message_admins("has transfered the [ALs.name] laws to [owner][admin_overwrite ? " and overwrote their zeroth law":""].")
+ ALs.sync(owner, FALSE, admin_overwrite)
+ current_view = 0
if("notify_laws")
to_chat(owner, "Law Notice")
diff --git a/code/modules/tgui/modules/tgui_input_list.dm b/code/modules/tgui/modules/tgui_input_list.dm
new file mode 100644
index 000000000000..c642ef6bc9d2
--- /dev/null
+++ b/code/modules/tgui/modules/tgui_input_list.dm
@@ -0,0 +1,180 @@
+/**
+ * Creates a TGUI input list window and returns the user's response.
+ *
+ * This proc should be used to create alerts that the caller will wait for a response from.
+ * Arguments:
+ * * user - The user to show the input box to.
+ * * message - The content of the input box, shown in the body of the TGUI window.
+ * * title - The title of the input box, shown on the top of the TGUI window.
+ * * buttons - The options that can be chosen by the user, each string is assigned a button on the UI.
+ * * timeout - The timeout of the input box, after which the input box will close and qdel itself. Set to zero for no timeout.
+ */
+/proc/tgui_input_list(mob/user, message, title, list/buttons, timeout = 0)
+ if(!user)
+ user = usr
+ if(!length(buttons))
+ return
+ if(!istype(user))
+ if(!isclient(user))
+ return
+ var/client/client = user
+ user = client.mob
+ var/datum/tgui_list_input/input = new(user, message, title, buttons, timeout)
+ input.ui_interact(user)
+ input.wait()
+ if(input)
+ . = input.choice
+ qdel(input)
+
+/**
+ * Creates an asynchronous TGUI input list window with an associated callback.
+ *
+ * This proc should be used to create inputs that invoke a callback with the user's chosen option.
+ * Arguments:
+ * * user - The user to show the input box to.
+ * * message - The content of the input box, shown in the body of the TGUI window.
+ * * title - The title of the input box, shown on the top of the TGUI window.
+ * * buttons - The options that can be chosen by the user, each string is assigned a button on the UI.
+ * * callback - The callback to be invoked when a choice is made.
+ * * timeout - The timeout of the input box, after which the menu will close and qdel itself. Set to zero for no timeout.
+ */
+/proc/tgui_input_list_async(mob/user, message, title, list/buttons, datum/callback/callback, timeout = 60 SECONDS)
+ if(!user)
+ user = usr
+ if(!length(buttons))
+ return
+ if(!istype(user))
+ if(!isclient(user))
+ return
+ var/client/client = user
+ user = client.mob
+ var/datum/tgui_list_input/async/input = new(user, message, title, buttons, timeout, callback)
+ input.ui_interact(user)
+
+/**
+ * # tgui_list_input
+ *
+ * Datum used for instantiating and using a TGUI-controlled list input that prompts the user with
+ * a message and shows a list of selectable options
+ */
+/datum/tgui_list_input
+ /// The title of the TGUI window
+ var/title
+ /// The textual body of the TGUI window
+ var/message
+ /// The list of buttons (responses) provided on the TGUI window
+ var/list/buttons
+ /// Buttons (strings specifically) mapped to the actual value (e.g. a mob or a verb)
+ var/list/buttons_map
+ /// The button that the user has pressed, null if no selection has been made
+ var/choice
+ /// The time at which the tgui_list_input was created, for displaying timeout progress.
+ var/start_time
+ /// The lifespan of the tgui_list_input, after which the window will close and delete itself.
+ var/timeout
+ /// Boolean field describing if the tgui_list_input was closed by the user.
+ var/closed
+
+/datum/tgui_list_input/New(mob/user, message, title, list/buttons, timeout)
+ src.title = title
+ src.message = message
+ src.buttons = list()
+ src.buttons_map = list()
+
+ // Gets rid of illegal characters
+ var/static/regex/whitelistedWords = regex(@{"([^\u0020-\u8000]+)"})
+
+ for(var/i in buttons)
+ var/string_key = whitelistedWords.Replace("[i]", "")
+
+ src.buttons += string_key
+ src.buttons_map[string_key] = i
+
+
+ if(timeout)
+ src.timeout = timeout
+ start_time = world.time
+ QDEL_IN(src, timeout)
+
+/datum/tgui_list_input/Destroy(force, ...)
+ SStgui.close_uis(src)
+ QDEL_NULL(buttons)
+ . = ..()
+
+/**
+ * Waits for a user's response to the tgui_list_input's prompt before returning. Returns early if
+ * the window was closed by the user.
+ */
+/datum/tgui_list_input/proc/wait()
+ while(!choice && !closed)
+ stoplag(1)
+
+/datum/tgui_list_input/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.always_state)
+ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ ui = new(user, src, ui_key, "ListInput", title, 325, 330, master_ui, state)
+ ui.set_autoupdate(FALSE)
+ ui.open()
+
+/datum/tgui_list_input/ui_close(mob/user)
+ . = ..()
+ closed = TRUE
+
+/datum/tgui_list_input/ui_static_data(mob/user)
+ var/list/data = list()
+ data["title"] = title
+ data["message"] = message
+ data["buttons"] = buttons
+ return data
+
+/datum/tgui_list_input/ui_data(mob/user)
+ var/list/data = list()
+ if(timeout)
+ data["timeout"] = clamp((timeout - (world.time - start_time) - 1 SECONDS) / (timeout - 1 SECONDS), 0, 1)
+
+/datum/tgui_list_input/ui_act(action, list/params)
+ if(..())
+ return
+
+ . = TRUE
+
+ switch(action)
+ if("choose")
+ if(!(params["choice"] in buttons))
+ return
+ choice = buttons_map[params["choice"]]
+ SStgui.close_uis(src)
+ if("cancel")
+ SStgui.close_uis(src)
+ closed = TRUE
+
+/**
+ * # async tgui_list_input
+ *
+ * An asynchronous version of tgui_list_input to be used with callbacks instead of waiting on user responses.
+ */
+/datum/tgui_list_input/async
+ /// The callback to be invoked by the tgui_list_input upon having a choice made.
+ var/datum/callback/callback
+
+/datum/tgui_list_input/async/New(mob/user, message, title, list/buttons, timeout, callback)
+ ..()
+ src.callback = callback
+
+/datum/tgui_list_input/async/Destroy(force, ...)
+ QDEL_NULL(callback)
+ . = ..()
+
+/datum/tgui_list_input/async/ui_close(mob/user)
+ . = ..()
+ qdel(src)
+
+/datum/tgui_list_input/async/ui_act(action, list/params)
+ . = ..()
+ if(!. || choice == null)
+ return
+ callback.InvokeAsync(choice)
+ qdel(src)
+
+/datum/tgui_list_input/async/wait()
+ return
diff --git a/icons/_nanomaps/CereStation_nanomap_z1.png b/icons/_nanomaps/CereStation_nanomap_z1.png
index 07ed565ea7e7..c7ea1cc10a09 100644
Binary files a/icons/_nanomaps/CereStation_nanomap_z1.png and b/icons/_nanomaps/CereStation_nanomap_z1.png differ
diff --git a/icons/_nanomaps/Cyberiad_nanomap_z1.png b/icons/_nanomaps/Cyberiad_nanomap_z1.png
index a6eef0d86304..82b86d50776f 100644
Binary files a/icons/_nanomaps/Cyberiad_nanomap_z1.png and b/icons/_nanomaps/Cyberiad_nanomap_z1.png differ
diff --git a/icons/_nanomaps/Delta_nanomap_z1.png b/icons/_nanomaps/Delta_nanomap_z1.png
index bf42af5d0c5c..ea08217e00d2 100644
Binary files a/icons/_nanomaps/Delta_nanomap_z1.png and b/icons/_nanomaps/Delta_nanomap_z1.png differ
diff --git a/icons/_nanomaps/MetaStation_nanomap_z1.png b/icons/_nanomaps/MetaStation_nanomap_z1.png
index 503051f13692..87cff412b31b 100644
Binary files a/icons/_nanomaps/MetaStation_nanomap_z1.png and b/icons/_nanomaps/MetaStation_nanomap_z1.png differ
diff --git a/icons/mob/hud/sechud.dmi b/icons/mob/hud/sechud.dmi
index a8a9c7a9bfa9..193e3b323456 100644
Binary files a/icons/mob/hud/sechud.dmi and b/icons/mob/hud/sechud.dmi differ
diff --git a/icons/obj/baton.dmi b/icons/obj/baton.dmi
new file mode 100644
index 000000000000..4003a6f4055c
Binary files /dev/null and b/icons/obj/baton.dmi differ
diff --git a/icons/obj/bedsheet.dmi b/icons/obj/bedsheet.dmi
new file mode 100644
index 000000000000..d3af437208f7
Binary files /dev/null and b/icons/obj/bedsheet.dmi differ
diff --git a/icons/obj/card.dmi b/icons/obj/card.dmi
index d6a4b47392f9..7596aae9be05 100644
Binary files a/icons/obj/card.dmi and b/icons/obj/card.dmi differ
diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi
index e4581d18ab60..559cd27cd806 100644
Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ
diff --git a/icons/obj/energy_melee.dmi b/icons/obj/energy_melee.dmi
new file mode 100644
index 000000000000..07f3290f21a2
Binary files /dev/null and b/icons/obj/energy_melee.dmi differ
diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi
index a885ed81d0be..05e713412ed1 100644
Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ
diff --git a/icons/obj/lighter.dmi b/icons/obj/lighter.dmi
new file mode 100644
index 000000000000..6c4846a6d798
Binary files /dev/null and b/icons/obj/lighter.dmi differ
diff --git a/icons/obj/mining_tool.dmi b/icons/obj/mining_tool.dmi
new file mode 100644
index 000000000000..e922b9afa840
Binary files /dev/null and b/icons/obj/mining_tool.dmi differ
diff --git a/icons/obj/paint.dmi b/icons/obj/paint.dmi
new file mode 100644
index 000000000000..58e1fb9efdb0
Binary files /dev/null and b/icons/obj/paint.dmi differ
diff --git a/icons/obj/restraints.dmi b/icons/obj/restraints.dmi
new file mode 100644
index 000000000000..8b05944f8c3b
Binary files /dev/null and b/icons/obj/restraints.dmi differ
diff --git a/icons/obj/ruin_objects.dmi b/icons/obj/ruin_objects.dmi
new file mode 100644
index 000000000000..a170911c537b
Binary files /dev/null and b/icons/obj/ruin_objects.dmi differ
diff --git a/icons/obj/shield.dmi b/icons/obj/shield.dmi
new file mode 100644
index 000000000000..cfbd178c1132
Binary files /dev/null and b/icons/obj/shield.dmi differ
diff --git a/icons/obj/space/voyager.dmi b/icons/obj/space/voyager.dmi
deleted file mode 100644
index 70d66df2522e..000000000000
Binary files a/icons/obj/space/voyager.dmi and /dev/null differ
diff --git a/icons/obj/spear.dmi b/icons/obj/spear.dmi
new file mode 100644
index 000000000000..725e5a9718a5
Binary files /dev/null and b/icons/obj/spear.dmi differ
diff --git a/icons/obj/toy.dmi b/icons/obj/toy.dmi
index 276f34b86292..8782e222d2b9 100644
Binary files a/icons/obj/toy.dmi and b/icons/obj/toy.dmi differ
diff --git a/modular_ss220/loadout/code/donor_items.dm b/modular_ss220/loadout/code/donor_items.dm
index 5c0709ff29d8..1d7c901c161c 100644
--- a/modular_ss220/loadout/code/donor_items.dm
+++ b/modular_ss220/loadout/code/donor_items.dm
@@ -3,8 +3,8 @@
icon_state = "firstaid"
/obj/item/storage/firstaid/regular/donor/populate_contents()
- new /obj/item/reagent_containers/food/pill/patch/styptic(src)
- new /obj/item/reagent_containers/food/pill/salicylic(src)
- new /obj/item/reagent_containers/food/pill/patch/silver_sulf(src)
+ new /obj/item/reagent_containers/patch/styptic(src)
+ new /obj/item/reagent_containers/pill/salicylic(src)
+ new /obj/item/reagent_containers/patch/silver_sulf(src)
new /obj/item/healthanalyzer(src)
new /obj/item/reagent_containers/hypospray/autoinjector/epinephrine(src)
diff --git a/modular_ss220/vending/code/vending.dm b/modular_ss220/vending/code/vending.dm
index 3612d261cb81..dc8913719c4f 100644
--- a/modular_ss220/vending/code/vending.dm
+++ b/modular_ss220/vending/code/vending.dm
@@ -106,14 +106,14 @@
/obj/item/storage/belt/medical/surgery/loaded = 2,
/obj/item/storage/belt/medical/response_team = 3,
/obj/item/storage/pill_bottle = 4,
- /obj/item/reagent_containers/food/pill/mannitol = 10,
- /obj/item/reagent_containers/food/pill/salbutamol = 10,
- /obj/item/reagent_containers/food/pill/morphine = 8,
- /obj/item/reagent_containers/food/pill/charcoal = 10,
- /obj/item/reagent_containers/food/pill/mutadone = 8,
+ /obj/item/reagent_containers/pill/mannitol = 10,
+ /obj/item/reagent_containers/pill/salbutamol = 10,
+ /obj/item/reagent_containers/pill/morphine = 8,
+ /obj/item/reagent_containers/pill/charcoal = 10,
+ /obj/item/reagent_containers/pill/mutadone = 8,
/obj/item/storage/pill_bottle/patch_pack = 4,
- /obj/item/reagent_containers/food/pill/patch/silver_sulf = 10,
- /obj/item/reagent_containers/food/pill/patch/styptic = 10,
+ /obj/item/reagent_containers/patch/silver_sulf = 10,
+ /obj/item/reagent_containers/patch/styptic = 10,
/obj/item/storage/firstaid/surgery = 2,
/obj/item/scalpel/laser = 2,
/obj/item/reagent_containers/applicator/brute = 10,
diff --git a/paradise.dme b/paradise.dme
index f72a5b5f712d..438f05c686b1 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -2728,6 +2728,7 @@
#include "code\modules\tgui\modules\module_base.dm"
#include "code\modules\tgui\modules\power_monitor.dm"
#include "code\modules\tgui\modules\robot_self_diagnosis.dm"
+#include "code\modules\tgui\modules\tgui_input_list.dm"
#include "code\modules\tgui\modules\volume_mixer.dm"
#include "code\modules\tgui\plugins\modal.dm"
#include "code\modules\tgui\plugins\tgui_login.dm"
diff --git a/tgui/packages/tgui/components/Autofocus.js b/tgui/packages/tgui/components/Autofocus.js
new file mode 100644
index 000000000000..726d96717e12
--- /dev/null
+++ b/tgui/packages/tgui/components/Autofocus.js
@@ -0,0 +1,19 @@
+import { Component, createRef } from 'inferno';
+
+export class Autofocus extends Component {
+ ref = createRef();
+
+ componentDidMount() {
+ setTimeout(() => {
+ this.ref.current?.focus();
+ }, 1);
+ }
+
+ render() {
+ return (
+