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)