diff --git a/.github/workflows/compare_screenshots.yml b/.github/workflows/compare_screenshots.yml index d9fdaa2b1ff..87c9b96a6d9 100644 --- a/.github/workflows/compare_screenshots.yml +++ b/.github/workflows/compare_screenshots.yml @@ -13,7 +13,7 @@ jobs: run: mkdir -p artifacts # If we ever add more artifacts, this is going to break, but it'll be obvious. - name: Download screenshot tests - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v6 with: path: artifacts - name: ls -R @@ -34,7 +34,7 @@ jobs: echo ${{ github.event.pull_request.number }} > artifacts/screenshot_comparisons/pull_request_number.txt - name: Upload bad screenshots if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: bad-screenshots path: artifacts/screenshot_comparisons diff --git a/.github/workflows/run_integration_tests.yml b/.github/workflows/run_integration_tests.yml index d732f63cef3..71b8e4cd266 100644 --- a/.github/workflows/run_integration_tests.yml +++ b/.github/workflows/run_integration_tests.yml @@ -36,7 +36,7 @@ jobs: major: ${{ inputs.major }} minor: ${{ inputs.minor }} - name: Download build outputs - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v6 with: name: build-artifact-${{ inputs.major || env.BYOND_MAJOR }}-${{ inputs.minor || env.BYOND_MINOR}} path: ./ @@ -63,7 +63,7 @@ jobs: bash tools/ci/run_server.sh ${{ inputs.map }} - name: Upload screenshot tests if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: test_artifacts_${{ inputs.map }}_${{ inputs.major }}_${{ inputs.minor }} path: data/screenshots_new/ diff --git a/.github/workflows/setup_build_artifact.yml b/.github/workflows/setup_build_artifact.yml index aaf4cfb4553..3cbfd8f39d9 100644 --- a/.github/workflows/setup_build_artifact.yml +++ b/.github/workflows/setup_build_artifact.yml @@ -35,7 +35,7 @@ jobs: bash tools/ci/copy_build_output.sh $OUTPUT_DIR - name: Upload artifact if: success() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: build-artifact-${{ inputs.major }}-${{ inputs.minor }} path: ${{ env.OUTPUT_DIR }} diff --git a/code/__DEFINES/icon_smoothing.dm b/code/__DEFINES/icon_smoothing.dm index 5471e58b1d4..3f4558d89fb 100644 --- a/code/__DEFINES/icon_smoothing.dm +++ b/code/__DEFINES/icon_smoothing.dm @@ -239,6 +239,8 @@ DEFINE_BITFIELD(smoothing_junction, list( #define SMOOTH_GROUP_PLATFORMS_PIZZA S_OBJ(85) ///obj/structure/platform/pizza #define SMOOTH_GROUP_PLATFORMS_PAPER S_OBJ(86) ///obj/structure/platform/paper +#define SMOOTH_GROUP_BOULDER_PLATFORM S_OBJ(89) ///obj/structure/lattice/catwalk/boulder + /// Performs the work to set smoothing_groups and canSmoothWith. /// An inlined function used in both turf/Initialize and atom/Initialize. #define SETUP_SMOOTHING(...) \ diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm index 37faad6a2fb..9ae6ebca333 100644 --- a/code/__DEFINES/sound.dm +++ b/code/__DEFINES/sound.dm @@ -385,6 +385,8 @@ GLOBAL_LIST_EMPTY(sfx_datum_by_key) #define SFX_GAS_MASK_PICKUP "gas_mask_pickup" #define SFX_GAS_MASK_DROP "gas_mask_drop" #define SFX_GAS_MASK_EQUIP "gas_mask_equip" +#define SFX_GENERIC_DEVICE_PICKUP "generic_device_pickup" +#define SFX_GENERIC_DEVICE_DROP "generic_device_drop" // Standard is 44.1khz #define MIN_EMOTE_PITCH 40000 diff --git a/code/datums/ai/monkey/monkey_controller.dm b/code/datums/ai/monkey/monkey_controller.dm index 4c778f66122..d7929bf9a8e 100644 --- a/code/datums/ai/monkey/monkey_controller.dm +++ b/code/datums/ai/monkey/monkey_controller.dm @@ -31,8 +31,12 @@ have ways of interacting with a specific mob and control it. /datum/targeting_strategy/basic/monkey /datum/targeting_strategy/basic/monkey/faction_check(datum/ai_controller/controller, mob/living/living_mob, mob/living/the_target) + // if they wronged us, all bets are off if(controller.blackboard[BB_MONKEY_ENEMIES][the_target]) return FALSE + // target was forcibly set, all bets are off again + if(controller.blackboard[BB_MONKEY_CURRENT_ATTACK_TARGET] == the_target) + return FALSE return ..() /datum/ai_controller/monkey/process(seconds_per_tick) diff --git a/code/datums/ai/monkey/monkey_subtrees.dm b/code/datums/ai/monkey/monkey_subtrees.dm index 1210fe44ba1..9feb69df99c 100644 --- a/code/datums/ai/monkey/monkey_subtrees.dm +++ b/code/datums/ai/monkey/monkey_subtrees.dm @@ -55,7 +55,8 @@ controller.queue_behavior(/datum/ai_behavior/recruit_monkeys, BB_MONKEY_CURRENT_ATTACK_TARGET) return - controller.queue_behavior(/datum/ai_behavior/battle_screech/monkey) + if(SPT_PROB(ismonkey(living_pawn) ? 25 : 10, seconds_per_tick)) + controller.queue_behavior(/datum/ai_behavior/battle_screech/monkey) controller.queue_behavior(/datum/ai_behavior/monkey_attack_mob, BB_MONKEY_CURRENT_ATTACK_TARGET) return SUBTREE_RETURN_FINISH_PLANNING diff --git a/code/datums/components/space_allergy.dm b/code/datums/components/space_allergy.dm index 595c5fc0dfa..a89161cfb77 100644 --- a/code/datums/components/space_allergy.dm +++ b/code/datums/components/space_allergy.dm @@ -18,6 +18,8 @@ SIGNAL_HANDLER if(is_on_a_planet(parent) && parent.has_gravity()) - allergy = parent.apply_status_effect(/datum/status_effect/planet_allergy) //your gamer body cant stand real gravity < Soul + var/status_effect = parent.apply_status_effect(/datum/status_effect/planet_allergy) //your gamer body cant stand real gravity < Soul + if(status_effect) + allergy = status_effect else QDEL_NULL(allergy) diff --git a/code/datums/components/wall_mounted.dm b/code/datums/components/wall_mounted.dm index 757b171023e..ef050a7fc61 100644 --- a/code/datums/components/wall_mounted.dm +++ b/code/datums/components/wall_mounted.dm @@ -27,6 +27,7 @@ */ /datum/component/wall_mounted/proc/on_examine(datum/source, mob/user, list/examine_list) SIGNAL_HANDLER + if (parent in view(user.client?.view || world.view, user)) examine_list += span_notice("\The [hanging_wall_turf] is currently supporting [span_bold("[parent]")]. Deconstruction or excessive damage would cause it to [span_bold("fall to the ground")].") diff --git a/code/datums/status_effects/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm index f6043d0b16e..bec38533cdd 100644 --- a/code/datums/status_effects/debuffs/debuffs.dm +++ b/code/datums/status_effects/debuffs/debuffs.dm @@ -374,8 +374,8 @@ return FALSE marked_underlay = new() - marked_underlay.pixel_w = -owner.pixel_x - marked_underlay.pixel_z = -owner.pixel_y + marked_underlay.pixel_w = -(owner.base_pixel_x + owner.base_pixel_w) + marked_underlay.pixel_z = -(owner.base_pixel_y + owner.base_pixel_z) marked_underlay.transform *= 0.5 owner.vis_contents += marked_underlay animate(marked_underlay, ready_delay, transform = matrix() * 1.2, flags = CIRCULAR_EASING | EASE_IN) diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 2f5d5a49073..5fa595c1de1 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -302,6 +302,13 @@ target_location = get_turf(src) else target_location = get_turf(src) + + //give achievement for using unique material + if(design.materials[MAT_CATEGORY_ITEM_MATERIAL]) + for(var/datum/material/material in materials_needed) + if(!istype(material, /datum/material/glass) && !istype(material, /datum/material/iron)) + ui.user.client.give_award(/datum/award/achievement/misc/getting_an_upgrade, ui.user) + break addtimer(CALLBACK(src, PROC_REF(do_make_item), design, build_count, build_time_per_item, material_cost_coefficient, charge_per_item, materials_needed, target_location), build_time_per_item) return TRUE diff --git a/code/game/objects/items/cosmetics.dm b/code/game/objects/items/cosmetics.dm index 5b3bca0ecd5..d9b110c6107 100644 --- a/code/game/objects/items/cosmetics.dm +++ b/code/game/objects/items/cosmetics.dm @@ -194,6 +194,9 @@ inhand_icon_state = "razor" obj_flags = CONDUCTS_ELECTRICITY w_class = WEIGHT_CLASS_TINY + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP /obj/item/razor/suicide_act(mob/living/carbon/user) user.visible_message(span_suicide("[user] begins shaving [user.p_them()]self without the razor guard! It looks like [user.p_theyre()] trying to commit suicide!")) diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index 759790ab155..62ff966c91c 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -11,6 +11,9 @@ w_class = WEIGHT_CLASS_SMALL slot_flags = ITEM_SLOT_BELT item_flags = NOBLUDGEON + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP var/flush = FALSE var/mob/living/silicon/ai/AI diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 0512c992370..05f99b4a447 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -25,6 +25,10 @@ light_range = 4 light_power = 1 light_on = FALSE + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP + /// If we've been forcibly disabled for a temporary amount of time. COOLDOWN_DECLARE(disabled_time) /// Can we toggle this light on and off (used for contexual screentips only) diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm index 7b8257d9ede..c3b17c4ce1f 100644 --- a/code/game/objects/items/devices/gps.dm +++ b/code/game/objects/items/devices/gps.dm @@ -11,6 +11,9 @@ w_class = WEIGHT_CLASS_SMALL slot_flags = ITEM_SLOT_BELT obj_flags = UNIQUE_RENAME + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP var/gpstag var/tracking_on = TRUE var/debug_mode = FALSE diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index 3867ace4fc1..c7507b31bd0 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -9,6 +9,9 @@ obj_flags = CONDUCTS_ELECTRICITY slot_flags = ITEM_SLOT_BACK w_class = WEIGHT_CLASS_HUGE + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP custom_materials = list(/datum/material/iron=SHEET_MATERIAL_AMOUNT *5, /datum/material/glass=SHEET_MATERIAL_AMOUNT * 1.25) var/on = TRUE diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index 0fb0a30157f..b964310d663 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -42,10 +42,6 @@ find_and_hang_on_wall() GLOB.intercoms_list += src -/obj/item/radio/intercom/find_and_hang_on_wall() - if(!unscrewed) - return ..() - /obj/item/radio/intercom/Destroy() GLOB.intercoms_list -= src return ..() diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 266f515152a..8af26ca6651 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -11,6 +11,9 @@ desc = "A basic handheld radio that communicates with local telecommunication networks." dog_fashion = /datum/dog_fashion/back interaction_flags_atom = parent_type::interaction_flags_atom | INTERACT_ATOM_ALLOW_USER_LOCATION | INTERACT_ATOM_IGNORE_MOBILITY + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP obj_flags = CONDUCTS_ELECTRICITY slot_flags = ITEM_SLOT_BELT diff --git a/code/game/objects/items/devices/scanners/autopsy_scanner.dm b/code/game/objects/items/devices/scanners/autopsy_scanner.dm index af0ff55abd1..d407ce6b8e3 100644 --- a/code/game/objects/items/devices/scanners/autopsy_scanner.dm +++ b/code/game/objects/items/devices/scanners/autopsy_scanner.dm @@ -13,6 +13,9 @@ w_class = WEIGHT_CLASS_NORMAL custom_materials = list(/datum/material/iron = SMALL_MATERIAL_AMOUNT*2) custom_price = PAYCHECK_COMMAND + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP /obj/item/autopsy_scanner/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) if(!isliving(interacting_with)) diff --git a/code/game/objects/items/devices/scanners/health_analyzer.dm b/code/game/objects/items/devices/scanners/health_analyzer.dm index 3c1e452b6cf..ffd5947d3c5 100644 --- a/code/game/objects/items/devices/scanners/health_analyzer.dm +++ b/code/game/objects/items/devices/scanners/health_analyzer.dm @@ -22,6 +22,9 @@ custom_materials = list(/datum/material/iron=SMALL_MATERIAL_AMOUNT *2) interaction_flags_click = NEED_LITERACY|NEED_LIGHT|ALLOW_RESTING custom_price = PAYCHECK_COMMAND + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP /// Verbose/condensed var/mode = SCANNER_VERBOSE /// HEALTH/WOUND diff --git a/code/game/objects/items/devices/scanners/plant_analyzer.dm b/code/game/objects/items/devices/scanners/plant_analyzer.dm index 857454fb7fc..e653d09dcb8 100644 --- a/code/game/objects/items/devices/scanners/plant_analyzer.dm +++ b/code/game/objects/items/devices/scanners/plant_analyzer.dm @@ -13,6 +13,9 @@ w_class = WEIGHT_CLASS_TINY slot_flags = ITEM_SLOT_BELT custom_materials = list(/datum/material/iron = SMALL_MATERIAL_AMOUNT*0.3, /datum/material/glass =SMALL_MATERIAL_AMOUNT*0.2) + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP /// Cached data from ui_interact var/list/last_scan_data /// Weakref to the last thing we scanned diff --git a/code/game/objects/items/devices/scanners/sequence_scanner.dm b/code/game/objects/items/devices/scanners/sequence_scanner.dm index d22372fa108..938c5637b74 100644 --- a/code/game/objects/items/devices/scanners/sequence_scanner.dm +++ b/code/game/objects/items/devices/scanners/sequence_scanner.dm @@ -15,6 +15,9 @@ throw_speed = 3 throw_range = 7 custom_materials = list(/datum/material/iron=SMALL_MATERIAL_AMOUNT*2) + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP var/list/discovered = list() //hit a dna console to update the scanners database var/list/buffer diff --git a/code/game/objects/items/devices/scanners/t_scanner.dm b/code/game/objects/items/devices/scanners/t_scanner.dm index 0e8e2c44182..30083139abd 100644 --- a/code/game/objects/items/devices/scanners/t_scanner.dm +++ b/code/game/objects/items/devices/scanners/t_scanner.dm @@ -11,6 +11,9 @@ lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi' custom_materials = list(/datum/material/iron=SMALL_MATERIAL_AMOUNT * 1.5) + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP /// Is this T-Ray scanner currently on? var/on = FALSE diff --git a/code/game/objects/items/devices/sensor_device.dm b/code/game/objects/items/devices/sensor_device.dm index e68c8095fe0..97320669be8 100644 --- a/code/game/objects/items/devices/sensor_device.dm +++ b/code/game/objects/items/devices/sensor_device.dm @@ -11,6 +11,9 @@ slot_flags = ITEM_SLOT_BELT custom_price = PAYCHECK_CREW * 5 custom_premium_price = PAYCHECK_CREW * 6 + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP /obj/item/sensor_device/attack_self(mob/user) GLOB.crewmonitor.show(user,src) //Proc already exists, just had to call it diff --git a/code/game/objects/items/holosign_creator.dm b/code/game/objects/items/holosign_creator.dm index 23db75e850c..6e46cdb2a4d 100644 --- a/code/game/objects/items/holosign_creator.dm +++ b/code/game/objects/items/holosign_creator.dm @@ -13,6 +13,9 @@ throw_speed = 3 throw_range = 7 item_flags = NOBLUDGEON + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP var/list/signs var/max_signs = 10 //time to create a holosign in deciseconds. diff --git a/code/game/objects/items/inspector.dm b/code/game/objects/items/inspector.dm index 2f96f3fb737..8a08562bd84 100644 --- a/code/game/objects/items/inspector.dm +++ b/code/game/objects/items/inspector.dm @@ -22,6 +22,9 @@ interaction_flags_click = NEED_DEXTERITY throw_range = 1 throw_speed = 1 + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP ///How long it takes to print on time each mode, ordered NORMAL, FAST, HONK var/list/time_list = list(5 SECONDS, 1 SECONDS, 0.1 SECONDS) ///Which print time mode we're on. diff --git a/code/game/objects/items/pinpointer.dm b/code/game/objects/items/pinpointer.dm index 2d5c09546d9..4fcb9a7aa79 100644 --- a/code/game/objects/items/pinpointer.dm +++ b/code/game/objects/items/pinpointer.dm @@ -14,6 +14,9 @@ throw_speed = 3 throw_range = 7 custom_materials = list(/datum/material/iron = SMALL_MATERIAL_AMOUNT * 5, /datum/material/glass = SMALL_MATERIAL_AMOUNT * 2.5) + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP var/active = FALSE var/atom/movable/target //The thing we're searching for var/minimum_range = 0 //at what range the pinpointer declares you to be at your destination diff --git a/code/game/objects/items/storage/wallets.dm b/code/game/objects/items/storage/wallets.dm index 8ab4b176ee1..51bb6b6e0e1 100644 --- a/code/game/objects/items/storage/wallets.dm +++ b/code/game/objects/items/storage/wallets.dm @@ -35,7 +35,7 @@ is_magnetic_found = TRUE if(!is_magnetic_found) - var/card_tally = SSid_access.tally_access(id_card, ACCESS_FLAG_COMMAND) + var/card_tally = SSid_access.tally_access(id_card, ACCESS_FLAG_PRV_COMMAND) if(card_tally > winning_tally) winning_tally = card_tally front_id = id_card diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm index f2cf5cd6443..b0c2ef8cfe4 100644 --- a/code/game/objects/items/teleportation.dm +++ b/code/game/objects/items/teleportation.dm @@ -87,6 +87,9 @@ custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 5) armor_type = /datum/armor/item_hand_tele resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP ///List of portal pairs created by this hand tele var/list/active_portal_pairs = list() ///Maximum concurrent active portal pairs allowed diff --git a/code/game/objects/items/wall_mounted.dm b/code/game/objects/items/wall_mounted.dm index 3791970c38a..be07215f3dc 100644 --- a/code/game/objects/items/wall_mounted.dm +++ b/code/game/objects/items/wall_mounted.dm @@ -102,3 +102,6 @@ custom_materials = list(/datum/material/iron= SMALL_MATERIAL_AMOUNT * 0.5, /datum/material/glass= SMALL_MATERIAL_AMOUNT * 0.5) grind_results = list(/datum/reagent/iron = 10, /datum/reagent/silicon = 10) custom_price = PAYCHECK_CREW * 0.5 + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index 34279684ce1..4791a50f6fe 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -196,12 +196,11 @@ /obj/structure/lattice/catwalk/boulder name = "boulder platform" desc = "A boulder, floating on the molten hot deadly lava. More like a BOATlder." - icon = 'icons/obj/ore.dmi' - icon_state = "boulder_platform" + icon = 'icons/obj/smooth_structures/boulder_platform.dmi' + icon_state = "boulder_platform-0" base_icon_state = "boulder_platform" - smoothing_flags = NONE - smoothing_groups = null - canSmoothWith = null + smoothing_groups = SMOOTH_GROUP_BOULDER_PLATFORM + canSmoothWith = SMOOTH_GROUP_BOULDER_PLATFORM + SMOOTH_GROUP_FLOOR_LAVA build_material = null /// The type of particle to make before the platform collapses. var/warning_particle = /particles/smoke/ash @@ -224,10 +223,9 @@ . = ..() /obj/structure/lattice/catwalk/boulder/proc/pre_self_destruct() - if(istype(loc, /turf/open/lava/plasma)) - add_overlay("plasma_cracks") - else - add_overlay("lava_cracks") + var/mutable_appearance/cracks_overlay = mutable_appearance('icons/obj/ore.dmi', istype(loc, /turf/open/lava/plasma) ? "plasma_cracks" : "lava_cracks", src) + cracks_overlay.blend_mode = BLEND_INSET_OVERLAY + add_overlay(cracks_overlay) animate(src, alpha = 0, time = 2 SECONDS, pixel_y = -16, easing = QUAD_EASING|EASE_IN) addtimer(CALLBACK(src, PROC_REF(self_destruct)), 2 SECONDS) diff --git a/code/game/objects/structures/signs/_signs.dm b/code/game/objects/structures/signs/_signs.dm index d1baf9970d4..905d709b273 100644 --- a/code/game/objects/structures/signs/_signs.dm +++ b/code/game/objects/structures/signs/_signs.dm @@ -117,7 +117,6 @@ unwrenched_sign.sign_path = type unwrenched_sign.set_custom_materials(custom_materials) //This is here so picture frames and wooden things don't get messed up. unwrenched_sign.is_editable = is_editable - unwrenched_sign.update_integrity(get_integrity()) //Transfer how damaged it is. unwrenched_sign.setDir(dir) /obj/structure/sign/blank //This subtype is necessary for now because some other things (posters, picture frames, paintings) inherit from the parent type. diff --git a/code/game/sound/sound_keys/sound_keys.dm b/code/game/sound/sound_keys/sound_keys.dm index 0a7c4ea9e0f..e8d528408e1 100644 --- a/code/game/sound/sound_keys/sound_keys.dm +++ b/code/game/sound/sound_keys/sound_keys.dm @@ -1089,3 +1089,22 @@ 'sound/items/gas_mask/gas_mask_equip3.ogg', ) +/datum/sound_effect/generic_device_pickup + key = SFX_GENERIC_DEVICE_PICKUP + file_paths = list( + 'sound/items/generic_device/generic_device_pickup1.ogg', + 'sound/items/generic_device/generic_device_pickup2.ogg', + 'sound/items/generic_device/generic_device_pickup3.ogg', + 'sound/items/generic_device/generic_device_pickup4.ogg', + 'sound/items/generic_device/generic_device_pickup5.ogg', + ) + +/datum/sound_effect/generic_device_drop + key = SFX_GENERIC_DEVICE_DROP + file_paths = list( + 'sound/items/generic_device/generic_device_drop1.ogg', + 'sound/items/generic_device/generic_device_drop2.ogg', + 'sound/items/generic_device/generic_device_drop3.ogg', + 'sound/items/generic_device/generic_device_drop4.ogg', + 'sound/items/generic_device/generic_device_drop5.ogg', + ) diff --git a/code/modules/antagonists/heretic/status_effects/debuffs.dm b/code/modules/antagonists/heretic/status_effects/debuffs.dm index 0e840f485cd..2939f2066a8 100644 --- a/code/modules/antagonists/heretic/status_effects/debuffs.dm +++ b/code/modules/antagonists/heretic/status_effects/debuffs.dm @@ -157,7 +157,6 @@ /datum/status_effect/star_mark/extended duration = 3 MINUTES -f /// Used by moon heretics to make people mad /datum/status_effect/moon_converted diff --git a/code/modules/experisci/handheld_scanner.dm b/code/modules/experisci/handheld_scanner.dm index 67850aedd28..f89fda97f3f 100644 --- a/code/modules/experisci/handheld_scanner.dm +++ b/code/modules/experisci/handheld_scanner.dm @@ -11,6 +11,9 @@ icon_state = "experiscanner" lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi' + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP /obj/item/experi_scanner/Initialize(mapload) ..() diff --git a/code/modules/explorer_drone/control_console.dm b/code/modules/explorer_drone/control_console.dm index 78451dd71a1..21c64757bc1 100644 --- a/code/modules/explorer_drone/control_console.dm +++ b/code/modules/explorer_drone/control_console.dm @@ -23,16 +23,18 @@ RegisterSignal(controlled_drone,COMSIG_QDELETING, PROC_REF(drone_destroyed)) RegisterSignal(controlled_drone,COMSIG_EXODRONE_STATUS_CHANGED, PROC_REF(on_exodrone_status_changed)) update_icon() + playsound(src, 'sound/machines/terminal/terminal_on.ogg', 20, vary = TRUE) /obj/machinery/computer/exodrone_control_console/proc/on_exodrone_status_changed() SIGNAL_HANDLER //Notify we need human action and switch screeb icon to alert. - playsound(src,'sound/machines/ping.ogg',30,FALSE) + playsound(src, 'sound/machines/terminal/terminal_processing.ogg', 20, vary = TRUE) update_icon() /obj/machinery/computer/exodrone_control_console/proc/drone_destroyed() SIGNAL_HANDLER signal_lost = TRUE + playsound(src, 'sound/machines/terminal/terminal_alert.ogg', 20, vary = TRUE) end_drone_control() /obj/machinery/computer/exodrone_control_console/proc/end_drone_control() @@ -41,6 +43,7 @@ UnregisterSignal(controlled_drone,list(COMSIG_QDELETING,COMSIG_EXODRONE_STATUS_CHANGED)) controlled_drone = null update_icon() + playsound(src, 'sound/machines/terminal/terminal_off.ogg', 20, vary = TRUE) /obj/machinery/computer/exodrone_control_console/Destroy() . = ..() @@ -114,7 +117,7 @@ signal_lost = FALSE return TRUE if("self_destruct") - qdel(controlled_drone) //var will be nulled in signal response + controlled_drone.handle_deconstruct() return TRUE if("add_tool") if(controlled_drone && controlled_drone.drone_status == EXODRONE_IDLE) diff --git a/code/modules/explorer_drone/exodrone.dm b/code/modules/explorer_drone/exodrone.dm index e0b1aec07b2..08fc0ae9142 100644 --- a/code/modules/explorer_drone/exodrone.dm +++ b/code/modules/explorer_drone/exodrone.dm @@ -76,9 +76,14 @@ GLOBAL_LIST_EMPTY(exodrone_launchers) // Cargo storage create_storage(max_slots = EXODRONE_CARGO_SLOTS, canthold = GLOB.blacklisted_cargo_types) -/obj/item/exodrone/Destroy() +/obj/item/exodrone/handle_deconstruct(disassembled) . = ..() + explosion(src, 0, 0, 1, 1) + do_sparks(5, FALSE, src) + +/obj/item/exodrone/Destroy() GLOB.exodrones -= src + . = ..() /// Description for drone listing, describes location and current status /obj/item/exodrone/proc/ui_description() @@ -337,7 +342,7 @@ GLOBAL_LIST_EMPTY(exodrone_launchers) /obj/item/exodrone/proc/drone_log(message) if(length(drone_log) > EXODRONE_LOG_SIZE) - drone_log = list() + drone_log.Remove() drone_log.Insert(1,message) /obj/item/exodrone/proc/has_tool(tool_type) diff --git a/code/modules/explorer_drone/scanner_array.dm b/code/modules/explorer_drone/scanner_array.dm index 7588eae233a..237c3aee606 100644 --- a/code/modules/explorer_drone/scanner_array.dm +++ b/code/modules/explorer_drone/scanner_array.dm @@ -175,6 +175,7 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions()) var/datum/exoscan/scan = GLOB.exoscanner_controller.create_scan(scan_type,target) if(scan) RegisterSignal(scan, COMSIG_EXOSCAN_INTERRUPTED, PROC_REF(scan_failed)) + playsound(src, 'sound/machines/terminal/terminal_processing.ogg', 20, vary = TRUE) /obj/machinery/computer/exoscanner_control/proc/scan_failed() SIGNAL_HANDLER diff --git a/code/modules/fishing/aquarium/fish_analyzer.dm b/code/modules/fishing/aquarium/fish_analyzer.dm index 35b01e1edc9..9202420ee1f 100644 --- a/code/modules/fishing/aquarium/fish_analyzer.dm +++ b/code/modules/fishing/aquarium/fish_analyzer.dm @@ -72,37 +72,30 @@ if(target != scanned_object) unregister_scanned() register_scanned(target) - update_static_data_for_all_viewers() ui_interact(user) return ITEM_INTERACT_SUCCESS /obj/item/fish_analyzer/proc/register_scanned(atom/target) scanned_object = target RegisterSignal(target, COMSIG_QDELETING, PROC_REF(on_target_deleted)) - if(HAS_TRAIT(target, TRAIT_IS_AQUARIUM)) - RegisterSignals(target, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON, COMSIG_ATOM_EXITED), PROC_REF(aquarium_update)) /obj/item/fish_analyzer/proc/unregister_scanned() if(!scanned_object) return - UnregisterSignal(scanned_object, list(COMSIG_QDELETING, COMSIG_ATOM_ENTERED, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON, COMSIG_ATOM_EXITED)) + UnregisterSignal(scanned_object, COMSIG_QDELETING) scanned_object = null /obj/item/fish_analyzer/proc/on_target_deleted() SIGNAL_HANDLER unregister_scanned() -/obj/item/fish_analyzer/proc/aquarium_update() - SIGNAL_HANDLER - //update static data on the next tick. to give time to offsprings to properly inherit the parents' traits and all. - addtimer(CALLBACK(src, TYPE_PROC_REF(/datum, update_static_data_for_all_viewers)), 0) - /obj/item/fish_analyzer/ui_interact(mob/user, datum/tgui/ui) if(isnull(scanned_object)) balloon_alert(user, "no specimen data!") return TRUE if(!(scanned_object in view(7, get_turf(src)))) balloon_alert(user, "specimen data lost!") + unregister_scanned() return TRUE ui = SStgui.try_update_ui(user, src, ui) @@ -117,25 +110,13 @@ return UI_CLOSE return ..() -/obj/item/fish_analyzer/ui_static_data(mob/user) +/obj/item/fish_analyzer/ui_data(mob/user) var/list/data = list() data["fish_list"] = list() data["fish_scanned"] = FALSE if(isfish(scanned_object)) data["fish_scanned"] = TRUE - return extract_static_fish_info(data, scanned_object) - - for(var/obj/item/fish/fishie in scanned_object) - extract_static_fish_info(data, fishie) - - return data - -/obj/item/fish_analyzer/ui_data(mob/user) - var/list/data = list() - data["fish_list"] = list() - - if(isfish(scanned_object)) return extract_fish_info(data, scanned_object) for(var/obj/item/fish/fishie in scanned_object) @@ -143,7 +124,7 @@ return data -/obj/item/fish_analyzer/proc/extract_static_fish_info(list/data, obj/item/fish/fishie) +/obj/item/fish_analyzer/proc/extract_fish_info(list/data, obj/item/fish/fishie) var/list/fish_traits = list() var/list/fish_evolutions = list() @@ -175,12 +156,6 @@ "fish_traits" = fish_traits, "fish_evolutions" = fish_evolutions, "fish_suitable_temp" = fishie.fish_flags & FISH_FLAG_SAFE_TEMPERATURE, - )) - - return data - -/obj/item/fish_analyzer/proc/extract_fish_info(list/data, obj/item/fish/fishie) - data["fish_list"] += list(list( "fish_health" = fishie.status == FISH_DEAD ? 0 : PERCENT(fishie.get_health_percentage()), "fish_size" = fishie.size, "fish_weight" = fishie.weight, diff --git a/code/modules/fishing/fish/_fish.dm b/code/modules/fishing/fish/_fish.dm index e3f57d74582..aaec020028d 100644 --- a/code/modules/fishing/fish/_fish.dm +++ b/code/modules/fishing/fish/_fish.dm @@ -232,7 +232,7 @@ GLOBAL_LIST_INIT(fish_compatible_fluid_types, list( register_context() register_item_context() - if(!PERFORM_ALL_TESTS(focus_only/fish_population) || type == abstract_type || stable_population > 1) + if(!apply_qualities || !PERFORM_ALL_TESTS(focus_only/fish_population) || type == abstract_type || stable_population > 1) return if(length(compatible_types)) for(var/obj/item/fish/fishie as anything in compatible_types) diff --git a/code/modules/fishing/fish_mount.dm b/code/modules/fishing/fish_mount.dm index 491abe25ce7..3f5671e653e 100644 --- a/code/modules/fishing/fish_mount.dm +++ b/code/modules/fishing/fish_mount.dm @@ -69,7 +69,8 @@ return ITEM_INTERACT_SUCCESS /obj/structure/fish_mount/proc/add_first_fish() - var/obj/item/fish/fish_path = pick(subtypesof(/obj/item/fish) - list(typesof(/obj/item/fish/holo) + list(/obj/item/fish/starfish/chrystarfish))) // chrystarfish immediately shatters when placed + var/list/valid_picks = subtypesof(/obj/item/fish) - typesof(/obj/item/fish/holo) - /obj/item/fish/starfish/chrystarfish // chrystarfish immediately shatters when placed + var/obj/item/fish/fish_path = pick(valid_picks) if(fish_path.fish_id_redirect_path) fish_path = fish_path.fish_id_redirect_path var/fluff_name = pick("John Trasen III", "a nameless intern", "Pun Pun", AQUARIUM_COMPANY, "Unknown", "Central Command") diff --git a/code/modules/mod/modules/_module.dm b/code/modules/mod/modules/_module.dm index d2e916f2ff5..0c7e637d8b7 100644 --- a/code/modules/mod/modules/_module.dm +++ b/code/modules/mod/modules/_module.dm @@ -4,6 +4,9 @@ icon = 'icons/obj/clothing/modsuit/mod_modules.dmi' icon_state = "module" abstract_type = /obj/item/mod/module + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP /// If it can be removed var/removable = TRUE /// If it's passive, togglable, usable or active diff --git a/code/modules/modular_computers/computers/item/pda.dm b/code/modules/modular_computers/computers/item/pda.dm index b58b3b89083..b2f4839021f 100644 --- a/code/modules/modular_computers/computers/item/pda.dm +++ b/code/modules/modular_computers/computers/item/pda.dm @@ -31,6 +31,9 @@ shell_capacity = SHELL_CAPACITY_SMALL action_slots = ALL + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP ///The item currently inserted into the PDA, starts with a pen. var/obj/item/inserted_item = /obj/item/pen diff --git a/code/modules/pai/card.dm b/code/modules/pai/card.dm index 0c394227c6c..b5d2e183c9f 100644 --- a/code/modules/pai/card.dm +++ b/code/modules/pai/card.dm @@ -11,6 +11,9 @@ slot_flags = ITEM_SLOT_BELT w_class = WEIGHT_CLASS_SMALL worn_icon_state = "electronic" + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP /// Spam alert prevention var/alert_cooldown diff --git a/code/modules/power/apc/apc_main.dm b/code/modules/power/apc/apc_main.dm index 4a8572c4080..fca1ac293ac 100644 --- a/code/modules/power/apc/apc_main.dm +++ b/code/modules/power/apc/apc_main.dm @@ -173,29 +173,14 @@ //. += NAMEOF(src, locked) return . -/obj/machinery/power/apc/Initialize(mapload, ndir) +/obj/machinery/power/apc/Initialize(mapload) . = ..() + setDir(dir) //APCs get added to their own processing tasks for the machines subsystem. if (!(datum_flags & DF_ISPROCESSING)) datum_flags |= DF_ISPROCESSING SSmachines.processing_apcs += src - //Pixel offset its appearance based on its direction - dir = ndir - switch(dir) - if(NORTH) - offset_old = pixel_y - pixel_y = APC_PIXEL_OFFSET - if(SOUTH) - offset_old = pixel_y - pixel_y = -APC_PIXEL_OFFSET - if(EAST) - offset_old = pixel_x - pixel_x = APC_PIXEL_OFFSET - if(WEST) - offset_old = pixel_x - pixel_x = -APC_PIXEL_OFFSET - var/image/hud_image = image(icon = 'icons/mob/huds/hud.dmi', icon_state = "apc_hacked") hud_image.pixel_w = pixel_x hud_image.pixel_z = pixel_y @@ -278,6 +263,22 @@ disconnect_terminal() return ..() +/obj/machinery/power/apc/setDir(newdir) + . = ..() + switch(newdir) + if(NORTH) + offset_old = pixel_y + pixel_y = APC_PIXEL_OFFSET + if(SOUTH) + offset_old = pixel_y + pixel_y = -APC_PIXEL_OFFSET + if(EAST) + offset_old = pixel_x + pixel_x = APC_PIXEL_OFFSET + if(WEST) + offset_old = pixel_x + pixel_x = -APC_PIXEL_OFFSET + /obj/machinery/power/apc/on_saboteur(datum/source, disrupt_duration) . = ..() disrupt_duration *= 0.1 // so, turns out, failure timer is in seconds, not deciseconds; without this, disruptions last 10 times as long as they probably should diff --git a/code/modules/power/lighting/light_construct.dm b/code/modules/power/lighting/light_construct.dm index c3872130b25..c38a34318ca 100644 --- a/code/modules/power/lighting/light_construct.dm +++ b/code/modules/power/lighting/light_construct.dm @@ -145,6 +145,7 @@ if("bulb") new_light = new /obj/machinery/light/small/built(loc) new_light.setDir(dir) + new_light.find_and_hang_on_wall() transfer_fingerprints_to(new_light) if(!QDELETED(cell)) new_light.cell = cell diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 5ee9459b13c..c542f4c4079 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -1113,7 +1113,7 @@ return for(var/datum/surgery/surgery as anything in exposed_carbon.surgeries) - surgery.speed_modifier = max(0.2, surgery.speed_modifier) + surgery.speed_modifier = min(0.8, surgery.speed_modifier) */// BUBBER EDIT REMOVAL END /datum/reagent/space_cleaner/sterilizine/on_burn_wound_processing(datum/wound/burn/flesh/burn_wound) diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index a417b3609e6..c2b80584b06 100644 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -263,6 +263,9 @@ righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi' obj_flags = CONDUCTS_ELECTRICITY slot_flags = ITEM_SLOT_BELT + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP /obj/item/dest_tagger/borg name = "cyborg destination tagger" diff --git a/code/modules/research/stock_parts.dm b/code/modules/research/stock_parts.dm index 5a2a2a47630..ffbf453f393 100644 --- a/code/modules/research/stock_parts.dm +++ b/code/modules/research/stock_parts.dm @@ -9,6 +9,9 @@ If you create T5+ please take a pass at mech_fabricator.dm. The parts being good ///The generic category type that the stock part belongs to. Generic objects that should not be instantiated should have the same type and abstract_type abstract_type = /obj/item/stock_parts w_class = WEIGHT_CLASS_SMALL + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP var/rating = 1 ///Used when a base part has a different name to higher tiers of part. For example, machine frames want any servo and not just a micro-servo. var/base_name diff --git a/code/modules/surgery/organs/internal/eyes/_eyes.dm b/code/modules/surgery/organs/internal/eyes/_eyes.dm index 6d9582fc0c8..a466b2ee3db 100644 --- a/code/modules/surgery/organs/internal/eyes/_eyes.dm +++ b/code/modules/surgery/organs/internal/eyes/_eyes.dm @@ -160,9 +160,9 @@ organ_owner.remove_status_effect(/datum/status_effect/temporary_blindness) if (scarring) - owner.cure_nearsighted(TRAIT_RIGHT_EYE_SCAR) - owner.cure_nearsighted(TRAIT_LEFT_EYE_SCAR) - owner.cure_blind(EYE_SCARRING_TRAIT) + organ_owner.cure_nearsighted(TRAIT_RIGHT_EYE_SCAR) + organ_owner.cure_nearsighted(TRAIT_LEFT_EYE_SCAR) + organ_owner.cure_blind(EYE_SCARRING_TRAIT) organ_owner.update_tint() organ_owner.update_sight() diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index ec2c59bd640..7291157ba48 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -643,6 +643,9 @@ attack_verb_simple = list("pump", "siphon") tool_behaviour = TOOL_BLOODFILTER toolspeed = 1 + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP /// Assoc list of chem ids to names, used for deciding which chems to filter when used for surgery var/list/whitelist = list() var/surgical_tray_overlay = "filter" diff --git a/code/modules/unit_tests/unit_test.dm b/code/modules/unit_tests/unit_test.dm index e7d336478be..c461ebd035c 100644 --- a/code/modules/unit_tests/unit_test.dm +++ b/code/modules/unit_tests/unit_test.dm @@ -18,6 +18,8 @@ GLOBAL_LIST_EMPTY(unit_test_mapping_logs) /// Global assoc list of required mapping items, [item typepath] to [required item datum]. GLOBAL_LIST_EMPTY(required_map_items) +GLOBAL_LIST_EMPTY(test_run_times) + /// A list of every test that is currently focused. /// Use the PERFORM_ALL_TESTS macro instead. GLOBAL_VAR_INIT(focused_tests, focused_tests()) @@ -237,6 +239,8 @@ GLOBAL_VAR_INIT(focused_tests, focused_tests()) log_test(message) test_output_desc += " [duration / 10]s" + if(duration > 10) + GLOB.test_run_times[test_path] = duration if (test.succeeded) log_world("[TEST_OUTPUT_GREEN("PASS")] [test_output_desc]") @@ -409,6 +413,12 @@ GLOBAL_VAR_INIT(focused_tests, focused_tests()) RunUnitTest(unit_path, test_results) SSticker.delay_end = FALSE + log_world("::group::Expensive Unit Test Times") + sortTim(GLOB.test_run_times, cmp = GLOBAL_PROC_REF(cmp_numeric_dsc), associative = TRUE) + for(var/type, duration in GLOB.test_run_times) + log_world("[type] took [duration/10]s") + log_world("::endgroup::") + var/file_name = "data/unit_tests.json" fdel(file_name) file(file_name) << json_encode(test_results) diff --git a/code/modules/vehicles/mecha/mecha_parts.dm b/code/modules/vehicles/mecha/mecha_parts.dm index a8719eb1d4d..e0a31c762da 100644 --- a/code/modules/vehicles/mecha/mecha_parts.dm +++ b/code/modules/vehicles/mecha/mecha_parts.dm @@ -9,6 +9,9 @@ abstract_type = /obj/item/mecha_parts w_class = WEIGHT_CLASS_GIGANTIC obj_flags = CONDUCTS_ELECTRICITY + sound_vary = TRUE + pickup_sound = SFX_GENERIC_DEVICE_PICKUP + drop_sound = SFX_GENERIC_DEVICE_DROP /obj/item/mecha_parts/proc/try_attach_part(mob/user, obj/vehicle/sealed/mecha/M, attach_right = FALSE) //For attaching parts to a finished mech if(!user.transferItemToLoc(src, M)) diff --git a/html/changelogs/AutoChangeLog-pr-93461.yml b/html/changelogs/AutoChangeLog-pr-93461.yml deleted file mode 100644 index f0f660598cb..00000000000 --- a/html/changelogs/AutoChangeLog-pr-93461.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "Ghommie" -delete-after: True -changes: - - qol: "The fish analyzer UI should update more reliably." - - bugfix: "Fixed some of the fishes being unable to reproduce." - - balance: "Fish acquired through means other than fish farming itself takes less time to be able to reproduce." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-93499.yml b/html/changelogs/AutoChangeLog-pr-93499.yml deleted file mode 100644 index 93afa6515e0..00000000000 --- a/html/changelogs/AutoChangeLog-pr-93499.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Krysonism" -delete-after: True -changes: - - balance: "prosthetic item limbs are no longer considered equipped items for some purposes such as ventcrawling." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-93521.yml b/html/changelogs/AutoChangeLog-pr-93521.yml deleted file mode 100644 index c5a531e96df..00000000000 --- a/html/changelogs/AutoChangeLog-pr-93521.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Fixed dropped limbs rotating and disappearing when pulled/thrown" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-93534.yml b/html/changelogs/AutoChangeLog-pr-93534.yml deleted file mode 100644 index 06e318aec4a..00000000000 --- a/html/changelogs/AutoChangeLog-pr-93534.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SyncIt21" -delete-after: True -changes: - - bugfix: "wall mounts placed by player now falls off when the wall they are mounted on is destroyed" - - code_imp: "cleaned up wall mount code" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-93552.yml b/html/changelogs/AutoChangeLog-pr-93552.yml deleted file mode 100644 index 9c12166aabc..00000000000 --- a/html/changelogs/AutoChangeLog-pr-93552.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Fixed glow bleeding through chair and sofa armrests" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-93554.yml b/html/changelogs/AutoChangeLog-pr-93554.yml deleted file mode 100644 index 7092bb04750..00000000000 --- a/html/changelogs/AutoChangeLog-pr-93554.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "TheNobodyofimportance" -delete-after: True -changes: - - balance: "Vomit drinking now checks for fly mouth instead of fly species" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-93559.yml b/html/changelogs/AutoChangeLog-pr-93559.yml deleted file mode 100644 index 92d408c0e1e..00000000000 --- a/html/changelogs/AutoChangeLog-pr-93559.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Fixed an issue which could randomly completely break a player's visuals until an admin resets their HUD" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-93562.yml b/html/changelogs/AutoChangeLog-pr-93562.yml new file mode 100644 index 00000000000..8d9d9de7fcf --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-93562.yml @@ -0,0 +1,4 @@ +author: "JoJe3003" +delete-after: True +changes: + - bugfix: "Admin spawn panel toggle \"By name\"/\"By type\" updates search results without having to update the search string." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-93566.yml b/html/changelogs/AutoChangeLog-pr-93566.yml deleted file mode 100644 index e1141113e33..00000000000 --- a/html/changelogs/AutoChangeLog-pr-93566.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Aliceee2ch" -delete-after: True -changes: - - balance: "Minimal hacked APC amount for purchasing doomsday module was lowered from 15 to 10." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-93585.yml b/html/changelogs/AutoChangeLog-pr-93585.yml new file mode 100644 index 00000000000..a62e8e58b2b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-93585.yml @@ -0,0 +1,4 @@ +author: "Time-Green" +delete-after: True +changes: + - bugfix: "Voidwalker's 'planet allergy' effect goes away again when you leave a planet" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-93597.yml b/html/changelogs/AutoChangeLog-pr-93597.yml new file mode 100644 index 00000000000..5ede190b21a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-93597.yml @@ -0,0 +1,4 @@ +author: "TealSeer" +delete-after: True +changes: + - code_imp: "removed f" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-93604.yml b/html/changelogs/AutoChangeLog-pr-93604.yml new file mode 100644 index 00000000000..4bf5632f91d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-93604.yml @@ -0,0 +1,5 @@ +author: "mcbalaam" +delete-after: True +changes: + - qol: "Better exodrone console UI" + - rscadd: "Exodrones now create a small explosion (0, 0, 1, 1) when self-destruction is triggered" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-93606.yml b/html/changelogs/AutoChangeLog-pr-93606.yml new file mode 100644 index 00000000000..dd5f128af19 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-93606.yml @@ -0,0 +1,7 @@ +author: "SyncIt21" +delete-after: True +changes: + - bugfix: "hand crafted station intercoms now get deconstructed when the wall is destroyed" + - bugfix: "light fixtures applying the wall mounted component on completed light frames" + - bugfix: "APC offsets are correct" + - bugfix: "poster signs dropped from paintings again have positive integrity and will get destroyed properly" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-93612.yml b/html/changelogs/AutoChangeLog-pr-93612.yml new file mode 100644 index 00000000000..2bd3a6dbe6e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-93612.yml @@ -0,0 +1,4 @@ +author: "FeudeyTF" +delete-after: True +changes: + - bugfix: "Now you can get \"Getting an upgrade\" achievement. Craft your own unique item!" \ No newline at end of file diff --git a/html/changelogs/archive/2025-10.yml b/html/changelogs/archive/2025-10.yml index ae298c065aa..8c8fc28ec4c 100644 --- a/html/changelogs/archive/2025-10.yml +++ b/html/changelogs/archive/2025-10.yml @@ -761,3 +761,42 @@ layout, pipes and cables too - map: CATWALK - AI Upload - Re-balanced to have extra protection similar to every other map, layout tweaks for style as well as clearer layout of modules +2025-10-24: + Aliceee2ch: + - balance: Minimal hacked APC amount for purchasing doomsday module was lowered + from 15 to 10. + ArchBTW: + - qol: 'Changes Wallet Priority: Standard ID cards now go in order properly: from + left to right' + Ghommie: + - qol: The fish analyzer UI should update more reliably. + - bugfix: Fixed some of the fishes being unable to reproduce. + - balance: Fish acquired through means other than fish farming itself takes less + time to be able to reproduce. + Krysonism: + - balance: prosthetic item limbs are no longer considered equipped items for some + purposes such as ventcrawling. + Melbert: + - bugfix: Angry monkeys (and the primal instincts trauma) are VIOLENT again + - qol: Monkeys no longer screech every tick they are attacking someone (now ~1 in + 4 ticks, or ~1 in 10 for primal instincts) + SmArtKar: + - bugfix: Fixed dropped limbs rotating and disappearing when pulled/thrown + - bugfix: Fixed an issue which could randomly completely break a player's visuals + until an admin resets their HUD + - bugfix: Fixed glow bleeding through chair and sofa armrests + SyncIt21: + - bugfix: wall mounts placed by player now falls off when the wall they are mounted + on is destroyed + - code_imp: cleaned up wall mount code + TheNobodyofimportance: + - balance: Vomit drinking now checks for fly mouth instead of fly species +2025-10-25: + MGOOOOOO: + - bugfix: Sterilizine will now correctly apply its 20% surgery speed bonus. + SmArtKar: + - bugfix: Fixed PKC mark effect being offset to the side when applied to some mobs. + - image: Boulder platforms spawned by throwing boulders on lava or activating vents + now have new sprites that smooth together + grungussuss: + - sound: added handling sounds for various devices diff --git a/icons/obj/ore.dmi b/icons/obj/ore.dmi index 5346161a9e7..81a7cb03fdf 100644 Binary files a/icons/obj/ore.dmi and b/icons/obj/ore.dmi differ diff --git a/icons/obj/smooth_structures/boulder_platform.dmi b/icons/obj/smooth_structures/boulder_platform.dmi new file mode 100644 index 00000000000..34c99f2dd5c Binary files /dev/null and b/icons/obj/smooth_structures/boulder_platform.dmi differ diff --git a/icons/obj/smooth_structures/boulder_platform.png b/icons/obj/smooth_structures/boulder_platform.png new file mode 100644 index 00000000000..ac31e2b79be Binary files /dev/null and b/icons/obj/smooth_structures/boulder_platform.png differ diff --git a/icons/obj/smooth_structures/boulder_platform.png.toml b/icons/obj/smooth_structures/boulder_platform.png.toml new file mode 100644 index 00000000000..9bc68fe5cd5 --- /dev/null +++ b/icons/obj/smooth_structures/boulder_platform.png.toml @@ -0,0 +1,2 @@ +output_name = "boulder_platform" +template = "bitmask/diagonal_32x32.toml" diff --git a/sound/items/generic_device/attribution.txt b/sound/items/generic_device/attribution.txt new file mode 100644 index 00000000000..86532e8255b --- /dev/null +++ b/sound/items/generic_device/attribution.txt @@ -0,0 +1 @@ +generic_device sounds made by grungussuss, license: CC-BY-SA \ No newline at end of file diff --git a/sound/items/generic_device/generic_device_drop1.ogg b/sound/items/generic_device/generic_device_drop1.ogg new file mode 100644 index 00000000000..b2974510021 Binary files /dev/null and b/sound/items/generic_device/generic_device_drop1.ogg differ diff --git a/sound/items/generic_device/generic_device_drop2.ogg b/sound/items/generic_device/generic_device_drop2.ogg new file mode 100644 index 00000000000..a53ffc2f27a Binary files /dev/null and b/sound/items/generic_device/generic_device_drop2.ogg differ diff --git a/sound/items/generic_device/generic_device_drop3.ogg b/sound/items/generic_device/generic_device_drop3.ogg new file mode 100644 index 00000000000..d58e1dd736c Binary files /dev/null and b/sound/items/generic_device/generic_device_drop3.ogg differ diff --git a/sound/items/generic_device/generic_device_drop4.ogg b/sound/items/generic_device/generic_device_drop4.ogg new file mode 100644 index 00000000000..440126beb17 Binary files /dev/null and b/sound/items/generic_device/generic_device_drop4.ogg differ diff --git a/sound/items/generic_device/generic_device_drop5.ogg b/sound/items/generic_device/generic_device_drop5.ogg new file mode 100644 index 00000000000..f272337c26e Binary files /dev/null and b/sound/items/generic_device/generic_device_drop5.ogg differ diff --git a/sound/items/generic_device/generic_device_pickup1.ogg b/sound/items/generic_device/generic_device_pickup1.ogg new file mode 100644 index 00000000000..8d0c89d628e Binary files /dev/null and b/sound/items/generic_device/generic_device_pickup1.ogg differ diff --git a/sound/items/generic_device/generic_device_pickup2.ogg b/sound/items/generic_device/generic_device_pickup2.ogg new file mode 100644 index 00000000000..91c443738f3 Binary files /dev/null and b/sound/items/generic_device/generic_device_pickup2.ogg differ diff --git a/sound/items/generic_device/generic_device_pickup3.ogg b/sound/items/generic_device/generic_device_pickup3.ogg new file mode 100644 index 00000000000..f6dd7cb8002 Binary files /dev/null and b/sound/items/generic_device/generic_device_pickup3.ogg differ diff --git a/sound/items/generic_device/generic_device_pickup4.ogg b/sound/items/generic_device/generic_device_pickup4.ogg new file mode 100644 index 00000000000..348d4976a07 Binary files /dev/null and b/sound/items/generic_device/generic_device_pickup4.ogg differ diff --git a/sound/items/generic_device/generic_device_pickup5.ogg b/sound/items/generic_device/generic_device_pickup5.ogg new file mode 100644 index 00000000000..f4ed65563e1 Binary files /dev/null and b/sound/items/generic_device/generic_device_pickup5.ogg differ diff --git a/tgui/packages/tgui/interfaces/ExodroneConsole.tsx b/tgui/packages/tgui/interfaces/ExodroneConsole.tsx index b7caeeb4773..8b819187d1d 100644 --- a/tgui/packages/tgui/interfaces/ExodroneConsole.tsx +++ b/tgui/packages/tgui/interfaces/ExodroneConsole.tsx @@ -18,6 +18,7 @@ import { ProgressBar, Section, Stack, + Tooltip, } from 'tgui-core/components'; import { formatTime } from 'tgui-core/format'; import { capitalize } from 'tgui-core/string'; @@ -215,11 +216,7 @@ const SignalLostModal = (props) => { - @@ -279,39 +276,52 @@ const ToolSelectionModal = (props) => { const toolData = Object.keys(all_tools); return ( - - - Select Tool: - - - {(!!toolData && - toolData.map((tool_name) => ( - - - - ))) || ( - - + +
{ + setChoosingTools(false); + }} + /> + } + > + + {(!!toolData && + toolData.map((tool_name) => ( + + + + {' '} + + + )} + +
); }; @@ -325,32 +335,33 @@ const EquipmentBox = (props: { cargo: CargoData; drone: DroneData }) => { switch (cargo.type) { case 'tool': // Tool icon+Remove button if configurable return ( - + + + + - + {capitalize(cargo.name)} + {!!configurable && ( - + - - - { -
+
setChoosingTools(true)} + /> + ) + } + > - {!!configurable && ( - - )} - - - + {cargo.map((cargo_element, index) => ( { ); }; -const DroneStatus = (props: { - drone_integrity: number; - drone_max_integrity: number; -}) => { - const { drone_integrity, drone_max_integrity } = props; - - return ( - - - Integrity: - - - - - - ); -}; - const NoSiteDimmer = () => { return ( @@ -560,12 +618,7 @@ const TravelTargetSelectionScreen = (props: { Cancel )} - - - + } > @@ -582,8 +635,9 @@ const TravelTargetSelectionScreen = (props: { ml={1} onClick={() => travel_to(null)} disabled={!can_travel} + icon={can_travel ? 'rocket' : 'triangle-exclamation'} > - {can_travel ? 'Launch!' : travel_error} + {can_travel ? 'Launch' : travel_error} } @@ -600,8 +654,9 @@ const TravelTargetSelectionScreen = (props: { ml={1} onClick={() => travel_to(destination.ref)} disabled={!can_travel} + icon={can_travel ? 'rocket' : 'triangle-exclamation'} > - {can_travel ? 'Launch!' : travel_error} + {can_travel ? 'Launch' : travel_error} } @@ -681,16 +736,7 @@ const ExplorationScreen = (props: { drone: DroneExploration & DroneData }) => { ); } return ( -
- } - > +
@@ -704,11 +750,21 @@ const ExplorationScreen = (props: { drone: DroneExploration & DroneData }) => { - + {site.events.map((e) => ( +
@@ -728,16 +791,7 @@ const EventScreen = (props: { drone: DroneData; event: FullEventData }) => { const { drone, event } = props; return ( -
- } - > +
@@ -749,7 +803,9 @@ const EventScreen = (props: { drone: DroneData; event: FullEventData }) => { /> -
{event.description}
+
+ {event.description} +
@@ -791,18 +847,7 @@ export const AdventureScreen = (props: { const rawData = adventure_data.raw_image; const imgSource = rawData ? rawData : resolveAsset(adventure_data.image); return ( -
- ) - } - > +
@@ -882,21 +927,25 @@ const ExodroneConsoleContent = (props) => { - + + + + + +
+ + {drone_log.map((log_line, ix) => ( + + {log_line} + + ))} + +
+
+
- -
- - {drone_log.map((log_line, ix) => ( - - {log_line} - - ))} - -
-
); }; diff --git a/tgui/packages/tgui/interfaces/SpawnPanel/CreateObject.tsx b/tgui/packages/tgui/interfaces/SpawnPanel/CreateObject.tsx index ab6004dafc5..8e7064d4257 100644 --- a/tgui/packages/tgui/interfaces/SpawnPanel/CreateObject.tsx +++ b/tgui/packages/tgui/interfaces/SpawnPanel/CreateObject.tsx @@ -1,5 +1,5 @@ import { storage } from 'common/storage'; -import { useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { Button, DmIcon, @@ -55,10 +55,15 @@ export function CreateObject(props: CreateObjectProps) { const currentList = objList; const currentType = allObjects[data.copied_type ?? '']?.type || 'Objects'; + const getSearchString = useCallback( + (key: string) => (searchBy ? key : allObjects[key]?.name || ''), + [searchBy, allObjects], + ); + const { query, setQuery, results } = useFuzzySearch({ searchArray: Object.keys(allObjects), matchStrategy: 'smart', - getSearchString: (key) => (searchBy ? key : allObjects[key]?.name || ''), + getSearchString, }); const filteredResults = results.filter((obj) => {