From aff497ae1c5d1f84541dd8a3e41e3d462dc87fdf Mon Sep 17 00:00:00 2001 From: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Date: Mon, 13 Jan 2025 14:49:03 -0600 Subject: [PATCH 001/106] Drastically improves body marking update (and filter performance) by not calling it like 50 times per update call (#89019) --- .../markings_bodypart_overlay.dm | 29 +++++++++++++- .../mob/living/carbon/human/_species.dm | 40 +++---------------- .../human/species_types/lizardpeople.dm | 10 +++-- .../carbon/human/species_types/mothmen.dm | 9 ++++- code/modules/surgery/bodyparts/_bodyparts.dm | 13 +++--- 5 files changed, 53 insertions(+), 48 deletions(-) diff --git a/code/datums/bodypart_overlays/markings_bodypart_overlay.dm b/code/datums/bodypart_overlays/markings_bodypart_overlay.dm index 5c11fe9f70334..ce49f1c4f8c77 100644 --- a/code/datums/bodypart_overlays/markings_bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/markings_bodypart_overlay.dm @@ -6,13 +6,38 @@ /// Which dna feature key to draw from var/dna_feature_key /// Which bodyparts do we apply ourselves to? - var/list/applies_to = list(/obj/item/bodypart/head, /obj/item/bodypart/chest, /obj/item/bodypart/arm/left, /obj/item/bodypart/arm/right, \ - /obj/item/bodypart/leg/left, /obj/item/bodypart/leg/right) + var/list/applies_to = list( + /obj/item/bodypart/arm/left, + /obj/item/bodypart/arm/right, + /obj/item/bodypart/chest, + /obj/item/bodypart/head, + /obj/item/bodypart/leg/left, + /obj/item/bodypart/leg/right, + ) /// Get the accessory list from SSaccessories. Used in species.dm to get the right sprite /datum/bodypart_overlay/simple/body_marking/proc/get_accessory(name) CRASH("get_accessories() not overriden on [type] !") +/datum/bodypart_overlay/simple/body_marking/set_appearance(name, set_color) + var/datum/sprite_accessory/accessory = get_accessory(name) + if(isnull(accessory)) + return + + icon = accessory.icon + icon_state = accessory.icon_state + use_gender = accessory.gender_specific + draw_color = accessory.color_src ? set_color : null + cache_key = jointext(generate_icon_cache(), "_") + +/datum/bodypart_overlay/simple/body_marking/generate_icon_cache() + . = ..() + . += use_gender + . += draw_color + +/datum/bodypart_overlay/simple/body_marking/can_draw_on_bodypart(mob/living/carbon/human/human) + return icon_state != SPRITE_ACCESSORY_NONE + /datum/bodypart_overlay/simple/body_marking/get_image(layer, obj/item/bodypart/limb) var/gender_string = (use_gender && limb.is_dimorphic) ? (limb.gender == MALE ? MALE : FEMALE + "_") : "" //we only got male and female sprites return mutable_appearance(icon, gender_string + icon_state + "_" + limb.body_zone, layer = layer) diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index 00c186f8e7751..9fadf09c3a029 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -529,7 +529,6 @@ GLOBAL_LIST_EMPTY(features_by_species) species_human.overlays_standing[BODY_LAYER] = standing species_human.apply_overlay(BODY_LAYER) - update_body_markings(species_human) //This exists so sprite accessories can still be per-layer without having to include that layer's //number in their sprite name, which causes issues when those numbers change. @@ -2023,47 +2022,20 @@ GLOBAL_LIST_EMPTY(features_by_species) /datum/species/proc/add_body_markings(mob/living/carbon/human/hooman) for(var/markings_type in body_markings) //loop through possible species markings var/datum/bodypart_overlay/simple/body_marking/markings = new markings_type() // made to die... mostly because we cant use initial on lists but its convenient and organized - var/accessory_name = hooman.dna.features[markings.dna_feature_key] //get the accessory name from dna - var/datum/sprite_accessory/moth_markings/accessory = markings.get_accessory(accessory_name) //get the actual datum - - if(isnull(accessory)) - CRASH("Value: [accessory_name] did not have a corresponding sprite accessory!") - + var/accessory_name = hooman.dna.features[markings.dna_feature_key] || body_markings[markings_type] //get the accessory name from dna for(var/obj/item/bodypart/part as anything in markings.applies_to) //check through our limbs var/obj/item/bodypart/people_part = hooman.get_bodypart(initial(part.body_zone)) // and see if we have a compatible marking for that limb - - if(!people_part) + if(isnull(people_part)) continue - var/datum/bodypart_overlay/simple/body_marking/overlay = new markings_type () - - // Tell the overlay what it should look like - overlay.icon = accessory.icon - overlay.icon_state = accessory.icon_state - overlay.use_gender = accessory.gender_specific - overlay.draw_color = accessory.color_src ? hooman.dna.features["mcolor"] : null - + var/datum/bodypart_overlay/simple/body_marking/overlay = new markings_type() + overlay.set_appearance(accessory_name, hooman.dna.features["mcolor"]) people_part.add_bodypart_overlay(overlay) + qdel(markings) + /// Remove body markings /datum/species/proc/remove_body_markings(mob/living/carbon/human/hooman) for(var/obj/item/bodypart/part as anything in hooman.bodyparts) for(var/datum/bodypart_overlay/simple/body_marking/marking in part.bodypart_overlays) part.remove_bodypart_overlay(marking) - -/// Update the overlays if necessary -/datum/species/proc/update_body_markings(mob/living/carbon/human/hooman) - if(HAS_TRAIT(hooman, TRAIT_INVISIBLE_MAN)) - remove_body_markings(hooman) - return - - var/needs_update = FALSE - for(var/datum/bodypart_overlay/simple/body_marking/marking as anything in body_markings) - if(initial(marking.dna_feature_key) == body_markings[marking]) // dna is same as our species (sort of mini-cache), so no update needed - continue - needs_update = TRUE - break - - if(needs_update) - remove_body_markings(hooman) - add_body_markings(hooman) diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm index d7867ca68e6db..cbc2210cd3813 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -7,12 +7,14 @@ TRAIT_MUTANT_COLORS, ) inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_REPTILE - body_markings = list(/datum/bodypart_overlay/simple/body_marking/lizard = "None") + body_markings = list( + /datum/bodypart_overlay/simple/body_marking/lizard = SPRITE_ACCESSORY_NONE, + ) mutant_organs = list( - /obj/item/organ/horns = "None", - /obj/item/organ/frills = "None", + /obj/item/organ/horns = SPRITE_ACCESSORY_NONE, + /obj/item/organ/frills = SPRITE_ACCESSORY_NONE, /obj/item/organ/snout = "Round", - /obj/item/organ/spines = "None", + /obj/item/organ/spines = SPRITE_ACCESSORY_NONE, /obj/item/organ/tail/lizard = "Smooth", ) mutanttongue = /obj/item/organ/tongue/lizard diff --git a/code/modules/mob/living/carbon/human/species_types/mothmen.dm b/code/modules/mob/living/carbon/human/species_types/mothmen.dm index 680927e89b4a6..c5c98ab9774b7 100644 --- a/code/modules/mob/living/carbon/human/species_types/mothmen.dm +++ b/code/modules/mob/living/carbon/human/species_types/mothmen.dm @@ -3,8 +3,13 @@ plural_form = "Mothmen" id = SPECIES_MOTH inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG - body_markings = list(/datum/bodypart_overlay/simple/body_marking/moth = "None") - mutant_organs = list(/obj/item/organ/wings/moth = "Plain", /obj/item/organ/antennae = "Plain") + body_markings = list( + /datum/bodypart_overlay/simple/body_marking/moth = SPRITE_ACCESSORY_NONE, + ) + mutant_organs = list( + /obj/item/organ/wings/moth = "Plain", + /obj/item/organ/antennae = "Plain", + ) meat = /obj/item/food/meat/slab/human/mutant/moth mutanttongue = /obj/item/organ/tongue/moth mutanteyes = /obj/item/organ/eyes/moth diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index 96defc7f12b85..2d1b3570e3d96 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -955,7 +955,13 @@ update_draw_color() - recolor_bodypart_overlays() + // Recolors mutant overlays to match new mutant colors + for(var/datum/bodypart_overlay/mutant/overlay in bodypart_overlays) + overlay.inherit_color(src, force = TRUE) + // Ensures marking overlays are updated accordingly as well + for(var/datum/bodypart_overlay/simple/body_marking/marking in bodypart_overlays) + marking.set_appearance(human_owner.dna.features[marking.dna_feature_key], species_color) + return TRUE /obj/item/bodypart/proc/update_draw_color() @@ -1318,11 +1324,6 @@ owner.visible_message(span_danger("\The [current_gauze.name] on [owner]'s [name] falls away in rags."), span_warning("\The [current_gauze.name] on your [name] falls away in rags."), vision_distance=COMBAT_MESSAGE_RANGE) QDEL_NULL(current_gauze) -///Loops through all of the bodypart's external organs and update's their color. -/obj/item/bodypart/proc/recolor_bodypart_overlays() - for(var/datum/bodypart_overlay/mutant/overlay in bodypart_overlays) - overlay.inherit_color(src, force = TRUE) - ///A multi-purpose setter for all things immediately important to the icon and iconstate of the limb. /obj/item/bodypart/proc/change_appearance(icon, id, greyscale, dimorphic) var/icon_holder From 275adee60d1ab36eb34d246541b5a10ec05f7bb5 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 00:25:11 +0000 Subject: [PATCH 002/106] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-88593.yml | 5 --- html/changelogs/AutoChangeLog-pr-88668.yml | 6 ---- html/changelogs/AutoChangeLog-pr-88751.yml | 6 ---- html/changelogs/AutoChangeLog-pr-88873.yml | 5 --- html/changelogs/AutoChangeLog-pr-88900.yml | 5 --- html/changelogs/AutoChangeLog-pr-88905.yml | 4 --- html/changelogs/AutoChangeLog-pr-88907.yml | 4 --- html/changelogs/AutoChangeLog-pr-88923.yml | 4 --- html/changelogs/AutoChangeLog-pr-88931.yml | 4 --- html/changelogs/AutoChangeLog-pr-88957.yml | 4 --- html/changelogs/AutoChangeLog-pr-88980.yml | 4 --- html/changelogs/AutoChangeLog-pr-88993.yml | 4 --- html/changelogs/archive/2025-01.yml | 37 ++++++++++++++++++++++ 13 files changed, 37 insertions(+), 55 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-88593.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-88668.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-88751.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-88873.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-88900.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-88905.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-88907.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-88923.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-88931.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-88957.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-88980.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-88993.yml diff --git a/html/changelogs/AutoChangeLog-pr-88593.yml b/html/changelogs/AutoChangeLog-pr-88593.yml deleted file mode 100644 index 38ead90a80099..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88593.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Y0SH1M4S73R" -delete-after: True -changes: - - rscadd: "Adds circuit wirenet components, allowing data to be transmitted and received over cable networks." - - qol: "When attached to a machine, mech, modsuit, or borg, assembly circuit shells will use power from those instead of the circuit's own cell." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88668.yml b/html/changelogs/AutoChangeLog-pr-88668.yml deleted file mode 100644 index 5bb49a4e1640d..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88668.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "Dmeto" -delete-after: True -changes: - - map: "Metastation Science lobby camera moved away form Experimental Destructive Scanner(It was geting eaten on scan)" - - bugfix: "Lavaland base hydroponics scrubber attached to its network with missing pipes" - - map: " Redundent disconnected scrubber in cargo office removed on Metastation\nmap : Cable remove from under wall of Qm office on Metastation" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88751.yml b/html/changelogs/AutoChangeLog-pr-88751.yml deleted file mode 100644 index fd9e4632885c3..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88751.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "Paxilmaniac" -delete-after: True -changes: - - bugfix: "fixes plasma stabilizer module not showing a visor on modsuits" - - bugfix: "makes the plasma stabilizer module actually visible" - - bugfix: "makes rave module grey by default as it was meant to be" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88873.yml b/html/changelogs/AutoChangeLog-pr-88873.yml deleted file mode 100644 index 500d8f21f63ce..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88873.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Melbert" -delete-after: True -changes: - - rscadd: "[Icebox] Reworked Tech Storage" - - rscadd: "[Icebox] Reworked Public Mining" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88900.yml b/html/changelogs/AutoChangeLog-pr-88900.yml deleted file mode 100644 index 04a5d168fb0ab..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88900.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "EEASAS" -delete-after: True -changes: - - qol: "Gives cargo their APLU Big Bess on Ice Box Station" - - map: "Extended and revamped cargo's warehouse on Ice Box Station" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88905.yml b/html/changelogs/AutoChangeLog-pr-88905.yml deleted file mode 100644 index e800d8fc0dcde..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88905.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Fixed wawa's xenobio reagent grinders being inaccessible" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88907.yml b/html/changelogs/AutoChangeLog-pr-88907.yml deleted file mode 100644 index a97ab41fe1c98..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88907.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Fixed camouflage implant missing icon" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88923.yml b/html/changelogs/AutoChangeLog-pr-88923.yml deleted file mode 100644 index 9e75301e1245b..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88923.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Added a barboat seat projector to Wawa's bar" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88931.yml b/html/changelogs/AutoChangeLog-pr-88931.yml deleted file mode 100644 index 9464bad5b9350..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88931.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Zytolg" -delete-after: True -changes: - - map: "Who turned down Birdshots Thermostat?" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88957.yml b/html/changelogs/AutoChangeLog-pr-88957.yml deleted file mode 100644 index 7ad221511740b..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88957.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - map: "Updated the Turreted Outpost space ruin" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88980.yml b/html/changelogs/AutoChangeLog-pr-88980.yml deleted file mode 100644 index 0e6bba11bcada..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88980.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "TealSeer" -delete-after: True -changes: - - map: "fixed the lightswitch in Ice Box shared engineering storage being covered by the APC." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88993.yml b/html/changelogs/AutoChangeLog-pr-88993.yml deleted file mode 100644 index 506aac166f4ef..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88993.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Darkened-Earth" -delete-after: True -changes: - - bugfix: "NanoTrasen telecomms technicians operating on Tram class stations have been reminded not to charge their power tools directly from their TCOMMS SMES" \ No newline at end of file diff --git a/html/changelogs/archive/2025-01.yml b/html/changelogs/archive/2025-01.yml index 3e885fb3e5ab6..c074091a474a2 100644 --- a/html/changelogs/archive/2025-01.yml +++ b/html/changelogs/archive/2025-01.yml @@ -331,3 +331,40 @@ warbluke: - bugfix: Fake Nuclear Disks and Obviously Fake Nuclear Disks no longer teleport when changing Z-level outside of station. +2025-01-14: + Darkened-Earth: + - bugfix: NanoTrasen telecomms technicians operating on Tram class stations have + been reminded not to charge their power tools directly from their TCOMMS SMES + Dmeto: + - map: Metastation Science lobby camera moved away form Experimental Destructive + Scanner(It was geting eaten on scan) + - bugfix: Lavaland base hydroponics scrubber attached to its network with missing + pipes + - map: ' Redundent disconnected scrubber in cargo office removed on Metastation + + map : Cable remove from under wall of Qm office on Metastation' + EEASAS: + - qol: Gives cargo their APLU Big Bess on Ice Box Station + - map: Extended and revamped cargo's warehouse on Ice Box Station + Melbert: + - rscadd: '[Icebox] Reworked Tech Storage' + - rscadd: '[Icebox] Reworked Public Mining' + Paxilmaniac: + - bugfix: fixes plasma stabilizer module not showing a visor on modsuits + - bugfix: makes the plasma stabilizer module actually visible + - bugfix: makes rave module grey by default as it was meant to be + SmArtKar: + - bugfix: Fixed wawa's xenobio reagent grinders being inaccessible + - bugfix: Fixed camouflage implant missing icon + - bugfix: Added a barboat seat projector to Wawa's bar + - map: Updated the Turreted Outpost space ruin + TealSeer: + - map: fixed the lightswitch in Ice Box shared engineering storage being covered + by the APC. + Y0SH1M4S73R: + - rscadd: Adds circuit wirenet components, allowing data to be transmitted and received + over cable networks. + - qol: When attached to a machine, mech, modsuit, or borg, assembly circuit shells + will use power from those instead of the circuit's own cell. + Zytolg: + - map: Who turned down Birdshots Thermostat? From 2628ec2d5aa77fd874fda5ab31a577c198115fa5 Mon Sep 17 00:00:00 2001 From: paganiy <126676387+paganiy@users.noreply.github.com> Date: Tue, 14 Jan 2025 06:18:41 +0400 Subject: [PATCH 003/106] Nuar glasses for detective (#88902) ## About The Pull Request Adds a pair of nuar glasses in detdrobe premium tab, which makes them see the world in black and white colors. --- code/modules/clothing/glasses/_glasses.dm | 6 ++++++ code/modules/vending/wardrobes.dm | 1 + 2 files changed, 7 insertions(+) diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index cead31d6207c0..6f5e3220e2dcb 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -443,6 +443,12 @@ inhand_icon_state = "gar" glass_colour_type = /datum/client_colour/glass_colour/red +/obj/item/clothing/glasses/sunglasses/noir + name = "noir glasses" + desc = "A pair of sleek, futuristic glasses that allow the wearer to see the world in a different light." + glass_colour_type = /datum/client_colour/monochrome + forced_glass_color = TRUE + ///Syndicate item that upgrades the flash protection of your eyes. /obj/item/syndicate_contacts name = "suspicious contact lens case" diff --git a/code/modules/vending/wardrobes.dm b/code/modules/vending/wardrobes.dm index 5d19644d363ff..5c7fd7fc60b5d 100644 --- a/code/modules/vending/wardrobes.dm +++ b/code/modules/vending/wardrobes.dm @@ -698,6 +698,7 @@ GLOBAL_VAR_INIT(roaches_deployed, FALSE) ) premium = list( /obj/item/clothing/head/flatcap = 1, + /obj/item/clothing/glasses/sunglasses/noir = 1, ) refill_canister = /obj/item/vending_refill/wardrobe/det_wardrobe extra_price = PAYCHECK_COMMAND * 1.75 From 966201c6913805b92a974a6627950fdc2bba9e86 Mon Sep 17 00:00:00 2001 From: hyperjll <105099113+hyperjll@users.noreply.github.com> Date: Mon, 13 Jan 2025 21:19:00 -0500 Subject: [PATCH 004/106] Fixing a small typo within contractor.dm (#89039) ## About The Pull Request It just fixes a small typo i caught while testing other things on my private server. ## Why It's Good For The Game TYPOS BAD. ENGLISH GOOD. --- code/modules/uplink/uplink_items/contractor.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/uplink/uplink_items/contractor.dm b/code/modules/uplink/uplink_items/contractor.dm index 7d261410e314d..9283addc18115 100644 --- a/code/modules/uplink/uplink_items/contractor.dm +++ b/code/modules/uplink/uplink_items/contractor.dm @@ -83,7 +83,7 @@ /datum/uplink_item/contractor/partner name = "Contractor Reinforcement" - desc = "A reinforecment operative will be sent to aid you in your goals, \ + desc = "A reinforcement operative will be sent to aid you in your goals, \ they are paid separately, and will not take a cut from your profits." item = /obj/item/antag_spawner/loadout/contractor limited_stock = 1 From e036221d5f9ad5e48f3fd54d70c87302a552cc79 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 02:19:03 +0000 Subject: [PATCH 005/106] Automatic changelog for PR #88902 [ci skip] --- html/changelogs/AutoChangeLog-pr-88902.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-88902.yml diff --git a/html/changelogs/AutoChangeLog-pr-88902.yml b/html/changelogs/AutoChangeLog-pr-88902.yml new file mode 100644 index 0000000000000..352a8b7ccdd20 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-88902.yml @@ -0,0 +1,4 @@ +author: "paganiy" +delete-after: True +changes: + - rscadd: "nuar glasses for detective in their detdrobe" \ No newline at end of file From 97bd49395f67242d8a2e254099020b8d2052d28b Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 02:19:19 +0000 Subject: [PATCH 006/106] Automatic changelog for PR #89039 [ci skip] --- html/changelogs/AutoChangeLog-pr-89039.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-89039.yml diff --git a/html/changelogs/AutoChangeLog-pr-89039.yml b/html/changelogs/AutoChangeLog-pr-89039.yml new file mode 100644 index 0000000000000..b899a5d20c10c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-89039.yml @@ -0,0 +1,4 @@ +author: "hyperjll" +delete-after: True +changes: + - spellcheck: "We at the Syndicate hereby apologize for our lackluster spellcheck work. (reinforecment -> reinforcement -- found within the contractor reinforcement listing.)" \ No newline at end of file From 1df0a80a9132039e60e6db69c4bb1082ae77cb46 Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Tue, 14 Jan 2025 05:20:16 +0300 Subject: [PATCH 007/106] Fixes a barricade balloon runtime (#89043) ## About The Pull Request balloon_alert is async and thus should not be called on objects that are about to qdelete --- code/game/machinery/deployable.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index 4f78fbf3a52ee..1c596a026cc58 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -90,7 +90,7 @@ balloon_alert(user, "deconstructing barricade...") if(!tool.use_tool(src, user, 2 SECONDS, volume=50)) return - balloon_alert(user, "barricade deconstructed") + loc.balloon_alert(user, "barricade deconstructed") tool.play_tool_sound(src) new /obj/item/stack/sheet/mineral/wood(get_turf(src), drop_amount) qdel(src) From 352dd7a97b87589e9b37ebf79bf520c1691e5d6c Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 02:20:40 +0000 Subject: [PATCH 008/106] Automatic changelog for PR #89043 [ci skip] --- html/changelogs/AutoChangeLog-pr-89043.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-89043.yml diff --git a/html/changelogs/AutoChangeLog-pr-89043.yml b/html/changelogs/AutoChangeLog-pr-89043.yml new file mode 100644 index 0000000000000..addc4bed13732 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-89043.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Fixed a missing \"barricade deconstructed\" balloon alert when crowbaring a barricade" \ No newline at end of file From 217c52c890c67d33d7210e69f54ce4b7f2bb2e8c Mon Sep 17 00:00:00 2001 From: Gaxeer <44334376+Gaxeer@users.noreply.github.com> Date: Tue, 14 Jan 2025 16:22:38 +0200 Subject: [PATCH 009/106] Radio examine qol (#89028) ## About The Pull Request Add `span_class` macro to use instead of (now only used for changes I made to radio examine). Make radio channel tokens info from headset examine more readable by color coding and displaying it in list format. Currently set broadcast frequence is also color coded and bold. ## Why It's Good For The Game It's now easier to understand headset examine info :D
Before ![image](https://github.com/user-attachments/assets/6b5d7533-6b8e-47b9-9cd2-7c7a92552ca2) ![image](https://github.com/user-attachments/assets/7fcbde2b-0817-4db6-aca8-d15c17d708be)
After ![image](https://github.com/user-attachments/assets/6e9a7156-9c76-4843-8a45-7fce752a7b27) ![image](https://github.com/user-attachments/assets/50e5fb70-eb18-4fc5-803a-070774c73ccf)
## Changelog :cl: qol: tokens and channel names in radio headset examine are now color coded and display in list format qol: broadcast frequency in examine is also color coded code: add new `span_class` macro /:cl: --- code/__DEFINES/span.dm | 3 ++ .../objects/items/devices/radio/headset.dm | 40 +++++++++++-------- .../game/objects/items/devices/radio/radio.dm | 2 +- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/code/__DEFINES/span.dm b/code/__DEFINES/span.dm index d107782385833..18ce0a96a7147 100644 --- a/code/__DEFINES/span.dm +++ b/code/__DEFINES/span.dm @@ -1,3 +1,6 @@ +// Just a generic span with class +#define span_class(class, str) ("" + str + "") + // Sorted alphabetically #define span_abductor(str) ("" + str + "") #define span_admin(str) ("" + str + "") diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 8ad4f0d77d169..578c671bf5308 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -47,23 +47,31 @@ GLOBAL_LIST_INIT(channel_tokens, list( /obj/item/radio/headset/examine(mob/user) . = ..() - if(item_flags & IN_INVENTORY && loc == user) - // construction of frequency description - var/list/avail_chans = list("Use [RADIO_KEY_COMMON] for the currently tuned frequency") - if(special_channels & RADIO_SPECIAL_BINARY) - avail_chans += "use [MODE_TOKEN_BINARY] for [MODE_BINARY]" - if(length(channels)) - for(var/i in 1 to length(channels)) - if(i == 1) - avail_chans += "use [MODE_TOKEN_DEPARTMENT] or [GLOB.channel_tokens[channels[i]]] for [LOWER_TEXT(channels[i])]" - else - avail_chans += "use [GLOB.channel_tokens[channels[i]]] for [LOWER_TEXT(channels[i])]" - . += span_notice("A small screen on the headset displays the following available frequencies:\n[english_list(avail_chans)].") - - if(command) - . += span_info("Alt-click to toggle the high-volume mode.") - else + if(!(item_flags & IN_INVENTORY) || loc != user) . += span_notice("A small screen on the headset flashes, it's too small to read without holding or wearing the headset.") + return + + // construction of frequency description + var/list/available_channels = list() + available_channels += "
  • [span_radio(RADIO_KEY_COMMON)] for the currently tuned frequency
  • " + if(special_channels & RADIO_SPECIAL_BINARY) + available_channels += "
  • [span_binarysay(MODE_TOKEN_BINARY)] for [span_binarysay(capitalize(MODE_BINARY))]
  • " + + for(var/i in 1 to length(channels)) + var/channel_name = channels[i] + var/channel_token = GLOB.channel_tokens[channel_name] + var/channel_span_class = get_radio_span(GLOB.radiochannels[channel_name]) + + if(i == 1) + available_channels += "
  • [span_class(channel_span_class, MODE_TOKEN_DEPARTMENT)] or [span_class(channel_span_class, channel_token)] for [span_class(channel_span_class, channel_name)]
  • " + else + available_channels += "
  • [span_class(channel_span_class, channel_token)] for [span_class(channel_span_class, channel_name)]
  • " + + . += span_notice("A small screen on the headset displays the following available frequencies:") + . += span_notice("") + + if(command) + . += span_info("Alt-click to toggle the high-volume mode.") /obj/item/radio/headset/Initialize(mapload) . = ..() diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 25060d23af5b2..8391edb8319d1 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -528,7 +528,7 @@ /obj/item/radio/examine(mob/user) . = ..() if (frequency && in_range(src, user)) - . += span_notice("It is set to broadcast over the [frequency/10] frequency.") + . += span_notice("It is set to broadcast over the [span_radio("[frequency/10]")] frequency.") if (unscrewed) . += span_notice("It can be attached and modified.") else From a1a9eb56e1825acb0574ac38e9b2686165d5b842 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:22:59 +0000 Subject: [PATCH 010/106] Automatic changelog for PR #89028 [ci skip] --- html/changelogs/AutoChangeLog-pr-89028.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-89028.yml diff --git a/html/changelogs/AutoChangeLog-pr-89028.yml b/html/changelogs/AutoChangeLog-pr-89028.yml new file mode 100644 index 0000000000000..239752d684abf --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-89028.yml @@ -0,0 +1,6 @@ +author: "Gaxeer" +delete-after: True +changes: + - qol: "tokens and channel names in radio headset examine are now color coded and display in list format" + - qol: "broadcast frequency in examine is also color coded" + - code_imp: "add new `span_class` macro" \ No newline at end of file From 999dbe6e4c9afd3b11a559a5c3968c17946e8099 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Tue, 14 Jan 2025 14:24:08 +0000 Subject: [PATCH 011/106] Space carp speech includes fish puns (#89033) ## About The Pull Request This PR adds the fish pun speech filter to space carp. This was originally added and implemented for crabs and lobsters but it seems like it should be fine on space fish as well. Space Dragons don't have this because Dragons are more refined than the riff-raff and take classes on proper diction. ## Why It's Good For The Game For some reason space carp can speak common if they are sapient. Most sapient space carp come from space dragon rifts so it's useful for them to be able to speak to each other and coordinate. I think it's kind of weird that they can talk to the crew to be honest, but it's probably more fun that they can. That said, if they are going to be able to communicate with the crew then they should have to talk like a fish. ## Changelog :cl: add: Space Carp now have a more distinctive accent when speaking Common. /:cl: --- code/modules/mob/living/basic/space_fauna/carp/carp.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp.dm b/code/modules/mob/living/basic/space_fauna/carp/carp.dm index 0e0ba3b39a1ae..d62804f1ca1bf 100644 --- a/code/modules/mob/living/basic/space_fauna/carp/carp.dm +++ b/code/modules/mob/living/basic/space_fauna/carp/carp.dm @@ -104,6 +104,7 @@ AddElement(/datum/element/ai_flee_while_injured) setup_eating() + AddComponent(/datum/component/speechmod, replacements = strings("crustacean_replacement.json", "crustacean")) AddComponent(/datum/component/aggro_emote, emote_list = string_list(list("gnashes"))) AddComponent(/datum/component/regenerator, outline_colour = regenerate_colour) AddComponent(/datum/component/profound_fisher) @@ -119,6 +120,10 @@ ai_controller.set_blackboard_key(BB_CARP_RIFT, teleport) ai_controller.set_blackboard_key(BB_OBSTACLE_TARGETING_WHITELIST, allowed_obstacle_targets) +/mob/living/basic/carp/Destroy() + QDEL_NULL(teleport) + return ..() + /// Tell the elements and the blackboard what food we want to eat /mob/living/basic/carp/proc/setup_eating() AddElement(/datum/element/basic_eating, food_types = desired_food) From 7c70436e236a2e18b21ffc016f7de60ce6650a4a Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:24:27 +0000 Subject: [PATCH 012/106] Automatic changelog for PR #89033 [ci skip] --- html/changelogs/AutoChangeLog-pr-89033.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-89033.yml diff --git a/html/changelogs/AutoChangeLog-pr-89033.yml b/html/changelogs/AutoChangeLog-pr-89033.yml new file mode 100644 index 0000000000000..7529f5c47e232 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-89033.yml @@ -0,0 +1,4 @@ +author: "Jacquerel" +delete-after: True +changes: + - rscadd: "Space Carp now have a more distinctive accent when speaking Common." \ No newline at end of file From 7577ad965537ad391d52f1d14c8f84f9f6feb469 Mon Sep 17 00:00:00 2001 From: Lucy Date: Tue, 14 Jan 2025 09:25:01 -0500 Subject: [PATCH 013/106] Prevent gibspawners from randomly causing failures with mapping nearstation tests (#89026) ## About The Pull Request this stops gibs from being streaked from spawners during unit tests, as there's a chance it might just go into space, causing a mapping nearstation test failure. there's already a precedent for the "just disable it during unit tests" solution with https://github.com/tgstation/tgstation/pull/87878 ## Why It's Good For The Game flaky tests bad :3 ## Changelog no player-facing changes --- code/game/objects/effects/spawners/gibspawner.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/game/objects/effects/spawners/gibspawner.dm b/code/game/objects/effects/spawners/gibspawner.dm index 92343d91d219d..88d16c87acd30 100644 --- a/code/game/objects/effects/spawners/gibspawner.dm +++ b/code/game/objects/effects/spawners/gibspawner.dm @@ -50,10 +50,13 @@ gib.add_blood_DNA(dna_to_add) +// These might streak off into space and cause annoying flaky failures with mapping nearstation tests +#ifndef UNIT_TESTS var/list/directions = gibdirections[i] if(isturf(loc)) if(directions.len) gib.streak(directions, mapload) +#endif return INITIALIZE_HINT_QDEL From 6737d8cc7f8e78be7e470e2f9ace7f7d4b794d42 Mon Sep 17 00:00:00 2001 From: Jeremiah <42397676+jlsnow301@users.noreply.github.com> Date: Tue, 14 Jan 2025 06:25:39 -0800 Subject: [PATCH 014/106] Fixes icon spacing in late join ui (#89041) ## About The Pull Request An alternate to #89040 ![Screenshot 2025-01-12 035024](https://github.com/user-attachments/assets/230e599a-8cae-4dba-8dee-4e9975b7a61e) Refactors the UI Adds scrollbar to section rather than window so that the title doesnt disappear Gives more contrast to the window's main content section Tooltip now shows closer to the mouse. It was far off in some cases Functions! ## Why It's Good For The Game Fixes a ui bug ## Changelog :cl: fix: Fixed icon spacing in the late join menu. /:cl: --- .../packages/tgui/interfaces/JobSelection.tsx | 217 ++++++++++-------- 1 file changed, 117 insertions(+), 100 deletions(-) diff --git a/tgui/packages/tgui/interfaces/JobSelection.tsx b/tgui/packages/tgui/interfaces/JobSelection.tsx index e598ef37f7fe5..ad3af89648c86 100644 --- a/tgui/packages/tgui/interfaces/JobSelection.tsx +++ b/tgui/packages/tgui/interfaces/JobSelection.tsx @@ -5,6 +5,7 @@ import { Button, Icon, NoticeBox, + Section, Stack, StyleableSection, } from 'tgui-core/components'; @@ -39,16 +40,18 @@ type Data = { round_duration: string; }; -export const JobEntry = (data: { +type JobEntryProps = { jobName: string; job: Job; department: Department; onClick: () => void; -}) => { - const jobName = data.jobName; - const job = data.job; - const department = data.department; +}; + +function JobEntry(props: JobEntryProps) { + const { jobName, job, department, onClick } = props; + const jobIcon = JOB2ICON[jobName] || null; + return ( ); +} + +type DepartmentEntryProps = { + name: string; + department: Department; }; -export const JobSelection = (props) => { +function DepartmentEntry(props: DepartmentEntryProps) { + const { name, department } = props; + const { act } = useBackend(); + + return ( + + + {name} + + {department.open_slots + + (department.open_slots === 1 ? ' slot' : ' slots') + + ' available'} + + + } + style={{ + backgroundColor: department.color, + marginBottom: '1em', + breakInside: 'avoid-column', + }} + titleStyle={{ + 'border-bottom-color': Color.fromHex(department.color) + .darken(50) + .toString(), + }} + textStyle={{ + color: Color.fromHex(department.color).darken(80).toString(), + }} + > + + {Object.entries(department.jobs).map(([name, job]) => ( + + { + act('select_job', { job: name }); + }} + /> + + ))} + + + + ); +} + +export function JobSelection(props) { const { act, data } = useBackend(); if (!data?.departments_static) { return null; // Stop TGUI whitescreens with TGUI-dev! } + const departments: Record = deepMerge( data.departments, data.departments_static, ); + const { shuttle_status, round_duration } = data; + return ( - - - + +
    act('select_job', { job: 'Random' })} + tooltip="Roll target random job. You can re-roll or cancel your random job if you don't like it." + > + Random Job! + + } + fill + scrollable title={ <> - {data.shuttle_status && ( - {data.shuttle_status} - )} - - It is currently {data.round_duration} into the shift. - -
    ); -}; +} From 7e879a95310c58d7c85b86ae0cf15ccbece789e4 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:26:35 +0000 Subject: [PATCH 015/106] Automatic changelog for PR #89041 [ci skip] --- html/changelogs/AutoChangeLog-pr-89041.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-89041.yml diff --git a/html/changelogs/AutoChangeLog-pr-89041.yml b/html/changelogs/AutoChangeLog-pr-89041.yml new file mode 100644 index 0000000000000..dd7af61eee121 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-89041.yml @@ -0,0 +1,4 @@ +author: "jlsnow301" +delete-after: True +changes: + - bugfix: "Fixed icon spacing in the late join menu." \ No newline at end of file From 660a9103d652cabd9a7f390f50047077990f25f5 Mon Sep 17 00:00:00 2001 From: _0Steven <42909981+00-Steven@users.noreply.github.com> Date: Tue, 14 Jan 2025 15:27:46 +0100 Subject: [PATCH 016/106] Cap perceived food quality, fix examine index out of bounds runtime when perceived food quality is too high (#89011) ## About The Pull Request When going through runtime logs earlier, I noticed the edible component's examine logic would have an index out of bounds runtime whenever a lizard were to observe a piece of stinging flatbread. This seems to be because its `examine(...)` proc would call `get_perceived_food_quality(...)`, getting an `8`, and then use the resulting value as an index for `GLOB.food_quality_description`, while the highest value for such is `FOOD_QUALITY_TOP = 7`. Trying to find similar issues I noticed `checkLiked(...)` would cap it to `min(food_quality, FOOD_QUALITY_TOP)` before running anything that cared about it. So in this pr we just move that `min(food_quality, FOOD_QUALITY_TOP)` call into `get_perceived_food_quality(...)` right before it returns, catching all our potential out of bounds issues. This fixes our issues. ## Why It's Good For The Game Fixes jank. ## Changelog :cl: fix: Examining edible items with too high of a perceived food quality no longer runtimes and actually displays a food quality message. /:cl: --- code/datums/components/food/edible.dm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/datums/components/food/edible.dm b/code/datums/components/food/edible.dm index 7d0ca5dbe1275..b466f32c99e7d 100644 --- a/code/datums/components/food/edible.dm +++ b/code/datums/components/food/edible.dm @@ -584,7 +584,6 @@ Behavior that's still missing from this component that original food items had t if(food_quality == 0) return // meh - food_quality = min(food_quality, FOOD_QUALITY_TOP) var/atom/owner = parent var/timeout_mod = owner.reagents.get_average_purity(/datum/reagent/consumable) * 2 // mood event duration is 100% at average purity of 50% var/datum/mood_event/event = GLOB.food_quality_events[food_quality] @@ -640,7 +639,7 @@ Behavior that's still missing from this component that original food items had t food_quality += DISLIKED_FOOD_QUALITY_CHANGE * count_matching_foodtypes(foodtypes, eater.get_disliked_foodtypes()) food_quality += LIKED_FOOD_QUALITY_CHANGE * count_matching_foodtypes(foodtypes, eater.get_liked_foodtypes()) - return food_quality + return min(food_quality, FOOD_QUALITY_TOP) /// Get the number of matching food types in provided bitfields /datum/component/edible/proc/count_matching_foodtypes(bitfield_one, bitfield_two) From 55daed09950e1619a78f5cf933b782aa38fb13af Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:28:07 +0000 Subject: [PATCH 017/106] Automatic changelog for PR #89011 [ci skip] --- html/changelogs/AutoChangeLog-pr-89011.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-89011.yml diff --git a/html/changelogs/AutoChangeLog-pr-89011.yml b/html/changelogs/AutoChangeLog-pr-89011.yml new file mode 100644 index 0000000000000..991a30333e0ce --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-89011.yml @@ -0,0 +1,4 @@ +author: "00-Steven" +delete-after: True +changes: + - bugfix: "Examining edible items with too high of a perceived food quality no longer runtimes and actually displays a food quality message." \ No newline at end of file From 214e5d9223741443d3344bb6ab394e30e1df9246 Mon Sep 17 00:00:00 2001 From: Aniantan Date: Tue, 14 Jan 2025 15:29:07 +0100 Subject: [PATCH 018/106] Prevents xenobio autoinjectors from being deepfried (#89008) ## About The Pull Request #82676 Added medipens into deepfryer blacklist as it allowed them to be filled with custom reagents. Xenobio autoinjectors that are made from industrial crossbreeds function very similarly to medipens with few differences. However, they have a different typepath from medipens so they were not included in the original PR. This adds them into the blacklist too. ## Why It's Good For The Game Xenobio autoinjectors are not ment to be filled with custom reagents, this fixes that. ## Changelog :cl: fix: Xenobio autoinjectors, such as mending solution from industrial purple crossbreed, cannot be deepfried and thus filled with custom reagents using saltshaker anymore. /:cl: --- code/modules/food_and_drinks/machinery/deep_fryer.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/food_and_drinks/machinery/deep_fryer.dm b/code/modules/food_and_drinks/machinery/deep_fryer.dm index 4dfab9fb9474e..e7d1e84dd4b8f 100644 --- a/code/modules/food_and_drinks/machinery/deep_fryer.dm +++ b/code/modules/food_and_drinks/machinery/deep_fryer.dm @@ -13,6 +13,7 @@ GLOBAL_LIST_INIT(oilfry_blacklisted_items, typecacheof(list( /obj/item/reagent_containers/cup, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray/medipen, //letting medipens become edible opens them to being injected/drained with IV drip & saltshakers + /obj/item/slimecrossbeaker/autoinjector, //same as medipen ))) /obj/machinery/deepfryer From 6891379919820c73c8e8efeb0f05e368de48f3d3 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:29:33 +0000 Subject: [PATCH 019/106] Automatic changelog for PR #89008 [ci skip] --- html/changelogs/AutoChangeLog-pr-89008.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-89008.yml diff --git a/html/changelogs/AutoChangeLog-pr-89008.yml b/html/changelogs/AutoChangeLog-pr-89008.yml new file mode 100644 index 0000000000000..0d8e675304857 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-89008.yml @@ -0,0 +1,4 @@ +author: "Aniantan" +delete-after: True +changes: + - bugfix: "Xenobio autoinjectors, such as mending solution from industrial purple crossbreed, cannot be deepfried and thus filled with custom reagents using saltshaker anymore." \ No newline at end of file From 0115e0d4a52d470f64212d97bb4acaaa25a6a149 Mon Sep 17 00:00:00 2001 From: Lucy Date: Tue, 14 Jan 2025 09:29:45 -0500 Subject: [PATCH 020/106] Fix an icon smoothing runtime caused by shuttles during recursive map loading (#89024) ## About The Pull Request So, funny thing. The syndie base lazy template loads recursively, as it contains two shuttle docks (infiltrator and steel rain). But stationary shuttle docks will immediately load their `roundstart_template` _asynchronously_ upon Initialize. This can cause issues - such as the shuttle's atoms being initialized before everything else is, in a weird way. The usual side-effect of this would be runtimes resulting from the shuttle's initialized walls trying to smooth with non-initialized turfs on the template that loaded it. I simply moved to stationary docking port's async load to LateInitialize. There's prolly a better long-term solution, but this doesn't hurt, and solves the relevant issue. you know i really hope we don't have _3_ layer map templates anywhere. ## Why It's Good For The Game less runtime good. ## Changelog :cl: fix: Fixed an icon smoothing error caused by shuttles during recursive map loading, i.e the nukie shuttles with their base. /:cl: --- code/modules/shuttle/stationary_port/stationary_port.dm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/code/modules/shuttle/stationary_port/stationary_port.dm b/code/modules/shuttle/stationary_port/stationary_port.dm index 49437730cb071..6e68cf5dc0c3d 100644 --- a/code/modules/shuttle/stationary_port/stationary_port.dm +++ b/code/modules/shuttle/stationary_port/stationary_port.dm @@ -23,7 +23,10 @@ T.turf_flags |= NO_RUINS if(SSshuttle.initialized) - INVOKE_ASYNC(SSshuttle, TYPE_PROC_REF(/datum/controller/subsystem/shuttle, setup_shuttles), list(src)) + return INITIALIZE_HINT_LATELOAD + +/obj/docking_port/stationary/LateInitialize() + INVOKE_ASYNC(SSshuttle, TYPE_PROC_REF(/datum/controller/subsystem/shuttle, setup_shuttles), list(src)) #ifdef TESTING highlight("#f00") From 7e6a5b0a453777bf3c9bc0aac6df69578609f1db Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:30:08 +0000 Subject: [PATCH 021/106] Automatic changelog for PR #89024 [ci skip] --- html/changelogs/AutoChangeLog-pr-89024.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-89024.yml diff --git a/html/changelogs/AutoChangeLog-pr-89024.yml b/html/changelogs/AutoChangeLog-pr-89024.yml new file mode 100644 index 0000000000000..b7af4f6343f72 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-89024.yml @@ -0,0 +1,4 @@ +author: "Absolucy" +delete-after: True +changes: + - bugfix: "Fixed an icon smoothing error caused by shuttles during recursive map loading, i.e the nukie shuttles with their base." \ No newline at end of file From c47049212fd510ab904bc02e980e70751fb863b4 Mon Sep 17 00:00:00 2001 From: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com> Date: Tue, 14 Jan 2025 16:31:31 +0200 Subject: [PATCH 022/106] Fixes the watcher trophy not working on basic mobs (#88991) ## About The Pull Request currently, the watcher trophy has no effect on 95% of the lavaland mobs since theyve all been refactored to basic mobs, this rectifies that ## Why It's Good For The Game Fixes the watcher trophy not working on basic mobs ## Changelog :cl: fix: Fixes the watcher trophy not working on basic mobs /:cl: --------- Co-authored-by: Jacquerel --- code/__DEFINES/cooldowns.dm | 8 +++++ code/__DEFINES/crusher_defines.dm | 16 ++++++++++ .../signals/signals_mob/signals_mob_main.dm | 3 ++ code/datums/components/ranged_attacks.dm | 5 +++ .../kinetic_crusher_trophies.dm | 6 +++- .../kinetic_crusher/trophies_fauna.dm | 31 ++++++++++++++----- .../kinetic_crusher/trophies_megafauna.dm | 16 ++++++++++ tgstation.dme | 1 + 8 files changed, 78 insertions(+), 8 deletions(-) create mode 100644 code/__DEFINES/crusher_defines.dm diff --git a/code/__DEFINES/cooldowns.dm b/code/__DEFINES/cooldowns.dm index 0ff525dac5ae0..bd6310575c3e3 100644 --- a/code/__DEFINES/cooldowns.dm +++ b/code/__DEFINES/cooldowns.dm @@ -116,3 +116,11 @@ #define COOLDOWN_STARTED(cd_source, cd_index) (cd_source.cd_index != 0) #define COOLDOWN_TIMELEFT(cd_source, cd_index) (max(0, cd_source.cd_index - world.time)) + +///adds to existing cooldown timer if its started, otherwise starts anew +#define COOLDOWN_INCREMENT(cd_source, cd_index, cd_increment) \ + if(COOLDOWN_FINISHED(cd_source, cd_index)) { \ + COOLDOWN_START(cd_source, cd_index, cd_increment); \ + return; \ + } \ + cd_source.cd_index += (cd_increment); \ diff --git a/code/__DEFINES/crusher_defines.dm b/code/__DEFINES/crusher_defines.dm new file mode 100644 index 0000000000000..9f403acd65c25 --- /dev/null +++ b/code/__DEFINES/crusher_defines.dm @@ -0,0 +1,16 @@ +//the IDs of crusher trophies +#define TROPHY_WATCHER "trophy watcher" +#define TROPHY_BEAR_PAW "trophy bear paw" +#define TROPHY_LOBSTER_CLAW "trophy lobster claw" +#define TROPHY_ICE_DEMON "trophy ice cube" +#define TROPHY_GOLIATH_TENTACLE "trophy goliath tentacle" +#define TROPHY_BRIMDEMON_FANG "trophy brimdemon fang" +#define TROPHY_BLASTER_TUBES "trophy blaster tubes" +#define TROPHY_WOLF_EAR "trophy wolf ear" +#define TROPHY_MINER_EYE "trophy miner eye" +#define TROPHY_TAIL_SPIKE "trophy tail spike" +#define TROPHY_VORTEX "trophy vortex" +#define TROPHY_ICE_BLOCK "trophy ice block" +#define TROPHY_BROOD_TONGUE "trophy brood tongue" +#define TROPHY_DEMON_CLAWS "trophy demon claws" +#define TROPHY_LEGIONNAIRE_SPINE "trophy legionnaire spine" diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm index 2ee1f7ce03890..f4557f4b5c17c 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm @@ -268,3 +268,6 @@ /// from /obj/item/reagent_containers/dropper/interact_with_atom(atom/target, mob/living/user, list/modifiers): (mob/living/user, atom/dropper, datum/reagents/reagents, fraction) #define COMSIG_MOB_REAGENTS_DROPPED_INTO_EYES "mob_reagents_drop_into_eyes" + +///from /obj/item/crusher_trophy/on_mark_activate(): (trophy, user) +#define COMSIG_MOB_TROPHY_ACTIVATED(identifier) "COMSIG_MOB_TROPHY_ACTIVATED[identifier]" diff --git a/code/datums/components/ranged_attacks.dm b/code/datums/components/ranged_attacks.dm index 58883ce58111f..e60c364520629 100644 --- a/code/datums/components/ranged_attacks.dm +++ b/code/datums/components/ranged_attacks.dm @@ -47,6 +47,7 @@ . = ..() RegisterSignal(parent, COMSIG_MOB_ATTACK_RANGED, PROC_REF(fire_ranged_attack)) ADD_TRAIT(parent, TRAIT_SUBTREE_REQUIRED_OPERATIONAL_DATUM, type) + RegisterSignal(parent, COMSIG_MOB_TROPHY_ACTIVATED(TROPHY_WATCHER), PROC_REF(disable_attack)) /datum/component/ranged_attacks/UnregisterFromParent() . = ..() @@ -88,3 +89,7 @@ SEND_SIGNAL(parent, COMSIG_BASICMOB_POST_ATTACK_RANGED, target, modifiers) return +/datum/component/ranged_attacks/proc/disable_attack(obj/item/crusher_trophy/used_trophy, mob/living/user) + SIGNAL_HANDLER + var/stun_duration = (used_trophy.bonus_value * 0.1) SECONDS + COOLDOWN_INCREMENT(src, fire_cooldown, stun_duration) diff --git a/code/modules/mining/equipment/kinetic_crusher/kinetic_crusher_trophies.dm b/code/modules/mining/equipment/kinetic_crusher/kinetic_crusher_trophies.dm index 6a00423206e00..be8530a678d9a 100644 --- a/code/modules/mining/equipment/kinetic_crusher/kinetic_crusher_trophies.dm +++ b/code/modules/mining/equipment/kinetic_crusher/kinetic_crusher_trophies.dm @@ -9,6 +9,8 @@ icon_state = "tail_spike" /// if it has a bonus effect, this is how much that effect is var/bonus_value = 10 + /// id of the trophy to be sent by the signal + var/trophy_id /// what type of trophies will block this trophy from being added, must be overriden var/denied_type = /obj/item/crusher_trophy @@ -60,4 +62,6 @@ /// Does an effect when you hit a mob that is marked via the projectile /obj/item/crusher_trophy/proc/on_mark_detonation(mob/living/target, mob/living/user) //the target and the user - return + SHOULD_CALL_PARENT(TRUE) + //if we dont have a set id, use the typepath as identifier + SEND_SIGNAL(target, COMSIG_MOB_TROPHY_ACTIVATED(trophy_id || type), src, user) diff --git a/code/modules/mining/equipment/kinetic_crusher/trophies_fauna.dm b/code/modules/mining/equipment/kinetic_crusher/trophies_fauna.dm index 2327980a98335..24b5dbc94f020 100644 --- a/code/modules/mining/equipment/kinetic_crusher/trophies_fauna.dm +++ b/code/modules/mining/equipment/kinetic_crusher/trophies_fauna.dm @@ -8,19 +8,23 @@ desc = "A wing ripped from a watcher. Suitable as a trophy for a kinetic crusher." icon_state = "watcher_wing" denied_type = /obj/item/crusher_trophy/watcher_wing + trophy_id = TROPHY_WATCHER bonus_value = 5 /obj/item/crusher_trophy/watcher_wing/effect_desc() return "mark detonation to prevent certain creatures from using certain attacks for [bonus_value*0.1] second\s" /obj/item/crusher_trophy/watcher_wing/on_mark_detonation(mob/living/target, mob/living/user) - if(ishostile(target)) - var/mob/living/simple_animal/hostile/H = target - if(H.ranged) //briefly delay ranged attacks - if(H.ranged_cooldown >= world.time) - H.ranged_cooldown += bonus_value - else - H.ranged_cooldown = bonus_value + world.time + . = ..() + if(!ishostile(target)) + return + var/mob/living/simple_animal/hostile/hostile_animal = target + if(!hostile_animal.ranged) + return + if(hostile_animal.ranged_cooldown >= world.time) //briefly delay ranged attacks + hostile_animal.ranged_cooldown += bonus_value + else + hostile_animal.ranged_cooldown = bonus_value + world.time //magmawing watcher /obj/item/crusher_trophy/blaster_tubes/magma_wing @@ -75,6 +79,7 @@ icon_state = "goliath_tentacle" denied_type = /obj/item/crusher_trophy/goliath_tentacle bonus_value = 2 + trophy_id = TROPHY_GOLIATH_TENTACLE /// Your missing health is multiplied by this value to find the bonus damage var/missing_health_ratio = 0.1 /// Amount of health you must lose to gain damage, according to the examine text. Cached so we don't recalculate it every examine. @@ -88,6 +93,7 @@ return "mark detonation to do [bonus_value] more damage for every [missing_health_desc] health you are missing" /obj/item/crusher_trophy/goliath_tentacle/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() var/missing_health = user.maxHealth - user.health missing_health *= missing_health_ratio //bonus is active at all times, even if you're above 90 health missing_health *= bonus_value //multiply the remaining amount by bonus_value @@ -100,12 +106,14 @@ icon_state = "lobster_claw" desc = "A lobster claw." denied_type = /obj/item/crusher_trophy/lobster_claw + trophy_id = TROPHY_LOBSTER_CLAW bonus_value = 1 /obj/item/crusher_trophy/lobster_claw/effect_desc() return "mark detonation to briefly rebuke the target for [bonus_value] seconds" /obj/item/crusher_trophy/lobster_claw/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() target.apply_status_effect(/datum/status_effect/rebuked, bonus_value SECONDS) // Brimdemon - makes a funny sound, the most essential trophy out of all @@ -114,6 +122,7 @@ icon_state = "brimdemon_fang" desc = "A fang from a brimdemon's corpse." denied_type = /obj/item/crusher_trophy/brimdemon_fang + trophy_id = TROPHY_BRIMDEMON_FANG /// Cartoon punching vfx var/static/list/comic_phrases = list("BOOM", "BANG", "KABLOW", "KAPOW", "OUCH", "BAM", "KAPOW", "WHAM", "POW", "KABOOM") @@ -121,6 +130,7 @@ return "mark detonation to create visual and audiosensory effects at the target" /obj/item/crusher_trophy/brimdemon_fang/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() target.balloon_alert_to_viewers("[pick(comic_phrases)]!") playsound(target, 'sound/mobs/non-humanoids/brimdemon/brimdemon_crush.ogg', 100) @@ -155,6 +165,7 @@ return "mark detonation launches projectiles in cardinal directions on a 10 second cooldown. Also gives you an AOE when mining minerals" /obj/item/crusher_trophy/bileworm_spewlet/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() //ability itself handles cooldowns. ability.InterceptClickOn(user, null, target) @@ -180,6 +191,7 @@ desc = "A stone cold cube dropped from an ice demon." icon_state = "ice_demon_cube" denied_type = /obj/item/crusher_trophy/ice_demon_cube + trophy_id = TROPHY_ICE_DEMON ///how many will we summon? var/summon_amount = 2 ///cooldown to summon demons upon the target @@ -189,6 +201,7 @@ return "mark detonation to unleash demonic ice clones upon the target" /obj/item/crusher_trophy/ice_demon_cube/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() if(isnull(target) || !COOLDOWN_FINISHED(src, summon_cooldown)) return for(var/i in 1 to summon_amount) @@ -214,12 +227,14 @@ name = "wolf ear" desc = "It's a wolf ear." icon_state = "wolf_ear" + trophy_id = TROPHY_WOLF_EAR denied_type = /obj/item/crusher_trophy/wolf_ear /obj/item/crusher_trophy/wolf_ear/effect_desc() return "mark detonation to gain a slight speed boost temporarily" /obj/item/crusher_trophy/wolf_ear/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() user.apply_status_effect(/datum/status_effect/speed_boost, 1 SECONDS) // Polar bear @@ -227,12 +242,14 @@ name = "polar bear paw" desc = "It's a polar bear paw." icon_state = "bear_paw" + trophy_id = TROPHY_BEAR_PAW denied_type = /obj/item/crusher_trophy/bear_paw /obj/item/crusher_trophy/bear_paw/effect_desc() return "mark detonation to attack twice if you are below half your life" /obj/item/crusher_trophy/bear_paw/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() if(user.health / user.maxHealth > 0.5) return var/obj/item/I = user.get_active_held_item() diff --git a/code/modules/mining/equipment/kinetic_crusher/trophies_megafauna.dm b/code/modules/mining/equipment/kinetic_crusher/trophies_megafauna.dm index ba302999010c7..119099f587b8f 100644 --- a/code/modules/mining/equipment/kinetic_crusher/trophies_megafauna.dm +++ b/code/modules/mining/equipment/kinetic_crusher/trophies_megafauna.dm @@ -7,24 +7,28 @@ name = "eye of a blood-drunk hunter" desc = "Its pupil is collapsed and turned to mush. Suitable as a trophy for a kinetic crusher." icon_state = "hunter_eye" + trophy_id = TROPHY_MINER_EYE denied_type = /obj/item/crusher_trophy/miner_eye /obj/item/crusher_trophy/miner_eye/effect_desc() return "mark detonation to grant stun immunity and 90% damage reduction for 1 second" /obj/item/crusher_trophy/miner_eye/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() user.apply_status_effect(/datum/status_effect/blooddrunk) //ash drake /obj/item/crusher_trophy/tail_spike desc = "A spike taken from an ash drake's tail. Suitable as a trophy for a kinetic crusher." denied_type = /obj/item/crusher_trophy/tail_spike + trophy_id = TROPHY_TAIL_SPIKE bonus_value = 5 /obj/item/crusher_trophy/tail_spike/effect_desc() return "mark detonation to do [bonus_value] damage to nearby creatures and push them back" /obj/item/crusher_trophy/tail_spike/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() for(var/mob/living/living_target in oview(2, user)) if(user.faction_check_atom(living_target) || living_target.stat == DEAD) continue @@ -45,6 +49,7 @@ gender = PLURAL denied_type = /obj/item/crusher_trophy/demon_claws bonus_value = 10 + trophy_id = TROPHY_DEMON_CLAWS var/static/list/damage_heal_order = list(BRUTE, BURN, OXY) /obj/item/crusher_trophy/demon_claws/effect_desc() @@ -68,6 +73,7 @@ user.heal_ordered_damage(bonus_value * 0.1, damage_heal_order) /obj/item/crusher_trophy/demon_claws/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() user.heal_ordered_damage(bonus_value * 0.4, damage_heal_order) //colossus @@ -78,6 +84,7 @@ gender = PLURAL denied_type = /obj/item/crusher_trophy/blaster_tubes bonus_value = 15 + trophy_id = TROPHY_BLASTER_TUBES var/deadly_shot = FALSE /obj/item/crusher_trophy/blaster_tubes/effect_desc() @@ -92,6 +99,7 @@ deadly_shot = FALSE /obj/item/crusher_trophy/blaster_tubes/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() deadly_shot = TRUE addtimer(CALLBACK(src, PROC_REF(reset_deadly_shot)), 300, TIMER_UNIQUE|TIMER_OVERRIDE) @@ -103,12 +111,14 @@ name = "vortex talisman" desc = "A glowing trinket that was originally the Hierophant's beacon. Suitable as a trophy for a kinetic crusher." icon_state = "vortex_talisman" + trophy_id = TROPHY_VORTEX denied_type = /obj/item/crusher_trophy/vortex_talisman /obj/item/crusher_trophy/vortex_talisman/effect_desc() return "mark detonation to create a homing hierophant chaser" /obj/item/crusher_trophy/vortex_talisman/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() if(isliving(target)) var/obj/effect/temp_visual/hierophant/chaser/chaser = new(get_turf(user), user, target, 3, TRUE) chaser.monster_damage_boost = FALSE // Weaker cuz no cooldown @@ -120,12 +130,14 @@ name = "ice block talisman" desc = "A glowing trinket that a demonic miner had on him, it seems he couldn't utilize it for whatever reason." icon_state = "ice_trap_talisman" + trophy_id = TROPHY_ICE_BLOCK denied_type = /obj/item/crusher_trophy/ice_block_talisman /obj/item/crusher_trophy/ice_block_talisman/effect_desc() return "mark detonation to freeze a creature in a block of ice for a period, preventing them from moving" /obj/item/crusher_trophy/ice_block_talisman/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() target.apply_status_effect(/datum/status_effect/ice_block_talisman) // Wendigo @@ -156,6 +168,7 @@ icon_state = "broodmother_tongue" denied_type = /obj/item/crusher_trophy/broodmother_tongue bonus_value = 10 + trophy_id = TROPHY_BROOD_TONGUE /// Time at which the item becomes usable again var/use_time @@ -163,6 +176,7 @@ return "mark detonation to have a [bonus_value]% chance to summon a patch of goliath tentacles at the target's location" /obj/item/crusher_trophy/broodmother_tongue/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() if(prob(bonus_value) && target.stat != DEAD) new /obj/effect/goliath_tentacle/broodmother/patch(get_turf(target), user) @@ -189,6 +203,7 @@ icon_state = "legionnaire_spine" denied_type = /obj/item/crusher_trophy/legionnaire_spine bonus_value = 20 + trophy_id = TROPHY_LEGIONNAIRE_SPINE /// Time at which the item becomes usable again var/next_use_time @@ -196,6 +211,7 @@ return "mark detonation to have a [bonus_value]% chance to summon a loyal legion skull" /obj/item/crusher_trophy/legionnaire_spine/on_mark_detonation(mob/living/target, mob/living/user) + . = ..() if(!prob(bonus_value) || target.stat == DEAD) return var/mob/living/basic/legion_brood/minion = new (user.loc) diff --git a/tgstation.dme b/tgstation.dme index 979ceb8a1a7ee..4ccdc79f8d5e3 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -72,6 +72,7 @@ #include "code\__DEFINES\configuration.dm" #include "code\__DEFINES\cooldowns.dm" #include "code\__DEFINES\crafting.dm" +#include "code\__DEFINES\crusher_defines.dm" #include "code\__DEFINES\crushing.dm" #include "code\__DEFINES\ctf.dm" #include "code\__DEFINES\cult.dm" From eee3c3204faa1963d84a666dd7f4c5eeb5402ff0 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:32:18 +0000 Subject: [PATCH 023/106] Automatic changelog for PR #88991 [ci skip] --- html/changelogs/AutoChangeLog-pr-88991.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-88991.yml diff --git a/html/changelogs/AutoChangeLog-pr-88991.yml b/html/changelogs/AutoChangeLog-pr-88991.yml new file mode 100644 index 0000000000000..14bbc119315d2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-88991.yml @@ -0,0 +1,4 @@ +author: "Ben10Omintrix" +delete-after: True +changes: + - bugfix: "Fixes the watcher trophy not working on basic mobs" \ No newline at end of file From 6b0c3e1aa49b8ee41b7f2c4165c5cd62e569e1a5 Mon Sep 17 00:00:00 2001 From: NamelessFairy <40036527+NamelessFairy@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:36:33 +0000 Subject: [PATCH 024/106] The RCD can print hydroponics airlocks (#89045) ## About The Pull Request I've noticed that the RCD can print every station airlock type besides hydroponics, this seems to be an oversight. It still cannot be used to print science airlocks (not research) as these do not appear on the station by default, if you want to use these you'll need to use the airlock painter. ## Why It's Good For The Game This allows the RCD to print all airlock types that start on the station by default, fufilling its role as a repair tool. ## Changelog :cl: fix: The RCD can print Hydroponics airlocks /:cl: --- code/_globalvars/lists/rcd.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/_globalvars/lists/rcd.dm b/code/_globalvars/lists/rcd.dm index 86f546df22307..e1d88c4b51dea 100644 --- a/code/_globalvars/lists/rcd.dm +++ b/code/_globalvars/lists/rcd.dm @@ -57,6 +57,7 @@ GLOBAL_LIST_INIT(rcd_designs, list( list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/command/glass), list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/medical/glass), list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/research/glass), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/hydroponics/glass), list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/virology/glass), list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/mining/glass), list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/maintenance/glass), @@ -75,6 +76,7 @@ GLOBAL_LIST_INIT(rcd_designs, list( list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/medical), list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/research), list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/freezer), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/hydroponics), list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/virology), list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/mining), list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/maintenance), From d331f68807fd367b51c9658079e983c3c32bcf55 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:37:09 +0000 Subject: [PATCH 025/106] Automatic changelog for PR #89045 [ci skip] --- html/changelogs/AutoChangeLog-pr-89045.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-89045.yml diff --git a/html/changelogs/AutoChangeLog-pr-89045.yml b/html/changelogs/AutoChangeLog-pr-89045.yml new file mode 100644 index 0000000000000..1717e9b614bce --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-89045.yml @@ -0,0 +1,4 @@ +author: "NamelessFairy" +delete-after: True +changes: + - bugfix: "The RCD can print Hydroponics airlocks" \ No newline at end of file From 82da505786e15ead9199388a5a2b883751ccf7ae Mon Sep 17 00:00:00 2001 From: _0Steven <42909981+00-Steven@users.noreply.github.com> Date: Tue, 14 Jan 2025 15:37:36 +0100 Subject: [PATCH 026/106] Aquarium component: fixes admiring, fixes panel context, improves context (#89048) ## About The Pull Request Admiring was broken, and looking into it, it's because it didn't actually pass the user as `user` and instead as `source`, which is supposed to be the aquarium movable. Changing this fixes our issue. Then I noticed admiring was kind of jank for fish tanks (item)- you could right click to admire it, but only if it's not in-hand. At the same time, you could left click admire aquariums when the panel is closed, but you _can't_ left click admire fish tanks even when they're in hand. So in this pr we actually let you admire fish tanks when in your active hand, both left click and right click, left click only working if the panel is closed. Similarly, the tooltips for such would only get displayed when your hand were to be empty, so this makes it also account for the held item being the fish tank. I also noticed the open/close panel tooltip was inverted, so I inverted it to be the right way around. ## Why It's Good For The Game Nice if it works. Nice if it doesn't feel incredibly jank. Nice if the tooltips display more. ## Changelog :cl: fix: Aquarium/fish tank admiring works again. fix: Inverted aquarium/fish tank panel opening tooltip to be the right way. qol: You can actually admire an in-hand fish tank by clicking on it. qol: Aquarium/fish tank admiring tooltips are more consistent. /:cl: --- code/datums/components/aquarium.dm | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/code/datums/components/aquarium.dm b/code/datums/components/aquarium.dm index 36c3c2a1f53f7..924b2b940782c 100644 --- a/code/datums/components/aquarium.dm +++ b/code/datums/components/aquarium.dm @@ -114,6 +114,7 @@ if(isitem(movable)) RegisterSignal(movable, COMSIG_ITEM_ATTACK_SELF, PROC_REF(interact)) + RegisterSignal(movable, COMSIG_ITEM_ATTACK_SELF_SECONDARY, PROC_REF(secondary_interact)) RegisterSignals(movable, list(COMSIG_ATOM_ATTACK_ROBOT_SECONDARY, COMSIG_ATOM_ATTACK_HAND_SECONDARY), PROC_REF(on_secondary_attack_hand)) else RegisterSignal(movable, COMSIG_ATOM_UI_INTERACT, PROC_REF(interact)) @@ -453,15 +454,20 @@ /datum/component/aquarium/proc/interact(atom/movable/source, mob/user) SIGNAL_HANDLER - if(HAS_TRAIT(source, TRAIT_AQUARIUM_PANEL_OPEN)) INVOKE_ASYNC(src, PROC_REF(ui_interact), user) - else if(!isitem(source)) - INVOKE_ASYNC(src, PROC_REF(admire), user) + return + INVOKE_ASYNC(src, PROC_REF(admire), source, user) + +/datum/component/aquarium/proc/secondary_interact(atom/movable/source, mob/user) + SIGNAL_HANDLER + if(HAS_TRAIT(source, TRAIT_AQUARIUM_PANEL_OPEN)) + return + INVOKE_ASYNC(src, PROC_REF(admire), source, user) /datum/component/aquarium/proc/on_secondary_attack_hand(obj/item/source, mob/living/user) SIGNAL_HANDLER - INVOKE_ASYNC(src, PROC_REF(admire), user) + INVOKE_ASYNC(src, PROC_REF(admire), source, user) return COMPONENT_CANCEL_ATTACK_CHAIN /datum/component/aquarium/ui_interact(mob/user, datum/tgui/ui) @@ -579,13 +585,14 @@ /datum/component/aquarium/proc/on_requesting_context_from_item(atom/source, list/context, obj/item/held_item, mob/user) SIGNAL_HANDLER var/open_panel = HAS_TRAIT(source, TRAIT_AQUARIUM_PANEL_OPEN) - if(!held_item) + var/is_held_item = (held_item == source) + if(!held_item || is_held_item) var/isitem = isitem(source) - if(!isitem || open_panel) + if(!isitem || is_held_item) context[SCREENTIP_CONTEXT_LMB] = open_panel ? "Adjust settings" : "Admire" if(isitem) context[SCREENTIP_CONTEXT_RMB] = "Admire" - context[SCREENTIP_CONTEXT_ALT_LMB] = "[open_panel ? "Open" : "Close"] settings panel" + context[SCREENTIP_CONTEXT_ALT_LMB] = "[!open_panel ? "Open" : "Close"] settings panel" return CONTEXTUAL_SCREENTIP_SET if(istype(held_item, /obj/item/plunger)) context[SCREENTIP_CONTEXT_LMB] = "Empty feed storage" From 91270cf0c70e071a9dd2c56d08d3703cf5260520 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:41:38 +0000 Subject: [PATCH 027/106] Automatic changelog for PR #89048 [ci skip] --- html/changelogs/AutoChangeLog-pr-89048.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-89048.yml diff --git a/html/changelogs/AutoChangeLog-pr-89048.yml b/html/changelogs/AutoChangeLog-pr-89048.yml new file mode 100644 index 0000000000000..f459d5ebf1d86 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-89048.yml @@ -0,0 +1,7 @@ +author: "00-Steven" +delete-after: True +changes: + - bugfix: "Aquarium/fish tank admiring works again." + - bugfix: "Inverted aquarium/fish tank panel opening tooltip to be the right way." + - qol: "You can actually admire an in-hand fish tank by clicking on it." + - qol: "Aquarium/fish tank admiring tooltips are more consistent." \ No newline at end of file From 4958f949f6c4ba2952564f43ed54c8734674d562 Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Tue, 14 Jan 2025 17:42:29 +0300 Subject: [PATCH 028/106] [NO GBP] Fixes division by zero runtimes caused by black eyes (#89042) ## About The Pull Request Fully black eyes caused division by zero in their overlays yeah. ## Changelog :cl: fix: Fixed division by zero runtimes caused by black eyes /:cl: --- code/modules/surgery/organs/internal/eyes/_eyes.dm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/modules/surgery/organs/internal/eyes/_eyes.dm b/code/modules/surgery/organs/internal/eyes/_eyes.dm index c23d7c3f55024..e3b072111829d 100644 --- a/code/modules/surgery/organs/internal/eyes/_eyes.dm +++ b/code/modules/surgery/organs/internal/eyes/_eyes.dm @@ -295,8 +295,10 @@ var/list/color_left = rgb2num(eye_color_left, COLORSPACE_HSL) var/list/color_right = rgb2num(eye_color_right, COLORSPACE_HSL) // Ugly as sin? Indeed it is! But otherwise eyeballs turn out to be super dark, and this way even lighter colors are mostly preserved - color_left[3] /= sqrt(color_left[3] * 0.01) - color_right[3] /= sqrt(color_right[3] * 0.01) + if (color_left[3]) + color_left[3] /= sqrt(color_left[3] * 0.01) + if (color_right[3]) + color_right[3] /= sqrt(color_right[3] * 0.01) left_iris.color = rgb(color_left[1], color_left[2], color_left[3], space = COLORSPACE_HSL) right_iris.color = rgb(color_right[1], color_right[2], color_right[3], space = COLORSPACE_HSL) . += left_iris From 8257fccb796fd98cb0e52fc3c6ca7d6b5f417e8f Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:43:05 +0000 Subject: [PATCH 029/106] Automatic changelog for PR #89042 [ci skip] --- html/changelogs/AutoChangeLog-pr-89042.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-89042.yml diff --git a/html/changelogs/AutoChangeLog-pr-89042.yml b/html/changelogs/AutoChangeLog-pr-89042.yml new file mode 100644 index 0000000000000..6ea8b22dcc02e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-89042.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Fixed division by zero runtimes caused by black eyes" \ No newline at end of file From 4aa908e7bf64e4b5e8ed1e3e87882ce2468280f1 Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Tue, 14 Jan 2025 17:43:40 +0300 Subject: [PATCH 030/106] Sanitizes custom vendor inputs, and fixes a division by zero in their examine code (#89036) ## About The Pull Request Closes #89006 Also fixed a division by zero in very, very weird examine code ## Changelog :cl: fix: Custom vendors now sanitize their inputs fix: Fixed a division by zero in custom vendor code /:cl: --- code/modules/vending/_vending.dm | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index ca5e6e487082b..ebff7e8ed1990 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -359,10 +359,11 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock) . = ..() if(isnull(refill_canister)) return // you can add the comment here instead - if((total_loaded_stock() / total_max_stock()) < 1) - . += span_notice("\The [src] can be restocked with [span_boldnotice("\a [initial(refill_canister.machine_name)] [initial(refill_canister.name)]")] with the panel open.") - else - . += span_notice("\The [src] is fully stocked.") + if(total_max_stock()) + if(total_loaded_stock() < total_max_stock()) + . += span_notice("\The [src] can be restocked with [span_boldnotice("\a [initial(refill_canister.machine_name)] [initial(refill_canister.name)]")] with the panel open.") + else + . += span_notice("\The [src] is fully stocked.") if(credits_contained < CREDITS_DUMP_THRESHOLD && credits_contained > 0) . += span_notice("It should have a handfull of credits stored based on the missing items.") else if (credits_contained > PAYCHECK_CREW) @@ -1801,15 +1802,19 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock) linked_account = card_used.registered_account speak("\The [src] has been linked to [card_used].") - if(compartmentLoadAccessCheck(user)) - if(IS_WRITING_UTENSIL(attack_item)) - name = tgui_input_text(user, "Set name", "Name", name, max_length = 20) - desc = tgui_input_text(user, "Set description", "Description", desc, max_length = 60) - slogan_list += tgui_input_text(user, "Set slogan", "Slogan", "Epic", max_length = 60) - last_slogan = world.time + rand(0, slogan_delay) - return + if(!compartmentLoadAccessCheck(user) || !IS_WRITING_UTENSIL(attack_item)) + return ..() - return ..() + var/new_name = reject_bad_name(tgui_input_text(user, "Set name", "Name", name, max_length = 20), allow_numbers = TRUE, strict = TRUE, cap_after_symbols = FALSE) + if (new_name) + name = new_name + var/new_desc = reject_bad_text(tgui_input_text(user, "Set description", "Description", desc, max_length = 60)) + if (new_desc) + desc = new_desc + var/new_slogan = reject_bad_text(tgui_input_text(user, "Set slogan", "Slogan", "Epic", max_length = 60)) + if (new_slogan) + slogan_list += new_slogan + last_slogan = world.time + rand(0, slogan_delay) /obj/machinery/vending/custom/crowbar_act(mob/living/user, obj/item/attack_item) return FALSE From 6c50df649857018f9c1bff4a4f8cd332fd5a014d Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:46:26 +0000 Subject: [PATCH 031/106] Automatic changelog for PR #89036 [ci skip] --- html/changelogs/AutoChangeLog-pr-89036.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-89036.yml diff --git a/html/changelogs/AutoChangeLog-pr-89036.yml b/html/changelogs/AutoChangeLog-pr-89036.yml new file mode 100644 index 0000000000000..3f5606c7d7348 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-89036.yml @@ -0,0 +1,5 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Custom vendors now sanitize their inputs" + - bugfix: "Fixed a division by zero in custom vendor code" \ No newline at end of file From 9aec2007a215d2f3e1f0ee5f69d718cc6a159260 Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Tue, 14 Jan 2025 17:48:06 +0300 Subject: [PATCH 032/106] Adds a localhost-only "Start Now" lobby button (#88973) ## About The Pull Request Adds a new extremely high quality lobby button on which we spent all of 2025's coderbus budget. It shows up only for localhost users and starts the round immediately. ![image](https://github.com/user-attachments/assets/fdabe880-465e-4e24-9e50-dd955585311b) ## Why It's Good For The Game Ensures that maintainers don't accidentally commit a funni on live servers. ## Changelog :cl: admin: Added a localhost-only "Start Now" lobby button /:cl: --- code/_onclick/hud/new_player.dm | 26 ++++++++++++++++++++++++++ icons/hud/lobby/start_now.dmi | Bin 0 -> 11181 bytes 2 files changed, 26 insertions(+) create mode 100644 icons/hud/lobby/start_now.dmi diff --git a/code/_onclick/hud/new_player.dm b/code/_onclick/hud/new_player.dm index 594449575ea06..852aa387ae71b 100644 --- a/code/_onclick/hud/new_player.dm +++ b/code/_onclick/hud/new_player.dm @@ -28,6 +28,15 @@ lobbyscreen.RegisterSignal(src, COMSIG_HUD_LOBBY_COLLAPSED, TYPE_PROC_REF(/atom/movable/screen/lobby, collapse_button)) lobbyscreen.RegisterSignal(src, COMSIG_HUD_LOBBY_EXPANDED, TYPE_PROC_REF(/atom/movable/screen/lobby, expand_button)) + if (!owner.client.is_localhost()) + return + + var/atom/movable/screen/lobby/button/start_now/start_button = new(our_hud = src) + start_button.SlowInit() + static_inventory += start_button + start_button.RegisterSignal(src, COMSIG_HUD_LOBBY_COLLAPSED, TYPE_PROC_REF(/atom/movable/screen/lobby, collapse_button)) + start_button.RegisterSignal(src, COMSIG_HUD_LOBBY_EXPANDED, TYPE_PROC_REF(/atom/movable/screen/lobby, expand_button)) + /// Load and then display the buttons for relevant station traits /datum/hud/new_player/proc/show_station_trait_buttons() if (!mymob?.client || mymob.client.interviewee || !length(GLOB.lobby_station_traits)) @@ -606,6 +615,23 @@ //pull the shutter back off-screen animate(transform = matrix(), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_IN) +/// LOCALHOST ONLY - Start Now button +/atom/movable/screen/lobby/button/start_now + name = "Start Now (LOCALHOST ONLY)" + screen_loc = "TOP:-146,CENTER:-54" + icon = 'icons/hud/lobby/start_now.dmi' + icon_state = "start_now" + base_icon_state = "start_now" + always_available = FALSE + select_sound_play = FALSE + +/atom/movable/screen/lobby/button/start_now/Click(location, control, params) + . = ..() + if(!. || !usr.client.is_localhost() || !check_rights_for(usr.client, R_SERVER)) + return + SEND_SOUND(hud.mymob, sound('sound/effects/splat.ogg', volume = 50)) + SSticker.start_immediately = TRUE + #undef SHUTTER_MOVEMENT_DURATION #undef SHUTTER_WAIT_DURATION #undef MAX_STATION_TRAIT_BUTTONS_VERTICAL diff --git a/icons/hud/lobby/start_now.dmi b/icons/hud/lobby/start_now.dmi new file mode 100644 index 0000000000000000000000000000000000000000..ec77059011be0e8e995cbb0dadbbbcf7834d5b1a GIT binary patch literal 11181 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

    Date: Tue, 14 Jan 2025 14:48:40 +0000 Subject: [PATCH 033/106] Automatic changelog for PR #88973 [ci skip] --- html/changelogs/AutoChangeLog-pr-88973.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-88973.yml diff --git a/html/changelogs/AutoChangeLog-pr-88973.yml b/html/changelogs/AutoChangeLog-pr-88973.yml new file mode 100644 index 0000000000000..63a1a2207b58a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-88973.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - admin: "Added a localhost-only \"Start Now\" lobby button" \ No newline at end of file From 7fe8f29fdbd22283cd49f762cd5b7344dfe0acf4 Mon Sep 17 00:00:00 2001 From: Y0SH1M4S73R Date: Tue, 14 Jan 2025 09:50:03 -0500 Subject: [PATCH 034/106] Corpses with clients in them can no longer perform mech actions (#88959) ## About The Pull Request Turns out most mech actions only cared about the person attempting to use them being inside the mech, without checking for things such as the mob being alive. This fixes that, but required a slight refactoring to the `ui_status` proc of mechs to account for the three fundamentally different types of mobs that can pilot a mech. ## Why It's Good For The Game Fixes #88933 ## Changelog :cl: fix: Corpses at the pilot seat of mechs can no longer toggle the lights, safeties, cabin sealing, strafing, overclocking, or durand shields, nor can they rename the mech or configure its equipment. /:cl: --- code/modules/tgui/status_composers.dm | 12 +++++++- code/modules/vehicles/mecha/combat/durand.dm | 4 ++- .../modules/vehicles/mecha/combat/marauder.dm | 8 +++-- code/modules/vehicles/mecha/combat/phazon.dm | 8 +++-- .../vehicles/mecha/combat/savannah_ivanov.dm | 6 +++- code/modules/vehicles/mecha/mecha_actions.dm | 30 ++++++++++++++----- code/modules/vehicles/mecha/mecha_ui.dm | 22 ++++++++------ code/modules/vehicles/mecha/working/clarke.dm | 6 +++- code/modules/vehicles/mecha/working/ripley.dm | 2 ++ code/modules/vehicles/sealed.dm | 1 + 10 files changed, 74 insertions(+), 25 deletions(-) diff --git a/code/modules/tgui/status_composers.dm b/code/modules/tgui/status_composers.dm index c4bbb3e7bfc59..4222769203bab 100644 --- a/code/modules/tgui/status_composers.dm +++ b/code/modules/tgui/status_composers.dm @@ -50,7 +50,9 @@ /// Returns a UI status such that those without blocked hands will be able to interact, /// but everyone else can only watch. -/proc/ui_status_user_has_free_hands(mob/user, atom/source) +/proc/ui_status_user_has_free_hands(mob/user, atom/source, allowed_source) + if(allowed_source) + return HAS_TRAIT_NOT_FROM(user, TRAIT_HANDS_BLOCKED, allowed_source) ? UI_UPDATE : UI_INTERACTIVE return HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) ? UI_UPDATE : UI_INTERACTIVE /// Returns a UI status such that advanced tool users will be able to interact, @@ -110,3 +112,11 @@ return UI_CLOSE return UI_INTERACTIVE + +/// Return UI_INTERACTIVE if the user is inside the target atom, whether they can see it or not. +/// Return UI_CLOSE otherwise. +/proc/ui_status_user_inside(mob/user, atom/target) + if(target.contains(user)) + return UI_INTERACTIVE + + return UI_CLOSE diff --git a/code/modules/vehicles/mecha/combat/durand.dm b/code/modules/vehicles/mecha/combat/durand.dm index 6995206942938..9095197b93ea0 100644 --- a/code/modules/vehicles/mecha/combat/durand.dm +++ b/code/modules/vehicles/mecha/combat/durand.dm @@ -143,7 +143,9 @@ Expects a turf. Returns true if the attack should be blocked, false if not.*/ button_icon_state = "mech_defense_mode_off" /datum/action/vehicle/sealed/mecha/mech_defense_mode/Trigger(trigger_flags, forced_state = FALSE) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return SEND_SIGNAL(chassis, COMSIG_MECHA_ACTION_TRIGGER, owner, args) //Signal sent to the mech, to be handed to the shield. See durand.dm for more details diff --git a/code/modules/vehicles/mecha/combat/marauder.dm b/code/modules/vehicles/mecha/combat/marauder.dm index 32fd0627c6fb8..f0f9b7ebf814d 100644 --- a/code/modules/vehicles/mecha/combat/marauder.dm +++ b/code/modules/vehicles/mecha/combat/marauder.dm @@ -59,7 +59,9 @@ button_icon_state = "mech_smoke" /datum/action/vehicle/sealed/mecha/mech_smoke/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return if(TIMER_COOLDOWN_FINISHED(src, COOLDOWN_MECHA_SMOKE) && chassis.smoke_charges>0) chassis.smoke_system.start() @@ -71,7 +73,9 @@ button_icon_state = "mech_zoom_off" /datum/action/vehicle/sealed/mecha/mech_zoom/Trigger(trigger_flags) - if(!owner?.client || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!owner.client || !chassis || !(owner in chassis.occupants)) return chassis.zoom_mode = !chassis.zoom_mode button_icon_state = "mech_zoom_[chassis.zoom_mode ? "on" : "off"]" diff --git a/code/modules/vehicles/mecha/combat/phazon.dm b/code/modules/vehicles/mecha/combat/phazon.dm index 8f37b0945ec20..1ff67996e792d 100644 --- a/code/modules/vehicles/mecha/combat/phazon.dm +++ b/code/modules/vehicles/mecha/combat/phazon.dm @@ -42,7 +42,9 @@ button_icon_state = "mech_damtype_brute" /datum/action/vehicle/sealed/mecha/mech_switch_damtype/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return var/new_damtype switch(chassis.damtype) @@ -65,7 +67,9 @@ button_icon_state = "mech_phasing_off" /datum/action/vehicle/sealed/mecha/mech_toggle_phasing/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return chassis.phasing = chassis.phasing ? "" : "phasing" button_icon_state = "mech_phasing_[chassis.phasing ? "on" : "off"]" diff --git a/code/modules/vehicles/mecha/combat/savannah_ivanov.dm b/code/modules/vehicles/mecha/combat/savannah_ivanov.dm index 6395b39393ef8..ffc4c61e5a87f 100644 --- a/code/modules/vehicles/mecha/combat/savannah_ivanov.dm +++ b/code/modules/vehicles/mecha/combat/savannah_ivanov.dm @@ -81,6 +81,8 @@ var/skyfall_charge_level = 0 /datum/action/vehicle/sealed/mecha/skyfall/Trigger(trigger_flags) + if(!..()) + return if(!owner || !chassis || !(owner in chassis.occupants)) return if(chassis.phasing) @@ -251,7 +253,9 @@ return ..() /datum/action/vehicle/sealed/mecha/ivanov_strike/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return if(TIMER_COOLDOWN_RUNNING(chassis, COOLDOWN_MECHA_MISSILE_STRIKE)) var/timeleft = S_TIMER_COOLDOWN_TIMELEFT(chassis, COOLDOWN_MECHA_MISSILE_STRIKE) diff --git a/code/modules/vehicles/mecha/mecha_actions.dm b/code/modules/vehicles/mecha/mecha_actions.dm index 5e3c658a525e2..7c85d047996a2 100644 --- a/code/modules/vehicles/mecha/mecha_actions.dm +++ b/code/modules/vehicles/mecha/mecha_actions.dm @@ -24,7 +24,7 @@ button_icon_state = "mech_eject" /datum/action/vehicle/sealed/mecha/mech_eject/Trigger(trigger_flags) - if(!owner) + if(!..()) return if(!chassis || !(owner in chassis.occupants)) return @@ -36,7 +36,9 @@ desc = "Airtight cabin preserves internal air and can be pressurized with a mounted air tank." /datum/action/vehicle/sealed/mecha/mech_toggle_cabin_seal/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return chassis.set_cabin_seal(owner, !chassis.cabin_sealed) @@ -45,7 +47,9 @@ button_icon_state = "mech_lights_off" /datum/action/vehicle/sealed/mecha/mech_toggle_lights/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return chassis.toggle_lights(user = owner) @@ -54,7 +58,9 @@ button_icon_state = "mech_view_stats" /datum/action/vehicle/sealed/mecha/mech_view_stats/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return chassis.ui_interact(owner) @@ -68,7 +74,9 @@ RegisterSignal(chassis, COMSIG_MECH_SAFETIES_TOGGLE, PROC_REF(update_action_icon)) /datum/action/vehicle/sealed/mecha/mech_toggle_safeties/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return chassis.set_safety(owner) @@ -86,7 +94,9 @@ button_icon_state = "strafe" /datum/action/vehicle/sealed/mecha/strafe/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return chassis.toggle_strafe() @@ -114,7 +124,9 @@ button_icon_state = "mech_seat_swap" /datum/action/vehicle/sealed/mecha/swap_seat/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return if(chassis.occupants.len == chassis.max_occupants) @@ -143,7 +155,9 @@ button_icon_state = "mech_overload_off" /datum/action/vehicle/sealed/mecha/mech_overclock/Trigger(trigger_flags, forced_state = null) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return chassis.toggle_overclock(forced_state) button_icon_state = "mech_overload_[chassis.overclock_mode ? "on" : "off"]" diff --git a/code/modules/vehicles/mecha/mecha_ui.dm b/code/modules/vehicles/mecha/mecha_ui.dm index 3c06c901e4e1f..ca7f03130e0bd 100644 --- a/code/modules/vehicles/mecha/mecha_ui.dm +++ b/code/modules/vehicles/mecha/mecha_ui.dm @@ -10,18 +10,22 @@ ui_view.display_to(user) /obj/vehicle/sealed/mecha/ui_status(mob/user, datum/ui_state/state) - if(contains(user)) - return UI_INTERACTIVE - return min( + var/common_status = min( ui_status_user_is_abled(user, src), - ui_status_user_has_free_hands(user, src), - ui_status_user_is_advanced_tool_user(user), ui_status_only_living(user), - max( - ui_status_user_is_adjacent(user, src), - ui_status_silicon_has_access(user, src), - ) ) + var/mob_specific_status = UI_INTERACTIVE + if(ishuman(user)) + mob_specific_status = min( + ui_status_user_inside(user, src), + ui_status_user_has_free_hands(user, src, allowed_source = VEHICLE_TRAIT), + ui_status_user_is_advanced_tool_user(user), + ) + if(isAI(user)) + mob_specific_status = ui_status_silicon_has_access(user, src) + if(isbrain(user)) + mob_specific_status = ui_status_user_inside(user, src) + return min(common_status, mob_specific_status) /obj/vehicle/sealed/mecha/ui_assets(mob/user) return list( diff --git a/code/modules/vehicles/mecha/working/clarke.dm b/code/modules/vehicles/mecha/working/clarke.dm index 1ecf4a9a831bc..07482cebf82ef 100644 --- a/code/modules/vehicles/mecha/working/clarke.dm +++ b/code/modules/vehicles/mecha/working/clarke.dm @@ -121,6 +121,8 @@ button_icon_state = "mecha_sleeper_miner" /datum/action/vehicle/sealed/mecha/clarke_scoop_body/Trigger(trigger_flags) + if(!..()) + return var/obj/item/mecha_parts/mecha_equipment/sleeper/clarke/sleeper = locate() in chassis var/mob/living/carbon/human/human_target for(var/mob/living/carbon/human/body in range(1, chassis)) @@ -138,7 +140,9 @@ COOLDOWN_DECLARE(search_cooldown) /datum/action/vehicle/sealed/mecha/mech_search_ruins/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return if(!COOLDOWN_FINISHED(src, search_cooldown)) chassis.balloon_alert(owner, "on cooldown!") diff --git a/code/modules/vehicles/mecha/working/ripley.dm b/code/modules/vehicles/mecha/working/ripley.dm index 7d8452893ac21..c9fb6b8fdbe2a 100644 --- a/code/modules/vehicles/mecha/working/ripley.dm +++ b/code/modules/vehicles/mecha/working/ripley.dm @@ -181,6 +181,8 @@ button_icon_state = "mech_siren_[secmech?.siren ? "on" : "off"]" /datum/action/vehicle/sealed/mecha/siren/Trigger(trigger_flags, forced_state = FALSE) + if(!..()) + return var/obj/vehicle/sealed/mecha/ripley/paddy/secmech = chassis secmech.togglesiren() diff --git a/code/modules/vehicles/sealed.dm b/code/modules/vehicles/sealed.dm index 1c96c90ae68ef..a3ea8e3276cbe 100644 --- a/code/modules/vehicles/sealed.dm +++ b/code/modules/vehicles/sealed.dm @@ -1,5 +1,6 @@ /obj/vehicle/sealed flags_1 = PREVENT_CONTENTS_EXPLOSION_1 + interaction_flags_atom = parent_type::interaction_flags_atom | INTERACT_ATOM_IGNORE_MOBILITY interaction_flags_mouse_drop = NEED_HANDS var/enter_delay = 2 SECONDS From 2974fcda9996648d495c754be53fcc23375fb4b8 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:50:31 +0000 Subject: [PATCH 035/106] Automatic changelog for PR #88959 [ci skip] --- html/changelogs/AutoChangeLog-pr-88959.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-88959.yml diff --git a/html/changelogs/AutoChangeLog-pr-88959.yml b/html/changelogs/AutoChangeLog-pr-88959.yml new file mode 100644 index 0000000000000..9cbd7e5c4c17e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-88959.yml @@ -0,0 +1,4 @@ +author: "Y0SH1M4S73R" +delete-after: True +changes: + - bugfix: "Corpses at the pilot seat of mechs can no longer toggle the lights, safeties, cabin sealing, strafing, overclocking, or durand shields, nor can they rename the mech or configure its equipment." \ No newline at end of file From 6ac2f8424b8d1dbfe5dc2e277b0a88150718eee5 Mon Sep 17 00:00:00 2001 From: Iamgoofball Date: Tue, 14 Jan 2025 06:52:36 -0800 Subject: [PATCH 036/106] Updates the same-tile-item ban map lint to clarify it means the same tile and not adjacent tiles (#88949) this lint confused the hell out of me so I fixed it to be more clear --- tools/maplint/source/lint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/maplint/source/lint.py b/tools/maplint/source/lint.py index 0847b10ed7161..8b70bb9893522 100644 --- a/tools/maplint/source/lint.py +++ b/tools/maplint/source/lint.py @@ -365,7 +365,7 @@ def run(self, identified: Content, contents: list[Content], identified_index) -> if not banned_neighbor.matches(identified, neighbor): continue - failures.append(fail_content(identified, f"Typepath {identified.path} has a banned neighbor{when_text}: {neighbor.path}")) + failures.append(fail_content(identified, f"Typepath {identified.path} has a banned path on the same tile{when_text}: {neighbor.path}")) for required_neighbor in self.required_neighbors: found = False From 6ad99c6662f1f111411144d5d125ba001d9ef56c Mon Sep 17 00:00:00 2001 From: high-speedspin-cycle Date: Tue, 14 Jan 2025 14:53:19 +0000 Subject: [PATCH 037/106] Culture bottles now properly copy their cure from the inserted beaker (#88943) ## About The Pull Request Fixes #46014 by having a newly created culture copy the cures list and cure_text of the inserted beaker. ## Why It's Good For The Game Fixes the (somewhat niche) case where a virologist would intentionally remake a virus until a preferred cure was rolled, only to be surprised that cultures created from this virus would revert to the first cure rolled. ## Changelog :cl: fix: Culture bottles now properly copy their cure from the inserted beaker /:cl: --------- Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> --- .../reagents/chemistry/machinery/pandemic.dm | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm index aaa2763eea2bc..984b493d68ed6 100644 --- a/code/modules/reagents/chemistry/machinery/pandemic.dm +++ b/code/modules/reagents/chemistry/machinery/pandemic.dm @@ -186,6 +186,38 @@ return TRUE return FALSE + +/** + * Supporting proc to get the cures of a replicable virus. This may differ from the archived cures for that disease id. + * + * @param {number} disease_id - The id of the disease being replicated. + * + * @returns {list} - List of two elements - the cures list for the disease and the cure_text associated with it. Will be empty if anything fails. + * + */ +/obj/machinery/computer/pandemic/proc/get_beaker_cures(disease_id) + var/list/cures = list() + if(!beaker) + return cures + + var/datum/reagent/blood/blood = beaker.reagents.has_reagent(/datum/reagent/blood) + if(!blood) + return cures + + var/list/viruses = blood.get_diseases() + if(!length(viruses)) + return cures + + // Only check for cure if there is a beaker AND the beaker contains blood AND the blood contains a virus. + for(var/datum/disease/advance/disease in viruses) + if(disease.GetDiseaseID() == disease_id) // Double check the ids match. + cures.Add(disease.cures) + cures.Add(disease.cure_text) + break + + return cures + + /** * Creates a culture bottle (ie: replicates) of the the specified disease. * @@ -196,12 +228,19 @@ /obj/machinery/computer/pandemic/proc/create_culture_bottle(index) var/id = get_virus_id_by_index(text2num(index)) var/datum/disease/advance/adv_disease = SSdisease.archive_diseases[id] + + if(!istype(adv_disease) || !adv_disease.mutable) to_chat(usr, span_warning("ERROR: Cannot replicate virus strain.")) return FALSE use_energy(active_power_usage) adv_disease = adv_disease.Copy() + var/list/cures = get_beaker_cures(id) + if(cures.len) + adv_disease.cures = cures[1] + adv_disease.cure_text = cures[2] // Same as generate_cure() in advance.dm var/list/data = list("viruses" = list(adv_disease)) + var/obj/item/reagent_containers/cup/tube/bottle = new(drop_location()) bottle.name = "[adv_disease.name] culture tube" bottle.desc = "A small test tube containing [adv_disease.agent] culture in synthblood medium." From a84efba3638c610fd9f2eaa8c47445ee9fc398ad Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:53:40 +0000 Subject: [PATCH 038/106] Automatic changelog for PR #88943 [ci skip] --- html/changelogs/AutoChangeLog-pr-88943.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-88943.yml diff --git a/html/changelogs/AutoChangeLog-pr-88943.yml b/html/changelogs/AutoChangeLog-pr-88943.yml new file mode 100644 index 0000000000000..78221740bfd9c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-88943.yml @@ -0,0 +1,4 @@ +author: "high-speedspin-cycle" +delete-after: True +changes: + - bugfix: "Culture bottles now properly copy their cure from the inserted beaker" \ No newline at end of file From f057705c4ff34f7ffb7fa7521ec05a5dbba36fc1 Mon Sep 17 00:00:00 2001 From: Hatterhat <31829017+Hatterhat@users.noreply.github.com> Date: Tue, 14 Jan 2025 08:54:24 -0600 Subject: [PATCH 039/106] machine board naming convention pass (#88888) ## About The Pull Request Adjusts a bunch of machine board names to comply with the general machine board naming patterns I see. First pass just removed a bunch of errant (Machine Board)s that were still on board names despite them being automatically appended on initialization, second pass set some board designs to actually have "Board" on the end to specify that it's a board and not a whole machine. ## Why It's Good For The Game Machine board naming consistency is probably good, actually. ## Changelog :cl: spellcheck: A handful of machine boards should no longer have two (Machine Board)s showing up in their name. spellcheck: Boulder machinery boards are now labeled as boards from autolathes/circuit imprinters. /:cl: --------- Co-authored-by: Hatterhat --- code/game/machinery/gulag_teleporter.dm | 2 +- .../circuitboards/machines/machine_circuitboards.dm | 8 ++++---- code/modules/cargo/markets/market_telepad.dm | 6 +++--- code/modules/research/designs/autolathe/mining.dm | 4 ++-- code/modules/research/designs/machine_designs.dm | 12 ++++++------ .../wiremod/shell/brain_computer_interface.dm | 2 +- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/code/game/machinery/gulag_teleporter.dm b/code/game/machinery/gulag_teleporter.dm index 1799e51564be8..c47cf1ea9d524 100644 --- a/code/game/machinery/gulag_teleporter.dm +++ b/code/game/machinery/gulag_teleporter.dm @@ -175,7 +175,7 @@ The console is located at computer/gulag_teleporter.dm use_energy(active_power_usage) /obj/item/circuitboard/machine/gulag_teleporter - name = "labor camp teleporter (Machine Board)" + name = "Labor Camp Teleporter" build_path = /obj/machinery/gulag_teleporter req_components = list( /obj/item/stack/ore/bluespace_crystal = 2, diff --git a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm index caf6ac6466025..a1a82bbdce602 100644 --- a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm @@ -458,7 +458,7 @@ //Generic /obj/item/circuitboard/machine/component_printer - name = "\improper Component Printer (Machine Board)" + name = "\improper Component Printer" greyscale_colors = CIRCUIT_COLOR_SCIENCE build_path = /obj/machinery/component_printer req_components = list( @@ -467,7 +467,7 @@ ) /obj/item/circuitboard/machine/module_duplicator - name = "\improper Module Duplicator (Machine Board)" + name = "\improper Module Duplicator" greyscale_colors = CIRCUIT_COLOR_SCIENCE build_path = /obj/machinery/module_duplicator req_components = list( @@ -833,7 +833,7 @@ /obj/item/stack/sheet/glass = 1) /obj/item/circuitboard/machine/chem_mass_spec - name = "High-Performance Liquid Chromatography" + name = "High-Performance Liquid Chromatography Machine" greyscale_colors = CIRCUIT_COLOR_MEDICAL build_path = /obj/machinery/chem_mass_spec req_components = list( @@ -1612,7 +1612,7 @@ ) /obj/item/circuitboard/machine/coffeemaker - name = "Coffeemaker (Machine Board)" + name = "Coffeemaker" greyscale_colors = CIRCUIT_COLOR_SERVICE build_path = /obj/machinery/coffeemaker req_components = list( diff --git a/code/modules/cargo/markets/market_telepad.dm b/code/modules/cargo/markets/market_telepad.dm index f0c8e058fc0fb..ea04c1f5bb9e7 100644 --- a/code/modules/cargo/markets/market_telepad.dm +++ b/code/modules/cargo/markets/market_telepad.dm @@ -2,7 +2,7 @@ #define PLACE_ON_MARKET_COST PAYCHECK_LOWER * 1.2 /obj/item/circuitboard/machine/ltsrbt - name = "LTSRBT (Machine Board)" + name = "Long-To-Short-Range Bluespace Transceiver" icon_state = "bluespacearray" build_path = /obj/machinery/ltsrbt req_components = list( @@ -13,8 +13,8 @@ def_components = list(/obj/item/stack/ore/bluespace_crystal = /obj/item/stack/ore/bluespace_crystal/artificial) /obj/machinery/ltsrbt - name = "Long-To-Short-Range-Bluespace-Transceiver" - desc = "The LTSRBT is a compact teleportation machine for receiving and sending items outside the station and inside the station.\nUsing teleportation frequencies stolen from NT it is near undetectable.\nEssential for any illegal market operations on NT stations.\n" + name = "Long-To-Short-Range Bluespace Transceiver" + desc = "The LTSRBT is a compact teleportation machine for sending and receiving items both inside and outside the station.\nUsing teleportation frequencies stolen from NT, it is near undetectable.\nEssential for any illegal market operations on NT stations." icon = 'icons/obj/machines/ltsrbt.dmi' icon_state = "ltsrbt_idle" base_icon_state = "ltsrbt" diff --git a/code/modules/research/designs/autolathe/mining.dm b/code/modules/research/designs/autolathe/mining.dm index bc83d27123d6e..192b0d281a925 100644 --- a/code/modules/research/designs/autolathe/mining.dm +++ b/code/modules/research/designs/autolathe/mining.dm @@ -1,6 +1,6 @@ // Autolathe-able circuitboards for starting with boulder processing machines. /datum/design/board/smelter - name = "Boulder Smelter" + name = "Boulder Smelter Board" desc = "A circuitboard for a boulder smelter. Lowtech enough to be printed from the lathe." id = "b_smelter" build_type = AUTOLATHE @@ -16,7 +16,7 @@ departmental_flags = DEPARTMENT_BITFLAG_CARGO /datum/design/board/refinery - name = "Boulder Refinery" + name = "Boulder Refinery Board" desc = "A circuitboard for a boulder refinery. Lowtech enough to be printed from the lathe." id = "b_refinery" build_type = AUTOLATHE diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index 74e00231035cf..6364025924bd7 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -165,7 +165,7 @@ departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_SCIENCE /datum/design/board/botpad - name = "Machine Design (Bot launchpad)" + name = "Bot Launchpad Board" desc = "The circuit board for a bot launchpad." id = "botpad" build_type = IMPRINTER @@ -299,8 +299,8 @@ departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_MEDICAL /datum/design/board/chem_mass_spec - name = "High-Performance Liquid Chromatography Board" - desc = "The circuit board for a High-Performance Liquid Chromatography (Machine Board" + name = "High-Performance Liquid Chromatography Machine Board" + desc = "The circuit board for a High-Performance Liquid Chromatography machine." id = "chem_mass_spec" build_path = /obj/item/circuitboard/machine/chem_mass_spec category = list( @@ -1176,7 +1176,7 @@ departmental_flags = DEPARTMENT_BITFLAG_SERVICE | DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_SCIENCE /datum/design/board/navbeacon - name = "Machine Design (Bot Navigational Beacon)" + name = "Bot Navigational Beacon Board" desc = "The circuit board for a beacon that aids bot navigation." id = "botnavbeacon" build_path = /obj/item/circuitboard/machine/navbeacon @@ -1196,7 +1196,7 @@ departmental_flags = DEPARTMENT_BITFLAG_SERVICE | DEPARTMENT_BITFLAG_CARGO | DEPARTMENT_BITFLAG_SCIENCE /datum/design/board/brm - name = "Boulder Retrieval Matrix" + name = "Boulder Retrieval Matrix Board" id = "brm" materials = list( /datum/material/glass = SHEET_MATERIAL_AMOUNT, @@ -1349,7 +1349,7 @@ departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_CARGO /datum/design/board/mailsorter - name = "Mail Sorter" + name = "Mail Sorter Board" desc = "The circuit board for a mail sorting unit." id = "mailsorter" build_path = /obj/item/circuitboard/machine/mailsorter diff --git a/code/modules/wiremod/shell/brain_computer_interface.dm b/code/modules/wiremod/shell/brain_computer_interface.dm index 1ade714552f75..1806df021c88e 100644 --- a/code/modules/wiremod/shell/brain_computer_interface.dm +++ b/code/modules/wiremod/shell/brain_computer_interface.dm @@ -505,7 +505,7 @@ return ..() /obj/item/circuitboard/machine/bci_implanter - name = "Brain-Computer Interface Manipulation Chamber (Machine Board)" + name = "Brain-Computer Interface Manipulation Chamber" greyscale_colors = CIRCUIT_COLOR_SCIENCE build_path = /obj/machinery/bci_implanter req_components = list( From bd1856b338e7b6ac89635e8e4284b3946024a5c5 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:54:51 +0000 Subject: [PATCH 040/106] Automatic changelog for PR #88888 [ci skip] --- html/changelogs/AutoChangeLog-pr-88888.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-88888.yml diff --git a/html/changelogs/AutoChangeLog-pr-88888.yml b/html/changelogs/AutoChangeLog-pr-88888.yml new file mode 100644 index 0000000000000..db0d5af7f7888 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-88888.yml @@ -0,0 +1,5 @@ +author: "Hatterhat" +delete-after: True +changes: + - spellcheck: "A handful of machine boards should no longer have two (Machine Board)s showing up in their name." + - spellcheck: "Boulder machinery boards are now labeled as boards from autolathes/circuit imprinters." \ No newline at end of file From ded92967e4cc12ad2fe882039a80265b10f99cb0 Mon Sep 17 00:00:00 2001 From: Tim Date: Tue, 14 Jan 2025 08:55:02 -0600 Subject: [PATCH 041/106] Fix airlock authentication card not getting stored in containers (#88816) ## About The Pull Request Trying to insert an airlock auth card into a bag or container would not work due to a message saying the target must be an airlock. It's now fixed and should insert into a container regardless if on help or harm intent. ## Why It's Good For The Game Consistency. ## Changelog :cl: fix: Fix airlock authentication card not getting stored in containers /:cl: --- code/game/objects/items/emags.dm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/game/objects/items/emags.dm b/code/game/objects/items/emags.dm index 2adfeb585ae5f..9c0a95877aac8 100644 --- a/code/game/objects/items/emags.dm +++ b/code/game/objects/items/emags.dm @@ -176,6 +176,12 @@ . = ..() type_whitelist = list(typesof(/obj/machinery/door/airlock), typesof(/obj/machinery/door/window/), typesof(/obj/machinery/door/firedoor)) //list of all acceptable typepaths that this device can affect +/obj/item/card/emag/doorjack/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) + // only for doorjacks since regular emags still need to be able to break locks on storage items + if(interacting_with.atom_storage) + return NONE + . = ..() + /obj/item/card/emag/doorjack/proc/use_charge(mob/user) charges -- to_chat(user, span_notice("You use [src]. It now has [charges] charge[charges == 1 ? "" : "s"] remaining.")) From 705ccb8ace736a53217018d8245992f7f0a9c0b3 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:55:25 +0000 Subject: [PATCH 042/106] Automatic changelog for PR #88816 [ci skip] --- html/changelogs/AutoChangeLog-pr-88816.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-88816.yml diff --git a/html/changelogs/AutoChangeLog-pr-88816.yml b/html/changelogs/AutoChangeLog-pr-88816.yml new file mode 100644 index 0000000000000..e035ff7f9b680 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-88816.yml @@ -0,0 +1,4 @@ +author: "timothymtorres" +delete-after: True +changes: + - bugfix: "Fix airlock authentication card not getting stored in containers" \ No newline at end of file From d85eb8e18319f85829b2a7ba0b7b8d1c37b296da Mon Sep 17 00:00:00 2001 From: jimmyl <70376633+mc-oofert@users.noreply.github.com> Date: Tue, 14 Jan 2025 15:57:07 +0100 Subject: [PATCH 043/106] like 5 tiny deathmatch changes (#88812) ## About The Pull Request you may no longer fish in deathmatch chasms as a result that means doing literally anything with explosives wont send 9000000 lobstrosities onto the map fixed cuban pete loadout macrobomb lobbies will close after 5 minutes of inactivity changing map will now make a more accurate number of observers also removed that useless eye button in the lobby list ## Why It's Good For The Game 6 billion lobstroties because of a firecracker sucks bug bad afk empty lobbies bad ## Changelog :cl: fix: deathmatch - chasms will no longer do anything when blown up, cuban pete loadout macrobomb fixed, AFK lobbies will close after 5 minutes, fixed changing maps incorrectly taking one more observer than it should /:cl: --- code/datums/components/chasm.dm | 4 +++- .../modules/deathmatch/deathmatch_loadouts.dm | 2 +- code/modules/deathmatch/deathmatch_lobby.dm | 9 +++++++- .../tgui/interfaces/DeathmatchPanel.tsx | 23 ++++++++----------- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/code/datums/components/chasm.dm b/code/datums/components/chasm.dm index c281addacc231..7e516cd5f403e 100644 --- a/code/datums/components/chasm.dm +++ b/code/datums/components/chasm.dm @@ -49,7 +49,9 @@ //otherwise don't do anything because turfs and areas are initialized before movables. if(!mapload) addtimer(CALLBACK(src, PROC_REF(drop_stuff)), 0) - parent.AddComponent(/datum/component/fishing_spot, GLOB.preset_fish_sources[/datum/fish_source/chasm]) + var/turf/turf_parent = parent + if(!istype(turf_parent.loc, /area/deathmatch)) // there are so so so many explosives in deathmatch and i dont think anyone is going to fish in the *death*match arena + parent.AddComponent(/datum/component/fishing_spot, GLOB.preset_fish_sources[/datum/fish_source/chasm]) /datum/component/chasm/UnregisterFromParent() storage = null diff --git a/code/modules/deathmatch/deathmatch_loadouts.dm b/code/modules/deathmatch/deathmatch_loadouts.dm index 3c015c96f92c5..b50a579f34d08 100644 --- a/code/modules/deathmatch/deathmatch_loadouts.dm +++ b/code/modules/deathmatch/deathmatch_loadouts.dm @@ -643,7 +643,7 @@ r_hand = /obj/item/sbeacondrop/bomb l_pocket = /obj/item/grenade/syndieminibomb r_pocket = /obj/item/grenade/syndieminibomb - implants = list(/obj/item/implanter/explosive_macro) + implants = list(/obj/item/implant/explosive/macro) backpack_contents = list( /obj/item/assembly/signaler = 10, ) diff --git a/code/modules/deathmatch/deathmatch_lobby.dm b/code/modules/deathmatch/deathmatch_lobby.dm index cf15d0421888d..9a6773edec565 100644 --- a/code/modules/deathmatch/deathmatch_lobby.dm +++ b/code/modules/deathmatch/deathmatch_lobby.dm @@ -38,6 +38,7 @@ loadouts = GLOB.deathmatch_game.loadouts add_player(player, loadouts[1], TRUE) ui_interact(player) + addtimer(CALLBACK(src, PROC_REF(lobby_afk_probably)), 5 MINUTES) // being generous here /datum/deathmatch_lobby/Destroy(force, ...) . = ..() @@ -169,6 +170,12 @@ announce(span_reallybig("The players have took too long! Game ending!")) end_game() +/datum/deathmatch_lobby/proc/lobby_afk_probably() + if (QDELING(src) || playing) + return + announce(span_warning("Lobby ([host]) was closed due to not starting after 5 minutes, being potentially AFK. Please be faster next time.")) + GLOB.deathmatch_game.remove_lobby(host) + /datum/deathmatch_lobby/proc/end_game() if (!location) CRASH("Reservation of deathmatch game [host] deleted during game.") @@ -306,7 +313,7 @@ var/max_players = map.max_players for (var/possible_unlucky_loser in players) max_players-- - if (max_players <= 0) + if (max_players < 0) var/loser_mob = players[possible_unlucky_loser]["mob"] remove_ckey_from_play(possible_unlucky_loser) add_observer(loser_mob) diff --git a/tgui/packages/tgui/interfaces/DeathmatchPanel.tsx b/tgui/packages/tgui/interfaces/DeathmatchPanel.tsx index 3731d927c03b3..1be53d658d185 100644 --- a/tgui/packages/tgui/interfaces/DeathmatchPanel.tsx +++ b/tgui/packages/tgui/interfaces/DeathmatchPanel.tsx @@ -133,20 +133,15 @@ function LobbyDisplay(props) { {!lobby.playing ? ( - <> - - ) : ( + + + + + ); +} + +function ApcLoggedIn(props) { + const { act, data } = useBackend(); + const { restoring } = data; + + const [tabIndex, setTabIndex] = useState(Screen.ControlPanel); + const sortByState = useState('name'); + + return ( + + + + { + setTabIndex(Screen.ControlPanel); + act('check-apcs'); + }} + > + APC Control Panel + + { + setTabIndex(Screen.LogView); + act('check-logs'); + }} + > + Log View Panel + + + + {!!restoring && ( + + + {' Resetting...'} + + )} + + {tabIndex === Screen.ControlPanel && ( + + +

    + +
    + + +
    + +
    +
    + + )} + {tabIndex === Screen.LogView && ( +
    + + + +
    + )} + + + ); +} + +type ControlProps = { + sortByState: [string, (field: string) => void]; +}; + +function ControlPanel(props: ControlProps) { + const { act, data } = useBackend(); + const { emagged, logging } = data; + const [sortByField, setSortByField] = props.sortByState; + + return ( + + + + Sort by: + + setSortByField('name')} + > + Name + + setSortByField('charge')} + > + Charge + + setSortByField('draw')} + > + Draw + + + + + {!!emagged && ( + <> + + + + )} + + + + ); +} + +type WithIndex = APC & { id: string }; + +function ApcControlScene(props) { + const { data, act } = useBackend(); + + const [sortByField] = props.sortByState; + + const withIndex = data.apcs.map((apc, idx) => ({ + ...apc, + id: apc.name + idx, + })); + + let sorted: WithIndex[] = []; + if (sortByField === 'name') { + sorted = sortBy(withIndex, (apc) => apc.name); + } else if (sortByField === 'charge') { + sorted = sortBy(withIndex, (apc) => -apc.charge); + } else if (sortByField === 'draw') { + sorted = sortBy( + withIndex, + (apc) => -powerRank(apc.load), + (apc) => -parseFloat(apc.load), + ); + } + + return ( + + + On/Off + Area + Charge + + Draw + + Eqp + Lgt + Env + + {sorted.map((apc, i) => ( + + + + + + + + {apc.load} + + + + + + + + + + + ))} +
    + ); +} + +function LogPanel(props) { + const { data } = useBackend(); + + const logs = data.logs + .map((line, idx) => ({ ...line, id: line.entry + idx })) + .reverse(); + + return ( + + {logs.map((line) => { + const colonIndex = line.entry.lastIndexOf(':'); + const timestamp = line.entry.substring(0, colonIndex); + const message = line.entry.substring(colonIndex + 1); + + return ( + + + {timestamp}: + {' '} + {message} + + ); + })} + + ); +} + +function AreaStatusColorButton(props) { + const { target, status, apc, act } = props; + const power = Boolean(status & 2); + const mode = Boolean(status & 1); + + return ( +