diff --git a/code/datums/components/mood.dm b/code/datums/components/mood.dm index 9c542b505c..920886cc74 100644 --- a/code/datums/components/mood.dm +++ b/code/datums/components/mood.dm @@ -34,6 +34,7 @@ RegisterSignal(parent, COMSIG_MOB_HUD_CREATED, .proc/modify_hud) RegisterSignal(parent, COMSIG_MOB_DEATH, .proc/stop_processing) RegisterSignal(parent, COMSIG_VOID_MASK_ACT, .proc/direct_sanity_drain) + RegisterSignal(parent, COMSIG_ENTER_AREA, .proc/update_beauty) if(owner.hud_used) @@ -355,7 +356,7 @@ if(ETHEREAL_CHARGE_OVERLOAD to ETHEREAL_CHARGE_DANGEROUS) add_event(null, "charge", /datum/mood_event/supercharged) -/datum/component/mood/proc/update_beauty(area/A) +/datum/component/mood/proc/update_beauty(datum/source, area/A) if(A.outdoors) //if we're outside, we don't care. clear_event(null, "area_beauty") return FALSE diff --git a/code/datums/elements/connect_loc.dm b/code/datums/elements/connect_loc.dm new file mode 100644 index 0000000000..fee9072f75 --- /dev/null +++ b/code/datums/elements/connect_loc.dm @@ -0,0 +1,43 @@ +/// This element hooks a signal onto the loc the current object is on. +/// When the object moves, it will unhook the signal and rehook it to the new object. +/datum/element/connect_loc + element_flags = ELEMENT_BESPOKE + id_arg_index = 2 + + /// An assoc list of signal -> procpath to register to the loc this object is on. + var/list/connections + +/datum/element/connect_loc/Attach(atom/movable/listener, list/connections) + . = ..() + if (!istype(listener)) + return ELEMENT_INCOMPATIBLE + + src.connections = connections + + RegisterSignal(listener, COMSIG_MOVABLE_MOVED, .proc/on_moved, override = TRUE) + update_signals(listener) + +/datum/element/connect_loc/Detach(atom/movable/listener) + . = ..() + unregister_signals(listener, listener.loc) + UnregisterSignal(listener, COMSIG_MOVABLE_MOVED) + +/datum/element/connect_loc/proc/update_signals(atom/movable/listener) + var/atom/listener_loc = listener.loc + if(isnull(listener_loc)) + return + + for (var/signal in connections) + //override=TRUE because more than one connect_loc element instance tracked object can be on the same loc + listener.RegisterSignal(listener_loc, signal, connections[signal], override=TRUE) + +/datum/element/connect_loc/proc/unregister_signals(datum/listener, atom/old_loc) + if(isnull(old_loc)) + return + + listener.UnregisterSignal(old_loc, connections) + +/datum/element/connect_loc/proc/on_moved(atom/movable/listener, atom/old_loc) + SIGNAL_HANDLER + unregister_signals(listener, old_loc) + update_signals(listener) diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 62b2a6da8d..e1d7737f5c 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -149,10 +149,11 @@ Class Procs: circuit = new circuit(src) circuit.apply_default_parts(src) - if(!speed_process && init_process) - START_PROCESSING(SSmachines, src) - else - START_PROCESSING(SSfastprocess, src) + if(init_process) // Required to prevent non-speed non-init machines from running + if(speed_process) + START_PROCESSING(SSfastprocess, src) + else + START_PROCESSING(SSmachines, src) RegisterSignal(src, COMSIG_ENTER_AREA, .proc/power_change) if (occupant_typecache) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 1d7cbc7f53..966985c427 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -61,12 +61,17 @@ /obj/machinery/suit_storage_unit/engine suit_type = /obj/item/clothing/suit/space/hardsuit/engine mask_type = /obj/item/clothing/mask/breath - shoes_type= /obj/item/clothing/shoes/magboots + shoes_type = /obj/item/clothing/shoes/magboots + +/obj/machinery/suit_storage_unit/atmos + suit_type = /obj/item/clothing/suit/space/hardsuit/engine/atmos + mask_type = /obj/item/clothing/mask/breath + storage_type = /obj/item/watertank/atmos /obj/machinery/suit_storage_unit/ce suit_type = /obj/item/clothing/suit/space/hardsuit/engine/elite mask_type = /obj/item/clothing/mask/breath - shoes_type= /obj/item/clothing/shoes/magboots/advance + shoes_type = /obj/item/clothing/shoes/magboots/advance /obj/machinery/suit_storage_unit/security suit_type = /obj/item/clothing/suit/space/hardsuit/security @@ -165,7 +170,6 @@ /obj/machinery/suit_storage_unit/update_overlays() . = ..() - if(uv) if(uv_super) . += "super" @@ -182,7 +186,7 @@ . += "suit" if(helmet) . += "helm" - if(storage) + if(shoes || storage) . += "storage" else if(occupant) . += "human" @@ -199,7 +203,6 @@ helmet = null suit = null mask = null - shoes = null storage = null occupant = null @@ -210,109 +213,8 @@ new /obj/item/stack/sheet/metal(loc, 2) qdel(src) -/obj/machinery/suit_storage_unit/interact(mob/living/user) - var/static/list/items - - if (!items) - items = list( - "suit" = create_silhouette_of(/obj/item/clothing/suit/space/eva), - "helmet" = create_silhouette_of(/obj/item/clothing/head/helmet/space/eva), - "mask" = create_silhouette_of(/obj/item/clothing/mask/breath), - "shoes" = create_silhouette_of(/obj/item/clothing/shoes/magboots), - "storage" = create_silhouette_of(/obj/item/tank/internals/oxygen), - ) - - . = ..() - if (.) - return - - if (!check_interactable(user)) - return - - var/list/choices = list() - - if (locked) - choices["unlock"] = icon('modular_sand/icons/hud/radial.dmi', "radial_unlock") - else if (state_open) - choices["close"] = icon('modular_sand/icons/hud/radial.dmi', "radial_close") - - for (var/item_key in items) - var/item = vars[item_key] - if (item) - choices[item_key] = item - else - // If the item doesn't exist, put a silhouette in its place - choices[item_key] = items[item_key] - else - choices["open"] = icon('modular_sand/icons/hud/radial.dmi', "radial_open") - choices["disinfect"] = icon('modular_sand/icons/hud/radial.dmi', "radial_disinfect") - choices["lock"] = icon('modular_sand/icons/hud/radial.dmi', "radial_lock") - - var/choice = show_radial_menu( - user, - src, - choices, - custom_check = CALLBACK(src, .proc/check_interactable, user), - require_near = !issilicon(user), - ) - - if (!choice) - return - - switch (choice) - if ("open") - if (!state_open) - open_machine(drop = FALSE) - if (occupant) - dump_contents() - if ("close") - if (state_open) - close_machine() - if ("disinfect") - if (occupant && safeties) - return - else if (!helmet && !mask && !suit && !shoes && !storage && !occupant) - return - else - if (occupant) - var/mob/living/mob_occupant = occupant - to_chat(mob_occupant, "[src]'s confines grow warm, then hot, then scorching. You're being burned [!mob_occupant.stat ? "alive" : "away"]!") - cook() - if ("lock", "unlock") - if (!state_open) - locked = !locked - else - var/obj/item/item_to_dispense = vars[choice] - if (item_to_dispense) - vars[choice] = null - user.put_in_hands(item_to_dispense) - else - var/obj/item/in_hands = user.get_active_held_item() - if (in_hands) - attackby(in_hands, user) - - interact(user) - -/obj/machinery/suit_storage_unit/proc/check_interactable(mob/user) - if (!state_open && !can_interact(user)) - return FALSE - - if (panel_open) - return FALSE - - if (uv) - return FALSE - - return TRUE - -/obj/machinery/suit_storage_unit/proc/create_silhouette_of(atom/item) - var/image/image = image(initial(item.icon), initial(item.icon_state)) - image.alpha = 128 - image.color = COLOR_RED - return image - -/obj/machinery/suit_storage_unit/MouseDrop_T(atom/A, mob/living/user) - if(!istype(user) || user.stat || !Adjacent(user) || !Adjacent(A) || !isliving(A)) +/obj/machinery/suit_storage_unit/MouseDrop_T(atom/A, mob/user) + if(user.stat || user.lying || !Adjacent(user) || !Adjacent(A) || !isliving(A)) return var/mob/living/target = A if(!state_open) @@ -525,15 +427,93 @@ return ..() -/* ref tg-git issue #45036 - screwdriving it open while it's running a decontamination sequence without closing the panel prior to finish - causes the SSU to break due to state_open being set to TRUE at the end, and the panel becoming inaccessible. -*/ -/obj/machinery/suit_storage_unit/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I) - if(!(flags_1 & NODECONSTRUCT_1) && I.tool_behaviour == TOOL_SCREWDRIVER && uv) - to_chat(user, "It might not be wise to fiddle with [src] while it's running...") - return TRUE - return ..() +/obj/machinery/suit_storage_unit/ui_state(mob/user) + return GLOB.notcontained_state + +/obj/machinery/suit_storage_unit/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "SuitStorageUnit", name) + ui.open() + +/obj/machinery/suit_storage_unit/ui_data() + var/list/data = list() + data["locked"] = locked + data["open"] = state_open + data["safeties"] = safeties + data["uv_active"] = uv + data["uv_super"] = uv_super + if(helmet) + data["helmet"] = helmet.name + else + data["helmet"] = null + if(suit) + data["suit"] = suit.name + else + data["suit"] = null + if(mask) + data["mask"] = mask.name + else + data["mask"] = null + if(shoes) + data["shoes"] = shoes.name + else + data["shoes"] = null + if(storage) + data["storage"] = storage.name + else + data["storage"] = null + if(occupant) + data["occupied"] = TRUE + else + data["occupied"] = FALSE + return data + +/obj/machinery/suit_storage_unit/ui_act(action, params) + if(..() || uv) + return + switch(action) + if("door") + if(state_open) + close_machine() + else + open_machine(0) + if(occupant) + dump_contents() // Dump out contents if someone is in there. + . = TRUE + if("lock") + if(state_open) + return + locked = !locked + . = TRUE + if("uv") + if(occupant && safeties) + return + else if(!helmet && !mask && !suit && !storage && !occupant) + return + else + if(occupant) + var/mob/living/mob_occupant = occupant + to_chat(mob_occupant, "[src]'s confines grow warm, then hot, then scorching. You're being burned [!mob_occupant.stat ? "alive" : "away"]!") + cook() + . = TRUE + if("dispense") + if(!state_open) + return + + var/static/list/valid_items = list("helmet", "suit", "mask", "shoes", "storage") + var/item_name = params["item"] + if(item_name in valid_items) + var/obj/item/I = vars[item_name] + vars[item_name] = null + if(I) + var/mob/living/living_person = usr + if(!istype(living_person)) + return + if(!istype(living_person) || !Adjacent(living_person) || !living_person.put_in_active_hand(I)) + I.forceMove(loc) + . = TRUE + update_icon() /obj/machinery/suit_storage_unit/default_pry_open(obj/item/I)//needs to check if the storage is locked. . = !(state_open || panel_open || is_operational() || locked || (flags_1 & NODECONSTRUCT_1)) && I.tool_behaviour == TOOL_CROWBAR diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index eeef55941f..96a26e704c 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -399,7 +399,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb if(throwing) throwing.finalize(FALSE) if(loc == user) - if(!user.temporarilyRemoveItemFromInventory(I = src)) + if(!allow_attack_hand_drop(user) || !user.temporarilyRemoveItemFromInventory(src)) return . = FALSE @@ -428,7 +428,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb if(throwing) throwing.finalize(FALSE) if(loc == user) - if(!user.temporarilyRemoveItemFromInventory(src)) + if(!allow_attack_hand_drop(user) || !user.temporarilyRemoveItemFromInventory(I = src)) return pickup(user) diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 7b2143cf86..f44860d769 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -42,7 +42,7 @@ var/static/list/runes = list("rune1","rune2","rune3","rune4","rune5","rune6") var/static/list/randoms = list(RANDOM_ANY, RANDOM_RUNE, RANDOM_ORIENTED, RANDOM_NUMBER, RANDOM_GRAFFITI, RANDOM_LETTER, RANDOM_SYMBOL, RANDOM_PUNCTUATION, RANDOM_DRAWING) - var/static/list/graffiti_large_h = list("yiffhell", "secborg", "paint") + var/static/list/graffiti_large_h = list("yiffhell", "furrypride", "secborg", "paint") var/static/list/all_drawables = graffiti + symbols + drawings + oriented + runes + graffiti_large_h diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index 97c61caffd..c5e92349c7 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -257,8 +257,17 @@ used = TRUE if(istype(A, /obj/machinery/light)) if(!proximity && bluespace_toggle) - U.Beam(A, icon_state = "rped_upgrade", time = 1 SECONDS) - playsound(src, 'sound/items/pshoom.ogg', 40, 1) + // Set variable for target light + var/obj/machinery/light/target = A + + // Check light status before playing effects + if(target.status != LIGHT_OK) + // Display RPED beam + U.Beam(A, icon_state = "rped_upgrade", time = 1 SECONDS) + + // Play RPED sound + playsound(src, 'sound/items/pshoom.ogg', 40, 1) + ReplaceLight(A, U) if(!used) diff --git a/code/game/objects/items/mop.dm b/code/game/objects/items/mop.dm index 62a3530afe..9b0506855f 100644 --- a/code/game/objects/items/mop.dm +++ b/code/game/objects/items/mop.dm @@ -91,7 +91,7 @@ name = "advanced mop" mopcap = 10 icon_state = "advmop" - item_state = "mop" + item_state = "advmop" lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi' force = 6 diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index e55a092b32..b2a7f91e96 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -237,6 +237,12 @@ icon_state = "circle_glasses" item_state = "circle_glasses" +/obj/item/clothing/glasses/regular/modern + name = "modern glasses" + desc = "A Dork. Co. revamp and/or revision of Nerd. Co.'s classic prescription glasses, with less opaque lenses." + icon_state = "glasses_alt" + item_state = "glasses_alt" + //Here lies green glasses, so ugly they died. RIP /obj/item/clothing/glasses/sunglasses diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm index 3d89377952..0b7ca7adfd 100644 --- a/code/modules/mining/machine_processing.dm +++ b/code/modules/mining/machine_processing.dm @@ -121,6 +121,7 @@ icon_state = "furnace" density = TRUE needs_item_input = TRUE + init_process = TRUE var/obj/machinery/mineral/CONSOLE = null var/on = FALSE var/datum/material/selected_material = null diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index eabab35c3b..32b79343e8 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -11,6 +11,7 @@ output_dir = SOUTH req_access = list(ACCESS_MINERAL_STOREROOM) speed_process = TRUE + init_process = TRUE circuit = /obj/item/circuitboard/machine/ore_redemption layer = BELOW_OBJ_LAYER var/points = 0 diff --git a/code/modules/mining/machine_unloading.dm b/code/modules/mining/machine_unloading.dm index b39b0df6ab..16b3b3967f 100644 --- a/code/modules/mining/machine_unloading.dm +++ b/code/modules/mining/machine_unloading.dm @@ -9,6 +9,7 @@ input_dir = WEST output_dir = EAST speed_process = TRUE + init_process = TRUE /obj/machinery/mineral/unloading_machine/proc/horrible_quadratic_monster(var/turf/T) set waitfor = FALSE diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 7fff5cb71a..7f40744eb0 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -585,18 +585,28 @@ for(var/job in category) var/datum/job/job_datum = SSjob.name_occupations[job] if(job_datum && IsJobUnavailable(job_datum.title, TRUE) == JOB_AVAILABLE) + // Get currently occupied slots + var/num_positions_current = job_datum.current_positions + + // Get total slots that can be occupied + var/num_positions_total = job_datum.total_positions + + // Change to lemniscate for infinite-slot jobs + // This variable should only used to display text! + num_positions_total = (num_positions_total == -1 ? "∞" : num_positions_total) + var/command_bold = "" if(job in GLOB.command_positions) command_bold = " command" - //SKYRAT CHANGES + //Sandstorm changes var/jobline = "[job_datum.title] ([job_datum.current_positions])" if(job_datum in SSjob.prioritized_jobs) jobline = "[jobline]" if(client && client.prefs && client.prefs.alt_titles_preferences[job_datum.title]) jobline = "[jobline]
(as [client.prefs.alt_titles_preferences[job_datum.title]])" - jobline = "[jobline]" + jobline = "[jobline] ([num_positions_current]/[num_positions_total])" dept_dat += jobline - //END OF SKYRAT CHANGES + //End of Sandstorm changes if(!dept_dat.len) dept_dat += "No positions open." dat += jointext(dept_dat, "") diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm index a21b026080..b3ad29e637 100644 --- a/code/modules/recycling/conveyor2.dm +++ b/code/modules/recycling/conveyor2.dm @@ -308,13 +308,32 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) S.update_icon() CHECK_TICK -/obj/machinery/conveyor_switch/attackby(obj/item/I, mob/user, params) - if(I.tool_behaviour == TOOL_CROWBAR) - var/obj/item/conveyor_switch_construct/C = new/obj/item/conveyor_switch_construct(src.loc) - C.id = id - transfer_fingerprints_to(C) - to_chat(user, "You detach the conveyor switch.") - qdel(src) +/obj/machinery/conveyor_switch/crowbar_act(mob/user, obj/item/tool) + tool.play_tool_sound(src, 50) + var/obj/item/conveyor_switch_construct/switch_construct = new/obj/item/conveyor_switch_construct(src.loc) + switch_construct.id = id + transfer_fingerprints_to(switch_construct) + to_chat(user, span_notice("You detach [src].")) + qdel(src) + return TRUE + +/obj/machinery/conveyor_switch/screwdriver_act(mob/user, obj/item/tool) + tool.play_tool_sound(src, 50) + oneway = !oneway + to_chat(user, span_notice("You set [src] to [oneway ? "one way" : "default"] configuration.")) + return TRUE + +/obj/machinery/conveyor_switch/wrench_act(mob/user, obj/item/tool) + tool.play_tool_sound(src, 50) + invert_icon = !invert_icon + update_appearance() + to_chat(user, span_notice("You set [src] to [invert_icon ? "inverted": "normal"] position.")) + return TRUE + +/obj/machinery/conveyor_switch/examine(mob/user) + . = ..() + . += span_notice("[src] is set to [oneway ? "one way" : "default"] configuration. It can be changed with a screwdriver.") + . += span_notice("[src] is set to [invert_icon ? "inverted": "normal"] position. It can be rotated with a wrench.") /obj/machinery/conveyor_switch/oneway icon_state = "conveyor_switch_oneway" diff --git a/code/modules/recycling/conveyor_sorter.dm b/code/modules/recycling/conveyor_sorter.dm new file mode 100644 index 0000000000..0e42c79067 --- /dev/null +++ b/code/modules/recycling/conveyor_sorter.dm @@ -0,0 +1,144 @@ +// credits to jjpark-kb, see Skyrat-SS13/Skyrat-tg#8790 and related files +// - hatterhat + +/obj/item/conveyor_sorter + name = "conveyor sorter lister" + desc = "A tool that is used to create conveyor sorting marks, and give sorting lists to them." + icon = 'icons/obj/recycling.dmi' + icon_state = "lister" + ///the list of conveyor sorters spawned by + var/list/spawned_sorters = list() + ///the list of things that are currently within the sorting list + var/list/current_sort = list() + +/obj/item/conveyor_sorter/Destroy() + for(var/deleting_sorters in spawned_sorters) + qdel(deleting_sorters) + return ..() + +/obj/item/conveyor_sorter/examine(mob/user) + . = ..() + . += span_notice("Use it to place down a conveyor sorter, up to three.") + . += span_notice("Use Alt-Click to reset the sorting list.") + . += span_notice("Attack things to attempt to add to the sorting list.") + +/obj/item/conveyor_sorter/attack_self(mob/user, modifiers) + if(length(spawned_sorters) >= 3) + to_chat(user, span_warning("You may only have three spawned conveyor sorters!")) + return + var/obj/effect/decal/cleanable/conveyor_sorter/new_cs = new /obj/effect/decal/cleanable/conveyor_sorter(get_turf(src)) + new_cs.parent_item = src + spawned_sorters += new_cs + +/obj/item/conveyor_sorter/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + if(target == src) + return ..() + if(!proximity_flag) + return ..() + if(!ismovable(target)) + return ..() + if(istype(target, /obj/effect/decal/cleanable/conveyor_sorter)) + return + if(is_type_in_list(target, current_sort)) + to_chat(user, span_warning("[target] is already in [src]'s sorting list!")) + return + if(length(current_sort) >= 5) + to_chat(user, span_warning("[src] already has five things within the sorting list!")) + return + current_sort += target.type + to_chat(user, span_notice("[target] has been added to [src]'s sorting list.")) + +/obj/item/conveyor_sorter/AltClick(mob/user) + visible_message("[src] pings, resetting its sorting list!") + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + current_sort = list() + +/obj/effect/decal/cleanable/conveyor_sorter + name = "conveyor sorter" + desc = "A mark that sorts items out based on what they are." + icon = 'icons/obj/recycling.dmi' + icon_state = "sorter" + layer = OBJ_LAYER + plane = GAME_PLANE + ///the list of items that will be sorted to the sorted direction + var/list/sorting_list = list() + //the direction that the items in the sorting list will be moved to + dir = NORTH + ///the parent conveyor sorter lister item, used for deletion + var/obj/item/conveyor_sorter/parent_item + /// To prevent spam + COOLDOWN_DECLARE(use_cooldown) + + light_range = 3 + light_color = COLOR_RED_LIGHT + +/obj/effect/decal/cleanable/conveyor_sorter/Initialize(mapload, list/datum/disease/diseases) + . = ..() + var/static/list/loc_connections = list( + COMSIG_ATOM_ENTERED = .proc/on_entered, + ) + AddElement(/datum/element/connect_loc, loc_connections) + +/obj/effect/decal/cleanable/conveyor_sorter/Destroy() + if(parent_item) + parent_item.spawned_sorters -= src + parent_item = null + return ..() + +/obj/effect/decal/cleanable/conveyor_sorter/examine(mob/user) + . = ..() + . += span_notice("Attack with conveyor sorter lister to set the sorting list.") + . += span_notice("Slap with empty hands to change the sorting direction.") + . += span_notice("Alt-Click to reset the sorting list.") + . += span_notice("Ctrl-Click to remove.") + +/obj/effect/decal/cleanable/conveyor_sorter/attack_hand(mob/living/user, list/modifiers) + var/user_choice = tgui_input_list(user, "Choose which direction to sort to!", "Direction choice", list("North", "East", "South", "West")) + if(!user_choice) + return ..() + switch(user_choice) + if("North") + setDir(NORTH) + if("East") + setDir(EAST) + if("South") + setDir(SOUTH) + if("West") + setDir(WEST) + visible_message("[src] pings, updating its sorting direction!") + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + +/obj/effect/decal/cleanable/conveyor_sorter/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/conveyor_sorter)) + var/obj/item/conveyor_sorter/cs_item = W + sorting_list = cs_item.current_sort + visible_message("[src] pings, updating its sorting list!") + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + return + else + return ..() + +/obj/effect/decal/cleanable/conveyor_sorter/AltClick(mob/user) + visible_message("[src] pings, resetting its sorting list!") + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + sorting_list = list() + +/obj/effect/decal/cleanable/conveyor_sorter/CtrlClick(mob/user) + visible_message("[src] pings, before disappearing!") + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + qdel(src) + +/obj/effect/decal/cleanable/conveyor_sorter/proc/on_entered(datum/source, atom/movable/AM) + if(is_type_in_list(AM, sorting_list) && !AM.anchored && COOLDOWN_FINISHED(src, use_cooldown)) + COOLDOWN_START(src, use_cooldown, 1 SECONDS) + AM.Move(get_step(src, dir)) + +/datum/design/conveyor_sorter + name = "Conveyor Sorter" + desc = "A wonderful item that can set markers and forcefully move stuff to a direction." + id = "conveyor_sorter" + build_type = PROTOLATHE + build_path = /obj/item/conveyor_sorter + materials = list(/datum/material/iron = 500, /datum/material/plastic = 500) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_CARGO diff --git a/code/modules/research/techweb/nodes/engineering_nodes.dm b/code/modules/research/techweb/nodes/engineering_nodes.dm index 1deb97c3bd..51b9480c27 100644 --- a/code/modules/research/techweb/nodes/engineering_nodes.dm +++ b/code/modules/research/techweb/nodes/engineering_nodes.dm @@ -7,8 +7,8 @@ prereq_ids = list("base") design_ids = list("solarcontrol", "recharger", "powermonitor", "rped", "pacman", "adv_capacitor", "adv_scanning", "emitter", "high_cell", "adv_matter_bin", "atmosalerts", "atmos_control", "recycler", "autolathe", "autolathe_secure", "high_micro_laser", "nano_mani", "mesons", "thermomachine", "rad_collector", "tesla_coil", "grounding_rod", - "apc_control", "power control", "airlock_board", "firelock_board", "airalarm_electronics", "firealarm_electronics", "cell_charger", "stack_console", "stack_machine", "rcd_ammo","oxygen_tank", - "plasma_tank", "emergency_oxygen", "emergency_oxygen_engi", "plasmaman_tank_belt", "colormate") + "apc_control", "power control", "airlock_board", "firelock_board", "airalarm_electronics", "firealarm_electronics", "cell_charger", "stack_console", "stack_machine", "rcd_ammo", "oxygen_tank", + "plasma_tank", "emergency_oxygen", "emergency_oxygen_engi", "plasmaman_tank_belt", "colormate", "conveyor_sorter") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 6000) /datum/techweb_node/adv_engi diff --git a/code/modules/vehicles/cars/car.dm b/code/modules/vehicles/cars/car.dm index 81b2db6cf8..e024718f4c 100644 --- a/code/modules/vehicles/cars/car.dm +++ b/code/modules/vehicles/cars/car.dm @@ -2,6 +2,7 @@ layer = ABOVE_MOB_LAYER anchored = TRUE default_driver_move = FALSE + var/explode_on_death = TRUE var/car_traits = NONE //Bitflag for special behavior such as kidnapping var/engine_sound = 'sound/vehicles/carrev.ogg' var/last_enginesound_time @@ -12,6 +13,11 @@ . = ..() LoadComponent(/datum/component/riding) +/obj/vehicle/sealed/car/Destroy() + . = ..() + if(explode_on_death) + explosion(loc, 0, 1, 2, 3, 0) + /obj/vehicle/sealed/car/generate_actions() . = ..() initialize_controller_action_type(/datum/action/vehicle/sealed/remove_key, VEHICLE_CONTROL_DRIVE) diff --git a/code/modules/vehicles/sealed.dm b/code/modules/vehicles/sealed.dm index 1a1858522a..7bb4e878ec 100644 --- a/code/modules/vehicles/sealed.dm +++ b/code/modules/vehicles/sealed.dm @@ -1,7 +1,6 @@ /obj/vehicle/sealed enclosed = TRUE // you're in a sealed vehicle dont get dinked idiot var/enter_delay = 20 - var/explode_on_death = TRUE flags_1 = BLOCK_FACE_ATOM_1 /obj/vehicle/sealed/generate_actions() @@ -90,8 +89,6 @@ /obj/vehicle/sealed/Destroy() DumpMobs() - if(explode_on_death) - explosion(loc, 0, 1, 2, 3, 0) return ..() /obj/vehicle/sealed/proc/DumpMobs(randomstep = TRUE) diff --git a/html/changelogs/archive/2023-01.yml b/html/changelogs/archive/2023-01.yml index ba170f1622..b69203272d 100644 --- a/html/changelogs/archive/2023-01.yml +++ b/html/changelogs/archive/2023-01.yml @@ -17,6 +17,12 @@ - rscadd: Improves Moth in Command to be an improved version of Commander and Chief SpookyTheFox: - tweak: moved blueshift themed sec gear out of premium pricing. +2023-01-08: + LeDrascol: + - bugfix: Fixed techweb sequence break for Advanced Toolset Implant + - tweak: Cryptominer no longer functions in space + - tweak: Cryptominer no longer produces Co2 + - code_imp: Refactored processing for cryptominer 2023-01-09: LeDrascol: - tweak: Fluid Infuser implant uses an improved activation button diff --git a/icons/effects/96x32.dmi b/icons/effects/96x32.dmi index 937b2e8d42..a78d11530b 100644 Binary files a/icons/effects/96x32.dmi and b/icons/effects/96x32.dmi differ diff --git a/icons/mob/clothing/eyes.dmi b/icons/mob/clothing/eyes.dmi index 49702bf920..1525ba9a93 100644 Binary files a/icons/mob/clothing/eyes.dmi and b/icons/mob/clothing/eyes.dmi differ diff --git a/icons/mob/inhands/equipment/custodial_righthand.dmi b/icons/mob/inhands/equipment/custodial_righthand.dmi index 26d8e61163..c986155b10 100644 Binary files a/icons/mob/inhands/equipment/custodial_righthand.dmi and b/icons/mob/inhands/equipment/custodial_righthand.dmi differ diff --git a/icons/obj/abductor.dmi b/icons/obj/abductor.dmi index 75f84347b6..83d71c1093 100644 Binary files a/icons/obj/abductor.dmi and b/icons/obj/abductor.dmi differ diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi index 1752892b60..c98c984c7d 100644 Binary files a/icons/obj/clothing/glasses.dmi and b/icons/obj/clothing/glasses.dmi differ diff --git a/icons/obj/recycling.dmi b/icons/obj/recycling.dmi index 9604d6b97e..621b9e4241 100644 Binary files a/icons/obj/recycling.dmi and b/icons/obj/recycling.dmi differ diff --git a/modular_citadel/code/modules/client/loadout/glasses.dm b/modular_citadel/code/modules/client/loadout/glasses.dm index fe44abc3de..0ca9aa0e05 100644 --- a/modular_citadel/code/modules/client/loadout/glasses.dm +++ b/modular_citadel/code/modules/client/loadout/glasses.dm @@ -45,3 +45,7 @@ /datum/gear/glasses/prescription name = "Prescription glasses" path = /obj/item/clothing/glasses/regular + +/datum/gear/glasses/modern + name = "Modern prescription glasses" + path = /obj/item/clothing/glasses/regular/modern diff --git a/modular_citadel/code/modules/client/loadout/suit.dm b/modular_citadel/code/modules/client/loadout/suit.dm index 1d4a29ef3e..2685812232 100644 --- a/modular_citadel/code/modules/client/loadout/suit.dm +++ b/modular_citadel/code/modules/client/loadout/suit.dm @@ -18,7 +18,6 @@ /datum/gear/suit/redhood name = "Red cloak" path = /obj/item/clothing/suit/hooded/cloak/david - cost = 3 /datum/gear/suit/jacketbomber name = "Bomber jacket" @@ -160,14 +159,14 @@ /datum/gear/suit/coat/polycoat name = "Polychromic winter coat" path = /obj/item/clothing/suit/hooded/wintercoat/polychromic - cost = 4 //too many people with neon green coats is hard on the eyes + cost = 2 //too many people with neon green coats is hard on the eyes // it's probably fine now loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#6A6964", "#C4B8A6", "#0000FF") /datum/gear/suit/coat/wbreakpoly name = "Polychromic windbreaker" path = /obj/item/clothing/suit/toggle/wbreakpoly/polychromic - cost = 4 + cost = 2 loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#464F65", "#916035", "#474747") diff --git a/modular_citadel/code/modules/client/loadout/uniform.dm b/modular_citadel/code/modules/client/loadout/uniform.dm index 2a75f86ffc..5c22485c1f 100644 --- a/modular_citadel/code/modules/client/loadout/uniform.dm +++ b/modular_citadel/code/modules/client/loadout/uniform.dm @@ -280,36 +280,34 @@ /datum/gear/uniform/suit/poly name = "Polychromic Button-up Shirt" path = /obj/item/clothing/under/misc/poly_shirt - cost = 3 + cost = 2 loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#FFFFFF", "#353535", "#353535") /datum/gear/uniform/skirt/poly/pleated name = "Polychromic Pleated Sweaterskirt" path = /obj/item/clothing/under/dress/skirt/polychromic/pleated - cost = 3 + cost = 2 loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#8CC6FF", "#808080", "#FF3535") /datum/gear/uniform/polykilt name = "Polychromic Kilt" path = /obj/item/clothing/under/costume/kilt/polychromic - cost = 3 + cost = 2 loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#FFFFFF", "#F08080") /datum/gear/uniform/shorts/poly name = "Polychromic Shorts" path = /obj/item/clothing/under/misc/polyshorts - cost = 3 + cost = 2 loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#353535", "#808080", "#808080") /datum/gear/uniform/shorts/poly/athletic name = "Polychromic Athletic Shorts" path = /obj/item/clothing/under/shorts/polychromic - cost = 2 - loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#FFFFFF", "#F08080") /datum/gear/uniform/hopcasual diff --git a/modular_sand/code/game/machinery/cryptominers.dm b/modular_sand/code/game/machinery/cryptominers.dm index df17cf0c25..a3c6eccac9 100644 --- a/modular_sand/code/game/machinery/cryptominers.dm +++ b/modular_sand/code/game/machinery/cryptominers.dm @@ -8,13 +8,15 @@ idle_power_usage = 20 active_power_usage = 200 circuit = /obj/item/circuitboard/machine/cryptominer + init_process = FALSE // Don't process upon creation var/mining = FALSE var/miningtime = 3000 var/miningpoints = 50 var/mintemp = TCRYO // 225K equals approximately -55F or -48C var/midtemp = T0C // 273K equals 32F or 0C var/maxtemp = 500 // 500K equals approximately 440F or 226C - var/heatingPower = 40000 + var/heatingPower = 100 // Heat added each processing + var/require_conductivity = TRUE // Prevent use in space var/datum/bank_account/pay_me = null /obj/machinery/cryptominer/Initialize(mapload) @@ -76,43 +78,60 @@ . += "Alt-Click to reset to the Cargo budget." /obj/machinery/cryptominer/process() + // Get turf var/turf/T = get_turf(src) if(!T) return + + // Check for tiles with no conductivity (space) + if(T.thermal_conductivity == 0) + // Normal mode: Warn the user and stop processing + if(require_conductivity) + say("Invalid atmospheric conditions detected! Shutting off!") + playsound(loc, 'sound/machines/beep.ogg', 50, TRUE, -1) + set_mining(FALSE) + return + + // Cheat mode: Skip all atmos code and give points + else + produce_points(3) + return + + // Get air var/datum/gas_mixture/env = T.return_air() if(!env) return - if(!mining) - return - if(env.return_temperature() >= maxtemp) - if(mining) - playsound(loc, 'sound/machines/beep.ogg', 50, TRUE, -1) + + // Get temp + var/env_temp = env.return_temperature() + + // Check for temperature effects + // Minimum (most likely) + if(env_temp <= mintemp) + produce_points(3) + // Mid + else if((env_temp <= midtemp) && (env_temp >= mintemp)) + produce_points(1) + // Maximum + else if((env_temp <= maxtemp) && (env_temp >= midtemp)) + produce_points(0.20) + // Overheat + else if(env_temp >= maxtemp) + say("Critical overheating detected! Shutting off!") + playsound(loc, 'sound/machines/beep.ogg', 50, TRUE, -1) set_mining(FALSE) - return - if(env.return_temperature() <= maxtemp && env.return_temperature() >= midtemp) - if(mining) - produce_points(0.20) - produce_heat() - return - if(env.return_temperature() <= midtemp && env.return_temperature() >= mintemp) - if(mining) - produce_points(1) - produce_heat() - return - if(env.return_temperature() <= mintemp) - if(mining) - produce_points(3) - produce_heat() - return + + // Increase heat by heatingPower + env.set_temperature(env_temp + heatingPower) + + // Update air + air_update_turf() /obj/machinery/cryptominer/proc/produce_points(number) playsound(loc, 'sound/machines/ping.ogg', 50, TRUE, -1) if(pay_me) pay_me.adjust_money(FLOOR(miningpoints * number,1)) -/obj/machinery/cryptominer/proc/produce_heat() - atmos_spawn_air("co2=10;TEMP=2000") - /obj/machinery/cryptominer/attack_hand(mob/living/user) . = ..() if(!is_operational()) diff --git a/modular_sand/code/modules/mining/machine_bluespaceminer.dm b/modular_sand/code/modules/mining/machine_bluespaceminer.dm index 0d62ee9267..513a22e4cc 100644 --- a/modular_sand/code/modules/mining/machine_bluespaceminer.dm +++ b/modular_sand/code/modules/mining/machine_bluespaceminer.dm @@ -7,6 +7,7 @@ can_be_unanchored = TRUE circuit = /obj/item/circuitboard/machine/bluespace_miner layer = BELOW_OBJ_LAYER + init_process = TRUE var/list/ore_rates = list(/datum/material/iron = 0.3, /datum/material/glass = 0.3, /datum/material/plasma = 0.1, /datum/material/silver = 0.1, /datum/material/gold = 0.05, /datum/material/titanium = 0.05, /datum/material/uranium = 0.05, /datum/material/diamond = 0.02) var/datum/component/remote_materials/materials var/multiplier = 0 //Multiplier by tier, has been made fair and everything diff --git a/modular_sand/code/modules/research/techweb/nodes/all_nodes.dm b/modular_sand/code/modules/research/techweb/nodes/all_nodes.dm index 09aa866394..303af10462 100644 --- a/modular_sand/code/modules/research/techweb/nodes/all_nodes.dm +++ b/modular_sand/code/modules/research/techweb/nodes/all_nodes.dm @@ -27,7 +27,7 @@ id = "adv_toolset_implant" display_name = "Advanced Toolset Implant" description = "Allows the creation of alien powerful implants for your arms." - prereq_ids = list("alien_bio") + prereq_ids = list("alien_bio", "alien_engi", "adv_cyber_implants") design_ids = list("ci-toolset-adv","ci-surgery-adv") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) diff --git a/tgstation.dme b/tgstation.dme index 39a492dd4e..47e18c3c82 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -728,6 +728,7 @@ #include "code\datums\elements\bed_tucking.dm" #include "code\datums\elements\bsa_blocker.dm" #include "code\datums\elements\cleaning.dm" +#include "code\datums\elements\connect_loc.dm" #include "code\datums\elements\decal.dm" #include "code\datums\elements\dusts_on_catatonia.dm" #include "code\datums\elements\dusts_on_leaving_area.dm" @@ -3368,6 +3369,7 @@ #include "code\modules\reagents\reagent_containers\spray.dm" #include "code\modules\reagents\reagent_containers\syringes.dm" #include "code\modules\recycling\conveyor2.dm" +#include "code\modules\recycling\conveyor_sorter.dm" #include "code\modules\recycling\sortingmachinery.dm" #include "code\modules\recycling\disposal\bin.dm" #include "code\modules\recycling\disposal\construction.dm" diff --git a/tgui/packages/tgui/interfaces/SuitStorageUnit.js b/tgui/packages/tgui/interfaces/SuitStorageUnit.js index c6f66a79d2..0ac3c61932 100644 --- a/tgui/packages/tgui/interfaces/SuitStorageUnit.js +++ b/tgui/packages/tgui/interfaces/SuitStorageUnit.js @@ -14,6 +14,7 @@ export const SuitStorageUnit = (props, context) => { suit, helmet, mask, + shoes, storage, } = data; return ( @@ -89,6 +90,15 @@ export const SuitStorageUnit = (props, context) => { item: 'mask', })} /> + +