diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm
index 554721ff40e..164ff065758 100644
--- a/code/game/gamemodes/heist/heist.dm
+++ b/code/game/gamemodes/heist/heist.dm
@@ -134,7 +134,7 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind'
return 0
for(var/obj/stack in cortical_stacks)
- if (get_area(stack) != locate(/area/shuttle/vox/station))
+ if (get_area(stack.loc) != locate(/area/shuttle/vox/station))
return 0
return 1
diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm
index 824fd231180..5667a13a40d 100644
--- a/code/game/machinery/alarm.dm
+++ b/code/game/machinery/alarm.dm
@@ -824,12 +824,18 @@
ui.open()
ui.set_auto_update(1)
-/obj/machinery/alarm/proc/is_authenticated(mob/user as mob)
- if(isAI(user) || isrobot(user))
+/obj/machinery/alarm/proc/is_authenticated(mob/user as mob, href_list)
+ if(isAI(user) || isrobot(user) || emagged || is_auth_rcon(href_list))
return 1
else
return !locked
+/obj/machinery/alarm/proc/is_auth_rcon(href_list)
+ if(href_list["remote_connection"] && href_list["remote_access"])
+ return 1
+ else
+ return 0
+
/obj/machinery/alarm/CanUseTopic(var/mob/user, var/datum/topic_state/state, var/href_list = list())
if(buildstage != 2)
return STATUS_CLOSE
@@ -842,8 +848,8 @@
if(. == STATUS_INTERACTIVE)
var/extra_href = state.href_list(usr)
- // Prevent remote users from altering RCON settings unless they already have access
- if(href_list["rcon"] && extra_href["remote_connection"] && !extra_href["remote_access"])
+ // Prevent remote users from altering RCON settings or activating atmos alarms unless they already have access
+ if((href_list["atmos_alarm"] || href_list["rcon"]) && extra_href["remote_connection"] && !extra_href["remote_access"])
. = STATUS_UPDATE
return min(..(), .)
@@ -851,6 +857,8 @@
if(..(href, href_list, nowindow, state))
return 1
+ var/state_href = state.href_list(usr)
+
if(href_list["rcon"])
var/attempted_rcon_setting = text2num(href_list["rcon"])
switch(attempted_rcon_setting)
@@ -865,7 +873,7 @@
add_fingerprint(usr)
if(href_list["command"])
- if(!is_authenticated(usr))
+ if(!is_authenticated(usr, state_href))
return
var/device_id = href_list["id_tag"]
@@ -920,7 +928,7 @@
tlv.vars[varname] = newval
if(href_list["screen"])
- if(!is_authenticated(usr))
+ if(!is_authenticated(usr, state_href))
return
screen = text2num(href_list["screen"])
@@ -941,7 +949,7 @@
return 1
if(href_list["mode"])
- if(!is_authenticated(usr))
+ if(!is_authenticated(usr, state_href))
return
mode = text2num(href_list["mode"])
@@ -949,7 +957,7 @@
return 1
if(href_list["preset"])
- if(!is_authenticated(usr))
+ if(!is_authenticated(usr, state_href))
return
preset = text2num(href_list["preset"])
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index fe251b080f8..5dad4ba1170 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -464,11 +464,9 @@
usr << "There is no coin in this machine."
return
- coin.loc = src.loc
- if(!usr.get_active_hand())
- usr.put_in_hands(coin)
- usr << "\blue You remove the [coin] from the [src]"
+ usr.put_in_hands(coin)
coin = null
+ usr << "\blue You remove the [coin] from the [src]"
categories &= ~CAT_COIN
if (href_list["pay"])
@@ -560,9 +558,11 @@
user << "\blue You successfully pull the coin out before the [src] could swallow it."
else
user << "\blue You weren't able to pull the coin out fast enough, the machine ate it, string and all."
+ coin = null
qdel(coin)
categories &= ~CAT_COIN
else
+ coin = null
qdel(coin)
categories &= ~CAT_COIN
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index d5d1705dae5..6e8df50c0e7 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -342,7 +342,7 @@
if(istype(src, /obj/item/clothing/under) || istype(src, /obj/item/clothing/suit))
if(FAT in H.mutations)
- testing("[M] TOO FAT TO WEAR [src]!")
+ //testing("[M] TOO FAT TO WEAR [src]!")
if(!(flags & ONESIZEFITSALL))
if(!disable_warning)
H << "\red You're too fat to wear the [name]."
diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm
index 878efa196b9..b092d31e6d9 100644
--- a/code/game/objects/items/weapons/cards_ids.dm
+++ b/code/game/objects/items/weapons/cards_ids.dm
@@ -210,10 +210,18 @@
/obj/item/weapon/card/id/syndicate
name = "agent card"
- access = list(access_maint_tunnels, access_syndicate, access_external_airlocks)
+ var/list/initial_access = list(access_maint_tunnels, access_syndicate, access_external_airlocks)
origin_tech = "syndicate=3"
var/registered_user = null
-
+
+/obj/item/weapon/card/id/syndicate/New()
+ access = initial_access.Copy()
+ ..()
+
+/obj/item/weapon/card/id/syndicate/vox
+ name = "agent card"
+ initial_access = list(access_maint_tunnels, access_vox, access_external_airlocks)
+
/obj/item/weapon/card/id/syndicate/afterattack(var/obj/item/weapon/O as obj, mob/user as mob, proximity)
if(!proximity)
return
@@ -408,7 +416,7 @@
blood_type = initial(blood_type)
dna_hash = initial(dna_hash)
fingerprint_hash = initial(fingerprint_hash)
- access = initial(access)
+ access = initial_access.Copy() // Initial() doesn't work on lists
registered_user = null
user << "All information has been deleted from \the [src]."
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index 595bd5cad2d..467bceac1b8 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -47,6 +47,7 @@
/obj/Destroy()
machines -= src
processing_objects -= src
+ nanomanager.close_uis(src)
return ..()
/obj/item/proc/is_used_on(obj/O, mob/user)
diff --git a/code/modules/admin/verbs/striketeam_syndicate.dm b/code/modules/admin/verbs/striketeam_syndicate.dm
index f9ea83e4ba9..3113e58c2be 100644
--- a/code/modules/admin/verbs/striketeam_syndicate.dm
+++ b/code/modules/admin/verbs/striketeam_syndicate.dm
@@ -172,7 +172,7 @@ var/global/sent_syndicate_strike_team = 0
W.icon_state = "syndie"
W.access = get_all_accesses()//They get full station access because obviously the syndicate has HAAAX, and can make special IDs for their most elite members.
W.assignment = "Syndicate Commando"
- W.access = get_syndicate_access(W.assignment)
+ W.access += get_syndicate_access(W.assignment)
W.registered_name = real_name
equip_to_slot_or_del(W, slot_wear_id)
diff --git a/code/modules/admin/verbs/vox_raiders.dm b/code/modules/admin/verbs/vox_raiders.dm
index fc6c410b770..33854109bc4 100644
--- a/code/modules/admin/verbs/vox_raiders.dm
+++ b/code/modules/admin/verbs/vox_raiders.dm
@@ -52,10 +52,8 @@ var/global/vox_tick = 1
equip_to_slot_or_del(new /obj/item/weapon/tank/nitrogen(src), slot_back)
equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_r_store)
- var/obj/item/weapon/card/id/syndicate/W = new(src)
+ var/obj/item/weapon/card/id/syndicate/vox/W = new(src)
W.name = "[real_name]'s Legitimate Human ID Card"
- W.icon_state = "id"
- W.access = list(access_vox)
W.assignment = "Trader"
W.registered_name = real_name
W.registered_user = src
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 556bacbdf96..d2ad4b9dd71 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -431,7 +431,9 @@
var/armor_block = run_armor_check(affecting, "melee")
apply_damage(damage, BRUTE, affecting, armor_block)
-/mob/living/carbon/human/proc/is_loyalty_implanted(mob/living/carbon/human/M)
+/mob/living/carbon/human/proc/is_loyalty_implanted(mob/living/carbon/human/M)
+ if(!istype(M))
+ return 0
for(var/L in M.contents)
if(istype(L, /obj/item/weapon/implant/loyalty))
for(var/obj/item/organ/external/O in M.organs)
diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm
index cf8f0204d00..a5729c0f8ac 100644
--- a/code/modules/mob/living/carbon/human/species/station.dm
+++ b/code/modules/mob/living/carbon/human/species/station.dm
@@ -452,6 +452,9 @@
blood_color = "#1F181F"
flesh_color = "#AAAAAA"
reagent_tag = PROCESS_SYN
+
+ has_organ = list(
+ )
/datum/species/machine/handle_death(var/mob/living/carbon/human/H)
H.emote("deathgasp")
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index e0b987a60ba..f7db0be92ab 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -213,6 +213,7 @@ var/global/list/damage_icon_parts = list()
if(O.damage_state == "00") continue
var/icon/DI
var/cache_index = "[O.damage_state]/[O.icon_name]/[species.blood_color]/[species.name]"
+
if(damage_icon_parts[cache_index] == null)
DI = new /icon(species.damage_overlays, O.damage_state) // the damage icon for whole human
DI.Blend(new /icon(species.damage_mask, O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels
diff --git a/code/modules/mob/living/simple_animal/revenant/revenant.dm b/code/modules/mob/living/simple_animal/revenant/revenant.dm
index 659a38fda51..bad520aa326 100644
--- a/code/modules/mob/living/simple_animal/revenant/revenant.dm
+++ b/code/modules/mob/living/simple_animal/revenant/revenant.dm
@@ -216,7 +216,7 @@
..()
/datum/objective/revenant/check_completion()
- if(!istype(owner.current, /mob/living/simple_animal/revenant) || !owner.current)
+ if(!owner || !istype(owner.current, /mob/living/simple_animal/revenant))
return 0
var/mob/living/simple_animal/revenant/R = owner.current
if(!R || R.stat == DEAD)
diff --git a/code/modules/nano/interaction/base.dm b/code/modules/nano/interaction/base.dm
index 401a82cb919..85ac56eeedc 100644
--- a/code/modules/nano/interaction/base.dm
+++ b/code/modules/nano/interaction/base.dm
@@ -27,7 +27,7 @@
/mob/living/silicon/robot/shared_nano_interaction()
. = STATUS_INTERACTIVE
- if(cell.charge <= 0)
+ if(!cell || cell.charge <= 0)
return STATUS_CLOSE
if(lockcharge)
. = STATUS_DISABLED
diff --git a/code/modules/nano/modules/atmos_control.dm b/code/modules/nano/modules/atmos_control.dm
index 5a12c4db8a3..52da17c2c82 100644
--- a/code/modules/nano/modules/atmos_control.dm
+++ b/code/modules/nano/modules/atmos_control.dm
@@ -27,7 +27,6 @@
if(alarm)
var/datum/topic_state/TS = generate_state(alarm)
alarm.ui_interact(usr, master_ui = ui_ref, state = TS)
- return 1
/datum/nano_module/atmos_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state)
var/data[0]
@@ -69,4 +68,4 @@
return extra_href
/datum/topic_state/air_alarm/proc/has_access(var/mob/user)
- return user && (isAI(user) || atmos_control.access.allowed(user) || atmos_control.emagged || air_alarm.rcon_setting == RCON_YES || (air_alarm.alarm_area.atmosalm && air_alarm.rcon_setting == RCON_AUTO))
+ return user && (isAI(user) || atmos_control.access.allowed(user) || atmos_control.emagged || air_alarm.rcon_setting == RCON_YES || air_alarm.emagged || (air_alarm.alarm_area.atmosalm && air_alarm.rcon_setting == RCON_AUTO))
diff --git a/code/modules/nano/nanomanager.dm b/code/modules/nano/nanomanager.dm
index bb73178e94a..fcd2152f561 100644
--- a/code/modules/nano/nanomanager.dm
+++ b/code/modules/nano/nanomanager.dm
@@ -104,6 +104,26 @@
update_count++
return update_count
+ /**
+ * Close all /nanoui uis attached to src_object
+ *
+ * @param src_object /obj|/mob The obj or mob which the uis are attached to
+ *
+ * @return int The number of uis close
+ */
+/datum/nanomanager/proc/close_uis(src_object)
+ var/src_object_key = "\ref[src_object]"
+ if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
+ return 0
+
+ var/close_count = 0
+ for (var/ui_key in open_uis[src_object_key])
+ for (var/datum/nanoui/ui in open_uis[src_object_key][ui_key])
+ if(ui && ui.src_object && ui.user && ui.src_object.nano_host())
+ ui.close()
+ close_count++
+ return close_count
+
/**
* Update /nanoui uis belonging to user
*
diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm
index a116655e87e..f133dff4a16 100644
--- a/code/modules/power/smes.dm
+++ b/code/modules/power/smes.dm
@@ -150,7 +150,7 @@
return
if(terminal) //is there already a terminal ?
- user << "This SMES already have a power terminal!"
+ user << "This SMES already has a power terminal!"
return
if(!panel_open) //is the panel open ?
@@ -162,31 +162,14 @@
user << "You must first remove the floor plating!"
return
-
var/obj/item/stack/cable_coil/C = I
if(C.amount < 10)
user << "You need more wires."
return
- user << "You start building the power terminal..."
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
-
- if(do_after(user, 20) && C.amount >= 10)
- var/obj/structure/cable/N = T.get_cable_node() //get the connecting node cable, if there's one
- if (prob(50) && electrocute_mob(usr, N, N)) //animate the electrocution if uncautious and unlucky
- var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- s.set_up(5, 1, src)
- s.start()
- return
-
- C.use(10)
- user.visible_message(\
- "[user.name] has built a power terminal!",\
- "You build the power terminal.")
-
- //build the terminal and link it to the network
- make_terminal(T)
- terminal.connect_to_network()
+ //build the terminal and link it to the network
+ make_terminal(user)
+ terminal.connect_to_network()
return
//disassembling the terminal
@@ -196,7 +179,7 @@
user << "You must first expose the power terminal!"
return
- user << "You begin to dismantle the power terminal..."
+ user << "You begin to dismantle the power terminal..."
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
if(do_after(user, 50))
@@ -210,13 +193,20 @@
new /obj/item/stack/cable_coil(T,10)
user.visible_message(\
"[user.name] cuts the cables and dismantles the power terminal.",\
- "You cut the cables and dismantle the power terminal.")
+ "You cut the cables and dismantle the power terminal.")
inputting = 0 //stop inputting, since we have don't have a terminal anymore
qdel(terminal)
return
//crowbarring it !
default_deconstruction_crowbar(I)
+
+/obj/machinery/power/smes/disconnect_terminal()
+ if(terminal)
+ terminal.master = null
+ terminal = null
+ return 1
+ return 0
/obj/machinery/power/smes/Destroy()
if(ticker && ticker.current_state == GAME_STATE_PLAYING)
@@ -332,6 +322,18 @@
return 1
user << "You start adding cable to the [src]."
if(do_after(user, 50))
+ var/turf/T = get_turf(user)
+ var/obj/structure/cable/N = T.get_cable_node() //get the connecting node cable, if there's one
+ if (prob(50) && electrocute_mob(user, N, N)) //animate the electrocution if uncautious and unlucky
+ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+ s.set_up(5, 1, src)
+ s.start()
+ return
+
+ user.visible_message(\
+ "[user.name] adds the cables and connects the power terminal.",\
+ "You add the cables and connect the power terminal.")
+
terminal = new /obj/machinery/power/terminal(tempLoc)
terminal.dir = tempDir
terminal.master = src
diff --git a/code/modules/reagents/newchem/newchem_procs.dm b/code/modules/reagents/newchem/newchem_procs.dm
index edeed358cf0..5c87c0f0044 100644
--- a/code/modules/reagents/newchem/newchem_procs.dm
+++ b/code/modules/reagents/newchem/newchem_procs.dm
@@ -17,6 +17,8 @@ datum/reagents/proc/metabolize(var/mob/M)
handle_reactions()
for(var/A in reagent_list)
var/datum/reagent/R = A
+ if(!istype(R))
+ continue
if(ishuman(M))
var/mob/living/carbon/human/H = M
//Check if this mob's species is set and can process this type of reagent
diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm
index 73dd13a1d58..d77edbb6903 100644
--- a/code/modules/reagents/reagent_containers/food/snacks.dm
+++ b/code/modules/reagents/reagent_containers/food/snacks.dm
@@ -37,7 +37,7 @@
return
/obj/item/weapon/reagent_containers/food/snacks/attack(mob/M as mob, mob/user as mob, def_zone)
- if(!reagents.total_volume) //Shouldn't be needed but it checks to see if it has anything left in it.
+ if(reagents && !reagents.total_volume) //Shouldn't be needed but it checks to see if it has anything left in it.
user << "\red None of [src] left, oh no!"
M.unEquip(src) //so icons update :[
qdel(src)
diff --git a/icons/mob/human_races/r_slime.dmi b/icons/mob/human_races/r_slime.dmi
index b79a50f7fda..5b30997c6a6 100644
Binary files a/icons/mob/human_races/r_slime.dmi and b/icons/mob/human_races/r_slime.dmi differ