diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index f37feeea34..58238247ff 100755
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -609,9 +609,9 @@ SUBSYSTEM_DEF(ticker)
var/list/ded = SSblackbox.first_death
if(ded.len)
var/last_words = ded["last_words"] ? " Their last words were: \"[ded["last_words"]]\"" : ""
- news_message += " NT Sanctioned Psykers picked up faint traces of someone near the station, allegedly having had died. Their name was: [ded["name"]], [ded["role"]], at [ded["area"]].[last_words]"
+ news_message += "\nNT Sanctioned Psykers picked up faint traces of someone near the station, allegedly having had died. Their name was: [ded["name"]], [ded["role"]], at [ded["area"]].[last_words]"
else
- news_message += " NT Sanctioned Psykers proudly confirm reports that nobody died this shift!"
+ news_message += "\nNT Sanctioned Psykers proudly confirm reports that nobody died this shift!"
if(news_message)
send2otherserver(news_source, news_message,"News_Report")
diff --git a/code/datums/shuttles.dm b/code/datums/shuttles.dm
index 62f8cef5dc..add0668950 100644
--- a/code/datums/shuttles.dm
+++ b/code/datums/shuttles.dm
@@ -204,12 +204,11 @@
// first 10 minutes only
return world.time - SSticker.round_start_time < 6000
-// this is broken and does not work. Thanks TG
-// /datum/map_template/shuttle/emergency/airless/post_load()
-// . = ..()
-// //enable buying engines from cargo
-// var/datum/supply_pack/P = SSshuttle.supply_packs[/datum/supply_pack/engineering/shuttle_engine]
-// P.special_enabled = TRUE
+/datum/map_template/shuttle/emergency/construction/post_load()
+ . = ..()
+ //enable buying engines from cargo
+ var/datum/supply_pack/P = SSshuttle.supply_packs[/datum/supply_pack/engineering/shuttle_engine]
+ P.special_enabled = TRUE
/datum/map_template/shuttle/emergency/asteroid
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index d8a5f7d2c7..0e7b4aa0fa 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -48,13 +48,14 @@
)
/obj/machinery/autolathe/Initialize()
- AddComponent(/datum/component/material_container, SSmaterials.materialtypes_by_category[MAT_CATEGORY_RIGID], 0, TRUE, null, null, CALLBACK(src, .proc/AfterMaterialInsert))
. = ..()
-
wires = new /datum/wires/autolathe(src)
stored_research = new /datum/techweb/specialized/autounlocking/autolathe
matching_designs = list()
+/obj/machinery/autolathe/ComponentInitialize()
+ AddComponent(/datum/component/material_container, SSmaterials.materialtypes_by_category[MAT_CATEGORY_RIGID], 0, TRUE, null, null, CALLBACK(src, .proc/AfterMaterialInsert))
+
/obj/machinery/autolathe/Destroy()
QDEL_NULL(wires)
return ..()
@@ -439,6 +440,9 @@
/obj/machinery/autolathe/secure/Initialize()
. = ..()
+ // let's not leave the parent datum floating, right?
+ if(stored_research)
+ QDEL_NULL(stored_research)
stored_research = new /datum/techweb/specialized/autounlocking/autolathe/public
/obj/machinery/autolathe/toy
@@ -457,8 +461,18 @@
"Misc",
"Imported"
)
+/obj/machinery/autolathe/toy/Initialize()
+ . = ..()
+ // let's not leave the parent datum floating, right?
+ if(stored_research)
+ QDEL_NULL(stored_research)
+ stored_research = new /datum/techweb/specialized/autounlocking/autolathe/toy
/obj/machinery/autolathe/toy/hacked/Initialize()
. = ..()
adjust_hacked(TRUE)
- stored_research = new /datum/techweb/specialized/autounlocking/autolathe/toy
+
+// override the base to allow plastics
+/obj/machinery/autolathe/ComponentInitialize()
+ var/list/extra_mats = list(/datum/material/plastic)
+ AddComponent(/datum/component/material_container, SSmaterials.materialtypes_by_category[MAT_CATEGORY_RIGID] + extra_mats, 0, TRUE, null, null, CALLBACK(src, .proc/AfterMaterialInsert))
diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm
index d5bbcb0adc..bdf7a80c96 100644
--- a/code/game/machinery/constructable_frame.dm
+++ b/code/game/machinery/constructable_frame.dm
@@ -36,7 +36,7 @@
/obj/structure/frame/machine/examine(user)
. = ..()
if(state == 3 && req_components && req_component_names)
- var/hasContent = 0
+ var/hasContent = FALSE
var/requires = "It requires"
for(var/i = 1 to req_components.len)
@@ -46,10 +46,10 @@
continue
var/use_and = i == req_components.len
requires += "[(hasContent ? (use_and ? ", and" : ",") : "")] [amt] [amt == 1 ? req_component_names[tname] : "[req_component_names[tname]]\s"]"
- hasContent = 1
+ hasContent = TRUE
if(hasContent)
- . += requires + "."
+ . += "[requires]."
else
. += "It does not require any more components."
@@ -76,7 +76,7 @@
amt += req_components[path]
return amt
-/obj/structure/frame/machine/attackby(obj/item/P, mob/user, params)
+/obj/structure/frame/machine/attackby(obj/item/P, mob/living/user, params)
switch(state)
if(1)
if(istype(P, /obj/item/circuitboard/machine))
@@ -88,6 +88,7 @@
if(istype(P, /obj/item/stack/cable_coil))
if(!P.tool_start_check(user, amount=5))
return
+
to_chat(user, "You start to add cables to the frame...")
if(P.use_tool(src, user, 20, volume=50, amount=5, extra_checks = CALLBACK(src, .proc/check_state, 1)))
to_chat(user, "You add cables to the frame.")
@@ -97,39 +98,41 @@
return
if(P.tool_behaviour == TOOL_SCREWDRIVER && !anchored)
user.visible_message("[user] disassembles the frame.", \
- "You start to disassemble the frame...", "You hear banging and clanking.")
+ "You start to disassemble the frame...", "You hear banging and clanking.")
if(P.use_tool(src, user, 40, volume=50, extra_checks = CALLBACK(src, .proc/check_state, 1)))
- to_chat(user, "You disassemble the frame.")
- var/obj/item/stack/sheet/metal/M = new (loc, 5)
- M.add_fingerprint(user)
- qdel(src)
+ if(state == 1)
+ to_chat(user, "You disassemble the frame.")
+ var/obj/item/stack/sheet/metal/M = new (loc, 5)
+ M.add_fingerprint(user)
+ qdel(src)
return
if(P.tool_behaviour == TOOL_WRENCH)
- to_chat(user, "You start [anchored ? "un" : ""]securing [name]...")
+ to_chat(user, "You start [anchored ? "un" : ""]securing [src]...")
if(P.use_tool(src, user, 40, volume=75, extra_checks = CALLBACK(src, .proc/check_state, 1)))
- to_chat(user, "You [anchored ? "un" : ""]secure [name].")
- setAnchored(!anchored)
+ if(state == 1)
+ to_chat(user, "You [anchored ? "un" : ""]secure [src].")
+ set_anchored(!anchored)
return
if(2)
if(P.tool_behaviour == TOOL_WRENCH)
- to_chat(user, "You start [anchored ? "un" : ""]securing [name]...")
+ to_chat(user, "You start [anchored ? "un" : ""]securing [src]...")
if(P.use_tool(src, user, 40, volume=75, extra_checks = CALLBACK(src, .proc/check_state, 2)))
- to_chat(user, "You [anchored ? "un" : ""]secure [name].")
- setAnchored(!anchored)
+ to_chat(user, "You [anchored ? "un" : ""]secure [src].")
+ set_anchored(!anchored)
return
if(istype(P, /obj/item/circuitboard/machine))
var/obj/item/circuitboard/machine/B = P
if(!B.build_path)
- to_chat(user, "This circuitboard seems to be broken.")
+ to_chat(user, "This circuitboard seems to be broken.")
return
if(!anchored && B.needs_anchored)
to_chat(user, "The frame needs to be secured first!")
return
if(!user.transferItemToLoc(B, src))
return
- playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, TRUE)
to_chat(user, "You add the circuit board to the frame.")
circuit = B
icon_state = "box_2"
@@ -171,34 +174,49 @@
return
if(P.tool_behaviour == TOOL_WRENCH && !circuit.needs_anchored)
- to_chat(user, "You start [anchored ? "un" : ""]securing [name]...")
+ to_chat(user, "You start [anchored ? "un" : ""]securing [src]...")
if(P.use_tool(src, user, 40, volume=75, extra_checks = CALLBACK(src, .proc/check_state, 3)))
- to_chat(user, "You [anchored ? "un" : ""]secure [name].")
- setAnchored(!anchored)
+ to_chat(user, "You [anchored ? "un" : ""]secure [src].")
+ set_anchored(!anchored)
return
if(P.tool_behaviour == TOOL_SCREWDRIVER)
- var/component_check = 1
+ var/component_check = TRUE
for(var/R in req_components)
if(req_components[R] > 0)
- component_check = 0
+ component_check = FALSE
break
if(component_check)
P.play_tool_sound(src)
var/obj/machinery/new_machine = new circuit.build_path(loc)
- if(new_machine.circuit)
- QDEL_NULL(new_machine.circuit)
- new_machine.circuit = circuit
- new_machine.setAnchored(anchored)
- new_machine.on_construction()
- for(var/obj/O in new_machine.component_parts)
- qdel(O)
- new_machine.component_parts = list()
- for(var/obj/O in src)
- O.moveToNullspace()
- new_machine.component_parts += O
- circuit.moveToNullspace()
- new_machine.RefreshParts()
+ if(istype(new_machine))
+ // Machines will init with a set of default components. Move to nullspace so we don't trigger handle_atom_del, then qdel.
+ // Finally, replace with this frame's parts.
+ if(new_machine.circuit)
+ // Move to nullspace and delete.
+ new_machine.circuit.moveToNullspace()
+ QDEL_NULL(new_machine.circuit)
+ for(var/obj/old_part in new_machine.component_parts)
+ // Move to nullspace and delete.
+ old_part.moveToNullspace()
+ qdel(old_part)
+
+ // Set anchor state and move the frame's parts over to the new machine.
+ // Then refresh parts and call on_construction().
+
+ new_machine.set_anchored(anchored)
+ new_machine.component_parts = list()
+
+ circuit.forceMove(new_machine)
+ new_machine.component_parts += circuit
+ new_machine.circuit = circuit
+
+ for(var/obj/new_part in src)
+ new_part.forceMove(new_machine)
+ new_machine.component_parts += new_part
+ new_machine.RefreshParts()
+
+ new_machine.on_construction()
qdel(src)
return
@@ -232,12 +250,15 @@
for(var/obj/item/part in added_components)
if(istype(part,/obj/item/stack))
- var/obj/item/stack/S = part
- var/obj/item/stack/NS = locate(S.merge_type) in components //find a stack to merge with
- if(NS)
- S.merge(NS)
+ var/obj/item/stack/incoming_stack = part
+ for(var/obj/item/stack/merge_stack in components)
+ if(incoming_stack.can_merge(merge_stack))
+ incoming_stack.merge(merge_stack)
+ if(QDELETED(incoming_stack))
+ break
if(!QDELETED(part)) //If we're a stack and we merged we might not exist anymore
components += part
+ part.forceMove(src)
to_chat(user, "[part.name] applied.")
if(added_components.len)
replacer.play_rped_sound()
@@ -267,9 +288,9 @@
to_chat(user, "You add [P] to [src].")
components += P
req_components[I]--
- return 1
+ return TRUE
to_chat(user, "You cannot add that to the machine!")
- return 0
+ return FALSE
if(user.a_intent == INTENT_HARM)
return ..()
@@ -280,5 +301,4 @@
for(var/X in components)
var/obj/item/I = X
I.forceMove(loc)
-
..()
diff --git a/code/game/objects/items/circuitboards/computer_circuitboards.dm b/code/game/objects/items/circuitboards/computer_circuitboards.dm
index 01bed631fa..afab49ac76 100644
--- a/code/game/objects/items/circuitboards/computer_circuitboards.dm
+++ b/code/game/objects/items/circuitboards/computer_circuitboards.dm
@@ -549,6 +549,7 @@
contraband = TRUE
obj_flags |= EMAGGED
to_chat(user, "You adjust [src]'s routing and receiver spectrum, unlocking special supplies and contraband.")
+ return TRUE
/obj/item/circuitboard/computer/cargo/configure_machine(obj/machinery/computer/cargo/machine)
if(!istype(machine))
@@ -565,10 +566,12 @@
build_path = /obj/machinery/computer/cargo/express
/obj/item/circuitboard/computer/cargo/express/emag_act(mob/living/user)
+ . = ..()
if(!(obj_flags & EMAGGED))
contraband = TRUE
obj_flags |= EMAGGED
to_chat(user, "You change the routing protocols, allowing the Drop Pod to land anywhere on the station.")
+ return TRUE
/obj/item/circuitboard/computer/cargo/express/multitool_act(mob/living/user)
if (!(obj_flags & EMAGGED))
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index 7b251c075b..d126e39873 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -459,8 +459,8 @@
/obj/item/stack/AltClick(mob/living/user)
. = ..()
- if(isturf(loc)) // to prevent people that are alt clicking a tile to see its content from getting undesidered pop ups
- return
+ // if(isturf(loc)) // to prevent people that are alt clicking a tile to see its content from getting undesidered pop ups
+ // return
if(is_cyborg || !user.canUseTopic(src, BE_CLOSE, TRUE, FALSE) || zero_amount()) //, !iscyborg(user)
return
//get amount from user
diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm
index 29961d12b4..92e0cee7e8 100644
--- a/code/game/objects/items/tanks/jetpack.dm
+++ b/code/game/objects/items/tanks/jetpack.dm
@@ -15,7 +15,7 @@
var/datum/effect_system/trail_follow/ion/ion_trail
/obj/item/tank/jetpack/Initialize()
- ..()
+ . = ..()
ion_trail = new
ion_trail.set_up(src)
@@ -88,7 +88,7 @@
return TRUE
/obj/item/tank/jetpack/suicide_act(mob/user)
- if (istype(user, /mob/living/carbon/human/))
+ if (ishuman(user))
var/mob/living/carbon/human/H = user
H.forcesay("WHAT THE FUCK IS CARBON DIOXIDE?")
H.visible_message("[user] is suffocating [user.p_them()]self with [src]! It looks like [user.p_they()] didn't read what that jetpack says!")
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index ed0f6b7012..c502e36ae8 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -4,6 +4,10 @@
icon = 'icons/obj/closet.dmi'
icon_state = "generic"
density = TRUE
+ max_integrity = 200
+ integrity_failure = 0.25
+ armor = list("melee" = 20, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 60)
+
var/icon_door = null
var/icon_door_override = FALSE //override to have open overlay use icon different to its base's
var/secure = FALSE //secure locker or not, also used if overriding a non-secure locker with a secure door overlay to add fancy lights
@@ -12,9 +16,6 @@
var/locked = FALSE
var/large = TRUE
var/wall_mounted = 0 //never solid (You can always pass over it)
- max_integrity = 200
- integrity_failure = 0.25
- armor = list("melee" = 20, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 60)
var/breakout_time = 1200
var/message_cooldown
var/can_weld_shut = TRUE
@@ -40,12 +41,12 @@
var/should_populate_contents = TRUE
/obj/structure/closet/Initialize(mapload)
+ if(mapload && !opened) // if closed, any item at the crate's loc is put in the contents
+ addtimer(CALLBACK(src, .proc/take_contents), 0)
. = ..()
update_icon()
if(should_populate_contents)
PopulateContents()
- if(mapload && !opened) // if closed, any item at the crate's loc is put in the contents
- addtimer(CALLBACK(src, .proc/take_contents), 0)
if(secure)
lockerelectronics = new(src)
lockerelectronics.accesses = req_access
@@ -60,10 +61,10 @@
/obj/structure/closet/update_icon()
. = ..()
- if(!opened)
- layer = OBJ_LAYER
- else
- layer = BELOW_OBJ_LAYER
+ if(istype(src, /obj/structure/closet/supplypod))
+ return
+
+ layer = opened ? BELOW_OBJ_LAYER : OBJ_LAYER
/obj/structure/closet/update_overlays()
. = ..()
@@ -71,61 +72,57 @@
/obj/structure/closet/proc/closet_update_overlays(list/new_overlays)
. = new_overlays
- if(!opened)
- if(icon_door)
- . += "[icon_door]_door"
- else
- . += "[icon_state]_door"
- if(welded)
- . += "welded"
- if(!secure)
- return
- if(broken)
- . += "off"
- . += "sparking"
- else if(locked)
- . += "locked"
- else
- . += "unlocked"
- else
- if(icon_door_override)
- . += "[icon_door]_open"
- else
- . += "[icon_state]_open"
+ if(opened)
+ . += "[icon_door_override ? icon_door : icon_state]_open"
+ return
+
+ . += "[icon_door || icon_state]_door"
+ if(welded)
+ . += icon_welded
+
+ if(!secure)
+ return
+ if(broken)
+ . += "off"
+ . += "sparking"
+ //Overlay is similar enough for both that we can use the same mask for both
+ SSvis_overlays.add_vis_overlay(src, icon, "locked", EMISSIVE_LAYER, EMISSIVE_PLANE, dir, alpha)
+ . += locked ? "locked" : "unlocked"
/obj/structure/closet/examine(mob/user)
. = ..()
if(welded)
- . += "It's welded shut."
+ . += "It's welded shut."
if(anchored)
. += "It is bolted to the ground."
if(opened)
. += "The parts are welded together."
else if(secure && !opened)
+ . += "Alt-click to [locked ? "unlock" : "lock"]."
else if(broken)
. += "The lock is screwed in."
- else if(secure)
- . += "Alt-click to [locked ? "unlock" : "lock"]."
- if(isliving(user))
- var/mob/living/L = user
- if(HAS_TRAIT(L, TRAIT_SKITTISH))
- . += "Ctrl-Shift-click [src] to jump inside."
+
if(isobserver(user))
. += "It contains: [english_list(contents)]."
investigate_log("had its contents examined by [user] as a ghost.", INVESTIGATE_GHOST)
+ if(HAS_TRAIT(user, TRAIT_SKITTISH))
+ . += "If you bump into [p_them()] while running, you will jump inside."
+
/obj/structure/closet/CanPass(atom/movable/mover, turf/target)
if(wall_mounted)
return TRUE
return !density
-/obj/structure/closet/proc/can_open(mob/living/user)
+/obj/structure/closet/proc/can_open(mob/living/user, force = FALSE)
+ if(force)
+ return TRUE
if(welded || locked)
return FALSE
var/turf/T = get_turf(src)
for(var/mob/living/L in T)
- if(L.move_resist >= MOVE_FORCE_VERY_STRONG || (horizontal && L.mob_size > MOB_SIZE_TINY && L.density))
+ if(L.anchored || L.move_resist >= MOVE_FORCE_VERY_STRONG || (horizontal && L.mob_size > MOB_SIZE_TINY && L.density))
if(user)
to_chat(user, "There's something large on top of [src], preventing it from opening." )
return FALSE
@@ -137,44 +134,16 @@
if(closet != src && !closet.wall_mounted)
return FALSE
for(var/mob/living/L in T)
- if(L.move_resist >= MOVE_FORCE_VERY_STRONG || horizontal && L.mob_size > MOB_SIZE_TINY && L.density)
+ if(L.anchored || L.move_resist >= MOVE_FORCE_VERY_STRONG || (horizontal && L.mob_size > MOB_SIZE_TINY && L.density))
if(user)
to_chat(user, "There's something too large in [src], preventing it from closing.")
return FALSE
return TRUE
-/obj/structure/closet/proc/can_lock(mob/living/user, var/check_access = TRUE) //set check_access to FALSE if you only need to check if a locker has a functional lock rather than access
- if(!secure)
- return FALSE
- if(broken)
- to_chat(user, "[src] is broken!")
- return FALSE
- if(QDELETED(lockerelectronics) && !locked) //We want to be able to unlock it regardless of electronics, but only lockable with electronics
- to_chat(user, "[src] is missing locker electronics!")
- return FALSE
- if(!check_access)
- return TRUE
- if(allowed(user))
- return TRUE
- to_chat(user, "Access denied.")
-
-/obj/structure/closet/proc/togglelock(mob/living/user)
- add_fingerprint(user)
- if(eigen_target)
- return
- if(opened)
- return
- if(!can_lock(user))
- return
- locked = !locked
- user.visible_message("[user] [locked ? null : "un"]locks [src].",
- "You [locked ? null : "un"]lock [src].")
- update_icon()
-
-/obj/structure/closet/proc/dump_contents(var/override = TRUE) //Override is for not revealing the locker electronics when you open the locker, for example
+/obj/structure/closet/proc/dump_contents(override = TRUE) //Override is for not revealing the locker electronics when you open the locker, for example
var/atom/L = drop_location()
for(var/atom/movable/AM in src)
- if(AM == lockerelectronics && override)
+ if(AM == lockerelectronics && override) // this stops the electronics from being dumped out? huh
continue
AM.forceMove(L)
if(throwing) // you keep some momentum when getting out of a thrown closet
@@ -187,18 +156,30 @@
for(var/atom/movable/AM in L)
if(AM != src && insert(AM) == -1) // limit reached
break
+ // for(var/i in reverseRange(L.GetAllContents()))
+ // var/atom/movable/thing = i
+ // SEND_SIGNAL(thing, COMSIG_TRY_STORAGE_HIDE_ALL)
-/obj/structure/closet/proc/open(mob/living/user)
- if(opened || !can_open(user))
+/obj/structure/closet/proc/open(mob/living/user, force = FALSE)
+ if(!can_open(user, force))
return
- playsound(loc, open_sound, 15, 1, -3)
+ if(opened)
+ return
+ welded = FALSE
+ locked = FALSE // if you manage to open it, then its not welded/locked, hello?!
+ playsound(loc, open_sound, 15, TRUE, -3)
opened = TRUE
if(!dense_when_open)
density = FALSE
climb_time *= 0.5 //it's faster to climb onto an open thing
dump_contents()
update_icon()
- return 1
+ after_open(user, force)
+ return TRUE
+
+///Proc to override for effects after opening a door
+/obj/structure/closet/proc/after_open(mob/living/user, force = FALSE)
+ return
/obj/structure/closet/proc/insert(atom/movable/AM)
if(contents.len >= storage_capacity)
@@ -208,19 +189,19 @@
do_teleport(AM, get_turf(eigen_target), 0)
if(eigen_target.opened == FALSE)
eigen_target.bust_open()
- else
- AM.forceMove(src)
+ return TRUE
+
+ AM.forceMove(src)
return TRUE
else
return FALSE
-
/obj/structure/closet/proc/insertion_allowed(atom/movable/AM)
if(ismob(AM))
if(!isliving(AM)) //let's not put ghosts or camera mobs inside closets...
return FALSE
var/mob/living/L = AM
- if(L.move_resist >= MOVE_FORCE_VERY_STRONG || L.buckled || L.incorporeal_move || L.has_buckled_mobs())
+ if(L.anchored || L.move_resist >= MOVE_FORCE_VERY_STRONG || L.buckled || L.incorporeal_move || L.has_buckled_mobs())
return FALSE
if(L.mob_size > MOB_SIZE_TINY) // Tiny mobs are treated as items.
if(horizontal && L.density)
@@ -236,13 +217,13 @@
else if(istype(AM, /obj/structure/closet))
return FALSE
- else if(istype(AM, /obj/effect))
+ else if(iseffect(AM)) // todo: move to atom/movable
return FALSE
else if(isobj(AM))
if((!allow_dense && AM.density) || AM.anchored || AM.has_buckled_mobs())
return FALSE
- if(isitem(AM) && !HAS_TRAIT(AM, TRAIT_NODROP))
+ else if(isitem(AM) && !HAS_TRAIT(AM, TRAIT_NODROP))
return TRUE
else if(!allow_objects && !istype(AM, /obj/effect/dummy/chameleon))
return FALSE
@@ -255,25 +236,356 @@
if(!opened || !can_close(user))
return FALSE
take_contents()
- playsound(loc, close_sound, 15, 1, -3)
- climb_time = initial(climb_time)
+ playsound(loc, close_sound, 15, TRUE, -3)
opened = FALSE
density = TRUE
update_icon()
+ after_close(user)
return TRUE
+///Proc to override for effects after closing a door
+/obj/structure/closet/proc/after_close(mob/living/user)
+ return
+
+
/obj/structure/closet/proc/toggle(mob/living/user)
if(opened)
return close(user)
else
return open(user)
+
+/obj/structure/closet/deconstruct(disassembled = TRUE)
+ if(ispath(material_drop) && material_drop_amount && !(flags_1 & NODECONSTRUCT_1))
+ new material_drop(loc, material_drop_amount)
+ qdel(src)
+
+/obj/structure/closet/obj_break(damage_flag)
+ if(!broken && !(flags_1 & NODECONSTRUCT_1))
+ bust_open()
+
+/obj/structure/closet/attackby(obj/item/W, mob/user, params)
+ if(user in src)
+ return
+ if(src.tool_interact(W,user))
+ return 1 // No afterattack
+ else
+ return ..()
+
+/obj/structure/closet/proc/tool_interact(obj/item/W, mob/living/user)//returns TRUE if attackBy call shouldn't be continued (because tool was used/closet was of wrong type), FALSE if otherwise
+ . = TRUE
+ if(opened)
+ if(istype(W, /obj/item/weldingtool))
+ if(W.tool_behaviour == TOOL_WELDER)
+ // eigen check
+ if(eigen_teleport)
+ to_chat(user, "The unstable nature of \the [src] makes it impossible to deconstruct!")
+ return
+
+ if(!W.tool_start_check(user, amount=0))
+ return
+
+ to_chat(user, "You begin cutting \the [src] apart...")
+ if(W.use_tool(src, user, 40, volume=50))
+ if(!opened)
+ return
+ user.visible_message("[user] slices apart \the [src].",
+ "You cut \the [src] apart with \the [W].",
+ "You hear welding.")
+ deconstruct(TRUE)
+ return
+ else // for example cardboard box is cut with wirecutters
+ user.visible_message("[user] cut apart \the [src].", \
+ "You cut \the [src] apart with \the [W].")
+ deconstruct(TRUE)
+ return
+ if(user.transferItemToLoc(W, drop_location())) // so we put in unlit welder too
+ return
+ else if(W.tool_behaviour == TOOL_WELDER && can_weld_shut)
+ // eigen check
+ if(eigen_teleport)
+ to_chat(user, "The unstable nature of \the [src] makes it impossible to deconstruct!")
+ return
+ if(!W.tool_start_check(user, amount=0))
+ return
+
+ to_chat(user, "You begin [welded ? "unwelding":"welding"] \the [src]...")
+ if(W.use_tool(src, user, 40, volume=50))
+ if(opened)
+ return
+ welded = !welded
+ after_weld(welded)
+ user.visible_message("[user] [welded ? "welds shut" : "unwelded"] \the [src].",
+ "You [welded ? "weld" : "unwelded"] \the [src] with \the [W].",
+ "You hear welding.")
+ log_game("[key_name(user)] [welded ? "welded":"unwelded"] closet [src] with [W] at [AREACOORD(src)]")
+ update_icon()
+ else if(W.tool_behaviour == TOOL_WRENCH && anchorable)
+ if(isinspace() && !anchored)
+ return
+ set_anchored(!anchored)
+ W.play_tool_sound(src, 75)
+ user.visible_message("[user] [anchored ? "anchored" : "unanchored"] \the [src] [anchored ? "to" : "from"] the ground.", \
+ "You [anchored ? "anchored" : "unanchored"] \the [src] [anchored ? "to" : "from"] the ground.", \
+ "You hear a ratchet.")
+ else if(user.a_intent != INTENT_HARM && !(W.item_flags & NOBLUDGEON))
+ var/item_is_id = W.GetID()
+ if(!item_is_id)
+ return FALSE
+ if(item_is_id || !toggle(user))
+ togglelock(user)
+ // cit addons
+ else if(istype(W, /obj/item/electronics/airlock))
+ handle_lock_addition(user, W)
+ else if(W.tool_behaviour == TOOL_SCREWDRIVER)
+ handle_lock_removal(user, W)
+
+ else
+ return FALSE
+
+/obj/structure/closet/proc/after_weld(weld_state)
+ return
+
+/obj/structure/closet/MouseDrop_T(atom/movable/O, mob/living/user)
+ if(!istype(O) || O.anchored || istype(O, /obj/screen))
+ return
+ if(!istype(user) || user.incapacitated() || user.lying)
+ return
+ if(!Adjacent(user) || !user.Adjacent(O))
+ return
+ if(user == O) //try to climb onto it
+ return ..()
+ if(!opened)
+ return
+ if(!isturf(O.loc))
+ return
+
+ var/actuallyismob = 0
+ if(isliving(O))
+ actuallyismob = 1
+ else if(!isitem(O))
+ return
+ var/turf/T = get_turf(src)
+ var/list/targets = list(O, src)
+ add_fingerprint(user)
+ user.visible_message("[user] [actuallyismob ? "tries to ":""]stuff [O] into [src].", \
+ "You [actuallyismob ? "try to ":""]stuff [O] into [src].", \
+ "You hear clanging.")
+ if(actuallyismob)
+ if(do_after_mob(user, targets, 40))
+ user.visible_message("[user] stuffs [O] into [src].", \
+ "You stuff [O] into [src].", \
+ "You hear a loud metal bang.")
+ var/mob/living/L = O
+ if(!issilicon(L))
+ L.DefaultCombatKnockdown(40)
+ if(istype(src, /obj/structure/closet/supplypod/extractionpod))
+ O.forceMove(src)
+ else
+ O.forceMove(T)
+ close()
+ else
+ O.forceMove(T)
+ return 1
+
+/obj/structure/closet/relaymove(mob/living/user, direction)
+ if(user.stat || !isturf(loc))
+ return
+ if(locked)
+ if(message_cooldown <= world.time)
+ message_cooldown = world.time + 50
+ to_chat(user, "[src]'s door won't budge!")
+ return
+ container_resist(user)
+
+/obj/structure/closet/on_attack_hand(mob/user)
+ if(user.lying && get_dist(src, user) > 0)
+ return
+
+ if(!toggle(user))
+ togglelock(user)
+
+
+/obj/structure/closet/attack_paw(mob/user)
+ return attack_hand(user)
+
+/obj/structure/closet/attack_robot(mob/user)
+ if(user.Adjacent(src))
+ return attack_hand(user)
+
+// tk grab then use on self
+/obj/structure/closet/attack_self_tk(mob/user)
+ return attack_hand(user)
+
+/obj/structure/closet/verb/verb_toggleopen()
+ set src in view(1)
+ set category = "Object"
+ set name = "Toggle Open"
+
+ if(!usr.canUseTopic(src, BE_CLOSE) || !isturf(loc))
+ return
+
+ if(iscarbon(usr) || issilicon(usr) || isdrone(usr))
+ return toggle(usr)
+ else
+ to_chat(usr, "This mob type can't use this verb.")
+
+// Objects that try to exit a locker by stepping were doing so successfully,
+// and due to an oversight in turf/Enter() were going through walls. That
+// should be independently resolved, but this is also an interesting twist.
+/obj/structure/closet/Exit(atom/movable/AM)
+ open()
+ if(AM.loc == src)
+ return FALSE
+ return TRUE
+
+/obj/structure/closet/container_resist(mob/living/user)
+ if(opened)
+ return
+ if(ismovable(loc))
+ // user.changeNext_move(CLICK_CD_BREAKOUT)
+ // user.last_special = world.time + CLICK_CD_BREAKOUT
+ var/atom/movable/AM = loc
+ AM.relay_container_resist(user, src)
+ return
+ if(!welded && !locked)
+ open()
+ return
+
+ //okay, so the closet is either welded or locked... resist!!!
+ // user.changeNext_move(CLICK_CD_BREAKOUT)
+ // user.last_special = world.time + CLICK_CD_BREAKOUT
+ user.visible_message("[src] begins to shake violently!", \
+ "You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)", \
+ "You hear banging from [src].")
+ if(do_after(user,(breakout_time), target = src, required_mobility_flags = MOBILITY_RESIST))
+ if(!user || user.stat != CONSCIOUS || user.loc != src || opened || (!locked && !welded) )
+ return
+ //we check after a while whether there is a point of resisting anymore and whether the user is capable of resisting
+ user.visible_message("[user] successfully broke out of [src]!",
+ "You successfully break out of [src]!")
+ bust_open()
+ else
+ if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded.
+ to_chat(user, "You fail to break out of [src]!")
+
/obj/structure/closet/proc/bust_open()
welded = FALSE //applies to all lockers
locked = FALSE //applies to critter crates and secure lockers only
broken = TRUE //applies to secure lockers only
open()
+/obj/structure/closet/AltClick(mob/user)
+ ..()
+ if(!user.canUseTopic(src, BE_CLOSE) || !isturf(loc))
+ return
+ if(opened || !secure)
+ return
+ else
+ togglelock(user)
+
+/obj/structure/closet/proc/togglelock(mob/living/user, silent)
+ if(secure && !broken)
+ if(allowed(user))
+ if(iscarbon(user))
+ add_fingerprint(user)
+ locked = !locked
+ user.visible_message("[user] [locked ? null : "un"]locks [src].",
+ "You [locked ? null : "un"]lock [src].")
+ update_icon()
+ else if(!silent)
+ to_chat(user, "Access Denied.")
+ else if(secure && broken)
+ to_chat(user, "\The [src] is broken!")
+
+/obj/structure/closet/CtrlShiftClick(mob/living/user)
+ if(!HAS_TRAIT(user, TRAIT_SKITTISH))
+ return ..()
+ if(!user.canUseTopic(src) || !isturf(user.loc) || !user.Adjacent(src) || !user.CanReach(src))
+ return
+ dive_into(user)
+
+/obj/structure/closet/emag_act(mob/user)
+ . = ..()
+ if(!secure || broken)
+ return
+ if(user)
+ user.visible_message("Sparks fly from [src]!",
+ "You scramble [src]'s lock, breaking it open!",
+ "You hear a faint electrical spark.")
+ playsound(src, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
+ broken = TRUE
+ locked = FALSE
+ if(!QDELETED(lockerelectronics))
+ QDEL_NULL(lockerelectronics)
+ update_icon()
+
+/obj/structure/closet/get_remote_view_fullscreens(mob/user)
+ if(user.stat == DEAD || !(user.sight & (SEEOBJS|SEEMOBS)))
+ user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 1)
+
+/obj/structure/closet/emp_act(severity)
+ . = ..()
+ if(. & EMP_PROTECT_SELF)
+ return
+ if (!(. & EMP_PROTECT_CONTENTS))
+ for(var/obj/O in src)
+ O.emp_act(severity)
+ if(secure && !broken && !(. & EMP_PROTECT_SELF))
+ if(prob(50 / severity))
+ locked = !locked
+ update_icon()
+ if(prob(20 / severity) && !opened)
+ if(!locked)
+ open()
+ else
+ req_access = list()
+ req_access += pick(get_all_accesses())
+ if(!QDELETED(lockerelectronics))
+ lockerelectronics.accesses = req_access
+
+/obj/structure/closet/contents_explosion(severity, target)
+ for(var/atom/A in contents)
+ A.ex_act(severity, target)
+ CHECK_TICK
+
+/obj/structure/closet/singularity_act()
+ dump_contents()
+ ..()
+
+/obj/structure/closet/AllowDrop()
+ return TRUE
+
+
+/obj/structure/closet/return_temperature()
+ return
+
+/obj/structure/closet/proc/dive_into(mob/living/user)
+ var/turf/T1 = get_turf(user)
+ var/turf/T2 = get_turf(src)
+ if(!opened)
+ if(locked)
+ togglelock(user, TRUE)
+ if(!open(user))
+ to_chat(user, "It won't budge!")
+ return
+ step_towards(user, T2)
+ T1 = get_turf(user)
+ if(T1 == T2)
+ user.set_resting(TRUE, TRUE)
+ if(!close(user))
+ to_chat(user, "You can't get [src] to close!")
+ user.set_resting(FALSE, TRUE)
+ return
+ user.set_resting(FALSE, TRUE)
+ togglelock(user)
+ T1.visible_message("[user] dives into [src]!")
+
+/obj/structure/closet/canReachInto(atom/user, atom/target, list/next, view_only, obj/item/tool)
+ return (user in src)
+
+/// cit specific ///
+
/obj/structure/closet/proc/handle_lock_addition(mob/user, obj/item/electronics/airlock/E)
add_fingerprint(user)
if(lock_in_use)
@@ -336,294 +648,17 @@
update_icon()
return TRUE
-
-/obj/structure/closet/deconstruct(disassembled = TRUE)
- if(ispath(material_drop) && material_drop_amount && !(flags_1 & NODECONSTRUCT_1))
- new material_drop(loc, material_drop_amount)
- qdel(src)
-
-/obj/structure/closet/obj_break(damage_flag)
- if(!broken && !(flags_1 & NODECONSTRUCT_1))
- bust_open()
-
-/obj/structure/closet/attackby(obj/item/W, mob/user, params)
- if(user in src)
- return
- if(src.tool_interact(W,user))
- return 1 // No afterattack
- else
- return ..()
-
-/obj/structure/closet/proc/tool_interact(obj/item/W, mob/user)//returns TRUE if attackBy call shouldnt be continued (because tool was used/closet was of wrong type), FALSE if otherwise
- . = TRUE
- if(opened)
- if(istype(W, cutting_tool))
- var/welder = FALSE
- if(W.tool_behaviour == TOOL_WELDER)
- if(!W.tool_start_check(user, amount=0))
- return
- to_chat(user, "You begin [welder ? "slicing" : "deconstructing"] \the [src] apart...")
- welder = TRUE
- if(W.use_tool(src, user, 40, volume=50))
- if(eigen_teleport)
- to_chat(user, "The unstable nature of \the [src] makes it impossible to [welder ? "slice" : "deconstruct"]!")
- return
- if(!opened)
- return
- user.visible_message("[user] [welder ? "slice" : "deconstruct"]s apart \the [src].",
- "You [welder ? "slice" : "deconstruct"] \the [src] apart with \the [W].",
- "You hear [welder ? "welding" : "rustling of screws and metal"].")
- deconstruct(TRUE)
- return
- if(user.a_intent != INTENT_HARM && user.transferItemToLoc(W, drop_location())) // so we put in unlit welder too
- return TRUE
- else if(istype(W, /obj/item/electronics/airlock))
- handle_lock_addition(user, W)
- else if(W.tool_behaviour == TOOL_SCREWDRIVER)
- handle_lock_removal(user, W)
- else if(W.tool_behaviour == TOOL_WELDER && can_weld_shut)
- if(!W.tool_start_check(user, amount=0))
- return
-
- to_chat(user, "You begin [welded ? "unwelding":"welding"] \the [src]...")
- if(W.use_tool(src, user, 40, volume=50))
- if(eigen_teleport)
- to_chat(user, "The unstable nature of \the [src] makes it impossible to weld!")
- return
- if(opened)
- return
- welded = !welded
- after_weld(welded)
- user.visible_message("[user] [welded ? "welds shut" : "unwelds"] \the [src].",
- "You [welded ? "weld" : "unwelded"] \the [src] with \the [W].",
- "You hear welding.")
- update_icon()
- else if(W.tool_behaviour == TOOL_WRENCH && anchorable)
- if(isinspace() && !anchored)
- return
- setAnchored(!anchored)
- W.play_tool_sound(src, 75)
- user.visible_message("[user] [anchored ? "anchored" : "unanchored"] \the [src] [anchored ? "to" : "from"] the ground.", \
- "You [anchored ? "anchored" : "unanchored"] \the [src] [anchored ? "to" : "from"] the ground.", \
- "You hear a ratchet.")
- else if(user.a_intent != INTENT_HARM && !(W.item_flags & NOBLUDGEON))
- if(W.GetID() || !toggle(user))
- togglelock(user)
- else
+/obj/structure/closet/proc/can_lock(mob/living/user, var/check_access = TRUE) //set check_access to FALSE if you only need to check if a locker has a functional lock rather than access
+ if(!secure)
return FALSE
-
-/obj/structure/closet/proc/after_weld(weld_state)
- return
-
-/obj/structure/closet/MouseDrop_T(atom/movable/O, mob/living/user)
- if(!istype(O) || O.anchored || istype(O, /obj/screen))
- return
- if(!istype(user) || user.incapacitated() || user.lying)
- return
- if(!Adjacent(user) || !user.Adjacent(O))
- return
- if(user == O) //try to climb onto it
- return ..()
- if(!opened)
- return
- if(!isturf(O.loc))
- return
-
- var/actuallyismob = 0
- if(isliving(O))
- actuallyismob = 1
- else if(!isitem(O))
- return
- var/turf/T = get_turf(src)
- var/list/targets = list(O, src)
- add_fingerprint(user)
- user.visible_message("[user] [actuallyismob ? "tries to ":""]stuff [O] into [src].", \
- "You [actuallyismob ? "try to ":""]stuff [O] into [src].", \
- "You hear clanging.")
- if(actuallyismob)
- if(do_after_mob(user, targets, 40))
- user.visible_message("[user] stuffs [O] into [src].", \
- "You stuff [O] into [src].", \
- "You hear a loud metal bang.")
- var/mob/living/L = O
- if(!issilicon(L))
- L.DefaultCombatKnockdown(40)
- if(istype(src, /obj/structure/closet/supplypod/extractionpod))
- O.forceMove(src)
- else
- O.forceMove(T)
- close()
- else
- O.forceMove(T)
- return 1
-
-/obj/structure/closet/relaymove(mob/user)
- if(user.stat || !isturf(loc) || !isliving(user))
- return
- if(locked || welded)
- if(message_cooldown <= world.time)
- message_cooldown = world.time + 50
- to_chat(user, "[src]'s door won't budge!")
- return
- container_resist(user)
-
-/obj/structure/closet/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
- if(user.lying && get_dist(src, user) > 0)
- return
-
- if(!toggle(user))
- togglelock(user)
-
-/obj/structure/closet/attack_paw(mob/user)
- return attack_hand(user)
-
-/obj/structure/closet/attack_robot(mob/user)
- if(user.Adjacent(src))
- return attack_hand(user)
-
-// tk grab then use on self
-/obj/structure/closet/attack_self_tk(mob/user)
- return attack_hand(user)
-
-/obj/structure/closet/verb/verb_toggleopen()
- set src in oview(1)
- set category = "Object"
- set name = "Toggle Open"
-
- var/mob/living/L = usr
- if(!istype(L) || !CHECK_MOBILITY(L, MOBILITY_USE))
+ if(broken)
+ to_chat(user, "[src] is broken!")
return FALSE
-
- if(iscarbon(usr) || issilicon(usr) || isdrone(usr))
- return attack_hand(usr)
- else
- to_chat(usr, "This mob type can't use this verb.")
-
-// Objects that try to exit a locker by stepping were doing so successfully,
-// and due to an oversight in turf/Enter() were going through walls. That
-// should be independently resolved, but this is also an interesting twist.
-/obj/structure/closet/Exit(atom/movable/AM)
- open()
- if(AM.loc == src)
- return 0
- return 1
-
-/obj/structure/closet/container_resist(mob/living/user)
- if(opened)
- return
- if(ismovable(loc))
- var/atom/movable/AM = loc
- AM.relay_container_resist(user, src)
- return
- if(!welded && !locked)
- open()
- return
-
- //okay, so the closet is either welded or locked... resist!!!
- user.visible_message("[src] begins to shake violently!", \
- "You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)", \
- "You hear banging from [src].")
- if(do_after(user,(breakout_time), target = src, required_mobility_flags = MOBILITY_RESIST))
- if(!user || user.stat != CONSCIOUS || user.loc != src || opened || (!locked && !welded) )
- return
- //we check after a while whether there is a point of resisting anymore and whether the user is capable of resisting
- user.visible_message("[user] successfully broke out of [src]!",
- "You successfully break out of [src]!")
- bust_open()
- else
- if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded.
- to_chat(user, "You fail to break out of [src]!")
-
-/obj/structure/closet/AltClick(mob/user)
- . = ..()
- if(!user.canUseTopic(src, be_close=TRUE) || !isturf(loc))
- to_chat(user, "You can't do that right now!")
+ if(QDELETED(lockerelectronics) && !locked) //We want to be able to unlock it regardless of electronics, but only lockable with electronics
+ to_chat(user, "[src] is missing locker electronics!")
+ return FALSE
+ if(!check_access)
return TRUE
- togglelock(user)
- return TRUE
-
-/obj/structure/closet/CtrlShiftClick(mob/living/user)
- if(!HAS_TRAIT(user, TRAIT_SKITTISH))
- return ..()
- if(!user.canUseTopic(src) || !isturf(user.loc) || !user.Adjacent(src) || !user.CanReach(src))
- return
- dive_into(user)
-
-/obj/structure/closet/emag_act(mob/user)
- . = ..()
- if(!secure || broken)
- return
- user.visible_message("Sparks fly from [src]!",
- "You scramble [src]'s lock, breaking it open!",
- "You hear a faint electrical spark.")
- playsound(src, "sparks", 50, 1)
- broken = TRUE
- locked = FALSE
- if(!QDELETED(lockerelectronics))
- QDEL_NULL(lockerelectronics)
- update_icon()
-
-/obj/structure/closet/get_remote_view_fullscreens(mob/user)
- if(user.stat == DEAD || !(user.sight & (SEEOBJS|SEEMOBS)))
- user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 1)
-
-/obj/structure/closet/emp_act(severity)
- . = ..()
- if(. & EMP_PROTECT_SELF)
- return
- if (!(. & EMP_PROTECT_CONTENTS))
- for(var/obj/O in src)
- O.emp_act(severity)
- if(!secure || broken)
- return ..()
- if(prob(severity/2))
- locked = !locked
- update_icon()
- if(prob(severity/5) && !opened)
- if(!locked)
- open()
- else
- req_access = list()
- req_access += pick(get_all_accesses())
- if(!QDELETED(lockerelectronics))
- lockerelectronics.accesses = req_access
-
-/obj/structure/closet/contents_explosion(severity, target)
- for(var/atom/A in contents)
- A.ex_act(severity, target)
- CHECK_TICK
-
-/obj/structure/closet/singularity_act()
- dump_contents()
- ..()
-
-/obj/structure/closet/AllowDrop()
- return TRUE
-
-
-/obj/structure/closet/return_temperature()
- return
-
-/obj/structure/closet/proc/dive_into(mob/living/user)
- var/turf/T1 = get_turf(user)
- var/turf/T2 = get_turf(src)
- if(!opened)
- if(locked)
- togglelock(user, TRUE)
- if(!open(user))
- to_chat(user, "It won't budge!")
- return
- step_towards(user, T2)
- T1 = get_turf(user)
- if(T1 == T2)
- user.set_resting(TRUE, TRUE)
- if(!close(user))
- to_chat(user, "You can't get [src] to close!")
- user.set_resting(FALSE, TRUE)
- return
- user.set_resting(FALSE, TRUE)
- togglelock(user)
- T1.visible_message("[user] dives into [src]!")
-
-/obj/structure/closet/canReachInto(atom/user, atom/target, list/next, view_only, obj/item/tool)
- return (user in src)
+ if(allowed(user))
+ return TRUE
+ to_chat(user, "Access denied.")
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index ee202f9504..030f7f4edf 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -17,10 +17,13 @@
material_drop_amount = 5
var/obj/item/paper/fluff/jobs/cargo/manifest/manifest
-/obj/structure/closet/crate/New()
- ..()
+/obj/structure/closet/crate/Initialize()
+ . = ..()
if(icon_state == "[initial(icon_state)]open")
opened = TRUE
+ // AddElement(/datum/element/climbable, climb_time = crate_climb_time * 0.5, climb_stun = 0)
+ // else
+ // AddElement(/datum/element/climbable, climb_time = crate_climb_time, climb_stun = 0)
update_icon()
/obj/structure/closet/crate/CanPass(atom/movable/mover, turf/target)
@@ -46,21 +49,16 @@
if(manifest)
tear_manifest(user)
-/obj/structure/closet/crate/tool_interact(obj/item/W, mob/user)
- if(W.tool_behaviour == TOOL_WIRECUTTER && manifest)
- tear_manifest(user)
- return TRUE
- return ..()
-
-/obj/structure/closet/crate/open(mob/living/user)
+/obj/structure/closet/crate/open(mob/living/user, force = FALSE)
. = ..()
if(. && manifest)
to_chat(user, "The manifest is torn off [src].")
- playsound(src, 'sound/items/poster_ripped.ogg', 75, 1)
+ playsound(src, 'sound/items/poster_ripped.ogg', 75, TRUE)
manifest.forceMove(get_turf(src))
manifest = null
update_icon()
+// cit specific
/obj/structure/closet/crate/handle_lock_addition()
return
@@ -69,7 +67,7 @@
/obj/structure/closet/crate/proc/tear_manifest(mob/user)
to_chat(user, "You tear the manifest off of [src].")
- playsound(src, 'sound/items/poster_ripped.ogg', 75, 1)
+ playsound(src, 'sound/items/poster_ripped.ogg', 75, TRUE)
manifest.forceMove(loc)
if(ishuman(user))
diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm
index 9c3e0ef64a..90f8680da9 100644
--- a/code/modules/atmospherics/machinery/portable/canister.dm
+++ b/code/modules/atmospherics/machinery/portable/canister.dm
@@ -202,8 +202,9 @@
filled = 1
release_pressure = ONE_ATMOSPHERE*2
-/obj/machinery/portable_atmospherics/canister/Initialize(mapload, datum/gas_mixture/existing_mixture)
- . = ..()
+/obj/machinery/portable_atmospherics/canister/New(loc, datum/gas_mixture/existing_mixture)
+ ..()
+
if(existing_mixture)
air_contents.copy_from(existing_mixture)
else
@@ -221,10 +222,8 @@
air_contents.set_temperature(starter_temp)
/obj/machinery/portable_atmospherics/canister/air/create_gas()
- var/oh_two = /datum/gas/oxygen
- var/dihydrogen = /datum/gas/nitrogen //how to piss of chemists
- air_contents.set_moles(oh_two, (O2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
- air_contents.set_moles(dihydrogen, (N2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
+ air_contents.set_moles(/datum/gas/oxygen, (O2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
+ air_contents.set_moles(/datum/gas/nitrogen, (N2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
/obj/machinery/portable_atmospherics/canister/update_icon_state()
if(stat & BROKEN)
diff --git a/code/modules/cargo/supplypod.dm b/code/modules/cargo/supplypod.dm
index 90adf8e7ff..3d2264a593 100644
--- a/code/modules/cargo/supplypod.dm
+++ b/code/modules/cargo/supplypod.dm
@@ -130,26 +130,28 @@
/obj/structure/closet/supplypod/update_overlays()
. = ..()
- if (style == STYLE_INVISIBLE)
+ if(style == STYLE_INVISIBLE)
return
- if (rubble)
+
+ if(rubble)
. += rubble.getForeground(src)
- if (style == STYLE_SEETHROUGH)
- for (var/atom/A in contents)
+
+ if(style == STYLE_SEETHROUGH)
+ for(var/atom/A in contents)
var/mutable_appearance/itemIcon = new(A)
itemIcon.transform = matrix().Translate(-1 * SUPPLYPOD_X_OFFSET, 0)
. += itemIcon
- for (var/t in turfs_in_cargo)//T is just a turf's type
+ for(var/t in turfs_in_cargo)//T is just a turf's type
var/turf/turf_type = t
var/mutable_appearance/itemIcon = mutable_appearance(initial(turf_type.icon), initial(turf_type.icon_state))
itemIcon.transform = matrix().Translate(-1 * SUPPLYPOD_X_OFFSET, 0)
. += itemIcon
return
- if (opened) //We're opened means all we have to worry about is masking a decal if we have one
- if (!decal) //We don't have a decal to mask
+ if(opened) //We're opened means all we have to worry about is masking a decal if we have one
+ if(!decal) //We don't have a decal to mask
return
- if (!door) //We have a decal but no door, so let's just add the decal
+ if(!door) //We have a decal but no door, so let's just add the decal
. += decal
return
var/icon/masked_decal = new(icon, decal) //The decal we want to apply
@@ -159,23 +161,25 @@
door_masker.Blend("#000000", ICON_SUBTRACT)
masked_decal.Blend(door_masker, ICON_ADD)
. += masked_decal
- else //If we're closed
- if (!door) //We have no door, lets see if we have a decal. If not, theres nothing we need to do
- if (decal)
- . += decal
- return
- else if (GLOB.podstyles[style][POD_SHAPE] != POD_SHAPE_NORML) //If we're not a normal pod shape (aka, if we don't have fins), just add the door without masking
- . += door
- else
- var/icon/masked_door = new(icon, door) //The door we want to apply
- var/icon/fin_masker = new(icon, "mask_[fin_mask]") //The fin shape we want to 'cut out' of the door
- fin_masker.MapColors(0,0,0,1, 0,0,0,1, 0,0,0,1, 1,1,1,0, 0,0,0,1)
- fin_masker.SwapColor("#ffffffff", null)
- fin_masker.Blend("#000000", ICON_SUBTRACT)
- masked_door.Blend(fin_masker, ICON_ADD)
- . += masked_door
- if (decal)
+ return
+
+ //If we're closed
+ if(!door) //We have no door, lets see if we have a decal. If not, theres nothing we need to do
+ if(decal)
. += decal
+ return
+ else if (GLOB.podstyles[style][POD_SHAPE] != POD_SHAPE_NORML) //If we're not a normal pod shape (aka, if we don't have fins), just add the door without masking
+ . += door
+ else
+ var/icon/masked_door = new(icon, door) //The door we want to apply
+ var/icon/fin_masker = new(icon, "mask_[fin_mask]") //The fin shape we want to 'cut out' of the door
+ fin_masker.MapColors(0,0,0,1, 0,0,0,1, 0,0,0,1, 1,1,1,0, 0,0,0,1)
+ fin_masker.SwapColor("#ffffffff", null)
+ fin_masker.Blend("#000000", ICON_SUBTRACT)
+ masked_door.Blend(fin_masker, ICON_ADD)
+ . += masked_door
+ if(decal)
+ . += decal
/obj/structure/closet/supplypod/tool_interact(obj/item/W, mob/user)
if(bluespace) //We dont want to worry about interacting with bluespace pods, as they are due to delete themselves soon anyways.
@@ -192,7 +196,7 @@
/obj/structure/closet/supplypod/toggle(mob/living/user)
return
-/obj/structure/closet/supplypod/open(mob/living/user, force = TRUE)
+/obj/structure/closet/supplypod/open(mob/living/user, force = FALSE)
return
/obj/structure/closet/supplypod/proc/handleReturnAfterDeparting(atom/movable/holder = src)
@@ -550,9 +554,6 @@
var/obj/effect/pod_landingzone_effect/helper
var/list/smoke_effects = new /list(13)
-/obj/effect/ex_act()
- return
-
/obj/effect/pod_landingzone/Initialize(mapload, podParam, single_order = null, clientman)
. = ..()
if (ispath(podParam)) //We can pass either a path for a pod (as expressconsoles do), or a reference to an instantiated pod (as the centcom_podlauncher does)
@@ -647,4 +648,12 @@
desc = "This disk provides a firmware update to the Express Supply Console, granting the use of Nanotrasen's Bluespace Drop Pods to the supply department."
icon = 'icons/obj/module.dmi'
icon_state = "cargodisk"
+ // inhand_icon_state = "card-id"
w_class = WEIGHT_CLASS_SMALL
+
+// let's not.
+/obj/structure/closet/supplypod/handle_lock_addition()
+ return
+
+/obj/structure/closet/supplypod/handle_lock_removal()
+ return
diff --git a/code/modules/modular_computers/computers/item/laptop.dm b/code/modules/modular_computers/computers/item/laptop.dm
index 7616e31aa8..37eedcb312 100644
--- a/code/modules/modular_computers/computers/item/laptop.dm
+++ b/code/modules/modular_computers/computers/item/laptop.dm
@@ -25,6 +25,7 @@
/obj/item/modular_computer/laptop/examine(mob/user)
. = ..()
+ . += "Drag it in your hand to pick it up."
if(screen_on)
. += "Alt-click to close it."
@@ -76,6 +77,9 @@
M.put_in_hand(src, H.held_index)
/obj/item/modular_computer/laptop/on_attack_hand(mob/user)
+ . = ..()
+ if(!.)
+ return
if(screen_on && isturf(loc))
return attack_self(user)
diff --git a/code/modules/modular_computers/file_system/programs/jobmanagement.dm b/code/modules/modular_computers/file_system/programs/jobmanagement.dm
index 3f21d2cf2c..0babfcdddd 100644
--- a/code/modules/modular_computers/file_system/programs/jobmanagement.dm
+++ b/code/modules/modular_computers/file_system/programs/jobmanagement.dm
@@ -20,7 +20,8 @@
"Head of Security",
"Chief Engineer",
"Research Director",
- "Chief Medical Officer")
+ "Chief Medical Officer",
+ "Quartermaster")
//The scaling factor of max total positions in relation to the total amount of people on board the station in %
var/max_relative_positions = 30 //30%: Seems reasonable, limit of 6 @ 20 players
@@ -43,7 +44,7 @@
/datum/computer_file/program/job_management/proc/can_close_job(datum/job/job)
if(!(job?.title in blacklisted))
- if(job.total_positions > length(GLOB.player_list) * (max_relative_positions / 100))
+ if(job.total_positions > job.current_positions)
var/delta = (world.time / 10) - GLOB.time_last_changed_position
if((change_position_cooldown < delta) || (opened_positions[job.title] > 0))
return TRUE
@@ -67,7 +68,7 @@
if(!j || !can_open_job(j))
return
if(opened_positions[edit_job_target] >= 0)
- GLOB.time_last_changed_position = world.time / 10
+ GLOB.time_last_changed_position = world.time / 10 // global cd
j.total_positions++
opened_positions[edit_job_target]++
playsound(computer, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)