From 2fdc2313cb2a1bb6d370d43824986c493481aba9 Mon Sep 17 00:00:00 2001 From: JackEnoff <166665535+JackEnoff@users.noreply.github.com> Date: Sun, 16 Jun 2024 10:18:30 -0400 Subject: [PATCH 001/172] Changelings are (once again) weak to fire (#83953) ## About The Pull Request Being on fire will make the ling unable to use any ability that isn't for getting out of danger or reviving themselves (Adrenals, Fakedeath, Strained Muscles, Last Resort, Shriek, Defib Grasp and Biodegrade). And no, there is no armblade nerf, it is fine as it is. ## Why It's Good For The Game Changelings are really busted, as they are effectively immortal until completely removed (which means finding a cremator/gibber/shuttle, and by the time you get there most of the time they are already ready to revive) which really limits counterplay. Goof and Jac's approach to nerfing lings was a bit too much since it nerfed the armblade massively as well, but I found that their approach about lings being weak to fire was really good counterplay for lings (besides BZ (who even uses it?)). We shouldnt just leave the guys that are almost immortal and spawn multiple in a round with one single counterplay that relies on a knowledge check. ## Changelog :cl: balance: Certain changeling abilities won't work while on fire. /:cl: --- code/modules/antagonists/changeling/changeling_power.dm | 5 +++++ code/modules/antagonists/changeling/powers/adrenaline.dm | 1 + code/modules/antagonists/changeling/powers/biodegrade.dm | 1 + code/modules/antagonists/changeling/powers/defib_grasp.dm | 1 + code/modules/antagonists/changeling/powers/fakedeath.dm | 1 + code/modules/antagonists/changeling/powers/headcrab.dm | 1 + code/modules/antagonists/changeling/powers/shriek.dm | 2 ++ .../antagonists/changeling/powers/strained_muscles.dm | 1 + 8 files changed, 13 insertions(+) diff --git a/code/modules/antagonists/changeling/changeling_power.dm b/code/modules/antagonists/changeling/changeling_power.dm index 23b4f9548c424..d06d8fe91735a 100644 --- a/code/modules/antagonists/changeling/changeling_power.dm +++ b/code/modules/antagonists/changeling/changeling_power.dm @@ -32,6 +32,8 @@ var/ignores_fakedeath = FALSE /// used by a few powers that toggle var/active = FALSE + /// Does this ability stop working if you are burning? + var/disabled_by_fire = TRUE /* changeling code now relies on on_purchase to grant powers. @@ -61,6 +63,9 @@ the same goes for Remove(). if you override Remove(), call parent or else your p /datum/action/changeling/proc/try_to_sting(mob/living/user, mob/living/target) if(!can_sting(user, target)) return FALSE + if(disabled_by_fire && user.fire_stacks && user.on_fire) + user.balloon_alert(user, "on fire!") + return FALSE var/datum/antagonist/changeling/changeling = IS_CHANGELING(user) if(sting_action(user, target)) sting_feedback(user, target) diff --git a/code/modules/antagonists/changeling/powers/adrenaline.dm b/code/modules/antagonists/changeling/powers/adrenaline.dm index 9d2abfe623314..10c06656b2978 100644 --- a/code/modules/antagonists/changeling/powers/adrenaline.dm +++ b/code/modules/antagonists/changeling/powers/adrenaline.dm @@ -7,6 +7,7 @@ dna_cost = 2 req_human = FALSE req_stat = CONSCIOUS + disabled_by_fire = FALSE /datum/action/changeling/adrenaline/can_sting(mob/living/user, mob/living/target) . = ..() diff --git a/code/modules/antagonists/changeling/powers/biodegrade.dm b/code/modules/antagonists/changeling/powers/biodegrade.dm index 2b1753c27273a..8a5fae3bd8aed 100644 --- a/code/modules/antagonists/changeling/powers/biodegrade.dm +++ b/code/modules/antagonists/changeling/powers/biodegrade.dm @@ -6,6 +6,7 @@ chemical_cost = 30 //High cost to prevent spam dna_cost = 2 req_human = TRUE + disabled_by_fire = FALSE /datum/action/changeling/biodegrade/sting_action(mob/living/carbon/human/user) if(user.handcuffed) diff --git a/code/modules/antagonists/changeling/powers/defib_grasp.dm b/code/modules/antagonists/changeling/powers/defib_grasp.dm index 135b9b243f721..867a595e17dcd 100644 --- a/code/modules/antagonists/changeling/powers/defib_grasp.dm +++ b/code/modules/antagonists/changeling/powers/defib_grasp.dm @@ -6,6 +6,7 @@ while we are dead or in stasis. Will also stun cyborgs momentarily." owner_has_control = FALSE dna_cost = 0 + disabled_by_fire = FALSE /// Flags to pass to fully heal when we get zapped var/heal_flags = HEAL_DAMAGE|HEAL_BODY|HEAL_STATUS|HEAL_CC_STATUS diff --git a/code/modules/antagonists/changeling/powers/fakedeath.dm b/code/modules/antagonists/changeling/powers/fakedeath.dm index 75d4996b8b2d7..1dff58377fd4a 100644 --- a/code/modules/antagonists/changeling/powers/fakedeath.dm +++ b/code/modules/antagonists/changeling/powers/fakedeath.dm @@ -7,6 +7,7 @@ req_dna = 1 req_stat = DEAD ignores_fakedeath = TRUE + disabled_by_fire = FALSE /// How long it takes for revival to ready upon entering stasis. /// The changeling can opt to stay in fakedeath for longer, though. diff --git a/code/modules/antagonists/changeling/powers/headcrab.dm b/code/modules/antagonists/changeling/powers/headcrab.dm index 30970832df0a4..0b7668260d769 100644 --- a/code/modules/antagonists/changeling/powers/headcrab.dm +++ b/code/modules/antagonists/changeling/powers/headcrab.dm @@ -8,6 +8,7 @@ req_human = TRUE req_stat = DEAD ignores_fakedeath = TRUE + disabled_by_fire = FALSE /datum/action/changeling/headcrab/sting_action(mob/living/user) set waitfor = FALSE diff --git a/code/modules/antagonists/changeling/powers/shriek.dm b/code/modules/antagonists/changeling/powers/shriek.dm index aa204d89a166e..cfbcc7b64ec27 100644 --- a/code/modules/antagonists/changeling/powers/shriek.dm +++ b/code/modules/antagonists/changeling/powers/shriek.dm @@ -6,6 +6,7 @@ chemical_cost = 20 dna_cost = 1 req_human = TRUE + disabled_by_fire = FALSE //A flashy ability, good for crowd control and sowing chaos. /datum/action/changeling/resonant_shriek/sting_action(mob/user) @@ -41,6 +42,7 @@ button_icon_state = "dissonant_shriek" chemical_cost = 20 dna_cost = 1 + disabled_by_fire = FALSE /datum/action/changeling/dissonant_shriek/sting_action(mob/user) ..() diff --git a/code/modules/antagonists/changeling/powers/strained_muscles.dm b/code/modules/antagonists/changeling/powers/strained_muscles.dm index 19c4458a388bc..3ea59f5df089b 100644 --- a/code/modules/antagonists/changeling/powers/strained_muscles.dm +++ b/code/modules/antagonists/changeling/powers/strained_muscles.dm @@ -11,6 +11,7 @@ req_human = TRUE var/stacks = 0 //Increments every 5 seconds; damage increases over time active = FALSE //Whether or not you are a hedgehog + disabled_by_fire = FALSE /datum/action/changeling/strained_muscles/sting_action(mob/living/carbon/user) ..() From 0a9e4d0cf0afa0ccbfdcbebf2a89ad3ce22083e7 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Mon, 17 Jun 2024 02:18:51 +1200 Subject: [PATCH 002/172] Automatic changelog for PR #83953 [ci skip] --- html/changelogs/AutoChangeLog-pr-83953.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83953.yml diff --git a/html/changelogs/AutoChangeLog-pr-83953.yml b/html/changelogs/AutoChangeLog-pr-83953.yml new file mode 100644 index 0000000000000..fe5f444909fe3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83953.yml @@ -0,0 +1,4 @@ +author: "JackEnoff" +delete-after: True +changes: + - balance: "Certain changeling abilities won't work while on fire." \ No newline at end of file From 3fb84d5429715c7e4049932fbfe7ee53bffe4849 Mon Sep 17 00:00:00 2001 From: Lucy Grindler <110352801+LucyGrind@users.noreply.github.com> Date: Sun, 16 Jun 2024 12:37:13 -0700 Subject: [PATCH 003/172] Crit Dental Pills! (#83895) ## About The Pull Request What it says on the tin: Allows dental pills to be used in crit, simply gets rid of hands_free and adds a NONE flag ## Why It's Good For The Game Dental implants are among the lowest used surgeries in the game, and I think have a lot of potential for funny shenanigans, such as using ghoul powder to fake your own death, or just blowing yourself up when in crit. Requires another person to do the surgery, so its harder to powergame with and also reviver implants alongside other things set the precedent that this sorta change is okay. ## Changelog :cl: Hacks-The-Doors balance: dental pills can now be used in crit. balance: dental pills now give off a message when you start using them balance: dental pills have a 2.5 second delay when in soft crit /:cl: --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> --- code/game/objects/items/devices/flashlight.dm | 2 +- code/modules/clothing/head/jobs.dm | 2 +- code/modules/surgery/bodyparts/dismemberment.dm | 4 ++-- code/modules/surgery/dental_implant.dm | 15 ++++++++++++--- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 99e7c43235ab9..67ec498a1fbc6 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -170,7 +170,7 @@ organ_list += (O.gender == "plural" ? O.name : "\an [O.name]") var/pill_count = 0 - for(var/datum/action/item_action/hands_free/activate_pill/AP in M.actions) + for(var/datum/action/item_action/activate_pill/AP in M.actions) pill_count++ if(M == user)//if we're looking on our own mouth diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index cd1f6a2798ba2..5ea7d62313bd4 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -701,7 +701,7 @@ else var/obj/item/organ/internal/tongue/has_tongue = human_examined.get_organ_slot(ORGAN_SLOT_TONGUE) var/pill_count = 0 - for(var/datum/action/item_action/hands_free/activate_pill/pill in human_examined.actions) + for(var/datum/action/item_action/activate_pill/pill in human_examined.actions) pill_count++ if(pill_count >= 1 && has_tongue) diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index e942a1b2e3aca..1fa6db17e5a54 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -234,7 +234,7 @@ qdel(owner.GetComponent(/datum/component/creamed)) //clean creampie overlay flushed emoji //Handle dental implants - for(var/datum/action/item_action/hands_free/activate_pill/pill_action in owner.actions) + for(var/datum/action/item_action/activate_pill/pill_action in owner.actions) pill_action.Remove(owner) var/obj/pill = pill_action.target if(pill) @@ -342,7 +342,7 @@ //Handle dental implants for(var/obj/item/reagent_containers/pill/pill in src) - for(var/datum/action/item_action/hands_free/activate_pill/pill_action in pill.actions) + for(var/datum/action/item_action/activate_pill/pill_action in pill.actions) pill.forceMove(new_head_owner) pill_action.Grant(new_head_owner) break diff --git a/code/modules/surgery/dental_implant.dm b/code/modules/surgery/dental_implant.dm index 0d583d09a11b0..d720039d56b7e 100644 --- a/code/modules/surgery/dental_implant.dm +++ b/code/modules/surgery/dental_implant.dm @@ -27,7 +27,7 @@ user.transferItemToLoc(tool, target, TRUE) - var/datum/action/item_action/hands_free/activate_pill/pill_action = new(tool) + var/datum/action/item_action/activate_pill/pill_action = new(tool) pill_action.name = "Activate [tool.name]" pill_action.build_all_button_icons() pill_action.target = tool @@ -42,12 +42,21 @@ ) return ..() -/datum/action/item_action/hands_free/activate_pill +/datum/action/item_action/activate_pill name = "Activate Pill" + check_flags = NONE -/datum/action/item_action/hands_free/activate_pill/Trigger(trigger_flags) +/datum/action/item_action/activate_pill/IsAvailable(feedback) + if(owner.stat > SOFT_CRIT) + return FALSE + return ..() + +/datum/action/item_action/activate_pill/Trigger(trigger_flags) if(!..()) return FALSE + owner.balloon_alert_to_viewers("[owner] grinds their teeth!", "You grit your teeth.") + if(!do_after(owner, owner.stat * (2.5 SECONDS), owner, IGNORE_USER_LOC_CHANGE | IGNORE_INCAPACITATED)) + return FALSE var/obj/item/item_target = target to_chat(owner, span_notice("You grit your teeth and burst the implanted [item_target.name]!")) owner.log_message("swallowed an implanted pill, [target]", LOG_ATTACK) From 8ffe8f915bd0d1cdee2fa36e414de5f7c15182c4 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Mon, 17 Jun 2024 07:38:44 +1200 Subject: [PATCH 004/172] Automatic changelog for PR #83895 [ci skip] --- html/changelogs/AutoChangeLog-pr-83895.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83895.yml diff --git a/html/changelogs/AutoChangeLog-pr-83895.yml b/html/changelogs/AutoChangeLog-pr-83895.yml new file mode 100644 index 0000000000000..6b66da81feef3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83895.yml @@ -0,0 +1,6 @@ +author: "Hacks-The-Doors" +delete-after: True +changes: + - balance: "dental pills can now be used in crit." + - balance: "dental pills now give off a message when you start using them" + - balance: "dental pills have a 2.5 second delay when in soft crit" \ No newline at end of file From 6351073f56db14d4ac33bfcce7bea9f87494ad96 Mon Sep 17 00:00:00 2001 From: Lucy Grindler <110352801+LucyGrind@users.noreply.github.com> Date: Sun, 16 Jun 2024 16:11:44 -0700 Subject: [PATCH 005/172] Pegging Update (#83991) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## About The Pull Request We be addin' peg legs an' peg arms, makin' 'em craftable fer all ye scurvy dogs. Ye can attach 'em yerselves, no need fer a surgeon's touch, usin' the mighty ligament hook code. There be tons o' balance tweaks an' special properties fer these limbs. Yarrrrr! ## Why It's Good For The Game Arrr, this be givin' ye a ghetto alternative to headin' to medbay when yer limbs be blown off. Plus, the potential fer pirate RP be fantastic! Who doesn’t want peg limbs? If ye think otherwise, ye be lyin’ ,and ye'll be walkin’ the plank! Yarrrrr! ## Changelog :cl: Hacks-The-Doors (coding) & Septicchlorine (spriting) add: craftable peg limbs (2 planks) which are attachable without surgery bal: peg limbs take 1.5x burn and 1.3x brute, and do reduced damage bal: peg limbs have chunky fingers (like insuls, but per limb) /:cl: --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Co-authored-by: septic <105231896+septoBismol@users.noreply.github.com> Co-authored-by: Jacquerel --- code/__DEFINES/mobs.dm | 6 +- code/__DEFINES/surgery.dm | 2 + code/__DEFINES/traits/declarations.dm | 2 + code/_globalvars/bitfields.dm | 2 + code/_globalvars/traits/_traits.dm | 3 + .../items/stacks/sheets/sheet_types.dm | 21 +++++ code/game/objects/items/tools/weldingtool.dm | 2 +- .../mob/living/carbon/human/human_helpers.dm | 27 ++++++ code/modules/mob/mob_helpers.dm | 13 --- code/modules/power/cable.dm | 2 +- code/modules/surgery/bodyparts/_bodyparts.dm | 2 +- .../modules/surgery/bodyparts/ghetto_parts.dm | 79 ++++++++++++++++++ icons/mob/human/bodyparts.dmi | Bin 52010 -> 52823 bytes icons/mob/human/species/ghetto.dmi | Bin 0 -> 746 bytes tgstation.dme | 1 + 15 files changed, 145 insertions(+), 17 deletions(-) create mode 100644 code/modules/surgery/bodyparts/ghetto_parts.dm create mode 100644 icons/mob/human/species/ghetto.dmi diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index e8904f0bb1f86..2e5d9beadaf21 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -84,6 +84,8 @@ #define BODYTYPE_ALIEN (1<<3) ///The limb is from a golem #define BODYTYPE_GOLEM (1<<4) +//The limb is a peg limb +#define BODYTYPE_PEG (1<<5) // Bodyshape defines for how things can be worn, i.e., what "shape" the mob sprite is ///The limb fits the human mold. This is not meant to be literal, if the sprite "fits" on a human, it is "humanoid", regardless of origin. @@ -95,7 +97,7 @@ ///The limb is snouted. #define BODYSHAPE_SNOUTED (1<<3) -#define BODYTYPE_BIOSCRAMBLE_INCOMPATIBLE (BODYTYPE_ROBOTIC | BODYTYPE_LARVA_PLACEHOLDER | BODYTYPE_GOLEM) +#define BODYTYPE_BIOSCRAMBLE_INCOMPATIBLE (BODYTYPE_ROBOTIC | BODYTYPE_LARVA_PLACEHOLDER | BODYTYPE_GOLEM | BODYTYPE_PEG) #define BODYTYPE_CAN_BE_BIOSCRAMBLED(bodytype) (!(bodytype & BODYTYPE_BIOSCRAMBLE_INCOMPATIBLE)) // Defines for Species IDs. Used to refer to the name of a species, for things like bodypart names or species preferences. @@ -135,6 +137,8 @@ #define BODYPART_ID_LARVA "larva" #define BODYPART_ID_PSYKER "psyker" #define BODYPART_ID_MEAT "meat" +#define BODYPART_ID_PEG "peg" + //See: datum/species/var/digitigrade_customization ///The species does not have digitigrade legs in generation. diff --git a/code/__DEFINES/surgery.dm b/code/__DEFINES/surgery.dm index 42e00045761e5..feddc24c6f858 100644 --- a/code/__DEFINES/surgery.dm +++ b/code/__DEFINES/surgery.dm @@ -33,6 +33,8 @@ #define IS_ORGANIC_LIMB(limb) (limb.bodytype & BODYTYPE_ORGANIC) /// Helper to figure out if a limb is robotic #define IS_ROBOTIC_LIMB(limb) (limb.bodytype & BODYTYPE_ROBOTIC) +/// Helper to figure out if a limb is a peg limb +#define IS_PEG_LIMB(limb) (limb.bodytype & BODYTYPE_PEG) // Flags for the bodypart_flags var on /obj/item/bodypart /// Bodypart cannot be dismembered or amputated diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 17d9008a543b3..2d420339e1883 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -1153,5 +1153,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// This item cannot be selected for or used by a theft objective (Spies, Traitors, etc.) #define TRAIT_ITEM_OBJECTIVE_BLOCKED "item_objective_blocked" +/// This trait lets you attach limbs to any player without surgery. +#define TRAIT_EASY_ATTACH "easy_attach" // END TRAIT DEFINES diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index 67f33d0460e47..ead7b324cea13 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -390,6 +390,7 @@ DEFINE_BITFIELD(bodytype, list( "BODYTYPE_LARVA_PLACEHOLDER" = BODYTYPE_LARVA_PLACEHOLDER, "BODYTYPE_ALIEN" = BODYTYPE_ALIEN, "BODYTYPE_GOLEM" = BODYTYPE_GOLEM, + "BODYTYPE_PEG" = BODYTYPE_PEG, )) DEFINE_BITFIELD(acceptable_bodytype, list( @@ -398,6 +399,7 @@ DEFINE_BITFIELD(acceptable_bodytype, list( "BODYTYPE_LARVA_PLACEHOLDER" = BODYTYPE_LARVA_PLACEHOLDER, "BODYTYPE_ALIEN" = BODYTYPE_ALIEN, "BODYTYPE_GOLEM" = BODYTYPE_GOLEM, + "BODYTYPE_PEG" = BODYTYPE_PEG, )) DEFINE_BITFIELD(bodyshape, list( diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 1fe465da39f0d..ba065653fe6dc 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -548,6 +548,9 @@ GLOBAL_LIST_INIT(traits_by_type, list( /obj/item/bodypart = list( "TRAIT_PARALYSIS" = TRAIT_PARALYSIS, ), + /obj/item/bodypart = list( + "TRAIT_EASY_ATTACH" = TRAIT_EASY_ATTACH, + ), /obj/item/card/id = list( "TRAIT_JOB_FIRST_ID_CARD" = TRAIT_JOB_FIRST_ID_CARD, "TRAIT_MAGNETIC_ID_CARD" = TRAIT_MAGNETIC_ID_CARD, diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 7b6d4b6207340..662f94c61d5e1 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -347,6 +347,12 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \ new /datum/stack_recipe("pew (left)", /obj/structure/chair/pew/left, 3, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_FURNITURE), new /datum/stack_recipe("pew (right)", /obj/structure/chair/pew/right, 3, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_FURNITURE) )), + new/datum/stack_recipe_list("peg limbs", list( + new /datum/stack_recipe("peg arm (left)", /obj/item/bodypart/arm/left/ghetto, 2, crafting_flags = NONE, category = CAT_MISC), + new /datum/stack_recipe("peg arm (right)", /obj/item/bodypart/arm/right/ghetto, 2, crafting_flags = NONE, category = CAT_MISC), + new /datum/stack_recipe("peg leg (left)", /obj/item/bodypart/leg/left/ghetto, 2, crafting_flags = NONE, category = CAT_MISC), + new /datum/stack_recipe("peg leg (right)", /obj/item/bodypart/leg/right/ghetto, 2, crafting_flags = NONE, category = CAT_MISC) + )), null, \ )) @@ -377,6 +383,21 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \ /obj/item/stack/sheet/mineral/wood/fifty amount = 50 +/obj/item/stack/sheet/mineral/wood/interact_with_atom(mob/living/carbon/human/target, mob/user) + if(!istype(target)) + return NONE + + var/obj/item/bodypart/affecting = target.get_bodypart(check_zone(user.zone_selected)) + if(affecting && IS_PEG_LIMB(affecting)) + if(user == target) + user.visible_message(span_notice("[user] starts to fix their [affecting.name]."), span_notice("You start fixing [target == user ? "your" : "[target]'s"] [affecting.name].")) + if(!do_after(user, 5 SECONDS, target)) + return ITEM_INTERACT_FAILURE + if(target.item_heal(user, brute_heal = 15, burn_heal = 15, heal_message_brute = "splintering", heal_message_burn = "charring", required_bodytype = BODYTYPE_PEG)) + use(1) + return ITEM_INTERACT_SUCCESS + else + return NONE /* * Bamboo */ diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index 0e9b9743a4593..b2b0109c04c88 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -160,7 +160,7 @@ if(!use_tool(attacked_humanoid, user, use_delay, volume=50, amount=1)) return ITEM_INTERACT_BLOCKING - item_heal_robotic(attacked_humanoid, user, 15, 0) + attacked_humanoid.item_heal(user, brute_heal = 15, burn_heal = 0, heal_message_brute = "dents", heal_message_burn = "burnt wires", required_bodytype = BODYTYPE_ROBOTIC) return ITEM_INTERACT_SUCCESS /obj/item/weldingtool/afterattack(atom/target, mob/user, click_parameters) diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index da2c057d740bb..e588485aedc75 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -360,3 +360,30 @@ var/damage = ((min_damage / 4) + (max_damage / 4)) / 2 // We expect you to have 4 functional limbs- if you have fewer you're probably not going to be so good at lifting return ceil(damage * (ceil(athletics_level / 2)) * fitness_modifier * maxHealth) + +/mob/living/carbon/human/proc/item_heal(mob/user, brute_heal, burn_heal, heal_message_brute, heal_message_burn, required_bodytype) + var/obj/item/bodypart/affecting = src.get_bodypart(check_zone(user.zone_selected)) + if (!affecting || !(affecting.bodytype == required_bodytype)) + to_chat(user, span_warning("[affecting] is already in good condition!")) + return FALSE + + var/brute_damaged = affecting.brute_dam > 0 + var/burn_damaged = affecting.burn_dam > 0 + + var/nothing_to_heal = ((brute_heal <= 0 || !brute_damaged) && (burn_heal <= 0 || !burn_damaged)) + if (nothing_to_heal) + to_chat(user, span_notice("[affecting] is already in good condition!")) + return FALSE + + src.update_damage_overlays() + var/message + if ((brute_damaged && brute_heal > 0) && (burn_damaged && burn_heal > 0)) + message = "[heal_message_brute] and [heal_message_burn] on" + else if (brute_damaged && brute_heal > 0) + message = "[heal_message_brute] on" + else + message = "[heal_message_burn] on" + affecting.heal_damage(brute_heal, burn_heal, required_bodytype) + user.visible_message(span_notice("[user] fixes some of the [message] [src]'s [affecting.name]."), \ + span_notice("You fix some of the [message] [src == user ? "your" : "[src]'s"] [affecting.name].")) + return TRUE diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 9092efac428ca..a6a1c58c7eddf 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -331,19 +331,6 @@ toast.name = header toast.target_ref = WEAKREF(source) -/// Heals a robotic limb on a mob -/proc/item_heal_robotic(mob/living/carbon/human/human, mob/user, brute_heal, burn_heal) - var/obj/item/bodypart/affecting = human.get_bodypart(check_zone(user.zone_selected)) - if(!affecting || IS_ORGANIC_LIMB(affecting)) - to_chat(user, span_warning("[affecting] is already in good condition!")) - return FALSE - var/brute_damage = brute_heal > burn_heal //changes repair text based on how much brute/burn was supplied - if((brute_heal > 0 && affecting.brute_dam > 0) || (burn_heal > 0 && affecting.burn_dam > 0)) - if(affecting.heal_damage(brute_heal, burn_heal, required_bodytype = BODYTYPE_ROBOTIC)) - human.update_damage_overlays() - user.visible_message(span_notice("[user] fixes some of the [brute_damage ? "dents on" : "burnt wires in"] [human]'s [affecting.name]."), \ - span_notice("You fix some of the [brute_damage ? "dents on" : "burnt wires in"] [human == user ? "your" : "[human]'s"] [affecting.name].")) - return TRUE //successful heal ///Is the passed in mob a ghost with admin powers, doesn't check for AI interact like isAdminGhost() used to diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index e55442f31fd1f..a8e20cde8c7a0 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -575,7 +575,7 @@ GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list(/obj/structure/gri user.visible_message(span_notice("[user] starts to fix some of the wires in [H]'s [affecting.name]."), span_notice("You start fixing some of the wires in [H == user ? "your" : "[H]'s"] [affecting.name].")) if(!do_after(user, 5 SECONDS, H)) return - if(item_heal_robotic(H, user, 0, 15)) + if(H.item_heal(user, 0, 15, "dents", "burnt wires", BODYTYPE_ROBOTIC)) use(1) return else diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index 318926465ae08..c03a930395ab9 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -362,7 +362,7 @@ if(ishuman(victim)) var/mob/living/carbon/human/human_victim = victim - if(HAS_TRAIT(victim, TRAIT_LIMBATTACHMENT)) + if(HAS_TRAIT(victim, TRAIT_LIMBATTACHMENT) || HAS_TRAIT(src, TRAIT_EASY_ATTACH)) if(!human_victim.get_bodypart(body_zone)) user.temporarilyRemoveItemFromInventory(src, TRUE) if(!try_attach_limb(victim)) diff --git a/code/modules/surgery/bodyparts/ghetto_parts.dm b/code/modules/surgery/bodyparts/ghetto_parts.dm new file mode 100644 index 0000000000000..36c0310dead76 --- /dev/null +++ b/code/modules/surgery/bodyparts/ghetto_parts.dm @@ -0,0 +1,79 @@ +/obj/item/bodypart/arm/left/ghetto + name = "left peg arm" + desc = "A roughly hewn wooden peg replaces where a forearm should be. It's simple and sturdy, clearly made in a hurry with whatever materials were at hand. Despite its crude appearance, it gets the job done." + icon = 'icons/mob/human/species/ghetto.dmi' + icon_static = 'icons/mob/human/species/ghetto.dmi' + limb_id = BODYPART_ID_PEG + icon_state = "peg_l_arm" + bodytype = BODYTYPE_PEG + should_draw_greyscale = FALSE + attack_verb_simple = list("bashed", "slashed") + unarmed_damage_low = 3 + unarmed_damage_high = 9 + unarmed_effectiveness = 5 + brute_modifier = 1.2 + burn_modifier = 1.5 + bodypart_traits = list(TRAIT_CHUNKYFINGERS) + +/obj/item/bodypart/arm/left/ghetto/Initialize(mapload, ...) + . = ..() + ADD_TRAIT(src, TRAIT_EASY_ATTACH, INNATE_TRAIT) + +/obj/item/bodypart/arm/right/ghetto + name = "right peg arm" + desc = "A roughly hewn wooden peg replaces where a forearm should be. It's simple and sturdy, clearly made in a hurry with whatever materials were at hand. Despite its crude appearance, it gets the job done." + icon = 'icons/mob/human/species/ghetto.dmi' + icon_static = 'icons/mob/human/species/ghetto.dmi' + limb_id = BODYPART_ID_PEG + icon_state = "peg_r_arm" + bodytype = BODYTYPE_PEG + should_draw_greyscale = FALSE + attack_verb_simple = list("bashed", "slashed") + unarmed_damage_low = 3 + unarmed_damage_high = 9 + unarmed_effectiveness = 5 + brute_modifier = 1.2 + burn_modifier = 1.5 + bodypart_traits = list(TRAIT_CHUNKYFINGERS) + +/obj/item/bodypart/arm/right/ghetto/Initialize(mapload, ...) + . = ..() + ADD_TRAIT(src, TRAIT_EASY_ATTACH, INNATE_TRAIT) + +/obj/item/bodypart/leg/left/ghetto + name = "left peg leg" + desc = "Fashioned from what looks suspiciously like a table leg, this peg leg brings a whole new meaning to 'dining on the go.' It's a bit wobbly and creaks ominously with every step, but at least you can claim to have the most well-balanced diet on the seven seas." + icon = 'icons/mob/human/species/ghetto.dmi' + icon_static = 'icons/mob/human/species/ghetto.dmi' + limb_id = BODYPART_ID_PEG + icon_state = "peg_l_leg" + bodytype = BODYTYPE_PEG + should_draw_greyscale = FALSE + unarmed_damage_low = 2 + unarmed_damage_high = 5 + unarmed_effectiveness = 10 + brute_modifier = 1.2 + burn_modifier = 1.5 + +/obj/item/bodypart/leg/left/ghetto/Initialize(mapload, ...) + . = ..() + ADD_TRAIT(src, TRAIT_EASY_ATTACH, INNATE_TRAIT) + +/obj/item/bodypart/leg/right/ghetto + name = "right peg leg" + desc = "Fashioned from what looks suspiciously like a table leg, this peg leg brings a whole new meaning to 'dining on the go.' It's a bit wobbly and creaks ominously with every step, but at least you can claim to have the most well-balanced diet on the seven seas." + icon = 'icons/mob/human/species/ghetto.dmi' + icon_static = 'icons/mob/human/species/ghetto.dmi' + limb_id = BODYPART_ID_PEG + icon_state = "peg_r_leg" + bodytype = BODYTYPE_PEG + should_draw_greyscale = FALSE + unarmed_damage_low = 2 + unarmed_damage_high = 5 + unarmed_effectiveness = 10 + brute_modifier = 1.2 + burn_modifier = 1.5 + +/obj/item/bodypart/leg/right/ghetto/Initialize(mapload, ...) + . = ..() + ADD_TRAIT(src, TRAIT_EASY_ATTACH, INNATE_TRAIT) diff --git a/icons/mob/human/bodyparts.dmi b/icons/mob/human/bodyparts.dmi index d6e4472973a328fa22250471a71c9a647190085b..78be880423c1ea7988b9dc3b75a7af1bac9e0466 100644 GIT binary patch delta 12912 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 XFXAXf=`Z|{_)|sc@qMI%`MduC@WUfP delta 12180 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�fqUNnXh9ly#3Cj7i^pk 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 literal 0 HcmV?d00001 diff --git a/tgstation.dme b/tgstation.dme index dd55b451101ef..b6ddcc5e20956 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -5879,6 +5879,7 @@ #include "code\modules\surgery\advanced\bioware\vein_threading.dm" #include "code\modules\surgery\bodyparts\_bodyparts.dm" #include "code\modules\surgery\bodyparts\dismemberment.dm" +#include "code\modules\surgery\bodyparts\ghetto_parts.dm" #include "code\modules\surgery\bodyparts\head.dm" #include "code\modules\surgery\bodyparts\head_hair_and_lips.dm" #include "code\modules\surgery\bodyparts\helpers.dm" From 0b799f837585ee7144068debe976e6824a40fb68 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Mon, 17 Jun 2024 00:35:08 +0000 Subject: [PATCH 006/172] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-83840.yml | 4 ---- html/changelogs/AutoChangeLog-pr-83895.yml | 6 ------ html/changelogs/AutoChangeLog-pr-83949.yml | 4 ---- html/changelogs/AutoChangeLog-pr-83953.yml | 4 ---- html/changelogs/archive/2024-06.yml | 11 +++++++++++ 5 files changed, 11 insertions(+), 18 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-83840.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83895.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83949.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83953.yml diff --git a/html/changelogs/AutoChangeLog-pr-83840.yml b/html/changelogs/AutoChangeLog-pr-83840.yml deleted file mode 100644 index 5d879aece5df2..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83840.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "TheBoondock" -delete-after: True -changes: - - sound: "added compressed air sound for when air tanks are inserted into machinery" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83895.yml b/html/changelogs/AutoChangeLog-pr-83895.yml deleted file mode 100644 index 6b66da81feef3..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83895.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "Hacks-The-Doors" -delete-after: True -changes: - - balance: "dental pills can now be used in crit." - - balance: "dental pills now give off a message when you start using them" - - balance: "dental pills have a 2.5 second delay when in soft crit" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83949.yml b/html/changelogs/AutoChangeLog-pr-83949.yml deleted file mode 100644 index 62584dcc7c0fc..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83949.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "grungussuss" -delete-after: True -changes: - - rscadd: "Added Misha the bear to the HoS office on icebox." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83953.yml b/html/changelogs/AutoChangeLog-pr-83953.yml deleted file mode 100644 index fe5f444909fe3..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83953.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "JackEnoff" -delete-after: True -changes: - - balance: "Certain changeling abilities won't work while on fire." \ No newline at end of file diff --git a/html/changelogs/archive/2024-06.yml b/html/changelogs/archive/2024-06.yml index c0da4690e635b..f3c26e8d5e75a 100644 --- a/html/changelogs/archive/2024-06.yml +++ b/html/changelogs/archive/2024-06.yml @@ -742,3 +742,14 @@ carlarctg: - bugfix: Cosmos spells will no longer star mark your steed - qol: Baby plushies are now smaller than their parents +2024-06-17: + Hacks-The-Doors: + - balance: dental pills can now be used in crit. + - balance: dental pills now give off a message when you start using them + - balance: dental pills have a 2.5 second delay when in soft crit + JackEnoff: + - balance: Certain changeling abilities won't work while on fire. + TheBoondock: + - sound: added compressed air sound for when air tanks are inserted into machinery + grungussuss: + - rscadd: Added Misha the bear to the HoS office on icebox. From a836be707d3a969d7e1e4b049cc0a02e687d61a8 Mon Sep 17 00:00:00 2001 From: jimmyl <70376633+mc-oofert@users.noreply.github.com> Date: Mon, 17 Jun 2024 06:14:51 +0200 Subject: [PATCH 007/172] fixes two harddels (#84019) ## About The Pull Request build mode and space dragons should stop harddeling on destroy ## Why It's Good For The Game harddelete = bad ## Changelog :cl: fix: build mode and space dragons dont harddel on destroy /:cl: --- code/modules/buildmode/buildmode.dm | 2 ++ .../living/basic/space_fauna/space_dragon/space_dragon.dm | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/code/modules/buildmode/buildmode.dm b/code/modules/buildmode/buildmode.dm index 36a3db07f597e..80f5ae1ad27b0 100644 --- a/code/modules/buildmode/buildmode.dm +++ b/code/modules/buildmode/buildmode.dm @@ -50,6 +50,8 @@ holder.player_details.post_login_callbacks -= li_cb li_cb = null holder = null + modebutton = null + dirbutton = null QDEL_NULL(mode) QDEL_LIST(buttons) QDEL_LIST(modeswitch_buttons) diff --git a/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm b/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm index be31e121249a6..2286f65b79758 100644 --- a/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm +++ b/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm @@ -77,6 +77,11 @@ buffet = new(src) buffet.Grant(src) +/mob/living/basic/space_dragon/Destroy() + fire_breath = null + buffet = null + return ..() + /mob/living/basic/space_dragon/Login() . = ..() if(!isnull(chosen_colour)) From 91df95c76797444976fed2967cbf19ceefcfccc6 Mon Sep 17 00:00:00 2001 From: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Date: Sun, 16 Jun 2024 23:15:06 -0500 Subject: [PATCH 008/172] Fixes the other half of the crusher bug (#84028) ## About The Pull Request Fixes #83906 So when I test the first issue I just whacked the guy and the checked VV to see if it was tracking damage at all then I called it a day, turns out while it was applying damage it was actually negative damage from the crusher itself so while the final number of damage dealt may look like "2500" the tracker tracked like "1400". (I mean that's still a pretty interesting statistic is shows that the crusher itself, with none of its special effects, does just under 60% of the total damage dealt, so cool) ## Changelog :cl: Melbert fix: Crusher Fix For Real /:cl: --- code/datums/status_effects/neutral.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/status_effects/neutral.dm b/code/datums/status_effects/neutral.dm index c9e94e0dd97f5..3d4bd7e93655c 100644 --- a/code/datums/status_effects/neutral.dm +++ b/code/datums/status_effects/neutral.dm @@ -31,7 +31,7 @@ SIGNAL_HANDLER if(istype(attacking_item, /obj/item/kinetic_crusher)) - total_damage += damage_dealt + total_damage += (-1 * damage_dealt) /datum/status_effect/syphon_mark id = "syphon_mark" From 4c8351b32f031f1d285d6ec1fad5d2b0a8525973 Mon Sep 17 00:00:00 2001 From: GoblinBackwards <22856555+GoblinBackwards@users.noreply.github.com> Date: Mon, 17 Jun 2024 05:16:34 +0100 Subject: [PATCH 009/172] Fixes mulebots being able to run over players leaning on walls (#84020) ## About The Pull Request Mulebot was running over anyone who was on the same tile as it when it moved without checking if they were actually lying down, which meant they could run over people who were leaning against a wall. ## Why It's Good For The Game Fixes #84015 ## Changelog :cl: fix: Fixed mulebots being able to run over people who are leaning against a wall. /:cl: --- code/modules/mob/living/simple_animal/bot/mulebot.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 51b2f3954973d..7a205da5c089f 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -486,7 +486,8 @@ . = ..() if(has_gravity()) for(var/mob/living/carbon/human/future_pancake in loc) - run_over(future_pancake) + if(future_pancake.body_position == LYING_DOWN) + run_over(future_pancake) diag_hud_set_mulebotcell() From 9ddaa878cccba92e800d4c1117c6d7d186a5bb95 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Mon, 17 Jun 2024 16:20:31 +1200 Subject: [PATCH 010/172] Automatic changelog for PR #84019 [ci skip] --- html/changelogs/AutoChangeLog-pr-84019.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84019.yml diff --git a/html/changelogs/AutoChangeLog-pr-84019.yml b/html/changelogs/AutoChangeLog-pr-84019.yml new file mode 100644 index 0000000000000..63877aba2d051 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84019.yml @@ -0,0 +1,4 @@ +author: "mc-oofert" +delete-after: True +changes: + - bugfix: "build mode and space dragons dont harddel on destroy" \ No newline at end of file From a6a61e9e52cfec7050fe56dc95a4129e304d1517 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Mon, 17 Jun 2024 16:20:33 +1200 Subject: [PATCH 011/172] Automatic changelog for PR #84028 [ci skip] --- html/changelogs/AutoChangeLog-pr-84028.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84028.yml diff --git a/html/changelogs/AutoChangeLog-pr-84028.yml b/html/changelogs/AutoChangeLog-pr-84028.yml new file mode 100644 index 0000000000000..b21a26a8ddfde --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84028.yml @@ -0,0 +1,4 @@ +author: "Melbert" +delete-after: True +changes: + - bugfix: "Crusher Fix For Real" \ No newline at end of file From d55b792f035d6e10828e0aacb10a192d4e14e87a Mon Sep 17 00:00:00 2001 From: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Date: Sun, 16 Jun 2024 23:20:39 -0500 Subject: [PATCH 012/172] Examine block'd armor readout (#83992) ## About The Pull Request ![image](https://github.com/tgstation/tgstation/assets/51863163/ec8dab27-7ffc-44d2-b731-f808aac80e11) ## Why It's Good For The Game Way more readable ## Changelog :cl: Melbert qol: Block'd out armor readout, should be more readable now /:cl: --------- Co-authored-by: san7890 --- code/modules/clothing/clothing.dm | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index cd32002d0434b..98184b3fce25e 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -360,7 +360,7 @@ . = ..() if(href_list["list_armor"]) - var/list/readout = list("PROTECTION CLASSES") + var/list/readout = list() var/datum/armor/armor = get_armor() var/added_damage_header = FALSE @@ -369,9 +369,9 @@ if(!rating) continue if(!added_damage_header) - readout += "\nARMOR (I-X)" + readout += "ARMOR (I-X)" added_damage_header = TRUE - readout += "\n[armor_to_protection_name(damage_key)] [armor_to_protection_class(rating)]" + readout += "[armor_to_protection_name(damage_key)] [armor_to_protection_class(rating)]" var/added_durability_header = FALSE for(var/durability_key in ARMOR_LIST_DURABILITY()) @@ -379,9 +379,9 @@ if(!rating) continue if(!added_durability_header) - readout += "\nDURABILITY (I-X)" + readout += "DURABILITY (I-X)" added_damage_header = TRUE - readout += "\n[armor_to_protection_name(durability_key)] [armor_to_protection_class(rating)]" + readout += "[armor_to_protection_name(durability_key)] [armor_to_protection_class(rating)]" if(flags_cover & HEADCOVERSMOUTH || flags_cover & PEPPERPROOF) var/list/things_blocked = list() @@ -390,12 +390,15 @@ if(flags_cover & PEPPERPROOF) things_blocked += "pepperspray" if(length(things_blocked)) - readout += "\nCOVERAGE" - readout += "\nIt will block [english_list(things_blocked)]." + readout += "COVERAGE" + readout += "It will block [english_list(things_blocked)]." - readout += "" - to_chat(usr, "[readout.Join()]") + if(!length(readout)) + readout += "No armor or durability information available." + + var/formatted_readout = span_notice("PROTECTION CLASSES
[jointext(readout, "\n")]") + to_chat(usr, examine_block(formatted_readout)) /** * Rounds armor_value down to the nearest 10, divides it by 10 and then converts it to Roman numerals. From 4dd109909da3ce2783a0d4cb123ec6b9699def1e Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Mon, 17 Jun 2024 16:20:50 +1200 Subject: [PATCH 013/172] Automatic changelog for PR #84020 [ci skip] --- html/changelogs/AutoChangeLog-pr-84020.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84020.yml diff --git a/html/changelogs/AutoChangeLog-pr-84020.yml b/html/changelogs/AutoChangeLog-pr-84020.yml new file mode 100644 index 0000000000000..e47971b005d60 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84020.yml @@ -0,0 +1,4 @@ +author: "GoblinBackwards" +delete-after: True +changes: + - bugfix: "Fixed mulebots being able to run over people who are leaning against a wall." \ No newline at end of file From 665c55921662ebdc49577f01eb3240c436229085 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Mon, 17 Jun 2024 16:21:24 +1200 Subject: [PATCH 014/172] Automatic changelog for PR #83992 [ci skip] --- html/changelogs/AutoChangeLog-pr-83992.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83992.yml diff --git a/html/changelogs/AutoChangeLog-pr-83992.yml b/html/changelogs/AutoChangeLog-pr-83992.yml new file mode 100644 index 0000000000000..7a8e7408d3413 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83992.yml @@ -0,0 +1,4 @@ +author: "Melbert" +delete-after: True +changes: + - qol: "Block'd out armor readout, should be more readable now" \ No newline at end of file From 5349a86bb241785ccff430b2f25b14c3575c5a6f Mon Sep 17 00:00:00 2001 From: TheRyeGuyWhoWillNowDie <70169560+TheRyeGuyWhoWillNowDie@users.noreply.github.com> Date: Mon, 17 Jun 2024 00:22:01 -0400 Subject: [PATCH 015/172] adds a confirmation to malf AI shunting (#83965) ## About The Pull Request lol ## Why It's Good For The Game people's rounds shouldn't be ruined from misclicking the button that's right next to the "progress as an antagonist" button ## Changelog :cl: qol: adds a confirmation to malf AI shunting into APCs /:cl: --- code/modules/power/apc/apc_malf.dm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/modules/power/apc/apc_malf.dm b/code/modules/power/apc/apc_malf.dm index f4c27e15a4067..1419e12c46be3 100644 --- a/code/modules/power/apc/apc_malf.dm +++ b/code/modules/power/apc/apc_malf.dm @@ -36,6 +36,12 @@ return if(!is_station_level(z)) return + INVOKE_ASYNC(src, PROC_REF(malfshunt), malf) + +/obj/machinery/power/apc/proc/malfshunt(mob/living/silicon/ai/malf) + var/confirm = tgui_alert(malf, "Are you sure that you want to shunt? This will take you out of your core!", "Shunt to [name]?", list("Yes", "No")) + if(confirm != "Yes") + return malf.ShutOffDoomsdayDevice() occupier = malf if (isturf(malf.loc)) // create a deactivated AI core if the AI isn't coming from an emergency mech shunt From b7c0f3a991a03a1bb8429619bbfd99c1e6b0c089 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Mon, 17 Jun 2024 16:22:34 +1200 Subject: [PATCH 016/172] Automatic changelog for PR #83965 [ci skip] --- html/changelogs/AutoChangeLog-pr-83965.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83965.yml diff --git a/html/changelogs/AutoChangeLog-pr-83965.yml b/html/changelogs/AutoChangeLog-pr-83965.yml new file mode 100644 index 0000000000000..cc18775056e22 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83965.yml @@ -0,0 +1,4 @@ +author: "TheRyeGuyWhoWillNowDie" +delete-after: True +changes: + - qol: "adds a confirmation to malf AI shunting into APCs" \ No newline at end of file From c60556217e29a70eab7478afef0ab9efd1f2aa62 Mon Sep 17 00:00:00 2001 From: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Date: Mon, 17 Jun 2024 09:53:42 +0530 Subject: [PATCH 017/172] [NO GBP] Admin ctrl+shift works only on the clicked ghost (#84005) ## About The Pull Request - Fixes #83995 ## Changelog :cl: fix: ctrl+shift clicking on a ghost will only quick spawn that clicked target and not you /:cl: --- code/modules/mob/dead/observer/observer.dm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 556a959e4f8eb..3c02de4707317 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -984,8 +984,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp game.ui_interact(usr) /mob/dead/observer/CtrlShiftClickOn(atom/target) - if(check_rights(R_SPAWN)) - change_mob_type(/mob/living/carbon/human , null, null, TRUE) //always delmob, ghosts shouldn't be left lingering + if(isobserver(target) && check_rights(R_SPAWN)) + var/mob/dead/observer/target_ghost = target + + target_ghost.change_mob_type(/mob/living/carbon/human , null, null, TRUE) //always delmob, ghosts shouldn't be left lingering /mob/dead/observer/examine(mob/user) . = ..() From 09325d9f2c3d3cec88ea961d271e7f1a976d90af Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Mon, 17 Jun 2024 16:24:09 +1200 Subject: [PATCH 018/172] Automatic changelog for PR #84005 [ci skip] --- html/changelogs/AutoChangeLog-pr-84005.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84005.yml diff --git a/html/changelogs/AutoChangeLog-pr-84005.yml b/html/changelogs/AutoChangeLog-pr-84005.yml new file mode 100644 index 0000000000000..29deb18988bd8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84005.yml @@ -0,0 +1,4 @@ +author: "SyncIt21" +delete-after: True +changes: + - bugfix: "ctrl+shift clicking on a ghost will only quick spawn that clicked target and not you" \ No newline at end of file From 2ca366ce2272ad347c4c1b9509bd14b101df3690 Mon Sep 17 00:00:00 2001 From: Lucy Grindler <110352801+LucyGrind@users.noreply.github.com> Date: Sun, 16 Jun 2024 21:29:31 -0700 Subject: [PATCH 019/172] Fixes Ghetto Grinding Cigarettes (#84032) ## About The Pull Request fixes #83947 allowing cigarettes to be grinded in mortars again ## Why It's Good For The Game Need muh nic sippy cup for my orny child (fixing bugs is good for game health, duh) ## Changelog :cl: fix: allows cigarette grinding in mortar /:cl: --- code/game/objects/items/cigs_lighters.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index 174a8fde5f7c2..6ca951d262a67 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -282,7 +282,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/obj/item/reagent_containers/cup/glass = interacting_with if(!istype(glass)) //you can dip cigarettes into beakers return NONE - + if(istype(glass, /obj/item/reagent_containers/cup/mortar)) + return NONE if(glass.reagents.trans_to(src, chem_volume, transferred_by = user)) //if reagents were transferred, show the message to_chat(user, span_notice("You dip \the [src] into \the [glass].")) //if not, either the beaker was empty, or the cigarette was full From af86359446e509e0b1adf99fde1e0d7e1d6ce52a Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Mon, 17 Jun 2024 16:30:54 +1200 Subject: [PATCH 020/172] Automatic changelog for PR #84032 [ci skip] --- html/changelogs/AutoChangeLog-pr-84032.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84032.yml diff --git a/html/changelogs/AutoChangeLog-pr-84032.yml b/html/changelogs/AutoChangeLog-pr-84032.yml new file mode 100644 index 0000000000000..57e6705027013 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84032.yml @@ -0,0 +1,4 @@ +author: "LucyGrind" +delete-after: True +changes: + - bugfix: "allows cigarette grinding in mortar" \ No newline at end of file From 7bd966b4cb55447caee3ec9074bf2ffdc37c6683 Mon Sep 17 00:00:00 2001 From: Goat <126099705+Goat-Real@users.noreply.github.com> Date: Sun, 16 Jun 2024 22:42:36 -0600 Subject: [PATCH 021/172] Allows fire extinguishers to refill from plumbed tanks (#84004) ## About The Pull Request Changes `tanktype` to be a list and `AttemptRefill` to properly check for a list. Also adds a `has_reagent` check to `AttemptRefill` to prevent people from converting a fuel tank to plumbed to refill a fire extinguisher with welding fuel. ## Why It's Good For The Game People be allowed to refill fire extinguishers from the plumbed variant of tanks. Also I thought it would be funny if we could refill extinguishers from water coolers. fix: #68174 ## Changelog :cl: Goat qol: fire extinguishers can now be filled via stationary tanks. (and water coolers) /:cl: --- code/game/objects/items/extinguisher.dm | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/code/game/objects/items/extinguisher.dm b/code/game/objects/items/extinguisher.dm index be47d7009053b..ac309e275d77c 100644 --- a/code/game/objects/items/extinguisher.dm +++ b/code/game/objects/items/extinguisher.dm @@ -32,7 +32,11 @@ /// Can we refill this at a water tank? var/refilling = FALSE /// What tank we need to refill this. - var/tanktype = /obj/structure/reagent_dispensers/watertank + var/tanktypes = list( + /obj/structure/reagent_dispensers/watertank, + /obj/structure/reagent_dispensers/plumbed, + /obj/structure/reagent_dispensers/water_cooler, + ) /// something that should be replaced with base_icon_state var/sprite_name = "fire_extinguisher" /// Maximum distance launched water will travel. @@ -131,7 +135,10 @@ tank_holder_icon_state = "holder_foam_extinguisher" dog_fashion = null chem = /datum/reagent/firefighting_foam - tanktype = /obj/structure/reagent_dispensers/foamtank + tanktypes = list( + /obj/structure/reagent_dispensers/foamtank, + /obj/structure/reagent_dispensers/plumbed, + ) sprite_name = "foam_extinguisher" precision = TRUE max_water = 100 @@ -178,10 +185,14 @@ . += span_notice("Alt-click to empty it.") /obj/item/extinguisher/proc/AttemptRefill(atom/target, mob/user) - if(istype(target, tanktype) && target.Adjacent(user)) + if(is_type_in_list(target, tanktypes) && target.Adjacent(user)) if(reagents.total_volume == reagents.maximum_volume) balloon_alert(user, "already full!") return TRUE + // Make sure we're refilling with the proper chem. + if(!(target.reagents.has_reagent(chem))) + balloon_alert(user, "can't refill with this liquid!") + return TRUE var/obj/structure/reagent_dispensers/W = target //will it work? var/transferred = W.reagents.trans_to(src, max_water, transferred_by = user) if(transferred > 0) @@ -305,5 +316,8 @@ name = "fire extender" desc = "A traditional red fire extinguisher. Made in Britain... wait, what?" chem = /datum/reagent/fuel - tanktype = /obj/structure/reagent_dispensers/fueltank + tanktypes = list( + /obj/structure/reagent_dispensers/fueltank, + /obj/structure/reagent_dispensers/plumbed + ) cooling_power = 0 From db8e42dffa865ced524ce5250671dc006c92d1f0 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Mon, 17 Jun 2024 16:42:56 +1200 Subject: [PATCH 022/172] Automatic changelog for PR #84004 [ci skip] --- html/changelogs/AutoChangeLog-pr-84004.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84004.yml diff --git a/html/changelogs/AutoChangeLog-pr-84004.yml b/html/changelogs/AutoChangeLog-pr-84004.yml new file mode 100644 index 0000000000000..7c8855699fa8d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84004.yml @@ -0,0 +1,4 @@ +author: "Goat" +delete-after: True +changes: + - qol: "fire extinguishers can now be filled via stationary tanks. (and water coolers)" \ No newline at end of file From d1d593e516a2afbe55df7e86da5fcc9f4cb06991 Mon Sep 17 00:00:00 2001 From: GoblinBackwards <22856555+GoblinBackwards@users.noreply.github.com> Date: Mon, 17 Jun 2024 05:45:18 +0100 Subject: [PATCH 023/172] Fixes reactive armour not recognising anomaly subtypes (#84012) ## About The Pull Request Fixes reactive armour only not recognising subtypes of anomalies, which was making them become stealth instead of repulse armour when a core from a high intensity grav anomaly was used. ## Why It's Good For The Game Fixes #83712 ## Changelog :cl: fix: Fixed anomaly cores from the high-intensity grav anomaly event creating the wrong type of reactive armour. /:cl: --- code/modules/clothing/suits/reactive_armour.dm | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/code/modules/clothing/suits/reactive_armour.dm b/code/modules/clothing/suits/reactive_armour.dm index 155e4dbe42fb6..c1889cc77383d 100644 --- a/code/modules/clothing/suits/reactive_armour.dm +++ b/code/modules/clothing/suits/reactive_armour.dm @@ -5,8 +5,8 @@ icon = 'icons/obj/clothing/suits/armor.dmi' w_class = WEIGHT_CLASS_BULKY -/obj/item/reactive_armor_shell/attackby(obj/item/weapon, mob/user, params) - ..() +/obj/item/reactive_armor_shell/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + . = ..() var/static/list/anomaly_armour_types = list( /obj/effect/anomaly/grav = /obj/item/clothing/suit/armor/reactive/repulse, /obj/effect/anomaly/flux = /obj/item/clothing/suit/armor/reactive/tesla, @@ -17,15 +17,16 @@ /obj/effect/anomaly/ectoplasm = /obj/item/clothing/suit/armor/reactive/ectoplasm, ) - if(istype(weapon, /obj/item/assembly/signaler/anomaly)) - var/obj/item/assembly/signaler/anomaly/anomaly = weapon - var/armour_path = anomaly_armour_types[anomaly.anomaly_type] + if(istype(tool, /obj/item/assembly/signaler/anomaly)) + var/obj/item/assembly/signaler/anomaly/anomaly = tool + var/armour_path = is_path_in_list(anomaly.anomaly_type, anomaly_armour_types, TRUE) if(!armour_path) armour_path = /obj/item/clothing/suit/armor/reactive/stealth //Lets not cheat the player if an anomaly type doesnt have its own armour coded to_chat(user, span_notice("You insert [anomaly] into the chest plate, and the armour gently hums to life.")) new armour_path(get_turf(src)) qdel(src) qdel(anomaly) + return ITEM_INTERACT_SUCCESS //Reactive armor /obj/item/clothing/suit/armor/reactive From d3817d46cb7c92b54a95ba338f61a8d650b34355 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Mon, 17 Jun 2024 16:45:39 +1200 Subject: [PATCH 024/172] Automatic changelog for PR #84012 [ci skip] --- html/changelogs/AutoChangeLog-pr-84012.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84012.yml diff --git a/html/changelogs/AutoChangeLog-pr-84012.yml b/html/changelogs/AutoChangeLog-pr-84012.yml new file mode 100644 index 0000000000000..97e81c2ad7706 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84012.yml @@ -0,0 +1,4 @@ +author: "GoblinBackwards" +delete-after: True +changes: + - bugfix: "Fixed anomaly cores from the high-intensity grav anomaly event creating the wrong type of reactive armour." \ No newline at end of file From 8298576c469fab6d3597d59541079e229f170230 Mon Sep 17 00:00:00 2001 From: Joshua Kidder <49173900+Metekillot@users.noreply.github.com> Date: Mon, 17 Jun 2024 07:04:23 -0400 Subject: [PATCH 025/172] Fixes free chemsplosion reagent purging by replacing it with the same thing but dangerous (#83195) ## About The Pull Request https://github.com/tgstation/tgstation/pull/83168 From the above, it became clear to me that the penthrite combinations were likely never going to happen, because that requires the cooperation of miners, who are a notoriously fickle and treasure hungry lot. So instead, I reworked the methods that you can purge with reagent explosions. If you pair an explosion of at least 1 power in someone's bloodstream with omnizine and any of the purging reagents, it purges the chems from their blood. So omnizine, calomel, and 20u each of potassium and water will purge their blood in exchange for a hefty bit of damage and some slight delimbing. Penthrite + atropine and penthrite + epinephrine explosions will still clear your blood, too. I kept that in to prevent miner penstacking and, if somehow medbay gets hold of the chem combinations, for simple chemsplosion blood purging. You can also force people to vomit by causing an explosion of at least 1 power in their stomach, but that only purges everything in their stomach. This interaction doesn't require omnizine and a purging reagent. ## Why It's Good For The Game Chemsplosion purging in its current state is a longstanding bug that's been left implemented because blood filtering is otherwise boring and takes a long time. This makes it exciting and very quick but it will also fucking kill somebody if you're not careful. ## Changelog Unilateral blood purging with pseudo explosions has been replaced with blood purging explosions via pairing a minimum explosive power of 1 with omnizine and a purging reagent. You can also purge blood with penthrite + epinephrine and penthrite + atropine, though the latter will very likely gib the purged person in question. :cl: Bisar balance: Replaced the free reagent purging with actually purging by exploding someone in the blood while they have omnizine and a purgative in their bloodstream. Let's go practice medicine! fix: Fixed the free reagent purging mechanic from causing an explosion so weak that it doesn't cause any damage. /:cl: --- code/modules/reagents/chemistry/recipes.dm | 27 ++++++++-- .../chemistry/recipes/pyrotechnics.dm | 50 +++++++++++++++++-- 2 files changed, 70 insertions(+), 7 deletions(-) diff --git a/code/modules/reagents/chemistry/recipes.dm b/code/modules/reagents/chemistry/recipes.dm index f7fc1b04ac8de..40305c9a8bc47 100644 --- a/code/modules/reagents/chemistry/recipes.dm +++ b/code/modules/reagents/chemistry/recipes.dm @@ -281,7 +281,7 @@ * * modifier - a flat additive numeric to the size of the explosion - set this if you want a minimum range * * strengthdiv - the divisional factor of the explosion, a larger number means a smaller range - This is the part that modifies an explosion's range with volume (i.e. it divides it by this number) */ -/datum/chemical_reaction/proc/default_explode(datum/reagents/holder, created_volume, modifier = 0, strengthdiv = 10) +/datum/chemical_reaction/proc/default_explode(datum/reagents/holder, created_volume, modifier = 0, strengthdiv = 10, clear_mob_reagents) var/power = modifier + round(created_volume/strengthdiv, 1) if(power > 0) var/turf/T = get_turf(holder.my_atom) @@ -300,8 +300,29 @@ var/datum/effect_system/reagents_explosion/e = new() e.set_up(power , T, 0, 0) e.start(holder.my_atom) - holder.clear_reagents() - + if (ismob(holder.my_atom)) + if(!clear_mob_reagents) + return + // Only clear reagents if they use a special explosive reaction to do it; it shouldn't apply + // to any explosion inside a person + holder.clear_reagents() + if(iscarbon(holder.my_atom)) + var/mob/living/carbon/victim = holder.my_atom + var/vomit_flags = MOB_VOMIT_MESSAGE | MOB_VOMIT_FORCE + // The vomiting here is for effect, not meant to help with purging + victim.vomit(vomit_flags, distance = 5) + // Not quite the same if the reaction is in their stomach; they'll throw up + // from any explosion, but it'll only make them puke up everything in their + // stomach + else if (istype(holder.my_atom, /obj/item/organ/internal/stomach)) + var/obj/item/organ/internal/stomach/indigestion = holder.my_atom + if(power < 1) + return + indigestion.owner?.vomit(MOB_VOMIT_MESSAGE | MOB_VOMIT_FORCE, lost_nutrition = 150, distance = 5, purge_ratio = 1) + holder.clear_reagents() + return + else + holder.clear_reagents() /* *Creates a flash effect only - less expensive than explode() * diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm index d190a44aea063..f02aaa3ab2473 100644 --- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm +++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm @@ -1,13 +1,48 @@ +#define PURGING_REAGENTS list( \ + /datum/reagent/medicine/c2/multiver, \ + /datum/reagent/medicine/pen_acid, \ + /datum/reagent/medicine/calomel, \ + /datum/reagent/medicine/ammoniated_mercury, \ + /datum/reagent/medicine/c2/syriniver, \ + /datum/reagent/medicine/c2/musiver \ +) + /datum/chemical_reaction/reagent_explosion var/strengthdiv = 10 var/modifier = 0 reaction_flags = REACTION_INSTANT reaction_tags = REACTION_TAG_EXPLOSIVE | REACTION_TAG_MODERATE | REACTION_TAG_DANGEROUS required_temp = 0 //Prevent impromptu RPGs - -/datum/chemical_reaction/reagent_explosion/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume) - default_explode(holder, created_volume, modifier, strengthdiv) - + // Only clear mob reagents in special cases + var/clear_mob_reagents = FALSE + +/datum/chemical_reaction/reagent_explosion/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume, clear_mob_reagents) + // If an explosive reaction clears mob reagents, it should always be a minimum power + if(ismob(holder.my_atom) && clear_mob_reagents) + if(round((created_volume / strengthdiv) + modifier, 1) < 1) + modifier += 1 - ((created_volume / strengthdiv) + modifier) + // If this particular explosion doesn't automatically clear mob reagents as an inherent quality, + // then we can still clear mob reagents with some mad science malpractice that shouldn't work but + // does because omnizine is magic and also it's the future or whatever + if(ismob(holder.my_atom) && !clear_mob_reagents) + // The explosion needs to be a minimum power to clear reagents: see above + var/purge_power = round((created_volume / strengthdiv) + modifier, 1) + if(purge_power >= 1) + var/has_purging_chemical = FALSE + // They need one of the purge reagents in them + for(var/purging_chem as anything in PURGING_REAGENTS) + if(holder.has_reagent(purging_chem)) + // We have a purging chemical + has_purging_chemical = TRUE + break + // Then we need omnizine! MAGIC! + var/has_omnizine = holder.has_reagent(/datum/reagent/medicine/omnizine) + if(has_purging_chemical && has_omnizine) + // With all this medical "science" combined, we can clear mob reagents + clear_mob_reagents = TRUE + default_explode(holder, created_volume, modifier, strengthdiv, clear_mob_reagents) + +#undef PURGING_REAGENTS /datum/chemical_reaction/reagent_explosion/nitroglycerin results = list(/datum/reagent/nitroglycerin = 2) required_reagents = list(/datum/reagent/glycerol = 1, /datum/reagent/toxin/acid/nitracid = 1, /datum/reagent/toxin/acid = 1) @@ -104,11 +139,18 @@ /datum/chemical_reaction/reagent_explosion/penthrite_explosion_epinephrine required_reagents = list(/datum/reagent/medicine/c2/penthrite = 1, /datum/reagent/medicine/epinephrine = 1) strengthdiv = 5 + // Penthrite is rare as hell, so this clears your reagents + // Will most likely be from miners accidentally penstacking + clear_mob_reagents = TRUE + /datum/chemical_reaction/reagent_explosion/penthrite_explosion_atropine required_reagents = list(/datum/reagent/medicine/c2/penthrite = 1, /datum/reagent/medicine/atropine = 1) strengthdiv = 5 modifier = 5 + // Rare reagents clear your reagents + // Probably not good for you because you'll need healing chems to survive this most likely + clear_mob_reagents = TRUE /datum/chemical_reaction/reagent_explosion/potassium_explosion required_reagents = list(/datum/reagent/water = 1, /datum/reagent/potassium = 1) From c218bdf7cb42809cdab8c18dde3665bcf441a848 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Mon, 17 Jun 2024 23:04:43 +1200 Subject: [PATCH 026/172] Automatic changelog for PR #83195 [ci skip] --- html/changelogs/AutoChangeLog-pr-83195.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83195.yml diff --git a/html/changelogs/AutoChangeLog-pr-83195.yml b/html/changelogs/AutoChangeLog-pr-83195.yml new file mode 100644 index 0000000000000..3b3a75919a4a9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83195.yml @@ -0,0 +1,5 @@ +author: "Bisar" +delete-after: True +changes: + - balance: "Replaced the free reagent purging with actually purging by exploding someone in the blood while they have omnizine and a purgative in their bloodstream. Let's go practice medicine!" + - bugfix: "Fixed the free reagent purging mechanic from causing an explosion so weak that it doesn't cause any damage." \ No newline at end of file From fa21f8edd4ff9a1e1c9a387fed3b87d4a528a690 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 17 Jun 2024 17:06:03 +0300 Subject: [PATCH 027/172] Slime transparency fix [NO GBP] (#84031) ## About The Pull Request I forgot to add transparency for the non-metallic slime subtypes. This PR fixes that. ![image](https://github.com/tgstation/tgstation/assets/3625094/82a3c04a-ad41-4446-9665-dab9d38b40fb) ## Why It's Good For The Game A mistake was made. ## Changelog :cl: fix: Non-metallic slime types are semi-transparent /:cl: --------- Co-authored-by: san7890 --- code/__DEFINES/research/slimes.dm | 3 +++ code/modules/mob/living/basic/slime/slime.dm | 2 ++ .../mob/living/basic/slime/slime_type.dm | 17 ++++++++++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/code/__DEFINES/research/slimes.dm b/code/__DEFINES/research/slimes.dm index f54248a21a3ac..e03c6af8f581d 100644 --- a/code/__DEFINES/research/slimes.dm +++ b/code/__DEFINES/research/slimes.dm @@ -61,3 +61,6 @@ #define SLIME_TYPE_SEPIA "sepia" #define SLIME_TYPE_SILVER "silver" #define SLIME_TYPE_YELLOW "yellow" + +// The alpha value of transperent slime types +#define SLIME_TRANSPARENCY_ALPHA 180 diff --git a/code/modules/mob/living/basic/slime/slime.dm b/code/modules/mob/living/basic/slime/slime.dm index 4864cb82016a7..fa40ac28d816d 100644 --- a/code/modules/mob/living/basic/slime/slime.dm +++ b/code/modules/mob/living/basic/slime/slime.dm @@ -187,6 +187,8 @@ /mob/living/basic/slime/regenerate_icons() cut_overlays() + if(slime_type.transparent) + alpha = SLIME_TRANSPARENCY_ALPHA var/icon_text = "[slime_type.colour]-[life_stage]" icon_dead = "[icon_text]-dead" if(stat != DEAD) diff --git a/code/modules/mob/living/basic/slime/slime_type.dm b/code/modules/mob/living/basic/slime/slime_type.dm index 11f3798804017..048f861eeb08a 100644 --- a/code/modules/mob/living/basic/slime/slime_type.dm +++ b/code/modules/mob/living/basic/slime/slime_type.dm @@ -1,6 +1,8 @@ /datum/slime_type ///Our slime's colour as text. Used by both description, and icon var/colour + ///Whether the slime icons should be semi-transparent + var/transparent = FALSE ///The type our slime spawns var/core_type ///The possible mutations of our slime @@ -12,6 +14,7 @@ /datum/slime_type/grey colour = SLIME_TYPE_GREY + transparent = TRUE core_type = /obj/item/slime_extract/grey mutations = list( /datum/slime_type/blue = 1, @@ -21,11 +24,11 @@ ) rgb_code = COLOR_SLIME_GREY - //TIER 1 /datum/slime_type/blue colour = SLIME_TYPE_BLUE + transparent = TRUE core_type = /obj/item/slime_extract/blue mutations = list( /datum/slime_type/darkblue = 1, @@ -46,6 +49,7 @@ /datum/slime_type/purple colour = SLIME_TYPE_PURPLE + transparent = TRUE core_type = /obj/item/slime_extract/purple mutations = list( /datum/slime_type/darkblue = 1, @@ -56,6 +60,7 @@ /datum/slime_type/orange colour = SLIME_TYPE_ORANGE + transparent = TRUE core_type = /obj/item/slime_extract/orange mutations = list( /datum/slime_type/darkpurple = 1, @@ -68,6 +73,7 @@ /datum/slime_type/darkblue colour = SLIME_TYPE_DARK_BLUE + transparent = TRUE core_type = /obj/item/slime_extract/darkblue mutations = list( /datum/slime_type/blue = 1, @@ -98,6 +104,7 @@ /datum/slime_type/yellow colour = SLIME_TYPE_YELLOW + transparent = TRUE core_type = /obj/item/slime_extract/yellow mutations = list( /datum/slime_type/bluespace = 2, @@ -119,6 +126,7 @@ /datum/slime_type/cerulean colour = SLIME_TYPE_CERULEAN + transparent = TRUE core_type = /obj/item/slime_extract/cerulean mutations = list( /datum/slime_type/cerulean = 1, @@ -135,6 +143,7 @@ /datum/slime_type/sepia colour = SLIME_TYPE_SEPIA + transparent = TRUE core_type = /obj/item/slime_extract/sepia mutations = list( /datum/slime_type/sepia = 1, @@ -154,6 +163,7 @@ /datum/slime_type/green colour = SLIME_TYPE_GREEN + transparent = TRUE core_type = /obj/item/slime_extract/green mutations = list( /datum/slime_type/black = 1, @@ -163,6 +173,7 @@ /datum/slime_type/pink colour = SLIME_TYPE_PINK + transparent = TRUE core_type = /obj/item/slime_extract/pink mutations = list( /datum/slime_type/lightpink = 1, @@ -172,6 +183,7 @@ /datum/slime_type/red colour = SLIME_TYPE_RED + transparent = TRUE core_type = /obj/item/slime_extract/red mutations = list( /datum/slime_type/oil = 1, @@ -191,6 +203,7 @@ /datum/slime_type/black colour = SLIME_TYPE_BLACK + transparent = TRUE core_type = /obj/item/slime_extract/black mutations = list( /datum/slime_type/black = 1, @@ -199,6 +212,7 @@ /datum/slime_type/lightpink colour = SLIME_TYPE_LIGHT_PINK + transparent = TRUE core_type = /obj/item/slime_extract/lightpink mutations = list( /datum/slime_type/lightpink = 1, @@ -217,6 +231,7 @@ /datum/slime_type/rainbow colour = SLIME_TYPE_RAINBOW + transparent = TRUE core_type = /obj/item/slime_extract/rainbow mutations = list( /datum/slime_type/rainbow = 1, From d18c22ce4eec8e1f75657fc2025cca07a18a9788 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Tue, 18 Jun 2024 02:06:32 +1200 Subject: [PATCH 028/172] Automatic changelog for PR #84031 [ci skip] --- html/changelogs/AutoChangeLog-pr-84031.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84031.yml diff --git a/html/changelogs/AutoChangeLog-pr-84031.yml b/html/changelogs/AutoChangeLog-pr-84031.yml new file mode 100644 index 0000000000000..9e4459a752e7f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84031.yml @@ -0,0 +1,4 @@ +author: "MTandi" +delete-after: True +changes: + - bugfix: "Non-metallic slime types are semi-transparent" \ No newline at end of file From 5f36ef1d6e1cc31c58ef42402fc2421909d17629 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 17 Jun 2024 20:21:48 +0300 Subject: [PATCH 029/172] New Tech Tree (#84024) ## About The Pull Request Reshuffles the tech tree nodes, adding reagent purity and cybernetic organ scan experiments. The total point requirements barely changed. Made the discount experiments unlock nodes for free, instead of providing partial discounts, to provide more incentive to actually do them. Also devided all points by the amount generated per second, for convenience. Now points correspond to seconds.
New tech tree Tech New
## Why It's Good For The Game - Breaks bloated general nodes into more specialized nodes, making the tree more balanced - Combines scattered nodes dedicated to a single design into specialized nodes, reducing the number of nodes - Reshuffles the unlocks within specialized tree to adjust progression on some trees to follow the idead: Cheap nodes first, then nodes that require experiments or nodes of neighbouring trees, then expensive nodes with end-game tech. - You no longer need a dissection experiment to unlock a microwave, every experiment is relevant to the tree unlocked by it - With specialized nodes, it is easier to pick a node for the new things that people add - Better foundation for potential per-department point system. It will be easier to put it on top of a cleaner tree - The nodes are separated in tiers, with progressively increasing costs, so that early tech is cheap and easy to research with just points, but later tech is more expensive, making the discount experiments for those more likely to be performed. ## Changelog :cl: balance: Reshuffled tech tree, making nodes more specialized qol: Research points devided by the amount generated per second, so now research points correspond to seconds add: Introduced reagent purity scan experiments (required for Cryostasis node) add: Introduced synthetic organ scan experiment (required for top tier cyber organs) add: Added a variant of machinery scan experiment that accepts any machines with upgraded parts (required for tier 3 parts) del: Removed material scanning experiments from the tech tree /:cl: --- code/__DEFINES/research.dm | 9 +- code/modules/bitrunning/designs.dm | 13 - .../experisci/experiment/experiments.dm | 89 +- .../experiment/types/scanning_people.dm | 6 +- .../experiment/types/scanning_reagent.dm | 35 + .../experiment/types/scanning_vatgrown.dm | 2 +- code/modules/research/techweb/all_nodes.dm | 2498 ----------------- .../research/techweb/nodes/alien_nodes.dm | 100 + .../research/techweb/nodes/atmos_nodes.dm | 114 + .../research/techweb/nodes/bepis_nodes.dm | 123 + .../research/techweb/nodes/biology_nodes.dm | 64 + .../research/techweb/nodes/circuit_nodes.dm | 151 + .../research/techweb/nodes/cyborg_nodes.dm | 231 ++ .../research/techweb/nodes/engi_nodes.dm | 232 ++ .../research/techweb/nodes/mech_nodes.dm | 251 ++ .../research/techweb/nodes/medbay_nodes.dm | 97 + .../research/techweb/nodes/mining_nodes.dm | 104 + .../research/techweb/nodes/modsuit_nodes.dm | 139 + .../research/techweb/nodes/research_nodes.dm | 94 + .../research/techweb/nodes/robo_nodes.dm | 97 + .../research/techweb/nodes/security_nodes.dm | 107 + .../research/techweb/nodes/service_nodes.dm | 236 ++ .../research/techweb/nodes/surgery_nodes.dm | 72 + .../research/techweb/nodes/syndicate_nodes.dm | 48 + tgstation.dme | 19 +- 25 files changed, 2412 insertions(+), 2519 deletions(-) create mode 100644 code/modules/experisci/experiment/types/scanning_reagent.dm delete mode 100644 code/modules/research/techweb/all_nodes.dm create mode 100644 code/modules/research/techweb/nodes/alien_nodes.dm create mode 100644 code/modules/research/techweb/nodes/atmos_nodes.dm create mode 100644 code/modules/research/techweb/nodes/bepis_nodes.dm create mode 100644 code/modules/research/techweb/nodes/biology_nodes.dm create mode 100644 code/modules/research/techweb/nodes/circuit_nodes.dm create mode 100644 code/modules/research/techweb/nodes/cyborg_nodes.dm create mode 100644 code/modules/research/techweb/nodes/engi_nodes.dm create mode 100644 code/modules/research/techweb/nodes/mech_nodes.dm create mode 100644 code/modules/research/techweb/nodes/medbay_nodes.dm create mode 100644 code/modules/research/techweb/nodes/mining_nodes.dm create mode 100644 code/modules/research/techweb/nodes/modsuit_nodes.dm create mode 100644 code/modules/research/techweb/nodes/research_nodes.dm create mode 100644 code/modules/research/techweb/nodes/robo_nodes.dm create mode 100644 code/modules/research/techweb/nodes/security_nodes.dm create mode 100644 code/modules/research/techweb/nodes/service_nodes.dm create mode 100644 code/modules/research/techweb/nodes/surgery_nodes.dm create mode 100644 code/modules/research/techweb/nodes/syndicate_nodes.dm diff --git a/code/__DEFINES/research.dm b/code/__DEFINES/research.dm index d3f99314f1d8f..cf35d553ec4dc 100644 --- a/code/__DEFINES/research.dm +++ b/code/__DEFINES/research.dm @@ -4,8 +4,15 @@ //! Techweb names for new point types. Can be used to define specific point values for specific types of research (science, security, engineering, etc.) #define TECHWEB_POINT_TYPE_GENERIC "General Research" +//! Amount of points required to unlock nodes of corresponding tiers +#define TECHWEB_TIER_1_POINTS 40 +#define TECHWEB_TIER_2_POINTS 80 +#define TECHWEB_TIER_3_POINTS 120 +#define TECHWEB_TIER_4_POINTS 160 +#define TECHWEB_TIER_5_POINTS 200 + //! Amount of points gained per second by a single R&D server, see: [research][code/controllers/subsystem/research.dm] -#define TECHWEB_SINGLE_SERVER_INCOME 52.3 +#define TECHWEB_SINGLE_SERVER_INCOME 1 //! Swab cell line types #define CELL_LINE_TABLE_SLUDGE "cell_line_sludge_table" diff --git a/code/modules/bitrunning/designs.dm b/code/modules/bitrunning/designs.dm index 4e7bca1c1a8dd..96ae65d41e99b 100644 --- a/code/modules/bitrunning/designs.dm +++ b/code/modules/bitrunning/designs.dm @@ -72,16 +72,3 @@ RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_COMPUTER_CARGO ) departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING - - -/datum/techweb_node/bitrunning - id = "bitrunning" - display_name = "Bitrunning Technology" - description = "Bluespace technology has led to the development of quantum-scale computing, which unlocks the means to materialize atomic structures while executing advanced programs." - prereq_ids = list("practical_bluespace") - design_ids = list( - "byteforge", - "quantum_console", - "netpod", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) diff --git a/code/modules/experisci/experiment/experiments.dm b/code/modules/experisci/experiment/experiments.dm index 3434fb6fdb1ed..f0915bdbf77cd 100644 --- a/code/modules/experisci/experiment/experiments.dm +++ b/code/modules/experisci/experiment/experiments.dm @@ -118,6 +118,14 @@ experiment_proper = TRUE required_gas = /datum/gas/nitrous_oxide +/datum/experiment/ordnance/gaseous/plasma + name = "Plasma Gas Shells" + description = "The delivery of Plasma gas into an area of operation might prove useful. Pack the specified gas into a tank and burst it using a Tank Compressor. Publish the data in a paper." + gain = list(10,40) + target_amount = list(200,600) + experiment_proper = TRUE + required_gas = /datum/gas/plasma + /datum/experiment/ordnance/gaseous/bz name = "BZ Gas Shells" description = "The delivery of BZ gas into an area of operation might prove useful. Pack the specified gas into a tank and burst it using a Tank Compressor. Publish the data in a paper." @@ -315,7 +323,7 @@ required_stock_part = /obj/item/stock_parts/micro_laser/ultra /datum/experiment/scanning/random/mecha_damage_scan - name = "Exosuit Materials 1: Stress Failure Test" + name = "Exosuit Materials: Stress Failure Test" description = "Your exosuit fabricators allow for rapid production on a small scale, but the structural integrity of created parts is inferior to more traditional means." exp_tag = "Scan" possible_types = list(/obj/vehicle/sealed/mecha) @@ -324,7 +332,7 @@ var/damage_percent /datum/experiment/scanning/random/mecha_equipped_scan - name = "Exosuit Materials 2: Load Strain Test" + name = "Exosuit Materials: Load Strain Test" description = "Exosuit equipment places unique strain upon the structure of the vehicle. Scan exosuits you have assembled from your exosuit fabricator and fully equipped to accelerate our structural stress simulations." possible_types = list(/obj/vehicle/sealed/mecha) total_requirement = 2 @@ -368,3 +376,80 @@ continue return TRUE return FALSE + +/// Scan for cybernetic organs +/datum/experiment/scanning/people/augmented_organs + name = "Human Field Research: Augmented Organs" + description = "We need to gather data on how cybernetic vital organs integrate with human biology. Conduct a scan on a human with these implants to help us understand their compatibility" + performance_hint = "Perform an organ manipulation surgery to replace one of the vital organs with a cybernetic variant." + required_traits_desc = "augmented vital organs" + +/datum/experiment/scanning/people/augmented_organs/is_valid_scan_target(mob/living/carbon/human/check) + . = ..() + if (!.) + return + var/static/list/vital_organ_slots = list( + ORGAN_SLOT_HEART, + ORGAN_SLOT_LUNGS, + ORGAN_SLOT_EYES, + ORGAN_SLOT_EARS, + ORGAN_SLOT_LIVER, + ORGAN_SLOT_STOMACH, + ) + + for (var/obj/item/organ/organ as anything in check.organs) + if (IS_ORGANIC_ORGAN(organ)) + continue + if (!(organ.slot in vital_organ_slots)) + continue + return TRUE + return FALSE + +/// Scan for skillchips +/datum/experiment/scanning/people/skillchip + name = "Human Field Research: Skill Chip Implants" + description = "Before sticking programmed circuits into human brain, we need to know how it handles simple ones. Scan a live person with a skill chip implant in their brain." + performance_hint = "Perform a skill chip implantation with a skill station." + required_traits_desc = "skill chip implant" + +/datum/experiment/scanning/people/skillchip/is_valid_scan_target(mob/living/carbon/human/check, datum/component/experiment_handler/experiment_handler) + . = ..() + if (!.) + return + var/obj/item/organ/internal/brain/scanned_brain = check.get_organ_slot(ORGAN_SLOT_BRAIN) + if (isnull(scanned_brain)) + experiment_handler.announce_message("Subject is brainless!") + return FALSE + if (scanned_brain.get_used_skillchip_slots() == 0) + experiment_handler.announce_message("No skill chips found!") + return FALSE + return TRUE + +/datum/experiment/scanning/reagent/cryostylane + name = "Pure Cryostylane Scan" + description = "It appears that the Cryostylane reagent can potentially halt all physiological processes in the human body. Produce Cryostylane with at least 99% purity and scan the beaker." + required_reagent = /datum/reagent/cryostylane + min_purity = 0.99 + +/datum/experiment/scanning/bluespace_crystal + name = "Bluespace Crystal Sampling" + description = "Investigate the properties of bluespace crystals by scanning either an artificial or naturally occurring variant. This will help us deepen our understanding of bluespace phenomena." + required_atoms = list(/obj/item/stack/ore/bluespace_crystal = 1) + +/datum/experiment/scanning/points/machinery_tiered_scan/tier2_any + name = "Upgraded Stock Parts Benchmark" + description = "Our newly-designed machinery components require practical application tests for hints at possible further advancements, as well as a general confirmation that we didn't actually design worse parts somehow. Scan any machinery with Upgraded Parts and report the results." + required_points = 8 + required_atoms = list( + /obj/machinery = 1 + ) + required_tier = 2 + +/datum/experiment/scanning/points/machinery_tiered_scan/tier3_any + name = "Advanced Stock Parts Benchmark" + description = "Our newly-designed machinery components require practical application tests for hints at possible further advancements, as well as a general confirmation that we didn't actually design worse parts somehow. Scan any machinery with Advanced Parts and report the results." + required_points = 8 + required_atoms = list( + /obj/machinery = 1 + ) + required_tier = 3 diff --git a/code/modules/experisci/experiment/types/scanning_people.dm b/code/modules/experisci/experiment/types/scanning_people.dm index 379d7e9089524..c3879e2a8d32c 100644 --- a/code/modules/experisci/experiment/types/scanning_people.dm +++ b/code/modules/experisci/experiment/types/scanning_people.dm @@ -18,15 +18,15 @@ return FALSE if(!ishuman(target)) return FALSE - return is_valid_scan_target(target) + return is_valid_scan_target(target, experiment_handler) /// Checks that the passed mob is valid human to scan -/datum/experiment/scanning/people/proc/is_valid_scan_target(mob/living/carbon/human/check) +/datum/experiment/scanning/people/proc/is_valid_scan_target(mob/living/carbon/human/check, datum/component/experiment_handler/experiment_handler) SHOULD_CALL_PARENT(TRUE) if(!mind_required || !isnull(check.mind)) return TRUE if(isliving(usr)) - check.balloon_alert(usr, "subject is mindless!") + experiment_handler.announce_message("Subject is mindless!") return FALSE /datum/experiment/scanning/people/serialize_progress_stage(atom/target, list/seen_instances) diff --git a/code/modules/experisci/experiment/types/scanning_reagent.dm b/code/modules/experisci/experiment/types/scanning_reagent.dm new file mode 100644 index 0000000000000..1a39e2941efeb --- /dev/null +++ b/code/modules/experisci/experiment/types/scanning_reagent.dm @@ -0,0 +1,35 @@ +/// An experiment where you scan a container with a specified reagent of certain purity +/datum/experiment/scanning/reagent + exp_tag = "Reagent Scan" + allowed_experimentors = list(/obj/item/experi_scanner, /obj/item/scanner_wand) + required_atoms = list(/obj/item/reagent_containers = 1) + /// The reagent required to present in the scanned container + var/datum/reagent/required_reagent = /datum/reagent/water + /// The minimum required purity of required_reagent + var/min_purity = 0 + +/datum/experiment/scanning/reagent/final_contributing_index_checks(datum/component/experiment_handler/experiment_handler, atom/target, typepath) + . = ..() + if(!.) + return FALSE + if(!is_reagent_container(target)) + return FALSE + return is_valid_scan_target(experiment_handler, target) + +/datum/experiment/scanning/reagent/proc/is_valid_scan_target(datum/component/experiment_handler/experiment_handler, obj/item/reagent_containers/container) + SHOULD_CALL_PARENT(TRUE) + if (container.reagents.total_volume == 0) + experiment_handler.announce_message("Container empty!") + return FALSE + var/datum/reagent/master_reagent = container.reagents.get_master_reagent() + if (master_reagent.type != required_reagent) + experiment_handler.announce_message("Reagent not found!") + return FALSE + if (master_reagent.purity < min_purity) + experiment_handler.announce_message("Purity too low!") + return FALSE + return TRUE + +/datum/experiment/scanning/reagent/serialize_progress_stage(atom/target, list/seen_instances) + return EXPERIMENT_PROG_INT("Scan a reagent container with [required_reagent::name] of at least [PERCENT(min_purity)] purity.", \ + seen_instances.len, required_atoms[target]) diff --git a/code/modules/experisci/experiment/types/scanning_vatgrown.dm b/code/modules/experisci/experiment/types/scanning_vatgrown.dm index f4578fdf41238..0a7ade381a4ea 100644 --- a/code/modules/experisci/experiment/types/scanning_vatgrown.dm +++ b/code/modules/experisci/experiment/types/scanning_vatgrown.dm @@ -3,7 +3,7 @@ description = "Base experiment for scanning atoms that were vatgrown" exp_tag = "Cytology Scan" total_requirement = 1 - possible_types = list(/mob/living/basic/cockroach) + possible_types = list(/mob/living/basic/slime) traits = EXPERIMENT_TRAIT_DESTRUCTIVE /datum/experiment/scanning/random/cytology/final_contributing_index_checks(datum/component/experiment_handler/experiment_handler, atom/target, typepath) diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm deleted file mode 100644 index 1c6e6f2b9f7ee..0000000000000 --- a/code/modules/research/techweb/all_nodes.dm +++ /dev/null @@ -1,2498 +0,0 @@ - -//Current rate: 135000 research points in 90 minutes - -//Base Nodes -/datum/techweb_node/base - id = "base" - starting_node = TRUE - display_name = "Basic Research Technology" - description = "NT default research technologies." - // Default research tech, prevents bricking - design_ids = list( - "basic_capacitor", - "basic_cell", - "basic_matter_bin", - "basic_micro_laser", - "basic_scanning", - "blast", - "bounced_radio", - "bowl", - "bucket", - "c-reader", - "c38_rubber", - "camera_assembly", - "camera_film", - "camera", - "capbox", - "chisel", - "circuit_imprinter_offstation", - "circuit_imprinter", - "circuit", - "circuitgreen", - "circuitred", - "coffee_cartridge", - "coffeemaker", - "coffeepot", - "condenser", - "conveyor_belt", - "conveyor_switch", - "custom_vendor_refill", - "destructive_analyzer", - "destructive_scanner", - "desttagger", - "doppler_array", - "drinking_glass", - "earmuffs", - "electropack", - "experi_scanner", - "experimentor", - "extinguisher", - "fax", - "fish_case", - "fishing_rod", - "fishing_portal_generator", - "flashlight", - "fluid_ducts", - "foam_dart", - "fork", - "gas_filter", - "handcuffs_s", - "handlabel", - "health_sensor", - "holodisk", - "igniter", - "infrared_emitter", - "intercom_frame", - "kitchen_knife", - "laptop", - "light_bulb", - "light_replacer", - "light_tube", - "mechfab", - "micro_servo", - "miniature_power_cell", - "newscaster_frame", - "oven_tray", - "packagewrap", - "pet_carrier", - "plasmaglass", - "plasmaman_gas_filter", - "plasmareinforcedglass", - "plasteel", - "plastic_fork", - "plastic_knife", - "plastic_spoon", - "plastitanium", - "plastitaniumglass", - "plate", - "prox_sensor", - "radio_headset", - "rdconsole", - "rdserver", - "rdservercontrol", - "recorder", - "rglass", - "roll", - "sec_38", - "sec_beanbag_slug", - "sec_dart", - "sec_Islug", - "sec_rshot", - "sec_pen", - "servingtray", - "shaker", - "shot_glass", - "signaler", - "slime_scanner", - "solar_panel", - "solar_tracker", - "souppot", - "space_heater", - "spoon", - "status_display_frame", - "sticky_tape", - "syrup_bottle", - "tape", - "tech_disk", - "timer", - "titaniumglass", - "toner_large", - "toner", - "tongs", - "toy_armblade", - "toy_balloon", - "toygun", - "tram_floor_dark", - "tram_floor_light", - "trapdoor_electronics", - "turbine_part_compressor", - "turbine_part_rotor", - "turbine_part_stator", - "turret_control", - "universal_scanner", - "voice_analyzer", - "watering_can", - ) - experiments_to_unlock = list( - /datum/experiment/autopsy/nonhuman, - /datum/experiment/scanning/random/material/medium/one, - /datum/experiment/scanning/random/material/medium/three, - /datum/experiment/scanning/random/material/hard/one, - /datum/experiment/scanning/random/material/hard/two, - /datum/experiment/scanning/people/novel_organs, - ) - -/datum/techweb_node/mmi - id = "mmi" - starting_node = TRUE - display_name = "Man Machine Interface" - description = "A slightly Frankensteinian device that allows human brains to interface natively with software APIs." - design_ids = list( - "mmi", - ) - -/datum/techweb_node/cyborg - id = "cyborg" - starting_node = TRUE - display_name = "Cyborg Construction" - description = "Sapient robots with preloaded tool modules and programmable laws." - design_ids = list( - "borg_chest", - "borg_head", - "borg_l_arm", - "borg_l_leg", - "borg_r_arm", - "borg_r_leg", - "borg_suit", - "borg_upgrade_rename", - "borg_upgrade_restart", - "borgupload", - "cyborgrecharger", - "robocontrol", - "sflash", - ) - -/datum/techweb_node/mech - id = "mecha" - starting_node = TRUE - display_name = "Mechanical Exosuits" - description = "Mechanized exosuits that are several magnitudes stronger and more powerful than the average human." - design_ids = list( - "mech_recharger", - "mecha_tracking", - "mechacontrol", - "mechapower", - "ripley_chassis", - "ripley_left_arm", - "ripley_left_leg", - "ripley_main", - "ripley_peri", - "ripley_right_arm", - "ripley_right_leg", - "ripley_torso", - "ripleyupgrade", - "mech_hydraulic_clamp", - "mech_radio", - "mech_air_tank", - "mech_thrusters", - ) - -/datum/techweb_node/mod_basic - id = "mod" - starting_node = TRUE - display_name = "Basic Modular Suits" - description = "Specialized back mounted power suits with various different modules." - design_ids = list( - "mod_boots", - "mod_chestplate", - "mod_gauntlets", - "mod_helmet", - "mod_paint_kit", - "mod_shell", - "mod_plating_standard", - "mod_storage", - "mod_welding", - "mod_safety", - "mod_mouthhole", - "mod_flashlight", - "mod_longfall", - "mod_thermal_regulator", - "mod_plasma", - "mod_sign_radio", - ) - -/datum/techweb_node/mech_tools - id = "mech_tools" - starting_node = TRUE - display_name = "Basic Exosuit Equipment" - description = "Various tools fit for basic mech units" - design_ids = list( - "mech_drill", - "mech_extinguisher", - "mech_mscanner", - ) - -/datum/techweb_node/basic_tools - id = "basic_tools" - starting_node = TRUE - display_name = "Basic Tools" - description = "Basic mechanical, electronic, surgical and botanical tools." - design_ids = list( - "airlock_painter", - "analyzer", - "boxcutter", - "cable_coil", - "cable_coil", - "crowbar", - "cultivator", - "decal_painter", - "hatchet", - "mop", - "multitool", - "normtrash", - "pipe_painter", - "plant_analyzer", - "plunger", - "pushbroom", - "rwd", - "razor", - "screwdriver", - "secateurs", - "shovel", - "spade", - "spraycan", - "tile_sprayer", - "tscanner", - "welding_helmet", - "welding_tool", - "wirebrush", - "wirecutters", - "wrench", - "pickaxe", - ) - -/datum/techweb_node/basic_medical - id = "basic_medical" - starting_node = TRUE - display_name = "Basic Medical Equipment" - description = "Basic medical tools and equipment." - design_ids = list( - "beaker", - "biopsy_tool", - "blood_filter", - "bonesetter", - "cautery", - "circular_saw", - "cybernetic_ears", - "cybernetic_eyes", - "cybernetic_eyes_moth", - "cybernetic_heart", - "cybernetic_liver", - "cybernetic_lungs", - "cybernetic_stomach", - "defibmountdefault", - "dropper", - "hemostat", - "large_beaker", - "medicalbed", - "mmi_m", - "operating", - "petri_dish", - "pillbottle", - "plumbing_rcd", - "plumbing_rcd_service", - "plumbing_rcd_sci", - "portable_chem_mixer", - "penlight", - "retractor", - "scalpel", - "stethoscope", - "surgical_drapes", - "surgical_tape", - "surgicaldrill", - "swab", - "syringe", - "xlarge_beaker", - ) - -/datum/techweb_node/basic_circuitry - id = "basic_circuitry" - starting_node = TRUE - display_name = "Basic Integrated Circuits" - description = "Research on how to fully exploit the power of integrated circuits" - design_ids = list( - "circuit_multitool", - "comp_access_checker", - "comp_arctan2", - "comp_arithmetic", - "comp_assoc_list_pick", - "comp_assoc_list_remove", - "comp_assoc_list_set", - "comp_binary_convert", - "comp_clock", - "comp_comparison", - "comp_concat", - "comp_concat_list", - "comp_decimal_convert", - "comp_delay", - "comp_direction", - "comp_element_find", - "comp_filter_list", - "comp_foreach", - "comp_format", - "comp_format_assoc", - "comp_get_column", - "comp_gps", - "comp_health", - "comp_health_state", - "comp_hear", - "comp_id_access_reader", - "comp_id_getter", - "comp_id_info_reader", - "comp_index", - "comp_index_assoc", - "comp_index_table", - "comp_laserpointer", - "comp_length", - "comp_light", - "comp_list_add", - "comp_list_assoc_literal", - "comp_list_clear", - "comp_list_literal", - "comp_list_pick", - "comp_list_remove", - "comp_logic", - "comp_matscanner", - "comp_mmi", - "comp_module", - "comp_multiplexer", - "comp_not", - "comp_ntnet_receive", - "comp_ntnet_send", - "comp_ntnet_send_list_literal", - "comp_pinpointer", - "comp_pressuresensor", - "comp_radio", - "comp_random", - "comp_reagents", - "comp_router", - "comp_select_query", - "comp_self", - "comp_set_variable_trigger", - "comp_soundemitter", - "comp_species", - "comp_speech", - "comp_speech", - "comp_split", - "comp_string_contains", - "comp_tempsensor", - "comp_textcase", - "comp_timepiece", - "comp_toggle", - "comp_tonumber", - "comp_tostring", - "comp_trigonometry", - "comp_typecast", - "comp_typecheck", - "comp_view_sensor", - "compact_remote_shell", - "component_printer", - "integrated_circuit", - "module_duplicator", - "usb_cable" - ) - -/////////////////////////Biotech///////////////////////// - -/datum/techweb_node/biotech - id = "biotech" - display_name = "Biological Technology" - description = "What makes us tick." //the MC, silly! - prereq_ids = list("base") - design_ids = list( - "beer_dispenser", - "blood_pack", - "chem_dispenser", - "chem_heater", - "chem_mass_spec", - "chem_master", - "chem_pack", - "defibmount", - "defibrillator", - "genescanner", - "healthanalyzer", - "med_spray_bottle", - "medical_kiosk", - "medigel", - "medipen_refiller", - "pandemic", - "penlight_paramedic", - "soda_dispenser", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - required_experiments = list(/datum/experiment/autopsy/human) - -/datum/techweb_node/adv_biotech - id = "adv_biotech" - display_name = "Advanced Biotechnology" - description = "Advanced Biotechnology" - prereq_ids = list("biotech") - design_ids = list( - "autopsyscanner", - "crewpinpointer", - "defibrillator_compact", - "harvester", - "healthanalyzer_advanced", - "holobarrier_med", - "limbgrower", - "meta_beaker", - "ph_meter", - "piercesyringe", - "plasmarefiller", - "smoke_machine", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) - required_experiments = list(/datum/experiment/autopsy/nonhuman) - discount_experiments = list(/datum/experiment/scanning/random/material/meat = 4000) - -/datum/techweb_node/xenoorgan_biotech - id = "xenoorgan_bio" - display_name = "Xeno-organ Biology" - description = "Plasmaman, Ethereals, Lizardpeople... What makes our non-human crewmembers tick?" - prereq_ids = list("adv_biotech") - design_ids = list( - "limbdesign_ethereal", - "limbdesign_felinid", - "limbdesign_lizard", - "limbdesign_plasmaman", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 6500) - discount_experiments = list( - /datum/experiment/scanning/random/cytology/easy = 1000, - /datum/experiment/scanning/points/slime/hard = 5000, - /datum/experiment/autopsy/xenomorph = 5000, - ) - -/datum/techweb_node/morphological_theory - id = "morphological_theory" - display_name = "Anomalous Morphology" - description = "Use poorly understood energies to change your body." - prereq_ids = list("adv_biotech", "anomaly_research") - design_ids = list("polymorph_belt") - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) - discount_experiments = list( - /datum/experiment/scanning/people/novel_organs = 5000, - ) - -/datum/techweb_node/bio_process - id = "bio_process" - display_name = "Biological Processing" - description = "From slimes to kitchens." - prereq_ids = list("biotech") - design_ids = list( - "deepfryer", - "dish_drive", - "fat_sucker", - "gibber", - "griddle", - "microwave", - "microwave_engineering", - "monkey_recycler", - "oven", - "processor", - "range", // should be in a further node, probably - "reagentgrinder", - "smartfridge", - "stove", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 4000) - discount_experiments = list(/datum/experiment/scanning/random/cytology = 3000) //Big discount to reinforce doing it. - -/datum/techweb_node/marine_util - id = "marine_util" - display_name = "Marine Utility" - description = "Fish are nice to look at and all, but they can be put to use." - prereq_ids = list("bio_process") - design_ids = list( - "bioelec_gen", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 4000) - // only available if you've done the first fishing experiment (thus unlocking fishing tech), but not a strict requirement to get the tech - discount_experiments = list(/datum/experiment/scanning/fish/second = 3000) - -/////////////////////////Advanced Surgery///////////////////////// - -/datum/techweb_node/imp_wt_surgery - id = "imp_wt_surgery" - display_name = "Improved Wound-Tending Surgery" - description = "Who would have known being more gentle with a hemostat decreases patient pain?" - prereq_ids = list("biotech") - design_ids = list( - "surgery_heal_brute_upgrade", - "surgery_heal_burn_upgrade", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000) - -/datum/techweb_node/oldstation_surgery - id = "oldstation_surgery" - display_name = "Experimental Dissection" - description = "Grants access to experimental dissections, which allows generation of research points." - design_ids = list( - "surgery_oldstation_dissection", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 500) - hidden = TRUE - show_on_wiki = FALSE - -/datum/techweb_node/adv_surgery - id = "adv_surgery" - display_name = "Advanced Surgery" - description = "When simple medicine doesn't cut it." - prereq_ids = list("imp_wt_surgery") - design_ids = list( - "surgery_heal_brute_upgrade_femto", - "surgery_heal_burn_upgrade_femto", - "surgery_heal_combo", - "surgery_lobotomy", - "surgery_wing_reconstruction", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1500) - -/datum/techweb_node/exp_surgery - id = "exp_surgery" - display_name = "Experimental Surgery" - description = "When evolution isn't fast enough." - prereq_ids = list("adv_surgery") - design_ids = list( - "surgery_cortex_folding", - "surgery_cortex_imprint", - "surgery_heal_combo_upgrade", - "surgery_ligament_hook", - "surgery_ligament_reinforcement", - "surgery_muscled_veins", - "surgery_nerve_ground", - "surgery_nerve_splice", - "surgery_pacify", - "surgery_vein_thread", - "surgery_viral_bond", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 7500) - discount_experiments = list(/datum/experiment/scanning/random/plants/traits = 4500) - -/datum/techweb_node/alien_surgery - id = "alien_surgery" - display_name = "Alien Surgery" - description = "Abductors did nothing wrong." - prereq_ids = list("exp_surgery", "alientech") - design_ids = list( - "surgery_brainwashing", - "surgery_heal_combo_upgrade_femto", - "surgery_zombie", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000) - -/////////////////////////data theory tech///////////////////////// - -/datum/techweb_node/datatheory //Computer science - id = "datatheory" - display_name = "Data Theory" - description = "Big Data, in space!" - prereq_ids = list("base") - design_ids = list( - "bounty_pad", - "bounty_pad_control", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - - -/////////////////////////engineering tech///////////////////////// - -/datum/techweb_node/engineering - id = "engineering" - display_name = "Industrial Engineering" - description = "A refresher course on modern engineering technology." - prereq_ids = list("base") - design_ids = list( - "adv_capacitor", - "adv_matter_bin", - "adv_scanning", - "airalarm_electronics", - "airlock_board", - "anomaly_refinery", - "apc_control", - "atmos_control", - "atmos_thermal", - "atmosalerts", - "autolathe", - "cell_charger", - "crystallizer", - "electrolyzer", - "emergency_oxygen_engi", - "emergency_oxygen", - "emitter", - "mass_driver", - "firealarm_electronics", - "firelock_board", - "generic_tank", - "grounding_rod", - "high_cell", - "high_micro_laser", - "mesons", - "nano_servo", - "oxygen_tank", - "pacman", - "plasma_tank", - "plasmaman_tank_belt", - "pneumatic_seal", - "power_control", - "powermonitor", - "recharger", - "recycler", - "rped", - "scanner_gate", - "solarcontrol", - "stack_console", - "stack_machine", - "suit_storage_unit", - "tank_compressor", - "tesla_coil", - "thermomachine", - "w-recycler", - "welding_goggles", - "flatpacker", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 12500) - discount_experiments = list(/datum/experiment/scanning/random/material/easy = 7500) - experiments_to_unlock = list(/datum/experiment/scanning/points/machinery_pinpoint_scan/tier2_microlaser) - -/datum/techweb_node/adv_engi - id = "adv_engi" - display_name = "Advanced Engineering" - description = "Pushing the boundaries of physics, one chainsaw-fist at a time." - prereq_ids = list("engineering", "emp_basic") - design_ids = list( - "HFR_core", - "HFR_corner", - "HFR_fuel_input", - "HFR_interface", - "HFR_moderator_input", - "HFR_waste_output", - "engine_goggles", - "forcefield_projector", - "magboots", - "rcd_loaded", - "rcd_ammo", - "rpd_loaded", - "rtd_loaded", - "sheetifier", - "weldingmask", - "bolter_wrench", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 15000) - discount_experiments = list( - /datum/experiment/scanning/random/material/medium/one = 4000, - /datum/experiment/ordnance/gaseous/bz = 10000, - ) - -/datum/techweb_node/anomaly - id = "anomaly_research" - display_name = "Anomaly Research" - description = "Unlock the potential of the mysterious anomalies that appear on station." - prereq_ids = list("adv_engi", "practical_bluespace") - design_ids = list( - "anomaly_neutralizer", - "reactive_armour", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) - -/datum/techweb_node/high_efficiency - id = "high_efficiency" - display_name = "High Efficiency Parts" - description = "Finely-tooled manufacturing techniques allowing for picometer-perfect precision levels." - prereq_ids = list("engineering", "datatheory") - design_ids = list( - "pico_servo", - "super_matter_bin", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 7500) - discount_experiments = list(/datum/experiment/scanning/points/machinery_tiered_scan/tier2_lathes = 5000) - -/datum/techweb_node/adv_power - id = "adv_power" - display_name = "Advanced Power Manipulation" - description = "How to get more zap." - prereq_ids = list("engineering") - design_ids = list( - "hyper_cell", - "power_turbine_console", - "smes", - "super_capacitor", - "super_cell", - "turbine_compressor", - "turbine_rotor", - "turbine_stator", - "modular_shield_generator", - "modular_shield_node", - "modular_shield_relay", - "modular_shield_charger", - "modular_shield_well", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3500) - discount_experiments = list(/datum/experiment/scanning/points/machinery_pinpoint_scan/tier2_capacitors = 2500) - -/////////////////////////Bluespace tech///////////////////////// -/datum/techweb_node/bluespace_basic //Bluespace-memery - id = "bluespace_basic" - display_name = "Basic Bluespace Theory" - description = "Basic studies into the mysterious alternate dimension known as bluespace." - prereq_ids = list("base") - design_ids = list( - "beacon", - "bluespace_crystal", - "telesci_gps", - "xenobioconsole", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/bluespace_travel - id = "bluespace_travel" - display_name = "Bluespace Travel" - description = "Application of Bluespace for static teleportation technology." - prereq_ids = list("practical_bluespace") - design_ids = list( - "bluespace_pod", - "launchpad", - "launchpad_console", - "quantumpad", - "tele_hub", - "tele_station", - "teleconsole", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) - discount_experiments = list(/datum/experiment/scanning/points/machinery_tiered_scan/tier3_bluespacemachines = 4000) - -/datum/techweb_node/micro_bluespace - id = "micro_bluespace" - display_name = "Miniaturized Bluespace Research" - description = "Extreme reduction in space required for bluespace engines, leading to portable bluespace technology." - prereq_ids = list("bluespace_travel", "practical_bluespace", "high_efficiency") - design_ids = list( - "bluespace_matter_bin", - "bluespacebodybag", - "medicalbed_emergency", - "femto_servo", - "quantum_keycard", - "swapper", - "triphasic_scanning", - "wormholeprojector", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000) - discount_experiments = list(/datum/experiment/scanning/points/machinery_tiered_scan/tier3_variety = 5000) - /* /datum/experiment/exploration_scan/random/condition) this should have a point cost but im not even sure the experiment works properly lmao*/ - -/datum/techweb_node/advanced_bluespace - id = "bluespace_storage" - display_name = "Advanced Bluespace Storage" - description = "With the use of bluespace we can create even more advanced storage devices than we could have ever done" - prereq_ids = list("micro_bluespace", "janitor") - design_ids = list( - "bag_holding", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) - -/datum/techweb_node/practical_bluespace - id = "practical_bluespace" - display_name = "Applied Bluespace Research" - description = "Using bluespace to make things faster and better." - prereq_ids = list("bluespace_basic", "engineering") - design_ids = list( - "bluespacebeaker", - "bluespacesyringe", - "bluespace_coffeepot", - "bs_rped", - "minerbag_holding", - "ore_silo", - "phasic_scanning", - "plumbing_receiver", - "roastingstick", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) - discount_experiments = list(/datum/experiment/scanning/points/machinery_pinpoint_scan/tier2_scanmodules = 3500) - -/datum/techweb_node/bluespace_power - id = "bluespace_power" - display_name = "Bluespace Power Technology" - description = "Even more powerful.. power!" - prereq_ids = list("adv_power", "practical_bluespace") - design_ids = list( - "bluespace_cell", - "quadratic_capacitor", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 4000) - discount_experiments = list(/datum/experiment/scanning/points/machinery_pinpoint_scan/tier3_cells = 3000) - -/datum/techweb_node/unregulated_bluespace - id = "unregulated_bluespace" - display_name = "Unregulated Bluespace Research" - description = "Bluespace technology using unstable or unbalanced procedures, prone to damaging the fabric of bluespace. Outlawed by galactic conventions." - prereq_ids = list("bluespace_travel", "syndicate_basic") - design_ids = list( - "desynchronizer", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - - -/////////////////////////plasma tech///////////////////////// -/datum/techweb_node/basic_plasma - id = "basic_plasma" - display_name = "Basic Plasma Research" - description = "Research into the mysterious and dangerous substance, plasma." - prereq_ids = list("engineering") - design_ids = list( - "mech_generator", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/adv_plasma - id = "adv_plasma" - display_name = "Advanced Plasma Research" - description = "Research on how to fully exploit the power of plasma." - prereq_ids = list("basic_plasma") - design_ids = list( - "mech_plasma_cutter", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/////////////////////////integrated circuits tech///////////////////////// - -/datum/techweb_node/adv_shells - id = "adv_shells" - display_name = "Advanced Shell Research" - description = "Grants access to more complicated shell designs." - prereq_ids = list("basic_circuitry", "engineering") - design_ids = list( - "assembly_shell", - "bot_shell", - "comp_equip_action", - "controller_shell", - "dispenser_shell", - "door_shell", - "gun_shell", - "keyboard_shell", - "module_shell", - "money_bot_shell", - "scanner_gate_shell", - "scanner_shell", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/bci_shells - id = "bci_shells" - display_name = "Brain-Computer Interfaces" - description = "Grants access to biocompatable shell designs and components." - prereq_ids = list("adv_shells") - design_ids = list( - "bci_implanter", - "bci_shell", - "comp_bar_overlay", - "comp_camera_bci", - "comp_counter_overlay", - "comp_install_detector", - "comp_object_overlay", - "comp_reagent_injector", - "comp_target_intercept", - "comp_thought_listener", - "comp_vox", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 500) - -/datum/techweb_node/movable_shells_tech - id = "movable_shells" - display_name = "Movable Shell Research" - description = "Grants access to movable shells." - prereq_ids = list("adv_shells", "robotics") - design_ids = list( - "comp_pathfind", - "comp_pull", - "drone_shell", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000) - -/datum/techweb_node/server_shell_tech - id = "server_shell" - display_name = "Server Technology Research" - description = "Grants access to a server shell that has a very high capacity for components." - prereq_ids = list("adv_shells", "computer_data_disks") - design_ids = list( - "server_shell", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000) - -/////////////////////////robotics tech///////////////////////// -/datum/techweb_node/robotics - id = "robotics" - display_name = "Basic Robotics Research" - description = "Programmable machines that make our lives lazier." - prereq_ids = list("base") - design_ids = list( - "paicard", - "mecha_camera", - "botnavbeacon", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/adv_robotics - id = "adv_robotics" - display_name = "Advanced Robotics Research" - description = "Advanced synthetic neural networks and synaptic pathways allows for extraordinary leaps in cybernetic intelligence and interfacing." - prereq_ids = list("robotics") - design_ids = list( - "advanced_l_arm", - "advanced_r_arm", - "advanced_l_leg", - "advanced_r_leg", - "mmi_posi", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/adv_bots - id = "adv_bots" - display_name = "Advanced Bots Research" - description = "Grants access to a special launchpad designed for bots." - prereq_ids = list("robotics") - design_ids = list( - "botpad", - "botpad_remote", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/exodrone_tech - id = "exodrone" - display_name = "Exploration Drone Research" - description = "Technology for exploring far away locations." - prereq_ids = list("robotics") - design_ids = list( - "exodrone_console", - "exodrone_launcher", - "exoscanner", - "exoscanner_console", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/neural_programming - id = "neural_programming" - display_name = "Neural Programming" - description = "Study into networks of processing units that mimic our brains." - prereq_ids = list("biotech", "datatheory") - design_ids = list( - "skill_station", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/cyborg_upg_util - id = "cyborg_upg_util" - display_name = "Cyborg Upgrades: Utility" - description = "Utility upgrades for cyborgs." - prereq_ids = list("adv_robotics") - design_ids = list( - "borg_upgrade_advancedmop", - "borg_upgrade_broomer", - "borg_upgrade_expand", - "borg_upgrade_prt", - "borg_upgrade_selfrepair", - "borg_upgrade_thrusters", - "borg_upgrade_trashofholding", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2000) - -/datum/techweb_node/cyborg_upg_util/New() - . = ..() - if(!CONFIG_GET(flag/disable_secborg)) - design_ids += "borg_upgrade_disablercooler" - -/datum/techweb_node/cyborg_upg_serv - id = "cyborg_upg_serv" - display_name = "Cyborg Upgrades: Service" - description = "Service upgrades for cyborgs." - prereq_ids = list("adv_robotics") - design_ids = list( - "borg_upgrade_rolling_table", - "borg_upgrade_condiment_synthesizer", - "borg_upgrade_silicon_knife", - "borg_upgrade_service_apparatus", - "borg_upgrade_drink_apparatus", - "borg_upgrade_service_cookbook", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2000) - -/datum/techweb_node/cyborg_upg_engiminer - id = "cyborg_upg_engiminer" - display_name = "Cyborg Upgrades: Engineering & Mining" - description = "Engineering and Mining upgrades for cyborgs." - prereq_ids = list("adv_engi", "basic_mining") - design_ids = list( - "borg_upgrade_circuitapp", - "borg_upgrade_diamonddrill", - "borg_upgrade_holding", - "borg_upgrade_lavaproof", - "borg_upgrade_rped", - "borg_upgrade_hypermod", - "borg_upgrade_inducer", - "borg_upgrade_engineeringomnitool", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2000) - -/datum/techweb_node/cyborg_upg_med - id = "cyborg_upg_med" - display_name = "Cyborg Upgrades: Medical" - description = "Medical upgrades for cyborgs." - prereq_ids = list("adv_biotech") - design_ids = list( - "borg_upgrade_beakerapp", - "borg_upgrade_defibrillator", - "borg_upgrade_expandedsynthesiser", - "borg_upgrade_piercinghypospray", - "borg_upgrade_pinpointer", - "borg_upgrade_surgicalprocessor", - "borg_upgrade_surgicalomnitool", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2000) - -/datum/techweb_node/ai_basic - id = "ai_basic" - display_name = "Artificial Intelligence" - description = "AI unit research." - prereq_ids = list("adv_robotics") - design_ids = list( - "aicore", - "borg_ai_control", - "intellicard", - "mecha_tracking_ai_control", - "aifixer", - "aiupload", - "reset_module", - "asimov_module", - "default_module", - "nutimov_module", - "paladin_module", - "robocop_module", - "corporate_module", - "drone_module", - "oxygen_module", - "safeguard_module", - "protectstation_module", - "quarantine_module", - "freeform_module", - "remove_module", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/ai_basic/New() - . = ..() - if(HAS_TRAIT(SSstation, STATION_TRAIT_HUMAN_AI)) - design_ids -= list( - "aicore", - "borg_ai_control", - "intellicard", - "mecha_tracking_ai_control", - "aifixer", - "aiupload", - ) - -/datum/techweb_node/ai_adv - id = "ai_adv" - display_name = "Advanced Artificial Intelligence" - description = "State of the art lawsets to be used for AI research." - prereq_ids = list("ai_basic") - design_ids = list( - "asimovpp_module", - "paladin_devotion_module", - "dungeon_master_module", - "painter_module", - "ten_commandments_module", - "hippocratic_module", - "maintain_module", - "liveandletlive_module", - "reporter_module", - "yesman_module", - "hulkamania_module", - "peacekeeper_module", - "overlord_module", - "tyrant_module", - "antimov_module", - "balance_module", - "thermurderdynamic_module", - "damaged_module", - "freeformcore_module", - "onehuman_module", - "purge_module", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000) - -//Any kind of point adjustment needs to happen before SSresearch sets up the whole node tree, it gets cached -/datum/techweb_node/ai/New() - . = ..() - if(HAS_TRAIT(SSstation, STATION_TRAIT_UNIQUE_AI)) - research_costs[TECHWEB_POINT_TYPE_GENERIC] *= 3 - -/////////////////////////EMP tech///////////////////////// -/datum/techweb_node/emp_basic //EMP tech for some reason - id = "emp_basic" - display_name = "Electromagnetic Theory" - description = "Study into usage of frequencies in the electromagnetic spectrum." - prereq_ids = list("base") - design_ids = list( - "holosign", - "holosignsec", - "holosignengi", - "holosignatmos", - "holosignrestaurant", - "holosignbar", - "inducer", - "inducerengi", - "tray_goggles", - "holopad", - "vendatray", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/emp_adv - id = "emp_adv" - display_name = "Advanced Electromagnetic Theory" - description = "Determining whether reversing the polarity will actually help in a given situation." - prereq_ids = list("emp_basic") - design_ids = list( - "ultra_micro_laser", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000) - discount_experiments = list(/datum/experiment/scanning/points/machinery_pinpoint_scan/tier2_microlaser = 1500) - -/datum/techweb_node/emp_super - id = "emp_super" - display_name = "Quantum Electromagnetic Technology" //bs - description = "Even better electromagnetic technology." - prereq_ids = list("emp_adv") - design_ids = list( - "quadultra_micro_laser", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 15000) - discount_experiments = list( - /datum/experiment/scanning/points/machinery_pinpoint_scan/tier3_microlaser = 4000, - /datum/experiment/ordnance/gaseous/noblium = 10000, - ) - -/////////////////////////Clown tech///////////////////////// -/datum/techweb_node/clown - id = "clown" - display_name = "Clown Technology" - description = "Honk?!" - prereq_ids = list("base") - design_ids = list( - "air_horn", - "borg_transform_clown", - "honk_chassis", - "honk_head", - "honk_left_arm", - "honk_left_leg", - "honk_right_arm", - "honk_right_leg", - "honk_torso", - "honker_main", - "honker_peri", - "honker_targ", - "implant_trombone", - "mech_banana_mortar", - "mech_honker", - "mech_mousetrap_mortar", - "mech_punching_face", - "clown_firing_pin", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -////////////////////////Computer tech//////////////////////// -/datum/techweb_node/comptech - id = "comptech" - display_name = "Computer Consoles" - description = "Computers and how they work." - prereq_ids = list("datatheory") - design_ids = list( - "bankmachine", - "barcode_scanner", - "cargo", - "cargorequest", - "comconsole", - "crewconsole", - "idcard", - "libraryconsole", - "mining", - "photobooth", - "rdcamera", - "seccamera", - "security_photobooth", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2000) - -/datum/techweb_node/data_disks - id = "computer_data_disks" - display_name = "Computer Data Disks" - description = "Data disks used for storing modular computer stuff." - prereq_ids = list("comptech") - design_ids = list( - "portadrive_advanced", - "portadrive_basic", - "portadrive_super", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000) - -/datum/techweb_node/computer_board_gaming - id = "computer_board_gaming" - display_name = "Arcade Games" - description = "For the slackers on the station." - prereq_ids = list("comptech") - design_ids = list( - "arcade_battle", - "arcade_orion", - "slotmachine", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3250) - discount_experiments = list(/datum/experiment/physical/arcade_winner = 3000) - -/datum/techweb_node/comp_recordkeeping - id = "comp_recordkeeping" - display_name = "Computerized Recordkeeping" - description = "Organized record databases and how they're used." - prereq_ids = list("comptech") - design_ids = list( - "account_console", - "automated_announcement", - "med_data", - "prisonmanage", - "secdata", - "vendor", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000) - -/datum/techweb_node/telecomms - id = "telecomms" - display_name = "Telecommunications Technology" - description = "Subspace transmission technology for near-instant communications devices." - prereq_ids = list("comptech", "bluespace_basic") - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - design_ids = list( - "comm_monitor", - "comm_server", - "gigabeacon", - "message_monitor", - "ntnet_relay", - "s_amplifier", - "s_analyzer", - "s_ansible", - "s_broadcaster", - "s_bus", - "s_crystal", - "s_filter", - "s_hub", - "s_messaging", - "s_processor", - "s_receiver", - "s_relay", - "s_server", - "s_transmitter", - "s_treatment", - ) - -/datum/techweb_node/tram - id = "tram" - display_name = "Tram Technology" - description = "Technology for linear induction transportation systems." - prereq_ids = list("telecomms") - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1500) - design_ids = list( - "tram_controller", - "tram_display", - "crossing_signal", - "guideway_sensor", - ) - -/datum/techweb_node/integrated_hud - id = "integrated_HUDs" - display_name = "Integrated HUDs" - description = "The usefulness of computerized records, projected straight onto your eyepiece!" - prereq_ids = list("comp_recordkeeping", "emp_basic") - design_ids = list( - "diagnostic_hud", - "health_hud", - "scigoggles", - "security_hud", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1500) - -/datum/techweb_node/nvg_tech - id = "NVGtech" - display_name = "Night Vision Technology" - description = "Allows seeing in the dark without actual light!" - prereq_ids = list("integrated_HUDs", "adv_engi", "emp_adv") - design_ids = list( - "diagnostic_hud_night", - "health_hud_night", - "night_visision_goggles", - "nvgmesons", - "nv_scigoggles", - "security_hud_night", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) - -////////////////////////Medical//////////////////////// -/datum/techweb_node/genetics - id = "genetics" - display_name = "Genetic Engineering" - description = "We have the technology to change him." - prereq_ids = list("biotech") - design_ids = list( - "dna_disk", - "dnainfuser", - "dnascanner", - "scan_console", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/cryotech - id = "cryotech" - display_name = "Cryostasis Technology" - description = "Smart freezing of objects to preserve them!" - prereq_ids = list("adv_engi", "biotech") - design_ids = list( - "cryo_grenade", - "cryotube", - "splitbeaker", - "stasis", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2000) - -/datum/techweb_node/subdermal_implants - id = "subdermal_implants" - display_name = "Subdermal Implants" - description = "Electronic implants buried beneath the skin." - prereq_ids = list("biotech") - design_ids = list( - "c38_trac", - "implant_chem", - "implant_tracking", - "implant_exile", - "implantcase", - "implanter", - "locator", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/advanced_implants - id = "adv_subdermal_implants" - display_name = "Advanced Subdermal Implants" - description = "Subdermal implants that leverage bluespace research to control their bluespace signature." - prereq_ids = list("subdermal_implants", "micro_bluespace") - design_ids = list( - "implant_beacon", - "implant_bluespace", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/cyber_organs - id = "cyber_organs" - display_name = "Cybernetic Organs" - description = "We have the technology to rebuild him." - prereq_ids = list("biotech") - design_ids = list( - "cybernetic_ears_u", - "cybernetic_eyes_improved", - "cybernetic_eyes_improved_moth", - "cybernetic_heart_tier2", - "cybernetic_liver_tier2", - "cybernetic_lungs_tier2", - "cybernetic_stomach_tier2", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000) - -/datum/techweb_node/cyber_organs/New() - ..() - if(HAS_TRAIT(SSstation, STATION_TRAIT_CYBERNETIC_REVOLUTION)) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 500) - -/datum/techweb_node/cyber_organs_upgraded - id = "cyber_organs_upgraded" - display_name = "Upgraded Cybernetic Organs" - description = "We have the technology to upgrade him." - prereq_ids = list("adv_biotech", "cyber_organs") - design_ids = list( - "cybernetic_ears_whisper", - "cybernetic_ears_xray", - "ci-gloweyes", - "ci-welding", - "ci-gloweyes-moth", - "ci-welding-moth", - "cybernetic_heart_tier3", - "cybernetic_liver_tier3", - "cybernetic_lungs_tier3", - "cybernetic_stomach_tier3", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1500) - -/datum/techweb_node/cyber_organs_upgraded/New() - ..() - if(HAS_TRAIT(SSstation, STATION_TRAIT_CYBERNETIC_REVOLUTION)) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000) - -/datum/techweb_node/cyber_implants - id = "cyber_implants" - display_name = "Cybernetic Implants" - description = "Electronic implants that improve humans." - prereq_ids = list("adv_biotech", "datatheory") - design_ids = list( - "ci-breather", - "ci-diaghud", - "ci-medhud", - "ci-nutriment", - "ci-sechud", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/cyber_implants/New() - ..() - if(HAS_TRAIT(SSstation, STATION_TRAIT_CYBERNETIC_REVOLUTION)) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000) - -/datum/techweb_node/adv_cyber_implants - id = "adv_cyber_implants" - display_name = "Advanced Cybernetic Implants" - description = "Upgraded and more powerful cybernetic implants." - prereq_ids = list("neural_programming", "cyber_implants","integrated_HUDs") - design_ids = list( - "ci-nutrimentplus", - "ci-reviver", - "ci-surgery", - "ci-toolset", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/adv_cyber_implants/New() - ..() - if(HAS_TRAIT(SSstation, STATION_TRAIT_CYBERNETIC_REVOLUTION)) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1500) - -/datum/techweb_node/combat_cyber_implants - id = "combat_cyber_implants" - display_name = "Combat Cybernetic Implants" - description = "Military grade combat implants to improve performance." - prereq_ids = list("adv_cyber_implants","weaponry","NVGtech","high_efficiency") - design_ids = list( - "ci-antidrop", - "ci-antistun", - "ci-thermals", - "ci-thrusters", - "ci-xray", - "ci-thermals-moth", - "ci-xray-moth", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/combat_cyber_implants/New() - ..() - if(HAS_TRAIT(SSstation, STATION_TRAIT_CYBERNETIC_REVOLUTION)) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1500) - -////////////////////////Tools//////////////////////// - -/datum/techweb_node/basic_mining - id = "basic_mining" - display_name = "Mining Technology" - description = "Better than Efficiency V." - prereq_ids = list("engineering", "basic_plasma") - design_ids = list( - "borg_upgrade_cooldownmod", - "borg_upgrade_damagemod", - "borg_upgrade_rangemod", - "cargoexpress", - "cooldownmod", - "damagemod", - "drill", - "mecha_kineticgun", - "mining_equipment_vendor", - "ore_redemption", - "plasmacutter", - "rangemod", - "superresonator", - "triggermod", - "mining_scanner", - "brm", - "b_smelter", - "b_refinery", - )//e a r l y g a m e) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/adv_mining - id = "adv_mining" - display_name = "Advanced Mining Technology" - description = "Efficiency Level 127" //dumb mc references - prereq_ids = list("basic_mining", "adv_power", "adv_plasma") - design_ids = list( - "drill_diamond", - "hypermod", - "jackhammer", - "plasmacutter_adv", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 7500) - discount_experiments = list(/datum/experiment/scanning/random/material/hard/one = 5000) - -/datum/techweb_node/janitor - id = "janitor" - display_name = "Advanced Sanitation Technology" - description = "Clean things better, faster, stronger, and harder!" - prereq_ids = list("adv_engi") - design_ids = list( - "advmop", - "beartrap", - "blutrash", - "buffer", - "vacuum", - "holobarrier_jani", - "light_replacer_blue", - "paint_remover", - "spraybottle", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 4000) - discount_experiments = list(/datum/experiment/scanning/random/janitor_trash = 3000) //75% discount for scanning some trash, seems fair right? - -/datum/techweb_node/botany - id = "botany" - display_name = "Botanical Engineering" - description = "Botanical tools" - prereq_ids = list("biotech") - design_ids = list( - "biogenerator", - "flora_gun", - "gene_shears", - "hydro_tray", - "portaseeder", - "seed_extractor", - "adv_watering_can", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 4000) - required_experiments = list(/datum/experiment/scanning/random/plants/wild) - discount_experiments = list(/datum/experiment/scanning/random/plants/traits = 3000) - -/datum/techweb_node/fishing - id = "fishing" - display_name = "Fishing Technology" - description = "Cutting edge fishing advancements." - prereq_ids = list("base") - design_ids = list( - "fishing_rod_tech", - "stabilized_hook", - "auto_reel", - "fish_analyzer", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2000) - required_experiments = list(/datum/experiment/scanning/fish) - -/datum/techweb_node/exp_tools - id = "exp_tools" - display_name = "Experimental Tools" - description = "Highly advanced tools." - prereq_ids = list("adv_engi") - design_ids = list( - "exwelder", - "handdrill", - "jawsoflife", - "laserscalpel", - "mechanicalpinches", - "rangedanalyzer", - "searingtool", - "adv_fire_extinguisher", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 7500) - discount_experiments = list(/datum/experiment/scanning/random/material/hard/one = 5000) - -/datum/techweb_node/sec_basic - id = "sec_basic" - display_name = "Basic Security Equipment" - description = "Standard equipment used by security." - prereq_ids = list("base") - design_ids = list( - "bola_energy", - "evidencebag", - "pepperspray", - "seclite", - "zipties", - "inspector", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000) - -/datum/techweb_node/rcd_upgrade - id = "rcd_upgrade" - display_name = "Rapid Device Upgrade Designs" - description = "Unlocks new designs that improve rapid devices." - prereq_ids = list("adv_engi") - design_ids = list( - "rcd_upgrade_anti_interrupt", - "rcd_upgrade_cooling", - "rcd_upgrade_frames", - "rcd_upgrade_furnishing", - "rcd_upgrade_simple_circuits", - "rpd_upgrade_unwrench", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/adv_rcd_upgrade - id = "adv_rcd_upgrade" - display_name = "Advanced RCD Designs Upgrade" - description = "Unlocks new RCD designs." - design_ids = list( - "rcd_upgrade_silo_link", - ) - prereq_ids = list( - "bluespace_travel", - "rcd_upgrade", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000) - discount_experiments = list(/datum/experiment/scanning/random/material/hard/two = 5000) - -/////////////////////////weaponry tech///////////////////////// -/datum/techweb_node/weaponry - id = "weaponry" - display_name = "Weapon Development Technology" - description = "Our researchers have found new ways to weaponize just about everything now." - prereq_ids = list("engineering") - design_ids = list( - "ballistic_shield", - "pin_testing", - "tele_shield", - "lasershell", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 20000) - discount_experiments = list(/datum/experiment/ordnance/explosive/pressurebomb = 10000) - -/datum/techweb_node/adv_weaponry - id = "adv_weaponry" - display_name = "Advanced Weapon Development Technology" - description = "Our weapons are breaking the rules of reality by now." - prereq_ids = list("adv_engi", "weaponry") - design_ids = list( - "pin_loyalty", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000) - -/datum/techweb_node/electric_weapons - id = "electronic_weapons" - display_name = "Electric Weapons" - description = "Weapons using electric technology" - prereq_ids = list("weaponry", "adv_power" , "emp_basic") - design_ids = list( - "ioncarbine", - "stunrevolver", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/radioactive_weapons - id = "radioactive_weapons" - display_name = "Radioactive Weaponry" - description = "Weapons using radioactive technology." - prereq_ids = list("adv_engi", "adv_weaponry") - design_ids = list( - "nuclear_gun", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/beam_weapons - id = "beam_weapons" - display_name = "Beam Weaponry" - description = "Various basic beam weapons" - prereq_ids = list("adv_weaponry") - design_ids = list( - "temp_gun", - "xray_laser", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/adv_beam_weapons - id = "adv_beam_weapons" - display_name = "Advanced Beam Weaponry" - description = "Various advanced beam weapons" - prereq_ids = list("beam_weapons") - design_ids = list( - "beamrifle", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/explosive_weapons - id = "explosive_weapons" - display_name = "Explosive & Pyrotechnical Weaponry" - description = "If the light stuff just won't do it." - prereq_ids = list("adv_weaponry") - design_ids = list( - "adv_grenade", - "large_grenade", - "pyro_grenade", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/exotic_ammo - id = "exotic_ammo" - display_name = "Exotic Ammunition" - description = "They won't know what hit em." - prereq_ids = list("weaponry") - design_ids = list( - "c38_hotshot", - "c38_iceblox", - "techshotshell", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/gravity_gun - id = "gravity_gun" - display_name = "One-point Bluespace-gravitational Manipulator" - description = "Fancy wording for gravity gun." - prereq_ids = list("adv_weaponry", "bluespace_travel") - design_ids = list( - "gravitygun", - "mech_gravcatapult", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -//MODsuit tech - -/datum/techweb_node/mod_advanced - id = "mod_advanced" - display_name = "Advanced Modular Suits" - description = "More advanced modules, to improve modular suits." - prereq_ids = list("robotics") - design_ids = list( - "mod_visor_diaghud", - "mod_gps", - "mod_reagent_scanner", - "mod_clamp", - "mod_drill", - "mod_orebag", - "modlink_scryer", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/mod_engineering - id = "mod_engineering" - display_name = "Engineering Modular Suits" - description = "Engineering suits, for powered engineers." - prereq_ids = list("mod_advanced", "engineering") - design_ids = list( - "mod_plating_engineering", - "mod_visor_meson", - "mod_t_ray", - "mod_magboot", - "mod_tether", - "mod_constructor", - "mod_mister_atmos", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/mod_advanced_engineering - id = "mod_advanced_engineering" - display_name = "Advanced Engineering Modular Suits" - description = "Advanced Engineering suits, for advanced powered engineers." - prereq_ids = list("mod_engineering", "adv_engi") - design_ids = list( - "mod_plating_atmospheric", - "mod_jetpack", - "mod_rad_protection", - "mod_emp_shield", - "mod_storage_expanded", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3500) - -/datum/techweb_node/mod_advanced_engineering/New() - if(HAS_TRAIT(SSstation, STATION_TRAIT_RADIOACTIVE_NEBULA)) //we'll really need the rad protection modsuit module - starting_node = TRUE - - return ..() - -/datum/techweb_node/mod_medical - id = "mod_medical" - display_name = "Medical Modular Suits" - description = "Medical suits for quick rescue purposes." - prereq_ids = list("mod_advanced", "biotech") - design_ids = list( - "mod_plating_medical", - "mod_visor_medhud", - "mod_health_analyzer", - "mod_quick_carry", - "mod_injector", - "mod_organ_thrower", - "mod_dna_lock", - "mod_patienttransport", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/mod_advanced_medical - id = "mod_advanced_medical" - display_name = "Advanced Medical Modular Suits" - description = "Advanced medical suits for quicker rescue purposes." - prereq_ids = list("mod_medical", "adv_biotech") - design_ids = list( - "mod_defib", - "mod_threadripper", - "mod_surgicalprocessor", - "mod_statusreadout", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3500) - -/datum/techweb_node/mod_security - id = "mod_security" - display_name = "Security Modular Suits" - description = "Security suits for space crime handling." - prereq_ids = list("mod_advanced", "sec_basic") - design_ids = list( - "mod_plating_security", - "mod_visor_sechud", - "mod_stealth", - "mod_mag_harness", - "mod_pathfinder", - "mod_holster", - "mod_sonar", - "mod_projectile_dampener", - "mod_criminalcapture", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/mod_entertainment - id = "mod_entertainment" - display_name = "Entertainment Modular Suits" - description = "Powered suits for protection against low-humor environments." - prereq_ids = list("mod_advanced", "clown") - design_ids = list( - "mod_plating_cosmohonk", - "mod_bikehorn", - "mod_microwave_beam", - "mod_waddle", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/mod_anomaly - id = "mod_anomaly" - display_name = "Anomalock Modular Suits" - description = "Modules for modular suits that require anomaly cores to function." - prereq_ids = list("mod_advanced", "anomaly_research") - design_ids = list( - "mod_antigrav", - "mod_teleporter", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/mod_anomaly_engi - id = "mod_anomaly_engi" - display_name = "Engineering Anomalock Modular Suits" - description = "Advanced modules for modular suits, using anomaly cores to become even better engineers." - prereq_ids = list("mod_advanced_engineering", "mod_anomaly") - design_ids = list( - "mod_kinesis", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000) - -////////////////////////mech technology//////////////////////// -/datum/techweb_node/adv_mecha - id = "adv_mecha" - display_name = "Advanced Exosuits" - description = "For when you just aren't Gundam enough." - prereq_ids = list("adv_robotics") - design_ids = list( - "mech_repair_droid", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 7500) - discount_experiments = list(/datum/experiment/scanning/random/material/medium/three = 5000) - -/datum/techweb_node/odysseus - id = "mecha_odysseus" - display_name = "EXOSUIT: Odysseus" - description = "Odysseus exosuit designs" - prereq_ids = list("base") - design_ids = list( - "odysseus_chassis", - "odysseus_head", - "odysseus_left_arm", - "odysseus_left_leg", - "odysseus_main", - "odysseus_peri", - "odysseus_right_arm", - "odysseus_right_leg", - "odysseus_torso", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/clarke - id = "mecha_clarke" - display_name = "EXOSUIT: Clarke" - description = "Clarke exosuit designs" - prereq_ids = list("engineering") - design_ids = list( - "clarke_chassis", - "clarke_head", - "clarke_left_arm", - "clarke_main", - "clarke_peri", - "clarke_right_arm", - "clarke_torso", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/paddy - id = "mech_paddy" - display_name = "EXOSUIT: APLU \"Paddy\"" - description = "Paddy exosuit designs" - prereq_ids = list("adv_mecha", "adv_mecha_armor") - design_ids = list( - "paddyupgrade", - "mech_hydraulic_claw" - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) - discount_experiments = list(/datum/experiment/scanning/points/machinery_tiered_scan/tier3_mechbay = 5000) - -/datum/techweb_node/gygax - id = "mech_gygax" - display_name = "EXOSUIT: Gygax" - description = "Gygax exosuit designs" - prereq_ids = list("adv_mecha", "adv_mecha_armor") - design_ids = list( - "gygax_armor", - "gygax_chassis", - "gygax_head", - "gygax_left_arm", - "gygax_left_leg", - "gygax_main", - "gygax_peri", - "gygax_right_arm", - "gygax_right_leg", - "gygax_targ", - "gygax_torso", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) - discount_experiments = list(/datum/experiment/scanning/points/machinery_tiered_scan/tier3_mechbay = 5000) - -/datum/techweb_node/durand - id = "mech_durand" - display_name = "EXOSUIT: Durand" - description = "Durand exosuit designs" - prereq_ids = list("adv_mecha", "adv_mecha_armor") - design_ids = list( - "durand_armor", - "durand_chassis", - "durand_head", - "durand_left_arm", - "durand_left_leg", - "durand_main", - "durand_peri", - "durand_right_arm", - "durand_right_leg", - "durand_targ", - "durand_torso", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) - discount_experiments = list(/datum/experiment/scanning/points/machinery_tiered_scan/tier3_mechbay = 3500) - -/datum/techweb_node/phazon - id = "mecha_phazon" - display_name = "EXOSUIT: Phazon" - description = "Phazon exosuit designs" - prereq_ids = list("adv_mecha", "adv_mecha_armor" , "micro_bluespace") - design_ids = list( - "phazon_armor", - "phazon_chassis", - "phazon_head", - "phazon_left_arm", - "phazon_left_leg", - "phazon_main", - "phazon_peri", - "phazon_right_arm", - "phazon_right_leg", - "phazon_targ", - "phazon_torso", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) - discount_experiments = list(/datum/experiment/scanning/points/machinery_tiered_scan/tier3_mechbay = 2500) - -/datum/techweb_node/savannah_ivanov - id = "mecha_savannah_ivanov" - display_name = "EXOSUIT: Savannah-Ivanov" - description = "Savannah-Ivanov exosuit designs" - prereq_ids = list("adv_mecha", "weaponry", "exp_tools") - design_ids = list( - "savannah_ivanov_armor", - "savannah_ivanov_chassis", - "savannah_ivanov_head", - "savannah_ivanov_left_arm", - "savannah_ivanov_left_leg", - "savannah_ivanov_main", - "savannah_ivanov_peri", - "savannah_ivanov_right_arm", - "savannah_ivanov_right_leg", - "savannah_ivanov_targ", - "savannah_ivanov_torso", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) - discount_experiments = list(/datum/experiment/scanning/points/machinery_tiered_scan/tier3_mechbay = 3000) - -/datum/techweb_node/adv_mecha_tools - id = "adv_mecha_tools" - display_name = "Advanced Exosuit Equipment" - description = "Tools for high level mech suits" - prereq_ids = list("adv_mecha") - design_ids = list( - "mech_rcd", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/med_mech_tools - id = "med_mech_tools" - display_name = "Medical Exosuit Equipment" - description = "Tools for high level mech suits" - prereq_ids = list("adv_biotech") - design_ids = list( - "mech_medi_beam", - "mech_sleeper", - "mech_syringe_gun", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/mech_armor - id = "adv_mecha_armor" - display_name = "Exosuit Heavy Armor Research" - description = "Recreating heavy armor with new rapid fabrication techniques." - prereq_ids = list("adv_mecha", "bluespace_power") - design_ids = list( - "mech_ccw_armor", - "mech_proj_armor", - ) - required_experiments = list(/datum/experiment/scanning/random/mecha_damage_scan) - discount_experiments = list(/datum/experiment/scanning/random/mecha_equipped_scan = 5000) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000) - -/datum/techweb_node/mech_scattershot - id = "mecha_tools" - display_name = "Exosuit Weapon (LBX AC 10 \"Scattershot\")" - description = "An advanced piece of mech weaponry" - prereq_ids = list("adv_mecha") - design_ids = list( - "mech_scattershot", - "mech_scattershot_ammo", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/mech_carbine - id = "mech_carbine" - display_name = "Exosuit Weapon (FNX-99 \"Hades\" Carbine)" - description = "An advanced piece of mech weaponry" - prereq_ids = list("exotic_ammo") - design_ids = list( - "mech_carbine", - "mech_carbine_ammo", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/mech_ion - id = "mmech_ion" - display_name = "Exosuit Weapon (MKIV Ion Heavy Cannon)" - description = "An advanced piece of mech weaponry" - prereq_ids = list("electronic_weapons", "emp_adv") - design_ids = list( - "mech_ion", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/mech_tesla - id = "mech_tesla" - display_name = "Exosuit Weapon (MKI Tesla Cannon)" - description = "An advanced piece of mech weaponry" - prereq_ids = list("electronic_weapons", "adv_power") - design_ids = list( - "mech_tesla", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/mech_laser - id = "mech_laser" - display_name = "Exosuit Weapon (CH-PS \"Immolator\" Laser)" - description = "A basic piece of mech weaponry" - prereq_ids = list("beam_weapons") - design_ids = list( - "mech_laser", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/mech_laser_heavy - id = "mech_laser_heavy" - display_name = "Exosuit Weapon (CH-LC \"Solaris\" Laser Cannon)" - description = "An advanced piece of mech weaponry" - prereq_ids = list("adv_beam_weapons") - design_ids = list( - "mech_laser_heavy", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/mech_disabler - id = "mech_disabler" - display_name = "Exosuit Weapon (CH-DS \"Peacemaker\" Mounted Disabler)" - description = "A basic piece of mech weaponry" - prereq_ids = list("adv_mecha") - design_ids = list( - "mech_disabler", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/mech_grenade_launcher - id = "mech_grenade_launcher" - display_name = "Exosuit Weapon (SGL-6 Grenade Launcher)" - description = "An advanced piece of mech weaponry" - prereq_ids = list("explosive_weapons") - design_ids = list( - "mech_grenade_launcher", - "mech_grenade_launcher_ammo", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/mech_missile_rack - id = "mech_missile_rack" - display_name = "Exosuit Weapon (BRM-6 Missile Rack)" - description = "An advanced piece of mech weaponry" - prereq_ids = list("explosive_weapons") - design_ids = list( - "mech_missile_rack", - "mech_missile_rack_ammo", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/clusterbang_launcher - id = "clusterbang_launcher" - display_name = "Exosuit Module (SOB-3 Clusterbang Launcher)" - description = "An advanced piece of mech weaponry" - prereq_ids = list("explosive_weapons") - design_ids = list( - "clusterbang_launcher", - "clusterbang_launcher_ammo", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/mech_teleporter - id = "mech_teleporter" - display_name = "Exosuit Module (Teleporter Module)" - description = "An advanced piece of mech Equipment" - prereq_ids = list("micro_bluespace") - design_ids = list( - "mech_teleporter", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/mech_wormhole_gen - id = "mech_wormhole_gen" - display_name = "Exosuit Module (Localized Wormhole Generator)" - description = "An advanced piece of mech weaponry" - prereq_ids = list("bluespace_travel") - design_ids = list( - "mech_wormhole_gen", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/mech_lmg - id = "mech_lmg" - display_name = "Exosuit Weapon (\"Ultra AC 2\" LMG)" - description = "An advanced piece of mech weaponry" - prereq_ids = list("adv_mecha") - design_ids = list( - "mech_lmg", - "mech_lmg_ammo", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -/datum/techweb_node/mech_diamond_drill - id = "mech_diamond_drill" - display_name = "Exosuit Diamond Drill" - description = "A diamond drill fit for a large exosuit" - prereq_ids = list("adv_mining") - design_ids = list( - "mech_diamond_drill", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - -////////////////////////Alien technology//////////////////////// -/datum/techweb_node/alientech //AYYYYYYYYLMAOO tech - id = "alientech" - display_name = "Alien Technology" - description = "Things used by the greys." - prereq_ids = list("biotech","engineering") - required_items_to_unlock = list( - /obj/item/stack/sheet/mineral/abductor, - /obj/item/abductor, - /obj/item/cautery/alien, - /obj/item/circuitboard/machine/abductor, - /obj/item/circular_saw/alien, - /obj/item/crowbar/abductor, - /obj/item/gun/energy/alien, - /obj/item/gun/energy/shrink_ray, - /obj/item/hemostat/alien, - /obj/item/melee/baton/abductor, - /obj/item/multitool/abductor, - /obj/item/retractor/alien, - /obj/item/scalpel/alien, - /obj/item/screwdriver/abductor, - /obj/item/surgicaldrill/alien, - /obj/item/weldingtool/abductor, - /obj/item/wirecutters/abductor, - /obj/item/wrench/abductor, - ) - design_ids = list( - "alienalloy", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) - hidden = TRUE - -/datum/techweb_node/alientech/on_station_research() - SSshuttle.shuttle_purchase_requirements_met[SHUTTLE_UNLOCK_ALIENTECH] = TRUE - -/datum/techweb_node/alien_bio - id = "alien_bio" - display_name = "Alien Biological Tools" - description = "Advanced biological tools." - prereq_ids = list("alientech", "adv_biotech") - design_ids = list( - "alien_cautery", - "alien_drill", - "alien_hemostat", - "alien_retractor", - "alien_saw", - "alien_scalpel", - ) - - required_items_to_unlock = list( - /obj/item/abductor, - /obj/item/cautery/alien, - /obj/item/circuitboard/machine/abductor, - /obj/item/circular_saw/alien, - /obj/item/crowbar/abductor, - /obj/item/gun/energy/alien, - /obj/item/gun/energy/shrink_ray, - /obj/item/hemostat/alien, - /obj/item/melee/baton/abductor, - /obj/item/multitool/abductor, - /obj/item/retractor/alien, - /obj/item/scalpel/alien, - /obj/item/screwdriver/abductor, - /obj/item/surgicaldrill/alien, - /obj/item/weldingtool/abductor, - /obj/item/wirecutters/abductor, - /obj/item/wrench/abductor, - ) - - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 12500) - discount_experiments = list(/datum/experiment/scanning/points/slime/hard = 10000) - hidden = TRUE - -/datum/techweb_node/alien_engi - id = "alien_engi" - display_name = "Alien Engineering" - description = "Alien engineering tools" - prereq_ids = list("alientech", "adv_engi") - - design_ids = list( - "alien_crowbar", - "alien_multitool", - "alien_screwdriver", - "alien_welder", - "alien_wirecutters", - "alien_wrench", - ) - - required_items_to_unlock = list( - /obj/item/abductor, - /obj/item/circuitboard/machine/abductor, - /obj/item/crowbar/abductor, - /obj/item/gun/energy/shrink_ray, - /obj/item/melee/baton/abductor, - /obj/item/multitool/abductor, - /obj/item/screwdriver/abductor, - /obj/item/weldingtool/abductor, - /obj/item/wirecutters/abductor, - /obj/item/wrench/abductor, - ) - - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - hidden = TRUE - -/datum/techweb_node/syndicate_basic - id = "syndicate_basic" - display_name = "Illegal Technology" - description = "Dangerous research used to create dangerous objects." - prereq_ids = list("adv_engi", "adv_weaponry", "explosive_weapons") - design_ids = list( - "advanced_camera", - "ai_cam_upgrade", - "borg_syndicate_module", - "donksoft_refill", - "donksofttoyvendor", - "largecrossbow", - "mag_autorifle", - "mag_autorifle_ap", - "mag_autorifle_ic", - "rapidsyringe", - "suppressor", - "super_pointy_tape", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000) - hidden = TRUE - -/datum/techweb_node/syndicate_basic/New() //Crappy way of making syndicate gear decon supported until there's another way. - . = ..() - if(!SSearly_assets.initialized) - RegisterSignal(SSearly_assets, COMSIG_SUBSYSTEM_POST_INITIALIZE, PROC_REF(register_uplink_items)) - else - register_uplink_items() - -/** - * This needs some clarification: The uplink_items_by_type list is populated on datum/asset/json/uplink/generate. - * SStraitor doesn't actually initialize. I'm bamboozled. - */ -/datum/techweb_node/syndicate_basic/proc/register_uplink_items() - SIGNAL_HANDLER - UnregisterSignal(SSearly_assets, COMSIG_SUBSYSTEM_POST_INITIALIZE) - required_items_to_unlock = list() - for(var/datum/uplink_item/item_path as anything in SStraitor.uplink_items_by_type) - var/datum/uplink_item/item = SStraitor.uplink_items_by_type[item_path] - if(!item.item || !item.illegal_tech) - continue - required_items_to_unlock |= item.item //allows deconning to unlock. - - -////////////////////////B.E.P.I.S. Locked Techs//////////////////////// -/datum/techweb_node/light_apps - id = "light_apps" - display_name = "Illumination Applications" - description = "Applications of lighting and vision technology not originally thought to be commercially viable." - prereq_ids = list("base") - design_ids = list( - "bright_helmet", - "rld_mini", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - hidden = TRUE - experimental = TRUE - -/datum/techweb_node/extreme_office - id = "extreme_office" - display_name = "Advanced Office Applications" - description = "Some of our smartest lab guys got together on a Friday and improved our office efficiency by 350%. Here's how." - prereq_ids = list("base") - design_ids = list( - "mauna_mug", - "rolling_table", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - hidden = TRUE - experimental = TRUE - -/datum/techweb_node/spec_eng - id = "spec_eng" - display_name = "Specialized Engineering" - description = "Conventional wisdom has deemed these engineering products 'technically' safe, but far too dangerous to traditionally condone." - prereq_ids = list("base") - design_ids = list( - "eng_gloves", - "lava_rods", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - hidden = TRUE - experimental = TRUE - -/datum/techweb_node/aus_security - id = "aus_security" - display_name = "Australicus Security Protocols" - description = "It is said that security in the Australicus sector is tight, so we took some pointers from their equipment. Thankfully, our sector lacks any signs of these, 'dropbears'." - prereq_ids = list("base") - design_ids = list( - "pin_explorer", - "stun_boomerang", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - hidden = TRUE - experimental = TRUE - -/datum/techweb_node/interrogation - id = "interrogation" - display_name = "Enhanced Interrogation Technology" - description = "By cross-referencing several declassified documents from past dictatorial regimes, we were able to develop an incredibly effective interrogation device. \ - Ethical concerns about loss of free will do not apply to criminals, according to galactic law." - prereq_ids = list("base") - design_ids = list( - "hypnochair", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3500) - hidden = TRUE - experimental = TRUE - -/datum/techweb_node/sticky_advanced - id = "sticky_advanced" - display_name = "Advanced Sticky Technology" - description = "Taking a good joke too far? Nonsense!" - design_ids = list( - "pointy_tape", - "super_sticky_tape", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - hidden = TRUE - experimental = TRUE - -/datum/techweb_node/tackle_advanced - id = "tackle_advanced" - display_name = "Advanced Grapple Technology" - description = "Nanotrasen would like to remind its researching staff that it is never acceptable to \"glomp\" your coworkers, and further \"scientific trials\" on the subject \ - will no longer be accepted in its academic journals." - design_ids = list( - "tackle_dolphin", - "tackle_rocket", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - hidden = TRUE - experimental = TRUE - -/datum/techweb_node/mod_experimental - id = "mod_experimental" - display_name = "Experimental Modular Suits" - description = "Applications of experimentality when creating MODsuits have created these..." - prereq_ids = list("base") - design_ids = list( - "mod_disposal", - "mod_joint_torsion", - "mod_recycler", - "mod_shooting", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - hidden = TRUE - experimental = TRUE - -/datum/techweb_node/mod_experimental - id = "mod_experimental" - display_name = "Experimental Modular Suits" - description = "Applications of experimentality when creating MODsuits have created these..." - prereq_ids = list("base") - design_ids = list( - "mod_disposal", - "mod_joint_torsion", - "mod_recycler", - "mod_shooting", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - hidden = TRUE - experimental = TRUE - -/datum/techweb_node/posisphere - id = "positronic_sphere" - display_name = "Experimental Spherical Positronic Brain" - description = "Recent developments on cost-cutting measures have allowed us to cut positronic brain cubes into twice-as-cheap spheres. Unfortunately, it also allows them to move around the lab via rolling maneuvers." - prereq_ids = list("base") - design_ids = list( - "posisphere", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - hidden = TRUE - experimental = TRUE diff --git a/code/modules/research/techweb/nodes/alien_nodes.dm b/code/modules/research/techweb/nodes/alien_nodes.dm new file mode 100644 index 0000000000000..bf19c0c54a47d --- /dev/null +++ b/code/modules/research/techweb/nodes/alien_nodes.dm @@ -0,0 +1,100 @@ +/datum/techweb_node/alientech //AYYYYYYYYLMAOO tech + id = "alientech" + display_name = "Alien Technology" + description = "Things used by the greys." + prereq_ids = list("bluespace_travel") + required_items_to_unlock = list( + /obj/item/stack/sheet/mineral/abductor, + /obj/item/abductor, + /obj/item/cautery/alien, + /obj/item/circuitboard/machine/abductor, + /obj/item/circular_saw/alien, + /obj/item/crowbar/abductor, + /obj/item/gun/energy/alien, + /obj/item/gun/energy/shrink_ray, + /obj/item/hemostat/alien, + /obj/item/melee/baton/abductor, + /obj/item/multitool/abductor, + /obj/item/retractor/alien, + /obj/item/scalpel/alien, + /obj/item/screwdriver/abductor, + /obj/item/surgicaldrill/alien, + /obj/item/weldingtool/abductor, + /obj/item/wirecutters/abductor, + /obj/item/wrench/abductor, + ) + design_ids = list( + "alienalloy", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + hidden = TRUE + +/datum/techweb_node/alientech/on_station_research() + SSshuttle.shuttle_purchase_requirements_met[SHUTTLE_UNLOCK_ALIENTECH] = TRUE + +/datum/techweb_node/alien_engi + id = "alien_engi" + display_name = "Alien Engineering" + description = "Alien engineering tools" + prereq_ids = list("alientech", "exp_tools") + design_ids = list( + "alien_crowbar", + "alien_multitool", + "alien_screwdriver", + "alien_welder", + "alien_wirecutters", + "alien_wrench", + ) + required_items_to_unlock = list( + /obj/item/abductor, + /obj/item/circuitboard/machine/abductor, + /obj/item/crowbar/abductor, + /obj/item/gun/energy/shrink_ray, + /obj/item/melee/baton/abductor, + /obj/item/multitool/abductor, + /obj/item/screwdriver/abductor, + /obj/item/weldingtool/abductor, + /obj/item/wirecutters/abductor, + /obj/item/wrench/abductor, + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + hidden = TRUE + +/datum/techweb_node/alien_surgery + id = "alien_surgery" + display_name = "Alien Surgery" + description = "Abductors did nothing wrong." + prereq_ids = list("alientech", "surgery_tools") + design_ids = list( + "alien_cautery", + "alien_drill", + "alien_hemostat", + "alien_retractor", + "alien_saw", + "alien_scalpel", + "surgery_brainwashing", + "surgery_heal_combo_upgrade_femto", + "surgery_zombie", + ) + required_items_to_unlock = list( + /obj/item/abductor, + /obj/item/cautery/alien, + /obj/item/circuitboard/machine/abductor, + /obj/item/circular_saw/alien, + /obj/item/crowbar/abductor, + /obj/item/gun/energy/alien, + /obj/item/gun/energy/shrink_ray, + /obj/item/hemostat/alien, + /obj/item/melee/baton/abductor, + /obj/item/multitool/abductor, + /obj/item/retractor/alien, + /obj/item/scalpel/alien, + /obj/item/screwdriver/abductor, + /obj/item/surgicaldrill/alien, + /obj/item/weldingtool/abductor, + /obj/item/wirecutters/abductor, + /obj/item/wrench/abductor, + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_5_POINTS) + discount_experiments = list(/datum/experiment/scanning/points/slime/hard = TECHWEB_TIER_5_POINTS) + hidden = TRUE diff --git a/code/modules/research/techweb/nodes/atmos_nodes.dm b/code/modules/research/techweb/nodes/atmos_nodes.dm new file mode 100644 index 0000000000000..b97538070beba --- /dev/null +++ b/code/modules/research/techweb/nodes/atmos_nodes.dm @@ -0,0 +1,114 @@ +/datum/techweb_node/atmos + id = "atmos" + starting_node = TRUE + display_name = "Atmospherics" + description = "Maintaining station air and related life support systems." + design_ids = list( + "atmos_control", + "atmosalerts", + "thermomachine", + "space_heater", + "generic_tank", + "oxygen_tank", + "plasma_tank", + "plasmaman_tank_belt", + "plasmarefiller", + "extinguisher", + "gas_filter", + "plasmaman_gas_filter", + "analyzer", + "pipe_painter", + ) + +/datum/techweb_node/gas_compression + id = "gas_compression" + display_name = "Gas Compression" + description = "Highly pressurized gases hold potential for unlocking immense energy capabilities." + prereq_ids = list("atmos") + design_ids = list( + "tank_compressor", + "emergency_oxygen", + "emergency_oxygen_engi", + "power_turbine_console", + "turbine_part_compressor", + "turbine_part_rotor", + "turbine_part_stator", + "turbine_compressor", + "turbine_rotor", + "turbine_stator", + "atmos_thermal", + "pneumatic_seal", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + +/datum/techweb_node/plasma_control + id = "plasma_control" + display_name = "Controlled Plasma" + description = "Experiments with high-pressure gases and electricity resulting in crystallization and controlled plasma reactions." + prereq_ids = list("gas_compression", "energy_manipulation") + design_ids = list( + "crystallizer", + "electrolyzer", + "pacman", + "mech_generator", + "plasmacutter", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + required_experiments = list(/datum/experiment/ordnance/gaseous/plasma) + +/datum/techweb_node/fusion + id = "fusion" + display_name = "Fusion" + description = "Investigating fusion reactor technology to achieve sustainable and efficient energy production through controlled plasma reactions involving noble gases." + prereq_ids = list("plasma_control") + design_ids = list( + "HFR_core", + "HFR_corner", + "HFR_fuel_input", + "HFR_interface", + "HFR_moderator_input", + "HFR_waste_output", + "bolter_wrench", + "rpd_loaded", + "engine_goggles", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + required_experiments = list(/datum/experiment/ordnance/gaseous/bz) + discount_experiments = list(/datum/experiment/ordnance/gaseous/nitrous_oxide = TECHWEB_TIER_3_POINTS) + +/datum/techweb_node/exp_tools + id = "exp_tools" + display_name = "Experimental Tools" + description = "Enhances the functionality and versatility of station tools." + prereq_ids = list("fusion") + design_ids = list( + "flatpacker", + "handdrill", + "exwelder", + "jawsoflife", + "rangedanalyzer", + "rtd_loaded", + "rcd_loaded", + "rcd_ammo", + "weldingmask", + "magboots", + "adv_fire_extinguisher", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) + discount_experiments = list(/datum/experiment/ordnance/gaseous/noblium = TECHWEB_TIER_4_POINTS) + +/datum/techweb_node/rcd_upgrade + id = "rcd_upgrade" + display_name = "Rapid Device Upgrade Designs" + description = "New designs and enhancements for RCD and RPD." + prereq_ids = list("exp_tools", "parts_bluespace") + design_ids = list( + "rcd_upgrade_silo_link", + "rcd_upgrade_anti_interrupt", + "rcd_upgrade_cooling", + "rcd_upgrade_frames", + "rcd_upgrade_furnishing", + "rcd_upgrade_simple_circuits", + "rpd_upgrade_unwrench", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_5_POINTS) diff --git a/code/modules/research/techweb/nodes/bepis_nodes.dm b/code/modules/research/techweb/nodes/bepis_nodes.dm new file mode 100644 index 0000000000000..c051aab526f81 --- /dev/null +++ b/code/modules/research/techweb/nodes/bepis_nodes.dm @@ -0,0 +1,123 @@ +/datum/techweb_node/light_apps + id = "light_apps" + display_name = "Illumination Applications" + description = "Applications of lighting and vision technology not originally thought to be commercially viable." + design_ids = list( + "bright_helmet", + "rld_mini", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + hidden = TRUE + experimental = TRUE + +/datum/techweb_node/extreme_office + id = "extreme_office" + display_name = "Advanced Office Applications" + description = "Some of our smartest lab guys got together on a Friday and improved our office efficiency by 350%. Here's how." + design_ids = list( + "mauna_mug", + "rolling_table", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + hidden = TRUE + experimental = TRUE + +/datum/techweb_node/spec_eng + id = "spec_eng" + display_name = "Specialized Engineering" + description = "Conventional wisdom has deemed these engineering products 'technically' safe, but far too dangerous to traditionally condone." + design_ids = list( + "eng_gloves", + "lava_rods", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + hidden = TRUE + experimental = TRUE + +/datum/techweb_node/aus_security + id = "aus_security" + display_name = "Australicus Security Protocols" + description = "It is said that security in the Australicus sector is tight, so we took some pointers from their equipment. Thankfully, our sector lacks any signs of these, 'dropbears'." + design_ids = list( + "pin_explorer", + "stun_boomerang", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + hidden = TRUE + experimental = TRUE + +/datum/techweb_node/interrogation + id = "interrogation" + display_name = "Enhanced Interrogation Technology" + description = "By cross-referencing several declassified documents from past dictatorial regimes, we were able to develop an incredibly effective interrogation device. \ + Ethical concerns about loss of free will do not apply to criminals, according to galactic law." + design_ids = list( + "hypnochair", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + hidden = TRUE + experimental = TRUE + +/datum/techweb_node/sticky_advanced + id = "sticky_advanced" + display_name = "Advanced Sticky Technology" + description = "Taking a good joke too far? Nonsense!" + design_ids = list( + "pointy_tape", + "super_sticky_tape", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + hidden = TRUE + experimental = TRUE + +/datum/techweb_node/tackle_advanced + id = "tackle_advanced" + display_name = "Advanced Grapple Technology" + description = "Nanotrasen would like to remind its researching staff that it is never acceptable to \"glomp\" your coworkers, and further \"scientific trials\" on the subject \ + will no longer be accepted in its academic journals." + design_ids = list( + "tackle_dolphin", + "tackle_rocket", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + hidden = TRUE + experimental = TRUE + +/datum/techweb_node/mod_experimental + id = "mod_experimental" + display_name = "Experimental Modular Suits" + description = "Applications of experimentality when creating MODsuits have created these..." + design_ids = list( + "mod_disposal", + "mod_joint_torsion", + "mod_recycler", + "mod_shooting", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + hidden = TRUE + experimental = TRUE + +/datum/techweb_node/mod_experimental + id = "mod_experimental" + display_name = "Experimental Modular Suits" + description = "Applications of experimentality when creating MODsuits have created these..." + design_ids = list( + "mod_disposal", + "mod_joint_torsion", + "mod_recycler", + "mod_shooting", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + hidden = TRUE + experimental = TRUE + +/datum/techweb_node/posisphere + id = "positronic_sphere" + display_name = "Experimental Spherical Positronic Brain" + description = "Recent developments on cost-cutting measures have allowed us to cut positronic brain cubes into twice-as-cheap spheres. Unfortunately, it also allows them to move around the lab via rolling maneuvers." + design_ids = list( + "posisphere", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + hidden = TRUE + experimental = TRUE diff --git a/code/modules/research/techweb/nodes/biology_nodes.dm b/code/modules/research/techweb/nodes/biology_nodes.dm new file mode 100644 index 0000000000000..6a14d7d517c8f --- /dev/null +++ b/code/modules/research/techweb/nodes/biology_nodes.dm @@ -0,0 +1,64 @@ +/datum/techweb_node/bio_scan + id = "bio_scan" + display_name = "Biological Scan" + description = "Advanced technology for analyzing patient health and reagent compositions, ensuring precise diagnostics and treatment in the medical bay." + prereq_ids = list("medbay_equip") + design_ids = list( + "healthanalyzer", + "autopsyscanner", + "medical_kiosk", + "chem_master", + "ph_meter", + "scigoggles", + "mod_reagent_scanner", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + +/datum/techweb_node/cytology + id = "cytology" + display_name = "Cytology" + description = "Cellular biology research focused on cultivation of limbs and diverse organisms from cells." + prereq_ids = list("bio_scan") + design_ids = list( + "limbgrower", + "pandemic", + "petri_dish", + "swab", + "biopsy_tool", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + +/datum/techweb_node/xenobiology + id = "xenobiology" + display_name = "Xenobiology" + description = "Exploration of non-human biology, unlocking the secrets of extraterrestrial lifeforms and their unique biological processes." + prereq_ids = list("cytology") + design_ids = list( + "xenobioconsole", + "slime_scanner", + "limbdesign_ethereal", + "limbdesign_felinid", + "limbdesign_lizard", + "limbdesign_plasmaman", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + required_experiments = list(/datum/experiment/scanning/random/cytology) + +/datum/techweb_node/gene_engineering + id = "gene_engineering" + display_name = "Gene Engineering" + description = "Research into sophisticated DNA manipulation techniques, enabling the modification of human genetic traits to unlock specific abilities and enhancements." + prereq_ids = list("selection", "xenobiology") + design_ids = list( + "dnascanner", + "scan_console", + "dna_disk", + "dnainfuser", + "genescanner", + "mod_dna_lock", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) + discount_experiments = list( + /datum/experiment/scanning/random/plants/traits = TECHWEB_TIER_2_POINTS, + /datum/experiment/scanning/points/slime/hard = TECHWEB_TIER_2_POINTS, + ) diff --git a/code/modules/research/techweb/nodes/circuit_nodes.dm b/code/modules/research/techweb/nodes/circuit_nodes.dm new file mode 100644 index 0000000000000..81f6dad275f0d --- /dev/null +++ b/code/modules/research/techweb/nodes/circuit_nodes.dm @@ -0,0 +1,151 @@ +/datum/techweb_node/programming + id = "programming" + starting_node = TRUE + display_name = "Programming" + description = "Dedicate an entire shift to program a fridge to greet you when opened." + prereq_ids = list("robotics") + design_ids = list( + "component_printer", + "module_duplicator", + "circuit_multitool", + "compact_remote_shell", + "usb_cable", + "integrated_circuit", + "comp_access_checker", + "comp_arctan2", + "comp_arithmetic", + "comp_assoc_list_pick", + "comp_assoc_list_remove", + "comp_assoc_list_set", + "comp_binary_convert", + "comp_clock", + "comp_comparison", + "comp_concat", + "comp_concat_list", + "comp_decimal_convert", + "comp_delay", + "comp_direction", + "comp_element_find", + "comp_filter_list", + "comp_foreach", + "comp_format", + "comp_format_assoc", + "comp_get_column", + "comp_gps", + "comp_health", + "comp_health_state", + "comp_hear", + "comp_id_access_reader", + "comp_id_getter", + "comp_id_info_reader", + "comp_index", + "comp_index_assoc", + "comp_index_table", + "comp_laserpointer", + "comp_length", + "comp_light", + "comp_list_add", + "comp_list_assoc_literal", + "comp_list_clear", + "comp_list_literal", + "comp_list_pick", + "comp_list_remove", + "comp_logic", + "comp_matscanner", + "comp_mmi", + "comp_module", + "comp_multiplexer", + "comp_not", + "comp_ntnet_receive", + "comp_ntnet_send", + "comp_ntnet_send_list_literal", + "comp_pinpointer", + "comp_pressuresensor", + "comp_radio", + "comp_random", + "comp_reagents", + "comp_router", + "comp_select_query", + "comp_self", + "comp_set_variable_trigger", + "comp_soundemitter", + "comp_species", + "comp_speech", + "comp_speech", + "comp_split", + "comp_string_contains", + "comp_tempsensor", + "comp_textcase", + "comp_timepiece", + "comp_toggle", + "comp_tonumber", + "comp_tostring", + "comp_trigonometry", + "comp_typecast", + "comp_typecheck", + "comp_view_sensor", + ) + +/datum/techweb_node/circuit_shells + id = "circuit_shells" + display_name = "Advanced Circuit Shells" + description = "Adding brains to more things." + prereq_ids = list("programming") + design_ids = list( + "assembly_shell", + "bot_shell", + "controller_shell", + "dispenser_shell", + "door_shell", + "gun_shell", + "keyboard_shell", + "module_shell", + "money_bot_shell", + "scanner_gate_shell", + "scanner_shell", + "comp_equip_action", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + +/datum/techweb_node/bci + id = "bci" + display_name = "Brain-Computer Interface" + description = "Embedded brain circuits. May occasionally stream Nanotrasen ads in dreams." + prereq_ids = list("circuit_shells", "passive_implants") + design_ids = list( + "bci_implanter", + "bci_shell", + "comp_bar_overlay", + "comp_camera_bci", + "comp_counter_overlay", + "comp_install_detector", + "comp_object_overlay", + "comp_reagent_injector", + "comp_target_intercept", + "comp_thought_listener", + "comp_vox", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + discount_experiments = list(/datum/experiment/scanning/people/skillchip = TECHWEB_TIER_2_POINTS) + +/datum/techweb_node/programmed_robot + id = "programmed_robot" + display_name = "Programmed Robot" + description = "Grants access to movable shells, allowing for remote operations and pranks." + prereq_ids = list("circuit_shells") + design_ids = list( + "drone_shell", + "comp_pathfind", + "comp_pull", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + +/datum/techweb_node/programmed_server + id = "programmed_server" + display_name = "Programmed Server" + description = "Grants access to a server shell that has a very high capacity for components." + prereq_ids = list("bci") + design_ids = list( + "server_shell", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) diff --git a/code/modules/research/techweb/nodes/cyborg_nodes.dm b/code/modules/research/techweb/nodes/cyborg_nodes.dm new file mode 100644 index 0000000000000..a4e0debd6ebb8 --- /dev/null +++ b/code/modules/research/techweb/nodes/cyborg_nodes.dm @@ -0,0 +1,231 @@ +/datum/techweb_node/augmentation + id = "augmentation" + starting_node = TRUE + display_name = "Augmentation" + description = "For those who prefer shiny metal over squishy flesh." + prereq_ids = list("robotics") + design_ids = list( + "borg_chest", + "borg_head", + "borg_l_arm", + "borg_l_leg", + "borg_r_arm", + "borg_r_leg", + "cybernetic_eyes", + "cybernetic_eyes_moth", + "cybernetic_ears", + "cybernetic_lungs", + "cybernetic_stomach", + "cybernetic_liver", + "cybernetic_heart", + ) + +/datum/techweb_node/cybernetics + id = "cybernetics" + display_name = "Cybernetics" + description = "Sapient robots with preloaded tool modules and programmable laws." + prereq_ids = list("augmentation") + design_ids = list( + "robocontrol", + "borgupload", + "cyborgrecharger", + "borg_suit", + "mmi_posi", + "mmi", + "mmi_m", + "advanced_l_arm", + "advanced_r_arm", + "advanced_l_leg", + "advanced_r_leg", + "borg_upgrade_rename", + "borg_upgrade_restart", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + +/datum/techweb_node/borg_service + id = "borg_service" + display_name = "Service Cyborg Upgrades" + description = "Let them do the cookin' by the book." + prereq_ids = list("cybernetics") + design_ids = list( + "borg_upgrade_rolling_table", + "borg_upgrade_condiment_synthesizer", + "borg_upgrade_silicon_knife", + "borg_upgrade_service_apparatus", + "borg_upgrade_drink_apparatus", + "borg_upgrade_service_cookbook", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + +/datum/techweb_node/borg_mining + id = "borg_mining" + display_name = "Mining Cyborg Upgrades" + description = "To mine places too dangerous for humans." + prereq_ids = list("cybernetics") + design_ids = list( + "borg_upgrade_lavaproof", + "borg_upgrade_holding", + "borg_upgrade_diamonddrill", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + +/datum/techweb_node/borg_medical + id = "borg_medical" + display_name = "Medical Cyborg Upgrades" + description = "Let them follow Asimov's First Law." + prereq_ids = list("borg_service", "surgery_adv") + design_ids = list( + "borg_upgrade_pinpointer", + "borg_upgrade_beakerapp", + "borg_upgrade_defibrillator", + "borg_upgrade_expandedsynthesiser", + "borg_upgrade_piercinghypospray", + "borg_upgrade_surgicalprocessor", + "borg_upgrade_surgicalomnitool", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + +/datum/techweb_node/borg_utility + id = "borg_utility" + display_name = "Untility Cyborg Upgrades" + description = "Let them wipe our floors for us." + prereq_ids = list("borg_service", "sanitation") + design_ids = list( + "borg_upgrade_advancedmop", + "borg_upgrade_broomer", + "borg_upgrade_expand", + "borg_upgrade_prt", + "borg_upgrade_selfrepair", + "borg_upgrade_thrusters", + "borg_upgrade_trashofholding", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + +/datum/techweb_node/borg_utility/New() + . = ..() + if(!CONFIG_GET(flag/disable_secborg)) + design_ids += "borg_upgrade_disablercooler" + +/datum/techweb_node/borg_engi + id = "borg_engi" + display_name = "Engineering Cyborg Upgrades" + description = "To slack even more." + prereq_ids = list("borg_mining", "parts_upg") + design_ids = list( + "borg_upgrade_rped", + "borg_upgrade_engineeringomnitool", + "borg_upgrade_circuitapp", + "borg_upgrade_inducer", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + +// Implants root node +/datum/techweb_node/passive_implants + id = "passive_implants" + display_name = "Passive Implants" + description = "Implants designed to operate seamlessly without active user input, enhancing various physiological functions or providing continuous benefits." + prereq_ids = list("augmentation") + design_ids = list( + "skill_station", + "implant_trombone", + "implant_chem", + "implant_tracking", + "implant_exile", + "implant_beacon", + "implant_bluespace", + "implantcase", + "implanter", + "locator", + "c38_trac", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + +/datum/techweb_node/cyber/cyber_implants + id = "cyber_implants" + display_name = "Cybernetic Implants" + description = "Advanced technological enhancements integrated into the body, offering improved physical capabilities." + prereq_ids = list("passive_implants", "cybernetics") + design_ids = list( + "ci-breather", + "ci-nutriment", + "ci-thrusters", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + +/datum/techweb_node/cyber/New() + ..() + if(HAS_TRAIT(SSstation, STATION_TRAIT_CYBERNETIC_REVOLUTION)) + research_costs[TECHWEB_POINT_TYPE_GENERIC] /= 2 + +/datum/techweb_node/cyber/combat_implants + id = "combat_implants" + display_name = "Combat Implants" + description = "To make sure that you can wake the f*** up, samurai." + prereq_ids = list("cyber_implants") + design_ids = list( + "ci-reviver", + "ci-antidrop", + "ci-antistun", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) + +/datum/techweb_node/cyber/integrated_toolsets + id = "integrated_toolsets" + display_name = "Integrated Toolsets" + description = "Decades of contraband smuggling by assistants have led to the development of a full toolbox that fits seamlessly into your arm." + prereq_ids = list("combat_implants", "exp_tools") + design_ids = list( + "ci-nutrimentplus", + "ci-toolset", + "ci-surgery", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_5_POINTS) + +/datum/techweb_node/cyber/cyber_organs + id = "cyber_organs" + display_name = "Cybernetic Organs" + description = "We have the technology to rebuild him." + prereq_ids = list("cybernetics") + design_ids = list( + "cybernetic_eyes_improved", + "cybernetic_eyes_improved_moth", + "cybernetic_ears_u", + "cybernetic_lungs_tier2", + "cybernetic_stomach_tier2", + "cybernetic_liver_tier2", + "cybernetic_heart_tier2", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + +/datum/techweb_node/cyber/cyber_organs_upgraded + id = "cyber_organs_upgraded" + display_name = "Upgraded Cybernetic Organs" + description = "We have the technology to upgrade him." + prereq_ids = list("cyber_organs") + design_ids = list( + "ci-gloweyes", + "ci-welding", + "ci-gloweyes-moth", + "ci-welding-moth", + "cybernetic_ears_whisper", + "cybernetic_lungs_tier3", + "cybernetic_stomach_tier3", + "cybernetic_liver_tier3", + "cybernetic_heart_tier3", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) + required_experiments = list(/datum/experiment/scanning/people/augmented_organs) + +/datum/techweb_node/cyber/cyber_organs_adv + id = "cyber_organs_adv" + display_name = "Advanced Cybernetic Organs" + description = "Cutting-edge cybernetic organs offering enhanced sensory capabilities, making it easier than ever to detect ERP." + prereq_ids = list("cyber_organs_upgraded", "night_vision") + design_ids = list( + "cybernetic_ears_xray", + "ci-thermals", + "ci-xray", + "ci-thermals-moth", + "ci-xray-moth", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_5_POINTS) diff --git a/code/modules/research/techweb/nodes/engi_nodes.dm b/code/modules/research/techweb/nodes/engi_nodes.dm new file mode 100644 index 0000000000000..182f689c372cd --- /dev/null +++ b/code/modules/research/techweb/nodes/engi_nodes.dm @@ -0,0 +1,232 @@ +// Parts root node +/datum/techweb_node/parts + id = "parts" + starting_node = TRUE + display_name = "Essential Stock Parts" + description = "Foundational components that form the backbone of station operations, encompassing a range of essential equipment necessary for day-to-day functionality." + design_ids = list( + "micro_servo", + "basic_capacitor", + "basic_matter_bin", + "basic_micro_laser", + "basic_scanning", + "high_cell", + "basic_cell", + "miniature_power_cell", + "condenser", + "igniter", + "infrared_emitter", + "prox_sensor", + "signaler", + "timer", + "voice_analyzer", + "health_sensor", + "sflash", + ) + +/datum/techweb_node/parts_upg + id = "parts_upg" + display_name = "Upgraded Parts" + description = "Offering enhanced capabilities beyond their basic counterparts." + prereq_ids = list("parts", "energy_manipulation") + design_ids = list( + "rped", + "high_micro_laser", + "adv_capacitor", + "nano_servo", + "adv_matter_bin", + "adv_scanning", + "super_cell", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + +/datum/techweb_node/parts_adv + id = "parts_adv" + display_name = "Advanced Parts" + description = "The most finely tuned and accurate stock parts." + prereq_ids = list("parts_upg") + design_ids = list( + "ultra_micro_laser", + "super_capacitor", + "pico_servo", + "super_matter_bin", + "phasic_scanning", + "hyper_cell", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + required_experiments = list(/datum/experiment/scanning/points/machinery_tiered_scan/tier2_any) + + +/datum/techweb_node/parts_bluespace + id = "parts_bluespace" + display_name = "Bluespace Parts" + description = "Integrating the latest in bluespace technology, these advanced components not only enhance functionality but also open up new possibilities for the station's technological capabilities." + prereq_ids = list("parts_adv", "bluespace_travel") + design_ids = list( + "bs_rped", + "quadultra_micro_laser", + "quadratic_capacitor", + "femto_servo", + "bluespace_matter_bin", + "triphasic_scanning", + "bluespace_cell", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) + discount_experiments = list(/datum/experiment/scanning/points/machinery_tiered_scan/tier3_any = TECHWEB_TIER_4_POINTS) + +/datum/techweb_node/telecomms + id = "telecomms" + display_name = "Telecommunications Technology" + description = "A comprehensive suite of machinery for station-wide communication setups, ensuring seamless connectivity and operational coordination." + prereq_ids = list("parts_bluespace") + design_ids = list( + "comm_monitor", + "comm_server", + "message_monitor", + "s_hub", + "s_messaging", + "s_server", + "s_processor", + "s_relay", + "s_bus", + "s_broadcaster", + "s_receiver", + "s_amplifier", + "s_analyzer", + "s_ansible", + "s_crystal", + "s_filter", + "s_transmitter", + "s_treatment", + "gigabeacon", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_5_POINTS) + +// Engineering root node +/datum/techweb_node/construction + id = "construction" + starting_node = TRUE + display_name = "Construction" + description = "Tools and essential machinery used for station maintenance and expansion." + design_ids = list( + "circuit_imprinter_offstation", + "circuit_imprinter", + "solarcontrol", + "solar_panel", + "solar_tracker", + "power_control", + "airalarm_electronics", + "airlock_board", + "firealarm_electronics", + "firelock_board", + "trapdoor_electronics", + "blast", + "tile_sprayer", + "airlock_painter", + "decal_painter", + "rwd", + "cable_coil", + "welding_helmet", + "welding_tool", + "tscanner", + "analyzer", + "multitool", + "wrench", + "crowbar", + "screwdriver", + "wirecutters", + "light_bulb", + "light_tube", + "intercom_frame", + "newscaster_frame", + "status_display_frame", + "circuit", + "circuitgreen", + "circuitred", + "tram_floor_dark", + "tram_floor_light", + "tram_controller", + "tram_display", + "crossing_signal", + "guideway_sensor", + ) + +/datum/techweb_node/energy_manipulation + id = "energy_manipulation" + display_name = "Energy Manipulation" + description = "Harnessing the raw power of lightning arcs through sophisticated energy control methods." + prereq_ids = list("construction") + design_ids = list( + "apc_control", + "powermonitor", + "smes", + "emitter", + "grounding_rod", + "tesla_coil", + "cell_charger", + "recharger", + "inducer", + "inducerengi", + "welding_goggles", + "tray_goggles", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + +/datum/techweb_node/holographics + id = "holographics" + display_name = "Holographics" + description = "Use of holographic technology for signage and barriers." + prereq_ids = list("energy_manipulation") + design_ids = list( + "forcefield_projector", + "holosign", + "holosignsec", + "holosignengi", + "holosignatmos", + "holosignrestaurant", + "holosignbar", + "holobarrier_jani", + "holobarrier_med", + "holopad", + "vendatray", + "holodisk", + "modular_shield_generator", + "modular_shield_node", + "modular_shield_relay", + "modular_shield_charger", + "modular_shield_well", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + +/datum/techweb_node/hud + id = "hud" + display_name = "Integrated HUDs" + description = "Initially developed for assistants to learn the nuances of different professions through augmented reality." + prereq_ids = list("holographics", "cyber_implants") + design_ids = list( + "health_hud", + "diagnostic_hud", + "security_hud", + "mod_visor_medhud", + "mod_visor_diaghud", + "mod_visor_sechud", + "ci-medhud", + "ci-diaghud", + "ci-sechud", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + +/datum/techweb_node/night_vision + id = "night_vision" + display_name = "Night Vision Technology" + description = "There are whispers that Nanotrasen pushed for this technology to extend shift durations, ensuring productivity around the clock." + prereq_ids = list("hud") + design_ids = list( + "diagnostic_hud_night", + "health_hud_night", + "night_visision_goggles", + "nvgmesons", + "nv_scigoggles", + "security_hud_night", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) diff --git a/code/modules/research/techweb/nodes/mech_nodes.dm b/code/modules/research/techweb/nodes/mech_nodes.dm new file mode 100644 index 0000000000000..4f58ed25c8955 --- /dev/null +++ b/code/modules/research/techweb/nodes/mech_nodes.dm @@ -0,0 +1,251 @@ +/datum/techweb_node/mech_assembly + id = "mech_assembly" + starting_node = TRUE + display_name = "Mech Assembly" + description = "Development of mech designed to contend with artificial gravity while transporting cargo." + prereq_ids = list("robotics") + design_ids = list( + "mechapower", + "mech_recharger", + "ripley_chassis", + "ripley_torso", + "ripley_left_arm", + "ripley_right_arm", + "ripley_left_leg", + "ripley_right_leg", + "ripley_main", + "ripley_peri", + "mech_hydraulic_clamp", + ) + +/datum/techweb_node/mech_equipment + id = "mech_equipment" + display_name = "Expedition Equipment" + description = "Specialized mech gear tailored for navigating space and celestial bodies, ensuring durability and functionality in the harshest conditions." + prereq_ids = list("mech_assembly") + design_ids = list( + "mechacontrol", + "botpad", + "botpad_remote", + "ripleyupgrade", + "mech_air_tank", + "mech_thrusters", + "mech_extinguisher", + "mecha_camera", + "mecha_tracking", + "mech_radio", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + +/datum/techweb_node/mech_clown + id = "mech_clown" + display_name = "Funny Robots" + description = "Fueled by laughter." + prereq_ids = list("mech_assembly") + design_ids = list( + "honk_chassis", + "honk_torso", + "honk_head", + "honk_left_arm", + "honk_right_arm", + "honk_left_leg", + "honk_right_leg", + "honker_main", + "honker_peri", + "honker_targ", + "mech_banana_mortar", + "mech_honker", + "mech_mousetrap_mortar", + "mech_punching_face", + "borg_transform_clown", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + +/datum/techweb_node/mech_medical + id = "mech_medical" + display_name = "Medical Mech" + description = "Advanced robotic unit equipped with syringe guns and healing beams, revolutionizing medical assistance in hazardous environments." + prereq_ids = list("mech_assembly", "chem_synthesis") + design_ids = list( + "odysseus_chassis", + "odysseus_torso", + "odysseus_head", + "odysseus_left_arm", + "odysseus_right_arm", + "odysseus_left_leg", + "odysseus_right_leg", + "odysseus_main", + "odysseus_peri", + "mech_medi_beam", + "mech_syringe_gun", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + +/datum/techweb_node/mech_mining + id = "mech_mining" + display_name = "Mining Mech" + description = "Robust mech engineered to withstand lava and storms for continuous off-station mining operations." + prereq_ids = list("mech_equipment", "mining") + design_ids = list( + "clarke_chassis", + "clarke_torso", + "clarke_head", + "clarke_left_arm", + "clarke_right_arm", + "clarke_main", + "clarke_peri", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + +/datum/techweb_node/mech_combat + id = "mech_combat" + display_name = "Combat Mechs" + description = "Modular armor upgrades and specialized equipment for security mechs." + prereq_ids = list("mech_equipment") + design_ids = list( + "mech_ccw_armor", + "mech_proj_armor", + "paddyupgrade", + "mech_hydraulic_claw", + "mech_disabler", + "mech_repair_droid", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + required_experiments = list(/datum/experiment/scanning/random/mecha_equipped_scan) + discount_experiments = list(/datum/experiment/scanning/random/mecha_damage_scan = TECHWEB_TIER_2_POINTS) + +/datum/techweb_node/mech_assault + id = "mech_assault" + display_name = "Assault Mech" + description = "Heavy battle mech boasting robust armor but sacrificing speed for enhanced durability." + prereq_ids = list("mech_combat") + design_ids = list( + "durand_armor", + "durand_chassis", + "durand_torso", + "durand_head", + "durand_left_arm", + "durand_right_arm", + "durand_left_leg", + "durand_right_leg", + "durand_main", + "durand_peri", + "durand_targ", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + +/datum/techweb_node/mech_light + id = "mech_light" + display_name = "Light Combat Mech" + description = "Agile combat mech equipped with overclocking capabilities for temporary speed boosts, prioritizing speed over durability on the battlefield." + prereq_ids = list("mech_combat") + design_ids = list( + "gygax_armor", + "gygax_chassis", + "gygax_torso", + "gygax_head", + "gygax_left_arm", + "gygax_right_arm", + "gygax_left_leg", + "gygax_right_leg", + "gygax_main", + "gygax_peri", + "gygax_targ", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + +/datum/techweb_node/mech_heavy + id = "mech_heavy" + display_name = "Heavy Mech" + description = "Advanced heavy mechanized unit with dual pilot capability, designed for robust battlefield performance and increased tactical versatility." + prereq_ids = list("mech_assault") + design_ids = list( + "savannah_ivanov_armor", + "savannah_ivanov_chassis", + "savannah_ivanov_torso", + "savannah_ivanov_head", + "savannah_ivanov_left_arm", + "savannah_ivanov_right_arm", + "savannah_ivanov_left_leg", + "savannah_ivanov_right_leg", + "savannah_ivanov_main", + "savannah_ivanov_peri", + "savannah_ivanov_targ", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) + +/datum/techweb_node/mech_infiltrator + id = "mech_infiltrator" + display_name = "Infiltration Mech" + description = "Advanced mech with phasing capabilities, allowing it to move through walls and obstacles, ideal for covert and special operations." + prereq_ids = list("mech_light", "anomaly_research") + design_ids = list( + "phazon_armor", + "phazon_chassis", + "phazon_torso", + "phazon_head", + "phazon_left_arm", + "phazon_right_arm", + "phazon_left_leg", + "phazon_right_leg", + "phazon_main", + "phazon_peri", + "phazon_targ", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) + +/datum/techweb_node/mech_energy_guns + id = "mech_energy_guns" + display_name = "Mech Energy Guns" + description = "Scaled-up versions of electric weapons optimized for mech deployment." + prereq_ids = list("mech_combat", "electric_weapons") + design_ids = list( + "mech_laser", + "mech_laser_heavy", + "mech_ion", + "mech_tesla", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) + +/datum/techweb_node/mech_firearms + id = "mech_firearms" + display_name = "Mech Firearms" + description = "Mounted ballistic weaponry, enhancing combat capabilities for mechanized units." + prereq_ids = list("mech_energy_guns", "exotic_ammo") + design_ids = list( + "mech_lmg", + "mech_lmg_ammo", + "mech_scattershot", + "mech_scattershot_ammo", + "mech_carbine", + "mech_carbine_ammo", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_5_POINTS) + +/datum/techweb_node/mech_heavy_arms + id = "mech_heavy_arms" + display_name = "Heavy Mech Firearms" + description = "High-impact weaponry integrated into mechs, optimized for maximum firepower." + prereq_ids = list("mech_heavy", "exotic_ammo") + design_ids = list( + "clusterbang_launcher", + "clusterbang_launcher_ammo", + "mech_grenade_launcher", + "mech_grenade_launcher_ammo", + "mech_missile_rack", + "mech_missile_rack_ammo", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_5_POINTS) + +/datum/techweb_node/mech_equip_bluespace + id = "mech_equip_bluespace" + display_name = "Bluespace Mech Equipment" + description = "An array of equipment empowered by bluespace, providing unmatched mobility and utility." + prereq_ids = list("mech_infiltrator", "bluespace_travel") + design_ids = list( + "mech_gravcatapult", + "mech_teleporter", + "mech_wormhole_gen", + "mech_rcd", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_5_POINTS) diff --git a/code/modules/research/techweb/nodes/medbay_nodes.dm b/code/modules/research/techweb/nodes/medbay_nodes.dm new file mode 100644 index 0000000000000..ce4ef103eda2d --- /dev/null +++ b/code/modules/research/techweb/nodes/medbay_nodes.dm @@ -0,0 +1,97 @@ +/datum/techweb_node/medbay_equip + id = "medbay_equip" + starting_node = TRUE + display_name = "Medbay Equipment" + description = "Essential medical tools to patch you up while medbay is still intact." + design_ids = list( + "operating", + "medicalbed", + "defibmountdefault", + "defibrillator", + "surgical_drapes", + "scalpel", + "retractor", + "hemostat", + "cautery", + "circular_saw", + "surgicaldrill", + "bonesetter", + "blood_filter", + "surgical_tape", + "penlight", + "penlight_paramedic", + "stethoscope", + "beaker", + "large_beaker", + "syringe", + "dropper", + "pillbottle", + ) + +/datum/techweb_node/chem_synthesis + id = "chem_synthesis" + display_name = "Chemical Synthesis" + description = "Synthesizing complex chemicals from electricity and thin air... Don't ask how..." + prereq_ids = list("medbay_equip") + design_ids = list( + "xlarge_beaker", + "blood_pack", + "chem_pack", + "med_spray_bottle", + "medigel", + "medipen_refiller", + "soda_dispenser", + "beer_dispenser", + "chem_dispenser", + "portable_chem_mixer", + "chem_heater", + "w-recycler", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + +/datum/techweb_node/plumbing + id = "plumbing" + display_name = "Plumbing" + description = "Essential infrastructure for building chemical factories. To scale up the production of happy pills to an industrial level." + prereq_ids = list("chem_synthesis") + design_ids = list( + "plumbing_rcd", + "plumbing_rcd_service", + "plumbing_rcd_sci", + "plunger", + "fluid_ducts", + "meta_beaker", + "piercesyringe", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + +/datum/techweb_node/cryostasis + id = "cryostasis" + display_name = "Cryostasis" + description = "The result of clown accidentally drinking a chemical, now repurposed for safely preserving crew members in suspended animation." + prereq_ids = list("plumbing", "plasma_control") + design_ids = list( + "cryotube", + "mech_sleeper", + "stasis", + "cryo_grenade", + "splitbeaker", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + required_experiments = list(/datum/experiment/scanning/reagent/cryostylane) + +/datum/techweb_node/medbay_equip_adv + id = "medbay_equip_adv" + display_name = "Advanced Medbay Equipment" + description = "State-of-the-art medical gear for keeping the crew in one piece — mostly." + prereq_ids = list("cryostasis") + design_ids = list( + "chem_mass_spec", + "healthanalyzer_advanced", + "mod_health_analyzer", + "crewpinpointer", + "defibrillator_compact", + "defibmount", + "medicalbed_emergency", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) diff --git a/code/modules/research/techweb/nodes/mining_nodes.dm b/code/modules/research/techweb/nodes/mining_nodes.dm new file mode 100644 index 0000000000000..e1caaf57902e2 --- /dev/null +++ b/code/modules/research/techweb/nodes/mining_nodes.dm @@ -0,0 +1,104 @@ +/datum/techweb_node/material_processing + id = "material_proc" + starting_node = TRUE + display_name = "Material Processing" + description = "Refinement and processing of alloys and ores to enhance their utility and value." + design_ids = list( + "pickaxe", + "shovel", + "conveyor_switch", + "conveyor_belt", + "mass_driver", + "recycler", + "stack_machine", + "stack_console", + "autolathe", + "rglass", + "plasmaglass", + "plasmareinforcedglass", + "plasteel", + "titaniumglass", + "plastitanium", + "plastitaniumglass", + ) + +/datum/techweb_node/mining + id = "mining" + display_name = "Mining Technology" + description = "Development of tools meant to optimize mining operations and resource extraction." + prereq_ids = list("material_proc") + design_ids = list( + "cargoexpress", + "brm", + "b_smelter", + "b_refinery", + "ore_redemption", + "mining_equipment_vendor", + "mining_scanner", + "mech_mscanner", + "superresonator", + "mech_drill", + "mod_drill", + "drill", + "mod_orebag", + "beacon", + "telesci_gps", + "mod_gps", + "mod_visor_meson", + "mesons", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + +/datum/techweb_node/low_pressure_excavation + id = "low_pressure_excavation" + display_name = "Low-Pressure Excavation" + description = "Research of Proto-Kinetic Accelerators (PKAs), pneumatic guns renowned for their exceptional performance in low-pressure environments." + prereq_ids = list("mining", "gas_compression") + design_ids = list( + "mecha_kineticgun", + "damagemod", + "rangemod", + "cooldownmod", + "triggermod", + "hypermod", + "borg_upgrade_damagemod", + "borg_upgrade_rangemod", + "borg_upgrade_cooldownmod", + "borg_upgrade_hypermod", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + +/datum/techweb_node/plasma_mining + id = "plasma_mining" + display_name = "Plasma Beam Mining" + description = "Engineers' plasma welders have proven highly effective in mining operations. This led to the development of a mech-mounted variant and an enhanced handheld cutter for miners." + prereq_ids = list("low_pressure_excavation", "plasma_control") + design_ids = list( + "mech_plasma_cutter", + "plasmacutter_adv", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + +/datum/techweb_node/bitrunning + id = "bitrunning" + display_name = "Bitrunning Technology" + description = "Bluespace technology has led to the development of quantum-scale computing, which unlocks the means to materialize atomic structures while executing advanced programs." + prereq_ids = list("gaming", "applied_bluespace") + design_ids = list( + "byteforge", + "quantum_console", + "netpod", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + +/datum/techweb_node/mining_adv + id = "mining_adv" + display_name = "Advanced Mining Technology" + description = "High-level mining equipment, pushing the boundaries of efficiency and effectiveness in resource extraction." + prereq_ids = list("plasma_mining") + design_ids = list( + "jackhammer", + "drill_diamond", + "mech_diamond_drill", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) diff --git a/code/modules/research/techweb/nodes/modsuit_nodes.dm b/code/modules/research/techweb/nodes/modsuit_nodes.dm new file mode 100644 index 0000000000000..a5005a66ee794 --- /dev/null +++ b/code/modules/research/techweb/nodes/modsuit_nodes.dm @@ -0,0 +1,139 @@ +/datum/techweb_node/mod_suit + id = "mod_suit" + starting_node = TRUE + display_name = "Modular Exosuit" + description = "Specialized back mounted power suits with various different modules." + prereq_ids = list("robotics") + design_ids = list( + "suit_storage_unit", + "mod_shell", + "mod_chestplate", + "mod_helmet", + "mod_gauntlets", + "mod_boots", + "mod_plating_standard", + "mod_paint_kit", + "mod_storage", + "mod_plasma", + "mod_flashlight", + ) + +/datum/techweb_node/mod_equip + id = "mod_equip" + display_name = "Modular Suit Equipment" + description = "More advanced modules, to improve modular suits." + prereq_ids = list("mod_suit") + design_ids = list( + "modlink_scryer", + "mod_clamp", + "mod_tether", + "mod_welding", + "mod_safety", + "mod_mouthhole", + "mod_longfall", + "mod_thermal_regulator", + "mod_sign_radio", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + +/datum/techweb_node/mod_entertainment + id = "mod_entertainment" + display_name = "Entertainment Modular Suit" + description = "Powered suits for protection against low-humor environments." + prereq_ids = list("mod_suit") + design_ids = list( + "mod_plating_cosmohonk", + "mod_bikehorn", + "mod_microwave_beam", + "mod_waddle", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + +/datum/techweb_node/mod_medical + id = "mod_medical" + display_name = "Medical Modular Suit" + description = "Medical exosuits for quick rescue purposes." + prereq_ids = list("mod_suit", "chem_synthesis") + design_ids = list( + "mod_plating_medical", + "mod_quick_carry", + "mod_injector", + "mod_organ_thrower", + "mod_patienttransport", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + +/datum/techweb_node/mod_engi + id = "mod_engi" + display_name = "Engineering Modular Suits" + description = "Engineering suits, for powered engineers." + prereq_ids = list("mod_equip") + design_ids = list( + "mod_plating_engineering", + "mod_t_ray", + "mod_magboot", + "mod_constructor", + "mod_mister_atmos", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + +/datum/techweb_node/mod_security + id = "mod_security" + display_name = "Security Modular Suits" + description = "Security suits for space crime handling." + prereq_ids = list("mod_equip") + design_ids = list( + "mod_plating_security", + "mod_stealth", + "mod_mag_harness", + "mod_pathfinder", + "mod_holster", + "mod_sonar", + "mod_projectile_dampener", + "mod_criminalcapture", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + +/datum/techweb_node/mod_medical_adv + id = "mod_medical_adv" + display_name = "Field Surgery Modules" + description = "Medical exosuit equipment designed for conducting surgical operations in field conditions." + prereq_ids = list("mod_medical", "surgery_adv") + design_ids = list( + "mod_defib", + "mod_threadripper", + "mod_surgicalprocessor", + "mod_statusreadout", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + +/datum/techweb_node/mod_engi_adv + id = "mod_engi_adv" + display_name = "Advanced Engineering Modular Suit" + description = "Advanced Engineering suits, for advanced powered engineers." + prereq_ids = list("mod_engi") + design_ids = list( + "mod_plating_atmospheric", + "mod_jetpack", + "mod_rad_protection", + "mod_emp_shield", + "mod_storage_expanded", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + +/datum/techweb_node/mod_engi_adv/New() + if(HAS_TRAIT(SSstation, STATION_TRAIT_RADIOACTIVE_NEBULA)) //we'll really need the rad protection modsuit module + starting_node = TRUE + return ..() + +/datum/techweb_node/mod_anomaly + id = "mod_anomaly" + display_name = "Anomalock Modular Suit" + description = "Modules for exosuits that require anomaly cores to function." + prereq_ids = list("mod_engi_adv", "anomaly_research") + design_ids = list( + "mod_antigrav", + "mod_teleporter", + "mod_kinesis", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) diff --git a/code/modules/research/techweb/nodes/research_nodes.dm b/code/modules/research/techweb/nodes/research_nodes.dm new file mode 100644 index 0000000000000..b3af62c72e994 --- /dev/null +++ b/code/modules/research/techweb/nodes/research_nodes.dm @@ -0,0 +1,94 @@ +/datum/techweb_node/fundamental_sci + id = "fundamental_sci" + starting_node = TRUE + display_name = "Fundamental Science" + description = "Establishing the bedrock of scientific understanding, paving the way for deeper exploration and theoretical inquiry." + design_ids = list( + "rdserver", + "rdservercontrol", + "rdconsole", + "tech_disk", + "doppler_array", + "experimentor", + "destructive_analyzer", + "destructive_scanner", + "experi_scanner", + "ntnet_relay", + "laptop", + "portadrive_basic", + "portadrive_advanced", + "portadrive_super", + ) + +/datum/techweb_node/bluespace_theory + id = "bluespace_theory" + display_name = "Bluespace Theory" + description = "Basic studies into the mysterious alternate dimension known as bluespace." + prereq_ids = list("fundamental_sci") + design_ids = list( + "bluespace_crystal", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + +/datum/techweb_node/applied_bluespace + id = "applied_bluespace" + display_name = "Applied Bluespace Research" + description = "With a heightened grasp of bluespace dynamics, sophisticated applications and technologies can be devised using data from bluespace crystal analyses." + prereq_ids = list("bluespace_theory") + design_ids = list( + "ore_silo", + "minerbag_holding", + "plumbing_receiver", + "bluespacebeaker", + "adv_watering_can", + "bluespace_coffeepot", + "bluespacesyringe", + "blutrash", + "light_replacer_blue", + "bluespacebodybag", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + required_experiments = list(/datum/experiment/scanning/bluespace_crystal) + +/datum/techweb_node/bluespace_travel + id = "bluespace_travel" + display_name = "Bluespace Travel" + description = "Facilitate teleportation methods based on bluespace principles to revolutionize logistical efficiency." + prereq_ids = list("applied_bluespace") + design_ids = list( + "teleconsole", + "tele_station", + "tele_hub", + "launchpad_console", + "quantumpad", + "launchpad", + "bluespace_pod", + "quantum_keycard", + "swapper", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + +/datum/techweb_node/anomaly_research + id = "anomaly_research" + display_name = "Anomaly Research" + description = "Delving into the study of mysterious anomalies to investigate methods to refine and harness their unpredictable energies." + prereq_ids = list("applied_bluespace") + design_ids = list( + "anomaly_refinery", + "anomaly_neutralizer", + "reactive_armour", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + +/datum/techweb_node/anomaly_shells + id = "anomaly_shells" + display_name = "Advanced Anomaly Shells" + description = "New shells designed to utilize anomaly cores, maximizing their potential in innovative ways." + prereq_ids = list("anomaly_research") + design_ids = list( + "bag_holding", + "wormholeprojector", + "gravitygun", + "polymorph_belt" + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) diff --git a/code/modules/research/techweb/nodes/robo_nodes.dm b/code/modules/research/techweb/nodes/robo_nodes.dm new file mode 100644 index 0000000000000..556fa560daf6b --- /dev/null +++ b/code/modules/research/techweb/nodes/robo_nodes.dm @@ -0,0 +1,97 @@ +/datum/techweb_node/robotics + id = "robotics" + starting_node = TRUE + display_name = "Robotics" + description = "Programmable machines that make our lives lazier." + design_ids = list( + "mechfab", + "botnavbeacon", + "paicard", + ) + +/datum/techweb_node/exodrone + id = "exodrone" + display_name = "Exploration Drones" + description = "Adapted arcade machines to covertly harness gamers' skills in controlling real drones for practical purposes." + prereq_ids = list("robotics") + design_ids = list( + "exoscanner_console", + "exoscanner", + "exodrone_console", + "exodrone_launcher", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + +// AI root node +/datum/techweb_node/ai + id = "ai" + display_name = "Artificial Intelligence" + description = "Exploration of AI systems, more intelligent than the entire crew put together." + prereq_ids = list("robotics") + design_ids = list( + "aiupload", + "aifixer", + "intellicard", + "mecha_tracking_ai_control", + "borg_ai_control", + "aicore", + "reset_module", + "asimov_module", + "default_module", + "nutimov_module", + "paladin_module", + "robocop_module", + "corporate_module", + "drone_module", + "oxygen_module", + "safeguard_module", + "protectstation_module", + "quarantine_module", + "freeform_module", + "remove_module", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + +/datum/techweb_node/ai/New() + . = ..() + if(HAS_TRAIT(SSstation, STATION_TRAIT_HUMAN_AI)) + design_ids -= list( + "aicore", + "borg_ai_control", + "intellicard", + "mecha_tracking_ai_control", + "aifixer", + "aiupload", + ) + else if(HAS_TRAIT(SSstation, STATION_TRAIT_UNIQUE_AI)) + research_costs[TECHWEB_POINT_TYPE_GENERIC] *= 3 + +/datum/techweb_node/ai_laws + id = "ai_laws" + display_name = "Advanced AI Laws" + description = "Delving into sophisticated AI directives, with hopes that they won't lead to humanity's extinction." + prereq_ids = list("ai") + design_ids = list( + "asimovpp_module", + "paladin_devotion_module", + "dungeon_master_module", + "painter_module", + "ten_commandments_module", + "hippocratic_module", + "maintain_module", + "liveandletlive_module", + "reporter_module", + "yesman_module", + "hulkamania_module", + "peacekeeper_module", + "overlord_module", + "tyrant_module", + "antimov_module", + "balance_module", + "thermurderdynamic_module", + "damaged_module", + "freeformcore_module", + "onehuman_module", + "purge_module", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) diff --git a/code/modules/research/techweb/nodes/security_nodes.dm b/code/modules/research/techweb/nodes/security_nodes.dm new file mode 100644 index 0000000000000..97092f2682a63 --- /dev/null +++ b/code/modules/research/techweb/nodes/security_nodes.dm @@ -0,0 +1,107 @@ +/datum/techweb_node/basic_arms + id = "basic_arms" + starting_node = TRUE + display_name = "Basic Arms" + description = "Ballistics can be unpredictable in space." + design_ids = list( + "toygun", + "c38_rubber", + "sec_38", + "capbox", + "foam_dart", + "sec_beanbag_slug", + "sec_dart", + "sec_Islug", + "sec_rshot", + ) + +/datum/techweb_node/sec_equip + id = "sec_equip" + display_name = "Security Equipment" + description = "All the essentials to subdue a mime." + prereq_ids = list("basic_arms") + design_ids = list( + "camera_assembly", + "secdata", + "mining", + "prisonmanage", + "rdcamera", + "seccamera", + "security_photobooth", + "photobooth", + "scanner_gate", + "turret_control", + "pepperspray", + "inspector", + "evidencebag", + "handcuffs_s", + "zipties", + "seclite", + "electropack", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + +/datum/techweb_node/riot_supression + id = "riot_supression" + display_name = "Riot Supression" + description = "When you are on the opposing side of a revolutionary movement." + prereq_ids = list("sec_equip") + design_ids = list( + "pin_testing", + "pin_loyalty", + "tele_shield", + "ballistic_shield", + "bola_energy", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + +/datum/techweb_node/explosives + id = "explosives" + display_name = "Explosives" + description = "For once, intentional explosions." + prereq_ids = list("riot_supression") + design_ids = list( + "large_grenade", + "adv_grenade", + "pyro_grenade", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + required_experiments = list(/datum/experiment/ordnance/explosive/lowyieldbomb) + discount_experiments = list(/datum/experiment/ordnance/explosive/highyieldbomb = TECHWEB_TIER_3_POINTS) + +/datum/techweb_node/exotic_ammo + id = "exotic_ammo" + display_name = "Exotic Ammunition" + description = "Specialized bullets designed to ignite, freeze, and inflict various other effects on targets, expanding combat capabilities." + prereq_ids = list("explosives") + design_ids = list( + "c38_hotshot", + "c38_iceblox", + "techshotshell", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) + +/datum/techweb_node/electric_weapons + id = "electric_weapons" + display_name = "Electric Weaponry" + description = "Energy-based weaponry designed for both lethal and non-lethal applications." + prereq_ids = list("riot_supression") + design_ids = list( + "stunrevolver", + "ioncarbine", + "temp_gun", + "lasershell", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + +/datum/techweb_node/beam_weapons + id = "beam_weapons" + display_name = "Advanced Beam Weaponry" + description = "So advanced, even engineers are baffled by its operational principles." + prereq_ids = list("electric_weapons") + design_ids = list( + "beamrifle", + "xray_laser", + "nuclear_gun", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) diff --git a/code/modules/research/techweb/nodes/service_nodes.dm b/code/modules/research/techweb/nodes/service_nodes.dm new file mode 100644 index 0000000000000..ff56afc115eb5 --- /dev/null +++ b/code/modules/research/techweb/nodes/service_nodes.dm @@ -0,0 +1,236 @@ +/datum/techweb_node/office_equip + id = "office_equip" + starting_node = TRUE + display_name = "Office Equipment" + description = "Nanotrasen's finest in ergonomic office tech, ensuring station admin stays productive and compliant with corporate policies — because even in space, paperwork never stops." + design_ids = list( + "fax", + "sec_pen", + "handlabel", + "roll", + "universal_scanner", + "desttagger", + "packagewrap", + "sticky_tape", + "toner_large", + "toner", + "boxcutter", + "bounced_radio", + "radio_headset", + "earmuffs", + "recorder", + "tape", + "toy_balloon", + "pet_carrier", + "chisel", + "spraycan", + "camera_film", + "camera", + "razor", + "bucket", + "mop", + "pushbroom", + "normtrash", + "wirebrush", + "flashlight", + ) + +/datum/techweb_node/sanitation + id = "sanitation" + display_name = "Advanced Sanitation Technology" + description = "Nanotrasen's latest in janitorial tech, making sure the station stays spotless and bear-free." + prereq_ids = list("office_equip") + design_ids = list( + "advmop", + "light_replacer", + "spraybottle", + "paint_remover", + "beartrap", + "buffer", + "vacuum", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + discount_experiments = list(/datum/experiment/scanning/random/janitor_trash = TECHWEB_TIER_2_POINTS) + +/datum/techweb_node/toys + id = "toys" + display_name = "New Toys" + description = "For new pranks." + prereq_ids = list("office_equip") + design_ids = list( + "smoke_machine", + "toy_armblade", + "air_horn", + "clown_firing_pin", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + +/datum/techweb_node/consoles + id = "consoles" + display_name = "Civilian Consoles" + description = "User-friendly consoles for non-technical crew members, enhancing communication and access to essential station information." + prereq_ids = list("office_equip") + design_ids = list( + "comconsole", + "automated_announcement", + "cargo", + "cargorequest", + "med_data", + "crewconsole", + "bankmachine", + "account_console", + "idcard", + "c-reader", + "libraryconsole", + "barcode_scanner", + "vendor", + "custom_vendor_refill", + "bounty_pad_control", + "bounty_pad", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + +/datum/techweb_node/gaming + id = "gaming" + display_name = "Gaming" + description = "For the slackers on the station." + prereq_ids = list("toys", "consoles") + design_ids = list( + "arcade_battle", + "arcade_orion", + "slotmachine", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + discount_experiments = list(/datum/experiment/physical/arcade_winner = TECHWEB_TIER_2_POINTS) + +// Kitchen root node +/datum/techweb_node/cafeteria_equip + id = "cafeteria_equip" + starting_node = TRUE + display_name = "Cafeteria Equipment" + description = "When standard-issue tubed food no longer satisfies the station crew's appetite..." + design_ids = list( + "griddle", + "microwave", + "bowl", + "plate", + "oven_tray", + "servingtray", + "tongs", + "spoon", + "fork", + "kitchen_knife", + "plastic_spoon", + "plastic_fork", + "plastic_knife", + "shaker", + "drinking_glass", + "shot_glass", + "coffee_cartridge", + "coffeemaker", + "coffeepot", + "syrup_bottle", + ) + +/datum/techweb_node/food_proc + id = "food_proc" + display_name = "Food Processing" + description = "Top-tier kitchen appliances from Nanotrasen, designed to keep the crew well-fed and happy." + prereq_ids = list("cafeteria_equip") + design_ids = list( + "deepfryer", + "oven", + "stove", + "range", + "souppot", + "processor", + "gibber", + "monkey_recycler", + "reagentgrinder", + "microwave_engineering", + "smartfridge", + "sheetifier", + "fat_sucker", + "dish_drive", + "roastingstick", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + +// Fishing root node +/datum/techweb_node/fishing_equip + id = "fishing_equip" + starting_node = TRUE + display_name = "Fishing Equipment" + description = "Basic fishing gear tailored for space station environments, perfect for extraterrestrial aquatic pursuits." + design_ids = list( + "fishing_portal_generator", + "fishing_rod", + "fish_case", + ) + +/datum/techweb_node/fishing_equip_adv + id = "fishing_equip_adv" + display_name = "Advanced Fishing Tools" + description = "Continuing advancements in fishing technology, incorporating cutting-edge features in space fishing operations. Just don't try this on space carps..." + prereq_ids = list("fishing_equip") + design_ids = list( + "fishing_rod_tech", + "stabilized_hook", + "auto_reel", + "fish_analyzer", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + required_experiments = list(/datum/experiment/scanning/fish) + +/datum/techweb_node/marine_util + id = "marine_util" + display_name = "Marine Utility" + description = "Fish are nice to look at and all, but they can be put to use." + prereq_ids = list("fishing_equip_adv") + design_ids = list( + "bioelec_gen", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + // only available if you've done the first fishing experiment (thus unlocking fishing tech), but not a strict requirement to get the tech + discount_experiments = list(/datum/experiment/scanning/fish/second = TECHWEB_TIER_3_POINTS) + +// Botany root node +/datum/techweb_node/botany_equip + id = "botany_equip" + starting_node = TRUE + display_name = "Botany Equipment" + description = "Essential tools for maintaining onboard gardens, supporting plant growth in the unique environment of the space station." + design_ids = list( + "seed_extractor", + "plant_analyzer", + "watering_can", + "spade", + "cultivator", + "secateurs", + "hatchet", + ) + +/datum/techweb_node/hydroponics + id = "hydroponics" + display_name = "Hydroponics" + description = "Research into advanced hydroponic systems for efficient and sustainable plant cultivation." + prereq_ids = list("botany_equip", "chem_synthesis") + design_ids = list( + "biogenerator", + "hydro_tray", + "portaseeder", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + +/datum/techweb_node/selection + id = "selection" + display_name = "Artificial Selection" + description = "Advancement in plant cultivation techniques through artificial selection, enabling precise manipulation of plant DNA." + prereq_ids = list("hydroponics") + design_ids = list( + "flora_gun", + "gene_shears", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + required_experiments = list(/datum/experiment/scanning/random/plants/wild) + discount_experiments = list(/datum/experiment/scanning/random/plants/traits = TECHWEB_TIER_3_POINTS) diff --git a/code/modules/research/techweb/nodes/surgery_nodes.dm b/code/modules/research/techweb/nodes/surgery_nodes.dm new file mode 100644 index 0000000000000..3cd3d373c0599 --- /dev/null +++ b/code/modules/research/techweb/nodes/surgery_nodes.dm @@ -0,0 +1,72 @@ +/datum/techweb_node/oldstation_surgery + id = "oldstation_surgery" + display_name = "Experimental Dissection" + description = "Grants access to experimental dissections, which allows generation of research points." + prereq_ids = list("medbay_equip") + design_ids = list( + "surgery_oldstation_dissection", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + hidden = TRUE + show_on_wiki = FALSE + +/datum/techweb_node/surgery + id = "surgery" + display_name = "Improved Wound-Tending" + description = "Who would have known being more gentle with a hemostat decreases patient pain?" + prereq_ids = list("medbay_equip") + design_ids = list( + "surgery_heal_brute_upgrade", + "surgery_heal_burn_upgrade", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + +/datum/techweb_node/surgery_adv + id = "surgery_adv" + display_name = "Advanced Surgery" + description = "When simple medicine doesn't cut it." + prereq_ids = list("surgery") + design_ids = list( + "harvester", + "surgery_heal_brute_upgrade_femto", + "surgery_heal_burn_upgrade_femto", + "surgery_heal_combo", + "surgery_lobotomy", + "surgery_wing_reconstruction", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + required_experiments = list(/datum/experiment/autopsy/human) + +/datum/techweb_node/surgery_exp + id = "surgery_exp" + display_name = "Experimental Surgery" + description = "When evolution isn't fast enough." + prereq_ids = list("surgery_adv") + design_ids = list( + "surgery_cortex_folding", + "surgery_cortex_imprint", + "surgery_heal_combo_upgrade", + "surgery_ligament_hook", + "surgery_ligament_reinforcement", + "surgery_muscled_veins", + "surgery_nerve_ground", + "surgery_nerve_splice", + "surgery_pacify", + "surgery_vein_thread", + "surgery_viral_bond", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + required_experiments = list(/datum/experiment/autopsy/nonhuman) + +/datum/techweb_node/surgery_tools + id = "surgery_tools" + display_name = "Advanced Surgery Tools" + description = "Surgical instruments of dual purpose for quick operations." + prereq_ids = list("surgery_exp") + design_ids = list( + "laserscalpel", + "searingtool", + "mechanicalpinches", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) + discount_experiments = list(/datum/experiment/autopsy/xenomorph = TECHWEB_TIER_4_POINTS) diff --git a/code/modules/research/techweb/nodes/syndicate_nodes.dm b/code/modules/research/techweb/nodes/syndicate_nodes.dm new file mode 100644 index 0000000000000..c571551877099 --- /dev/null +++ b/code/modules/research/techweb/nodes/syndicate_nodes.dm @@ -0,0 +1,48 @@ +/datum/techweb_node/syndicate_basic + id = "syndicate_basic" + display_name = "Illegal Technology" + description = "Dangerous research used to create dangerous objects." + prereq_ids = list("exp_tools", "exotic_ammo") + design_ids = list( + "advanced_camera", + "ai_cam_upgrade", + "borg_syndicate_module", + "donksoft_refill", + "donksofttoyvendor", + "largecrossbow", + "mag_autorifle", + "mag_autorifle_ap", + "mag_autorifle_ic", + "rapidsyringe", + "suppressor", + "super_pointy_tape", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_5_POINTS) + hidden = TRUE + +/datum/techweb_node/syndicate_basic/New() //Crappy way of making syndicate gear decon supported until there's another way. + . = ..() + if(!SSearly_assets.initialized) + RegisterSignal(SSearly_assets, COMSIG_SUBSYSTEM_POST_INITIALIZE, PROC_REF(register_uplink_items)) + else + register_uplink_items() + +/datum/techweb_node/syndicate_basic/proc/register_uplink_items() + SIGNAL_HANDLER + UnregisterSignal(SSearly_assets, COMSIG_SUBSYSTEM_POST_INITIALIZE) + required_items_to_unlock = list() + for(var/datum/uplink_item/item_path as anything in SStraitor.uplink_items_by_type) + var/datum/uplink_item/item = SStraitor.uplink_items_by_type[item_path] + if(!item.item || !item.illegal_tech) + continue + required_items_to_unlock |= item.item //allows deconning to unlock. + +/datum/techweb_node/unregulated_bluespace + id = "unregulated_bluespace" + display_name = "Unregulated Bluespace Research" + description = "Bluespace technology using unstable or unbalanced procedures, prone to damaging the fabric of bluespace. Outlawed by galactic conventions." + prereq_ids = list("parts_bluespace", "syndicate_basic") + design_ids = list( + "desynchronizer", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) diff --git a/tgstation.dme b/tgstation.dme index b6ddcc5e20956..e5e577755cb8a 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -4048,6 +4048,7 @@ #include "code\modules\experisci\experiment\types\scanning_people.dm" #include "code\modules\experisci\experiment\types\scanning_plants.dm" #include "code\modules\experisci\experiment\types\scanning_points.dm" +#include "code\modules\experisci\experiment\types\scanning_reagent.dm" #include "code\modules\experisci\experiment\types\scanning_vatgrown.dm" #include "code\modules\explorer_drone\adventure.dm" #include "code\modules\explorer_drone\control_console.dm" @@ -5678,8 +5679,24 @@ #include "code\modules\research\techweb\__techweb_helpers.dm" #include "code\modules\research\techweb\_techweb.dm" #include "code\modules\research\techweb\_techweb_node.dm" -#include "code\modules\research\techweb\all_nodes.dm" #include "code\modules\research\techweb\techweb_types.dm" +#include "code\modules\research\techweb\nodes\alien_nodes.dm" +#include "code\modules\research\techweb\nodes\atmos_nodes.dm" +#include "code\modules\research\techweb\nodes\bepis_nodes.dm" +#include "code\modules\research\techweb\nodes\biology_nodes.dm" +#include "code\modules\research\techweb\nodes\circuit_nodes.dm" +#include "code\modules\research\techweb\nodes\cyborg_nodes.dm" +#include "code\modules\research\techweb\nodes\engi_nodes.dm" +#include "code\modules\research\techweb\nodes\mech_nodes.dm" +#include "code\modules\research\techweb\nodes\medbay_nodes.dm" +#include "code\modules\research\techweb\nodes\mining_nodes.dm" +#include "code\modules\research\techweb\nodes\modsuit_nodes.dm" +#include "code\modules\research\techweb\nodes\research_nodes.dm" +#include "code\modules\research\techweb\nodes\robo_nodes.dm" +#include "code\modules\research\techweb\nodes\security_nodes.dm" +#include "code\modules\research\techweb\nodes\service_nodes.dm" +#include "code\modules\research\techweb\nodes\surgery_nodes.dm" +#include "code\modules\research\techweb\nodes\syndicate_nodes.dm" #include "code\modules\research\xenobiology\xenobio_camera.dm" #include "code\modules\research\xenobiology\xenobiology.dm" #include "code\modules\research\xenobiology\crossbreeding\__corecross.dm" From 0ccb927b5cc6b06f33430a3af9563c082029a7b1 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Tue, 18 Jun 2024 05:22:08 +1200 Subject: [PATCH 030/172] Automatic changelog for PR #84024 [ci skip] --- html/changelogs/AutoChangeLog-pr-84024.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84024.yml diff --git a/html/changelogs/AutoChangeLog-pr-84024.yml b/html/changelogs/AutoChangeLog-pr-84024.yml new file mode 100644 index 0000000000000..aeff257645e5b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84024.yml @@ -0,0 +1,9 @@ +author: "MTandi" +delete-after: True +changes: + - balance: "Reshuffled tech tree, making nodes more specialized" + - qol: "Research points devided by the amount generated per second, so now research points correspond to seconds" + - rscadd: "Introduced reagent purity scan experiments (required for Cryostasis node)" + - rscadd: "Introduced synthetic organ scan experiment (required for top tier cyber organs)" + - rscadd: "Added a variant of machinery scan experiment that accepts any machines with upgraded parts (required for tier 3 parts)" + - rscdel: "Removed material scanning experiments from the tech tree" \ No newline at end of file From c2e1ab080c0b3a23bafcd4e762abc79dd75d8418 Mon Sep 17 00:00:00 2001 From: Kaostico Date: Mon, 17 Jun 2024 17:44:50 -0300 Subject: [PATCH 031/172] Transcendent Olfaction fix: Pesky closets (#83993) ## About The Pull Request Change to using the more robust get_turf method to get locations, as all pinpointers currently do. ## Why It's Good For The Game The transcendent olfaction mutation is currently broken. When the target is inside a container, its x y z becomes zero, so it will always say the target is below you when comparing your z level to it, and it won't even point in the right direction. This PR fixes that. ## Changelog :cl: fix: Transcendent Olfaction mutation now works properly /:cl: --- code/datums/mutations/olfaction.dm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/code/datums/mutations/olfaction.dm b/code/datums/mutations/olfaction.dm index 305f6d16e8389..6328345f1c4b3 100644 --- a/code/datums/mutations/olfaction.dm +++ b/code/datums/mutations/olfaction.dm @@ -119,6 +119,9 @@ /// Actually go through and give the user a hint of the direction our target is. /datum/action/cooldown/spell/olfaction/proc/on_the_trail(mob/living/caster) var/mob/living/carbon/current_target = tracking_ref?.resolve() + //Using get_turf to deal with those pesky closets that put your x y z to 0 + var/turf/current_target_turf = get_turf(current_target) + var/turf/caster_turf = get_turf(caster) if(!current_target) to_chat(caster, span_warning("You're not tracking a scent, but the game thought you were. \ Something's gone wrong! Report this as a bug.")) @@ -130,14 +133,14 @@ to_chat(caster, span_warning("You smell out the trail to yourself. Yep, it's you.")) return - if(caster.z < current_target.z) + if(caster_turf.z < current_target_turf.z) to_chat(caster, span_warning("The trail leads... way up above you? Huh. They must be really, really far away.")) return - else if(caster.z > current_target.z) + else if(caster_turf.z > current_target_turf.z) to_chat(caster, span_warning("The trail leads... way down below you? Huh. They must be really, really far away.")) return - var/direction_text = span_bold("[dir2text(get_dir(caster, current_target))]") + var/direction_text = span_bold("[dir2text(get_dir(caster_turf, current_target_turf))]") if(direction_text) to_chat(caster, span_notice("You consider [current_target]'s scent. The trail leads [direction_text].")) From 569390867c17ba5d7e7d783363675292fee757db Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Tue, 18 Jun 2024 08:55:07 +1200 Subject: [PATCH 032/172] Automatic changelog for PR #83993 [ci skip] --- html/changelogs/AutoChangeLog-pr-83993.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83993.yml diff --git a/html/changelogs/AutoChangeLog-pr-83993.yml b/html/changelogs/AutoChangeLog-pr-83993.yml new file mode 100644 index 0000000000000..e3de498c176db --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83993.yml @@ -0,0 +1,4 @@ +author: "Kaostico" +delete-after: True +changes: + - bugfix: "Transcendent Olfaction mutation now works properly" \ No newline at end of file From dd2269397e1711ed62372b70e9f6db1015bc4dfb Mon Sep 17 00:00:00 2001 From: jimmyl <70376633+mc-oofert@users.noreply.github.com> Date: Mon, 17 Jun 2024 23:11:38 +0200 Subject: [PATCH 033/172] [no gbp] you may open the panel of a flatpacker (#84037) ## About The Pull Request you may open the panel of a flatpacker with a screwdriver so you can upgrade it ## Why It's Good For The Game bug bad ## Changelog :cl: fix: you may now open the panel of a flatpacker with a screwdriver /:cl: --- code/game/machinery/flatpacker.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/game/machinery/flatpacker.dm b/code/game/machinery/flatpacker.dm index 1eb8f6e2cc5cb..9468dacc24c56 100644 --- a/code/game/machinery/flatpacker.dm +++ b/code/game/machinery/flatpacker.dm @@ -231,6 +231,10 @@ materials.retrieve_sheets(amount, ejecting, drop_location()) return TRUE +/obj/machinery/flatpacker/screwdriver_act(mob/living/user, obj/item/tool) + . = ITEM_INTERACT_BLOCKING + if(default_deconstruction_screwdriver(user, icon_state, icon_state, tool)) + return ITEM_INTERACT_SUCCESS /obj/machinery/flatpacker/Destroy() QDEL_NULL(inserted_board) From 2326767476ac3baea7c84e6458e0525c8181bd7b Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Tue, 18 Jun 2024 09:23:53 +1200 Subject: [PATCH 034/172] Automatic changelog for PR #84037 [ci skip] --- html/changelogs/AutoChangeLog-pr-84037.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84037.yml diff --git a/html/changelogs/AutoChangeLog-pr-84037.yml b/html/changelogs/AutoChangeLog-pr-84037.yml new file mode 100644 index 0000000000000..397febdfdf042 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84037.yml @@ -0,0 +1,4 @@ +author: "mc-oofert" +delete-after: True +changes: + - bugfix: "you may now open the panel of a flatpacker with a screwdriver" \ No newline at end of file From afe6aa0a82c3e0a702f0c03315009a0fe1be6fe3 Mon Sep 17 00:00:00 2001 From: FinancialGoose <92416224+TheBoondock@users.noreply.github.com> Date: Mon, 17 Jun 2024 18:25:05 -0400 Subject: [PATCH 035/172] Add valve opening sound to manual valve (#84049) ## About The Pull Request Adds a squeaky turning sound and hissing sound to opening valve ## Why It's Good For The Game https://github.com/tgstation/tgstation/assets/92416224/9213a1bd-9bf9-4e49-97b2-0ceb2830a4ad ## Changelog :cl: sound: added squeaky turn and gas hissing sound to gas valve /:cl: --- .../objects/items/devices/transfer_valve.dm | 1 + .../components/binary_devices/valve.dm | 2 ++ sound/attributions.txt | 4 ++++ sound/effects/gas_hissing.ogg | Bin 0 -> 57954 bytes sound/effects/valve_opening.ogg | Bin 0 -> 30240 bytes 5 files changed, 7 insertions(+) create mode 100644 sound/effects/gas_hissing.ogg create mode 100644 sound/effects/valve_opening.ogg diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index c3203a0ace7a9..598c16c9041a8 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -211,6 +211,7 @@ it explodes properly when it gets a signal (and it does). */ /obj/item/transfer_valve/proc/toggle_valve(obj/item/tank/target, change_volume = TRUE) + playsound(src, 'sound/effects/valve_opening.ogg', 50) if(!valve_open && tank_one && tank_two) var/turf/bombturf = get_turf(src) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/valve.dm b/code/modules/atmospherics/machinery/components/binary_devices/valve.dm index 32f3eb7419ced..aeb14c9b5dd28 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/valve.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/valve.dm @@ -25,6 +25,7 @@ It's like a regular ol' straight pipe, but you can turn it on and off. normalize_cardinal_directions() if(animation) flick("[valve_type]valve_[on][!on]-[set_overlay_offset(piping_layer)]", src) + playsound(src, 'sound/effects/valve_opening.ogg', 50) icon_state = "[valve_type]valve_[on ? "on" : "off"]-[set_overlay_offset(piping_layer)]" /** @@ -37,6 +38,7 @@ It's like a regular ol' straight pipe, but you can turn it on and off. . = on on = to_open if(on) + playsound(src, 'sound/effects/gas_hissing.ogg', 50) update_icon_nopipes() update_parents() var/datum/pipeline/parent1 = parents[1] diff --git a/sound/attributions.txt b/sound/attributions.txt index bcd6f41edf278..29c86945dd1a1 100644 --- a/sound/attributions.txt +++ b/sound/attributions.txt @@ -188,3 +188,7 @@ https://freesound.org/people/BinaryMonkFlint/sounds/333296/ tank_remove_thunk.ogg was made by mixing two sound tracks from Freesound: https://freesound.org/people/lowdjinn/sounds/533885/ and; https://freesound.org/people/BMacZero/sounds/96137/ + +valve_opening.ogg was made by mixing water flowing samples from: +https://freesound.org/people/scriotxstudios/sounds/349111/?attribution=1 and squeaky scrape sound from: +https://freesound.org/people/Department64/sounds/669028/ which was modified with lower pitch diff --git a/sound/effects/gas_hissing.ogg b/sound/effects/gas_hissing.ogg new file mode 100644 index 0000000000000000000000000000000000000000..58df62ef0842ff67524bf12313a0f9ac6242bef5 GIT binary patch literal 57954 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%0Ao;+8gAbE?Xt| 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 XGP#}qpApPuQgxeL0GiqLU;&Ud*C9o6 literal 0 HcmV?d00001 diff --git a/sound/effects/valve_opening.ogg b/sound/effects/valve_opening.ogg new file mode 100644 index 0000000000000000000000000000000000000000..9e7191204146760ac98305567dc3d60b501d5fa7 GIT binary patch literal 30240 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

q7_C7~51=ElFl|I_P?`vT+ zd8P|^9zI}Q^(Hv$cxWls&;OYJ2W6R$DYgxlviy*dGlCunY>f@!4`L{Q2iQToq<-R| zMZ}V~XwB{HrCGqVvmb!u7%e17{rRr~fmXX!6ES9cCC5=00y~-u2{EEFYWTG6IqcwE z$NIYW-w(8scFFTWz)Uws0Ob}q`WcC&RcZttu6cNFx4+V^&yHp(>3uD>1jYe5E%!l8Y#TD#t0#TQ=NAXgXTc_jdPuixE8KDGb_N<=`mh^1A zyK#(zx3RIokA19Vb{;4Hd|sZ*c)pc2E7cq8#&7sLH{1JHi|>hu1!d~Kz#`G7ysfV5 z5{A|uUrCarOij4&yiIE<7`6W5_2y-!&#;rPNLPSY>Bqm*x^z1AmCx8N`uYAQWPJJi z;WfwgZQCX>TH-AYQ>;kbD)U~Q?3%eXV!tIiy)kG0Vavq#O5>hWAs(fa;F-*TttQ`y z!LS*FQ203K=Zk4Qq-6MZ$|!>P6CTyg7}4rXG|@;@bbMcFoH98PV*Bfhcab{RsHvZ^ z&Iguq70lhrnyp2rdKInT&fCwov%5BP9?YQ5V!pS&bf(-w*LJ&a`dH4Lwyvk( zw{M4HFR79$Y%GGOWjta?qPOzi;9naiM41>rMdBr< z*intm#~CWQ|7dl{SCJRfAvu+ zYME8K80wGT?}f}a_iw_1@TG+eA$yNdrEbAvYwufSIeuC7D{p7W>DbJBAAMn|W+;?^f ze^Jb{pN=!iMkdQPCoW+ce3tm_ya>!P_P$)PQeIwg9M4j=SV4j;E4D=j`x+;$j1j@d z%KQ56zlJTY0u224kECylzq&e`=ExTRBB$NJ0xx}DmRG8AK=bVHdml^E&HN8}NHguv z2Xkm9R>T08fAsVEZ!@>GR}fx>IbD*;%CR3p1@Nl|iyfq$5mYMge#|bD(GAyC=g3*( z#$WIHrwCPk1>#^R%Y(jsT=DEk6kcWv&Bvrma(MPY79ps0 zJ9eeXoD0jg#FJ2wyCRrtFW-cjsbaF7DFLar<`7aFFFTDfoJ2w|E?(blFcUMp| zN!!lsdMgJ2Cf@vBpjNM)Qy)LW(q%7cHg#aChj&YGJWq9TA<0=QVOAtJCs+RFbsBi2 zN+bpP$&Z&?Cl{O{*A`A8jt!x&vKG~xA@)Upft_@HG4a0YvqD({YAQSgG6BsQB2%r zaCRyE(5z?v-`|n1?muP~Zx;DXcXjI%H3N5r%5~c}a!&GI`vpV ziTZQF?%W;6zsrfk$@P6$=kbgs{s(D+cIPJ!$f4W_yH9RJhwOZK%)P#m_$~|zg&n| zNbo(Uv5TU+_*^R)GEGUTB`rlB;SbZR--Hg*Oa#{L`2KlT(rR|?b zF;laSutHXimUC#Kb-lgOA?R^`4NK=^em|6d$^-u}JC3A71#!g^RBCJdZN8xCH^R`D z+zuz`9FX?8=qSA*uA%C?Y7wVjns3SXs#55^Ck zYy`S}IFBOq$U-;&Q|c?k71gphIF#!hqO3l;i5}Mhm6Od6rF-Ic+DxH2wMx4p`5g=x*j)7yit!Mt3K36&Exu z>z?BVT;*v6KDRB7+voa=hPCgGfP=0qns7CR_q0*e2;Z*dtMQa~=voR|&<;c5YoiI! z1Rx%!_7X|v0Acg(|4LN$HY>nAlMiH^)K`#0P1s4)l-X%KN?6pN!En~g^YopK=ISyf zhaxvg6@xV3(B$%tLvxV>)Tim#4P}i94Nk1-I&)(UsiwDG@`a}knR3G;$%`YXt8@fw zcI;zC<9N?k^^~C)e>{{+U*A%>RJGYt>XCX)I5-)^eV^)o%UhnhVZb_7(Ms#%9(yuk z?fWd`D_>=)UIunXVP9K)p}JM%cbV3#7H91AEo~%q9#!wC@#Vi!)5g1-@6!cm1Ncduu5eb=kQlI#^zWY*xb18fU)i+%xn+|iDtU=kaj=&MZ5~}q zLr0hC;e~H=2JqkrDhwmX1|KE~QEpwYxe==9nnnRvW)+9sB%*uM!oj^`+s|g+OT%aa z$WOk_NU*_B1=!Y(IRZ({pqmrZI_$wXKpnH@hhiCnP6ib-s43QH*lst=u6FD)2ySVS ztIr>?jJ3DnpmHjJ5dL?OPd*Iqbblo1Q^TUg9R{asrjP2j3cq^ng_CnUC#hEtQse5! zj4W_NKs?)JyF9Q#$)9|?zS3*%qo-etBb=OC*;wqGZK`}eB=u%GB=?HLvq|u@QrxS} zgu{J;w!*`$nGXKQ?b~qJOk>0N`oU@RG4FFG7{2P%cwxwQD8r{0E?sgMe-Hu9A2Js;7dp^*vVx8&EFOccMdzKHb~@DD)m zJ>;R8^P9j&Q)GX7GkW6B%URZMZFJWU(f2*&s_2u*=0Vkz!X1|xZNGlrJq}#s!eUEj zUtY>xAKWp8#6y1MFr7{~a%b^)CXvpMc^fvDM2IPYW`GC+nb5V)0%4g4gC0`dTYlxQ zU?e?%0*)b{0yHY&@Qze~G-LC4O>1J+Kx4+S#yfC_67x3$Mn(akdfF%@z(ArlJO#Du zpO#y!luLTf`G?uW4przIa_nNKczIZfI*n)}{s+l&$i&^;6M&Z2YNlur7#Oupk(!e8 zJ+W`O^+WDM41-{jgSj7pjJp7@5e>koh`{h>Pi6gWYbvG^UC#Ll&U?C2yZwclE!frV z669yNykHpB3*`YMl}z^}9OE;iz-$%aXmp=gl{wt@Q|>ojmfmF1f7oIuD{WLLZ4AI#F}DyvCsV~(O@Na_JJ=0&ew!? zPAF)j@$t}9Gx;8ga@@OX7OD?;zUt0?%V-u4HcUPK=ErN~1jFy)n$Oyl7+%xeW`ot0 z|J6FLi70)-D|RoSA+{e6>~7EdE*A>_@$ycuCgqZ#QkJQ#tk>}JJky&t=gi8Y{hG)` z1{|sjV$5KGi2&T@y2D^i1=Ir=XZS}~dGT-j>v*ILC%zL-AQ-f^UQ2SjH4SLS&WOKS zwnx;>kc&$uWO>yrhA%7Be9OvBIo`6V+jw!pULi;}ki?_vc(+W}$~luzs^fV3Hw-YN zJH_b`uwQIIngTx)ZWaYiKS1HOOibU!pZ?_q09sf}UvM@;s=AdLd|CYRO;Q3fx%gv- z+Ar2SmNv}LeESf$Lo2Avx&P>fm}0$O)GEF$ho2$HVi5kVZBA(9rA=RfxG|w)?_hr< z#=sEAMi1Rq;}{s&`FgEQnT+wnf2B~2(E;=`Yds?%t>Jc)19D43dHaopJqWZ|_2-JK5ijcQ zO!cB;?S%o4CPO}s_Y+$CVqFpVL`Md+fs$iUJys2O?JiyREeXwJKaeUttfgL!Kwxk< zu4M-@U?MPsNsH2G>mFR9=t^#sFx%f(9o*BRmshdgkoqU=#pRz`dF-F+@8HxpsXFEB z<-YI$A6Iaw5TmlwcpW7&)j?qh3(}cqbBbN}@TGh^7k8?{f3o-CV|2&*!P(T$i(hOa zZ3@2LxYK>+nF)C#;kvi{{C{huK zBLfk~WG+DltT51s{lc`8L@k;V@NC0sH;a5={HReuSFwJxn@Lk8n)SzwQvwXxHT+on zt0$BHcy}$&`PNHp#x2U_tLB<-jiU}!S_J~U6&L5;+q5F)>PICB8VdHrN{CdGd$*eP zW3?l!LnNKj@pB?*ibk-u77+$Wz4_waoVmomctbJxR~b!1)aBGeWi#?~z4t^UQM>#% zRISBaJ-7!ReH|Waqf67FA!^;XAyoGEIGrHH!zPt-K0NzMx!JdRB4nkkp>y_UMvGqui^Jh3 zd<>vfK6Gd1D15oslZ6#r_E;j@+_i?jwBxe^1R7KV7LhQHzfi)F3ByYi%!)vd%j0RV zup?lJblh!CMmu5X2XGQ98$AvNql9-S8TvPzsWmPS8$lSUU%>(%m)U@I5Fpwc{3o}g z!-9v*x!tXOfk2H-d$=whUla%rp0n&``VDhWFwA%?#s>4$m!!#Fe45@C$0`GG?2jj~ zjq%qqlUHeFnxvK)sji|xpqz;Xo_p9SFoJRunST@%%_gTVf{S*_4N?oA%41!mup@qD zB2~7c<6&=Ct;eb?$o+r2f7IhVM)|U3ym;&;deU4WePa_I7frf(wNntt-MTAn?^|^l zeCC^+Z8OS}c3wquk2hkd;RyZCIE(a$s=LXagU!_#f5_&%-j$C;+QYnWd(qRUC+-)h z*BZxGsAvK8>~(t`*7T>6_X4rnrO(#2$&H^E0Ooc>Y2TN5*(U>ZhPkn@yGp6t&jrGj zz2X+T$VjfedGYX-HUXv@H}d$zfu8wu53g;Ez)!9mLHwekSZXR-X9d%Q&Fs{{wC1So zqX741v#h|9q~~wUSyw|%)VwQM#-?qK4}bkSP1VJXr})pElJb3_RbfNF$7X5T1>V6G zom+Bo7mWWCRuDUcG=%G=zCmhGlu`o`^A1L_JV^8$fE7{b`X~TPx;B8k`_4T zTgthoyryWZ({h|0KcO1>@S_c~-tjpJ!j=rUt07HkD_B6)dJ2zVKAl!4SWPe(U zfT|#=5&f=>xd|%s7tb&hc+3_|3`vReWn6MnO<0SHr7Nx9oQDQ`j}L}Ob#AF-#lpY- zSuCecIS!S7WS#j0hOzGHLS)|jMH`nv&>~vcriBx<-*P}p36@(@_^lQ{rU*8u%dh2s zp;K1#NaD%Cg*(z$wq+i_K^DstTzZonDyZ!sj<* ze{&)>#J;%v_a*?QFc5vW^B{@gXQF~>9I?P(3TZXqG9P|Z{Ojac)}__Bb(>@tWLrfe zP?~O%+B9wd_=1DkFkJ&HV>ADL%3F3lM@ESyTISp5ZJ#}|9Nhd&on^_rg(Trl+;q$8 zR@grq)M)c%*z=2(sSivA%Up1#x?bnDG_~;0qTXUu*p`osj8P3WUxs4}Z*MoxpV3(6 z_H~rk92~jn(XTXF#Kc;<#UW4X+Z^Q%Mu(a;2|IyWi9PoN$EX3l68@eaN_PY-sW~FO zu9^MR=!D&;BQyi(=I8-_G6VvXpA=?C?XBY=Pgyrm3qxEp`Cxrc^_$5O2@yoxnwZ5F@L2?JN+~3^w&m{~4{&K{b@8PKY>Go+2 z0xC7ExweXRPff@4Gmj{xFQ3m?^Pl_lR(*u*0PR1>R#Eb(RWmB|{dh5}{}6uTVZI9t z1SK7at1%wkI?lT{wr%H>V|P^-aa`)O>6JC{fNw~da!Tg-tkV0faOZwZ`R~L}%x=?; zv)p}~mDrXB;`yaCcJ<=E;UlMKJU4%0we$y7?LVzwjJstPT8_V#-cRtP;86N#iYeI-yf1_9wiq*751-%9l`D|cJ~b3I(|~%Y28Rkf2SvLJ@d;%&y)Mr44Z>! z(a%<~S+NTj-;V6JjFbimgeikMSe=r4ot}+cdTa&%HG6(|xB5nrP_@?CT*RZPz@VB$ zw{#;k+aP+lds4!VFs_E+Yccu9Zr{6A{%EkfgbWPDcBw_wRhmmJlU4`sQ~X)ul* zHo8wVtr2Ea=mTRmpJyWk8rF4GHupF@@DDzm5<6<&i+y=JfIJV^!M|zxm;7JREIWN> z+(S2ilG`AJ2_Uq|n)RpEb~vvyNKZB}6%)1#x);})pTz!_7zle=+U+b0$>6VWG!!esD-9 zK_)6!DYk`8O>7P>&cQk&;_!(b^i>xRu70_0aZNX-mI?n@rl2%1t(eST=lgnN?Geb7 zHW5X(eg>JM^8wHwT%*xomZ`?NoIl_|$4bs!z11c~gP_?$PpQ&3`C3RaI6PgFwG^e! z*{*a(Tv$*fVA;cLXV#K;_I6gFf$@fzkoYYVixM%m5}#sI`Sq4;-wb8{hsfDB3G^bN z8F!IxZpy7Vo;f2e0G_r?7N4fc{Qb&VlA_q_Vjzx6kf{OO=B2U2IH=LR)2L7|5&{J9-`M+}J(8&t^e(?w5hmO@Flgy|Sysrzq3W z!O^X;_E-*Cm`GyhhIptadvAKrC+WqhO@2giKx)n1`NYY}@JeraKq>@#Ja#I50gPmisd^1Nb>DIKd=dRGm4Fn{3GUf@-E(M9%1!+2n5sD%!D zrKmexcD?9N*5K|A#B=b?7?!|xzJybsGkh) z^W@Pm*4eT)omua%!!!h$)ajOFpC5Nq;c5jL^A4f}dJ}bKpR_-}qPB}q_P{`fC1v~! z=JXuT_7UXc3}fGAjm7EB`0Au4H^@%LZ(Qf*2uz8DW;--G>RW14%NWObK-{m|v5$Z4 zZ%)$GgIw(D;UwH?r;aGr=>F8V&XImoI5Jlgo3Lpc?$_w6bWl-}U?i_R<6Nk-t<=x@ zPo^or(fIbQ2X>8oG}})iR{6`4gDy&sex7%GEL42ms`Gz&8Zxnq7Wi`dtc|p{-#I*Y z!+E1imq7lVyu>4Wrhmr`^GOg8L0~&E2kt0VMS>@tv?(2g@1uEP1GjK9*8!RkgyVq& zvf&pcx{>nufI-4p7hpaRVw#|=>fZqZrhp-hWK_pMa ziIQ_9vlzBgPZXKI$E$#frvqQ#rEE1{TIc~P753(7wgDmke+hQSj+g7b`JpP#WJy9$ zGE!^b?EUYT{YyzJ8)qBK2&^n56VJEfR#?_FsPmcS`x1O6!=fo15z)1yg}dZepvT!R zRv`(<2XJX=nCFV#OjgYAeP$3KclG51ML);4u0E%$Qr5({?QWI5Za?y=UUR1gIU>MJ z&>UDSiy*pv+p+eX?)(D+y^~7|@t?8{G66@D=bD|2&@bdQvOIv03wmNoKz1M;3i-## zyTbr6!1UfF^q>IfQ+71rD0}G*AiyKj(c-6I$esRL9DrUh7xwpD1TDmoKqYK-mjbba zMu_}3uAGopD44qgt+Fwe&uWz*ZWJRvls!{LxG|EMLGXrU?#YW_RtW)n0|z$VR=y(R z`xYp?Xo>yfiSB~YGHV{+Cp=s-0ORenrvn_kUyf?W)ic{zw{c^*N} zae9T4BdS^RX42Y;`+3*yL88{D(`I1o+)|=hsz!H>hzcpkHb zV}S7CTxdfdB=l#7wkBwXt^pbegVvRR4m4ZRoz&!ZNeaBXe#<4g%fXF2?}WZ9ZVmf< z9b3?vTL z!Dv2A@uJ;3Lk$MZZg?_-3MdgnvX%nTQ1Klyf*lMy^z60ZGB}uP+l5X+;<7DtT=ASG z0A}cDZX1t4bAYMbhLKr0NQRKJ>QZ>H1FD~}+sg6W(0$CJW&lvkTC&ars_JeuSVSBf z9}a%ix!qPDn(s#%P*Up`p-?qRK&!w7srBo-zQaQOyl$@2h*GF?@T(HNrwX7TRpwFq zA9PMt#PKQXZ4j{0<>tFHq=Dx9Me~e&J&QOLmWj6MqTBG0?moQRYf-d7)qC>V!5bgc$382zAs5S;rN2|S^wY5cw~qO)u;+G4%9 z_9BPMxWf{)lAxM~4NNdbah%>(MSvZNy4%2FVTa*lLmY~@H`-7)P&+Uu{Pwg988l1H zkzizY(EQE-g+)sfxrVt<+o68&`&c2;f=OQw1K>4PGr!-vJoe;;5jG)DIOJ8mwIPFb z>#2`>chsVZ<(cm+0Y`X2jS5_D@pZ;h$!;F>`VVc3%R`=xmkQhB Date: Mon, 17 Jun 2024 18:25:15 -0400 Subject: [PATCH 036/172] Fixes logging path on civilian bounties (#84040) ## About The Pull Request Oops! The Civilian Bounty logging PR I did last week was runtiming and NOT working properly! Switches the object that an attempted bounty logs for it's type. ## Why It's Good For The Game Makes the logging work properly, and pulls the type straight from the ID's reserved bounty type. ## Changelog Once again, no player facing changes. --- code/game/machinery/civilian_bounties.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/machinery/civilian_bounties.dm b/code/game/machinery/civilian_bounties.dm index e5cd81cc965a1..fa0d28c999c88 100644 --- a/code/game/machinery/civilian_bounties.dm +++ b/code/game/machinery/civilian_bounties.dm @@ -168,7 +168,7 @@ return inserted_scan_id.registered_account.civilian_bounty = inserted_scan_id.registered_account.bounties[choice] inserted_scan_id.registered_account.bounties = null - SSblackbox.record_feedback("tally", "bounties_assigned", 1, choice.type) + SSblackbox.record_feedback("tally", "bounties_assigned", 1, inserted_scan_id.registered_account.civilian_bounty.type) return inserted_scan_id.registered_account.civilian_bounty /obj/machinery/computer/piratepad_control/civilian/click_alt(mob/user) From c9fbce26b781f81a13de9e09b24076274357423d Mon Sep 17 00:00:00 2001 From: GPeckman <21979502+GPeckman@users.noreply.github.com> Date: Mon, 17 Jun 2024 18:25:27 -0400 Subject: [PATCH 037/172] Mining borgs can now get multiple copies of a single modkit again (#84052) ## About The Pull Request A previous pull request cleaned borg upgrade code up a lot, and included a check to prevent duplicate upgrades from being installed. Usually this is a good thing, but there are some upgrades that are intended to allow duplicates. Namely, PKA modkits in mining borgs. This PR just fixes that, so mining borgs can have multiple modkits again. This does NOT allow borgs to go above the 90% complexity limit on their PKAs, as a separate piece of code handles that. ## Why It's Good For The Game Bugs are bad. ## Changelog :cl: fix: Mining borgs can get multiple modkits of the same type installed again. /:cl: --- code/modules/projectiles/guns/energy/kinetic_accelerator.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index c7fefc745f7e0..7237ee0e32747 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -254,6 +254,8 @@ require_model = TRUE model_type = list(/obj/item/robot_model/miner) model_flags = BORG_MODEL_MINER + //Most modkits are supposed to allow duplicates. The ones that don't should be blocked by PKA code anyways. + allow_duplicates = TRUE var/denied_type = null var/maximum_of_type = 1 var/cost = 30 From e3a4ceeacea433274bfbf081aba5d5275a6b3f9d Mon Sep 17 00:00:00 2001 From: san7890 Date: Mon, 17 Jun 2024 16:34:02 -0600 Subject: [PATCH 038/172] Moves Round Logs Website Message before the sleep in Reboot (#83914) ## About The Pull Request Closes #83823 Move the message about "You can access round logs and statistics at this website" up before we actually start the reboot countdown sleep. The logs probably won't have posted by that point (depending on how the server is set up) but at least it's slightly more useful before the links (apparently) invalidate. Also the reboot timer is ~60 seconds on /tg/ servers and people are either chatting in OOC or something around this time, may as well get the link to save for later in that "cooldown" period. ## Why It's Good For The Game I've actually never seen this message before and I think moving it slightly more upwards would be of value. ## Changelog :cl: qol: A message with a link to publicly accessible logs (if enabled by your server operators) should now be visible far earlier when a world is about to reboot. /:cl: --- code/controllers/subsystem/ticker.dm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 468882f0e86ec..efca8dd19b5cc 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -697,6 +697,13 @@ SUBSYSTEM_DEF(ticker) to_chat(world, span_boldannounce("Rebooting World in [DisplayTimeText(delay)]. [reason]")) + var/statspage = CONFIG_GET(string/roundstatsurl) + var/gamelogloc = CONFIG_GET(string/gamelogurl) + if(statspage) + to_chat(world, span_info("Round statistics and logs can be viewed at this website!")) + else if(gamelogloc) + to_chat(world, span_info("Round logs can be located at this website!")) + var/start_wait = world.time UNTIL(round_end_sound_sent || (world.time - start_wait) > (delay * 2)) //don't wait forever sleep(delay - (world.time - start_wait)) @@ -707,13 +714,6 @@ SUBSYSTEM_DEF(ticker) if(end_string) end_state = end_string - var/statspage = CONFIG_GET(string/roundstatsurl) - var/gamelogloc = CONFIG_GET(string/gamelogurl) - if(statspage) - to_chat(world, span_info("Round statistics and logs can be viewed at this website!")) - else if(gamelogloc) - to_chat(world, span_info("Round logs can be located at this website!")) - log_game(span_boldannounce("Rebooting World. [reason]")) world.Reboot() From e6083429b020a110ca7e95940779f01bc127d70f Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Tue, 18 Jun 2024 10:35:49 +1200 Subject: [PATCH 039/172] Automatic changelog for PR #84049 [ci skip] --- html/changelogs/AutoChangeLog-pr-84049.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84049.yml diff --git a/html/changelogs/AutoChangeLog-pr-84049.yml b/html/changelogs/AutoChangeLog-pr-84049.yml new file mode 100644 index 0000000000000..35a9bbea6588a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84049.yml @@ -0,0 +1,4 @@ +author: "TheBoondock" +delete-after: True +changes: + - sound: "added squeaky turn and gas hissing sound to gas valve" \ No newline at end of file From 76054b5e3a766627c49461637851ec88ee47f119 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Tue, 18 Jun 2024 10:38:02 +1200 Subject: [PATCH 040/172] Automatic changelog for PR #84052 [ci skip] --- html/changelogs/AutoChangeLog-pr-84052.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84052.yml diff --git a/html/changelogs/AutoChangeLog-pr-84052.yml b/html/changelogs/AutoChangeLog-pr-84052.yml new file mode 100644 index 0000000000000..d714cbd085f41 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84052.yml @@ -0,0 +1,4 @@ +author: "GPeckman" +delete-after: True +changes: + - bugfix: "Mining borgs can get multiple modkits of the same type installed again." \ No newline at end of file From e3e8e4d34ba926de071973da833c5692c723440d Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Tue, 18 Jun 2024 10:41:45 +1200 Subject: [PATCH 041/172] Automatic changelog for PR #83914 [ci skip] --- html/changelogs/AutoChangeLog-pr-83914.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83914.yml diff --git a/html/changelogs/AutoChangeLog-pr-83914.yml b/html/changelogs/AutoChangeLog-pr-83914.yml new file mode 100644 index 0000000000000..872508ff08bbb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83914.yml @@ -0,0 +1,4 @@ +author: "san7890" +delete-after: True +changes: + - qol: "A message with a link to publicly accessible logs (if enabled by your server operators) should now be visible far earlier when a world is about to reboot." \ No newline at end of file From 45e38f718c1ed9dd53d37a9eb3fd91bf48b29f14 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Tue, 18 Jun 2024 00:23:31 +0000 Subject: [PATCH 042/172] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-83195.yml | 5 --- html/changelogs/AutoChangeLog-pr-83914.yml | 4 -- html/changelogs/AutoChangeLog-pr-83965.yml | 4 -- html/changelogs/AutoChangeLog-pr-83992.yml | 4 -- html/changelogs/AutoChangeLog-pr-83993.yml | 4 -- html/changelogs/AutoChangeLog-pr-84004.yml | 4 -- html/changelogs/AutoChangeLog-pr-84005.yml | 4 -- html/changelogs/AutoChangeLog-pr-84012.yml | 4 -- html/changelogs/AutoChangeLog-pr-84019.yml | 4 -- html/changelogs/AutoChangeLog-pr-84020.yml | 4 -- html/changelogs/AutoChangeLog-pr-84024.yml | 9 ----- html/changelogs/AutoChangeLog-pr-84028.yml | 4 -- html/changelogs/AutoChangeLog-pr-84031.yml | 4 -- html/changelogs/AutoChangeLog-pr-84032.yml | 4 -- html/changelogs/AutoChangeLog-pr-84037.yml | 4 -- html/changelogs/AutoChangeLog-pr-84049.yml | 4 -- html/changelogs/AutoChangeLog-pr-84052.yml | 4 -- html/changelogs/archive/2024-06.yml | 47 ++++++++++++++++++++++ 18 files changed, 47 insertions(+), 74 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-83195.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83914.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83965.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83992.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83993.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84004.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84005.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84012.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84019.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84020.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84024.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84028.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84031.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84032.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84037.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84049.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84052.yml diff --git a/html/changelogs/AutoChangeLog-pr-83195.yml b/html/changelogs/AutoChangeLog-pr-83195.yml deleted file mode 100644 index 3b3a75919a4a9..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83195.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Bisar" -delete-after: True -changes: - - balance: "Replaced the free reagent purging with actually purging by exploding someone in the blood while they have omnizine and a purgative in their bloodstream. Let's go practice medicine!" - - bugfix: "Fixed the free reagent purging mechanic from causing an explosion so weak that it doesn't cause any damage." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83914.yml b/html/changelogs/AutoChangeLog-pr-83914.yml deleted file mode 100644 index 872508ff08bbb..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83914.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "san7890" -delete-after: True -changes: - - qol: "A message with a link to publicly accessible logs (if enabled by your server operators) should now be visible far earlier when a world is about to reboot." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83965.yml b/html/changelogs/AutoChangeLog-pr-83965.yml deleted file mode 100644 index cc18775056e22..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83965.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "TheRyeGuyWhoWillNowDie" -delete-after: True -changes: - - qol: "adds a confirmation to malf AI shunting into APCs" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83992.yml b/html/changelogs/AutoChangeLog-pr-83992.yml deleted file mode 100644 index 7a8e7408d3413..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83992.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Melbert" -delete-after: True -changes: - - qol: "Block'd out armor readout, should be more readable now" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83993.yml b/html/changelogs/AutoChangeLog-pr-83993.yml deleted file mode 100644 index e3de498c176db..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83993.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Kaostico" -delete-after: True -changes: - - bugfix: "Transcendent Olfaction mutation now works properly" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84004.yml b/html/changelogs/AutoChangeLog-pr-84004.yml deleted file mode 100644 index 7c8855699fa8d..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84004.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Goat" -delete-after: True -changes: - - qol: "fire extinguishers can now be filled via stationary tanks. (and water coolers)" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84005.yml b/html/changelogs/AutoChangeLog-pr-84005.yml deleted file mode 100644 index 29deb18988bd8..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84005.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SyncIt21" -delete-after: True -changes: - - bugfix: "ctrl+shift clicking on a ghost will only quick spawn that clicked target and not you" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84012.yml b/html/changelogs/AutoChangeLog-pr-84012.yml deleted file mode 100644 index 97e81c2ad7706..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84012.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "GoblinBackwards" -delete-after: True -changes: - - bugfix: "Fixed anomaly cores from the high-intensity grav anomaly event creating the wrong type of reactive armour." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84019.yml b/html/changelogs/AutoChangeLog-pr-84019.yml deleted file mode 100644 index 63877aba2d051..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84019.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "mc-oofert" -delete-after: True -changes: - - bugfix: "build mode and space dragons dont harddel on destroy" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84020.yml b/html/changelogs/AutoChangeLog-pr-84020.yml deleted file mode 100644 index e47971b005d60..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84020.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "GoblinBackwards" -delete-after: True -changes: - - bugfix: "Fixed mulebots being able to run over people who are leaning against a wall." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84024.yml b/html/changelogs/AutoChangeLog-pr-84024.yml deleted file mode 100644 index aeff257645e5b..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84024.yml +++ /dev/null @@ -1,9 +0,0 @@ -author: "MTandi" -delete-after: True -changes: - - balance: "Reshuffled tech tree, making nodes more specialized" - - qol: "Research points devided by the amount generated per second, so now research points correspond to seconds" - - rscadd: "Introduced reagent purity scan experiments (required for Cryostasis node)" - - rscadd: "Introduced synthetic organ scan experiment (required for top tier cyber organs)" - - rscadd: "Added a variant of machinery scan experiment that accepts any machines with upgraded parts (required for tier 3 parts)" - - rscdel: "Removed material scanning experiments from the tech tree" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84028.yml b/html/changelogs/AutoChangeLog-pr-84028.yml deleted file mode 100644 index b21a26a8ddfde..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84028.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Melbert" -delete-after: True -changes: - - bugfix: "Crusher Fix For Real" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84031.yml b/html/changelogs/AutoChangeLog-pr-84031.yml deleted file mode 100644 index 9e4459a752e7f..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84031.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "MTandi" -delete-after: True -changes: - - bugfix: "Non-metallic slime types are semi-transparent" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84032.yml b/html/changelogs/AutoChangeLog-pr-84032.yml deleted file mode 100644 index 57e6705027013..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84032.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "LucyGrind" -delete-after: True -changes: - - bugfix: "allows cigarette grinding in mortar" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84037.yml b/html/changelogs/AutoChangeLog-pr-84037.yml deleted file mode 100644 index 397febdfdf042..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84037.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "mc-oofert" -delete-after: True -changes: - - bugfix: "you may now open the panel of a flatpacker with a screwdriver" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84049.yml b/html/changelogs/AutoChangeLog-pr-84049.yml deleted file mode 100644 index 35a9bbea6588a..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84049.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "TheBoondock" -delete-after: True -changes: - - sound: "added squeaky turn and gas hissing sound to gas valve" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84052.yml b/html/changelogs/AutoChangeLog-pr-84052.yml deleted file mode 100644 index d714cbd085f41..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84052.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "GPeckman" -delete-after: True -changes: - - bugfix: "Mining borgs can get multiple modkits of the same type installed again." \ No newline at end of file diff --git a/html/changelogs/archive/2024-06.yml b/html/changelogs/archive/2024-06.yml index f3c26e8d5e75a..9f757c45df58b 100644 --- a/html/changelogs/archive/2024-06.yml +++ b/html/changelogs/archive/2024-06.yml @@ -753,3 +753,50 @@ - sound: added compressed air sound for when air tanks are inserted into machinery grungussuss: - rscadd: Added Misha the bear to the HoS office on icebox. +2024-06-18: + Bisar: + - balance: Replaced the free reagent purging with actually purging by exploding + someone in the blood while they have omnizine and a purgative in their bloodstream. + Let's go practice medicine! + - bugfix: Fixed the free reagent purging mechanic from causing an explosion so weak + that it doesn't cause any damage. + GPeckman: + - bugfix: Mining borgs can get multiple modkits of the same type installed again. + Goat: + - qol: fire extinguishers can now be filled via stationary tanks. (and water coolers) + GoblinBackwards: + - bugfix: Fixed mulebots being able to run over people who are leaning against a + wall. + - bugfix: Fixed anomaly cores from the high-intensity grav anomaly event creating + the wrong type of reactive armour. + Kaostico: + - bugfix: Transcendent Olfaction mutation now works properly + LucyGrind: + - bugfix: allows cigarette grinding in mortar + MTandi: + - bugfix: Non-metallic slime types are semi-transparent + - balance: Reshuffled tech tree, making nodes more specialized + - qol: Research points devided by the amount generated per second, so now research + points correspond to seconds + - rscadd: Introduced reagent purity scan experiments (required for Cryostasis node) + - rscadd: Introduced synthetic organ scan experiment (required for top tier cyber + organs) + - rscadd: Added a variant of machinery scan experiment that accepts any machines + with upgraded parts (required for tier 3 parts) + - rscdel: Removed material scanning experiments from the tech tree + Melbert: + - qol: Block'd out armor readout, should be more readable now + - bugfix: Crusher Fix For Real + SyncIt21: + - bugfix: ctrl+shift clicking on a ghost will only quick spawn that clicked target + and not you + TheBoondock: + - sound: added squeaky turn and gas hissing sound to gas valve + TheRyeGuyWhoWillNowDie: + - qol: adds a confirmation to malf AI shunting into APCs + mc-oofert: + - bugfix: build mode and space dragons dont harddel on destroy + - bugfix: you may now open the panel of a flatpacker with a screwdriver + san7890: + - qol: A message with a link to publicly accessible logs (if enabled by your server + operators) should now be visible far earlier when a world is about to reboot. From 0119b95d2deeab1f66034a8ce51a7c15d3cc96a3 Mon Sep 17 00:00:00 2001 From: carlarctg <53100513+carlarctg@users.noreply.github.com> Date: Tue, 18 Jun 2024 01:39:04 -0300 Subject: [PATCH 043/172] Genetics Rebalance: Negative mutations add stability, standarized instability cost for mutations (#83439) ## About The Pull Request PR has been reworked a bunch! Changes in bold. Some of the **HATE** is now outdated. **Negative mutations now allow you to have more positive mutations, via reducing your instability!** **All mutations have been overall standardized via defines on their instability values. Many mediocre positive mutations have had their cost reduced significantly!** ``` /// Negatives that are virtually harmless and mostly just funny (language) // Set to 0 because munchkinning via miscommunication = bad #define NEGATIVE_STABILITY_MINI 0 /// Negatives that are slightly annoying (unused) #define NEGATIVE_STABILITY_MINOR -20 /// Negatives that present an uncommon or weak, consistent hindrance to gameplay (cough, paranoia) #define NEGATIVE_STABILITY_MODERATE -30 /// Negatives that present a major consistent hindrance to gameplay (deaf, mute, acid flesh) #define NEGATIVE_STABILITY_MAJOR -40 /// Positives that provide basically no benefit (glowy) #define POSITIVE_INSTABILITY_MINI 5 /// Positives that are niche in application or useful in rare circumstances (parlor tricks, geladikinesis, autotomy) #define POSITIVE_INSTABILITY_MINOR 10 /// Positives that provide a new ability that's roughly par with station equipment (insulated, cryokinesis) #define POSITIVE_INSTABILITY_MODERATE 25 /// Positives that are unique, very powerful, and noticeably change combat/gameplay (hulk, tk) #define POSITIVE_INSTABILITY_MAJOR 35 ``` Added a new height mutation: Acromegaly! It's the opposite of Dwarfism and makes you uncannily tall. It also makes you hit your head 8% or 4% (with synch) of the time you pass through airlocks. Wear a helmet! **Injectors and activators' duration is now dependent on the in/stability (absolute value) of the mutations to be injected! With a minimum of 5-10-15 seconds for each type of injector. Also changed up a bit how part upgrade cooldowns work, by making each tier reduce cooldowns by 25-15-10% for each injector type.** ## Why It's Good For The Game **> Negative mutations now allow you to have more positive mutations, via reducing your instability!** Genetics has been long in dire need of a rework. This isn't really one, but it IS intended to increase genetics depth a bit and stave off its stagnation, making it slightly more interesting than 'free shit', by making it so **you can now gain more positive mutations, but you need to figure out what you're going to take as a downgrade in turn.** Genetic powers are heavily themed around comic book superheroes, and you know what those had a lot? Debilitating drawbacks to their powers. Let's replicate that. **I intend to make a sister PR for this that adds more interesting positive mutations (for the first time in decades) to genetics, so there's an actual element of pick-and-choose involved** > Added a new height mutation: Acromegaly! It's the opposite of Dwarfism and makes you uncannily tall. It also makes you hit your head 8% or 4% (with synch) of the time you pass through airlocks. Wear a helmet! We have Super Tall. Let's add it to the game somewhere! With a fun downside, of course. **Gigantism is now a recipe mutation, mix Acromegaly with Strength to get it.** > **Injectors and activators' duration is now dependent on the in/stability (absolute value) of the mutations to be injected! With a minimum of 5-10-15 seconds for each type of injector. Also changed up a bit how part upgrade cooldowns work, by making each tier reduce cooldowns by 25-15-10% for each injector type.** **Made no sense that a Glowy injector cost the same as a Hulk injector. Just annoying. The cooldown is based on the absolute value, so a -30 instability injector would take ~30 seconds. This mostly so that geneticists can't make a million modded syringe gun supersyringes** --- code/__DEFINES/mobs.dm | 1 + code/__DEFINES/traits/declarations.dm | 2 + code/_globalvars/traits/_traits.dm | 1 + code/datums/dna.dm | 2 +- code/datums/mutations/_mutations.dm | 20 +++ code/datums/mutations/adaptation.dm | 4 +- code/datums/mutations/antenna.dm | 4 +- code/datums/mutations/autotomy.dm | 2 +- code/datums/mutations/body.dm | 114 +++++++++++++----- code/datums/mutations/chameleon.dm | 2 +- code/datums/mutations/cold.dm | 4 +- code/datums/mutations/fire_breath.dm | 2 +- code/datums/mutations/hulk.dm | 2 +- code/datums/mutations/olfaction.dm | 2 +- code/datums/mutations/passive.dm | 4 +- code/datums/mutations/radioactive.dm | 2 +- code/datums/mutations/sight.dm | 7 +- code/datums/mutations/speech.dm | 9 ++ code/datums/mutations/telekinesis.dm | 2 +- code/datums/mutations/telepathy.dm | 2 +- code/datums/mutations/tongue_spike.dm | 4 +- code/datums/mutations/touch.dm | 2 +- code/datums/mutations/void_magnet.dm | 2 +- code/datums/mutations/webbing.dm | 2 +- code/game/machinery/computer/dna_console.dm | 79 +++++++++--- code/game/machinery/dna_scanner.dm | 4 +- code/game/objects/items/dna_injector.dm | 6 +- .../mob/living/carbon/human/human_helpers.dm | 5 + .../living/carbon/human/human_update_icons.dm | 40 ++++-- 29 files changed, 242 insertions(+), 90 deletions(-) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 2e5d9beadaf21..6f6a9d209a10e 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -635,6 +635,7 @@ // Otherwise they are completely arbitrary #define MONKEY_HEIGHT_DWARF 2 #define MONKEY_HEIGHT_MEDIUM 4 +#define MONKEY_HEIGHT_TALL HUMAN_HEIGHT_DWARF #define HUMAN_HEIGHT_DWARF 6 #define HUMAN_HEIGHT_SHORTEST 8 #define HUMAN_HEIGHT_SHORT 10 diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 2d420339e1883..93cba187da449 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -366,6 +366,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_GAMERGOD "gamer-god" #define TRAIT_GIANT "giant" #define TRAIT_DWARF "dwarf" +/// Makes you way too tall. Like just too much, dude, it's kind of creepy. Humanoid only. +#define TRAIT_TOO_TALL "too_tall" /// makes your footsteps completely silent #define TRAIT_SILENT_FOOTSTEPS "silent_footsteps" /// hnnnnnnnggggg..... you're pretty good.... diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index ba065653fe6dc..3bb59817ec489 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -465,6 +465,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_THINKING_IN_CHARACTER" = TRAIT_THINKING_IN_CHARACTER, "TRAIT_THROWINGARM" = TRAIT_THROWINGARM, "TRAIT_TIME_STOP_IMMUNE" = TRAIT_TIME_STOP_IMMUNE, + "TRAIT_TOO_TALL" = TRAIT_TOO_TALL, "TRAIT_TOWER_OF_BABEL" = TRAIT_TOWER_OF_BABEL, "TRAIT_TOXIMMUNE" = TRAIT_TOXIMMUNE, "TRAIT_TOXINLOVER" = TRAIT_TOXINLOVER, diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 75fb406e3371e..02773e375f3a3 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -423,7 +423,7 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) /datum/dna/proc/update_instability(alert=TRUE) stability = 100 for(var/datum/mutation/human/M in mutations) - if(M.class == MUT_EXTRA) + if(M.class == MUT_EXTRA || M.instability < 0) stability -= M.instability * GET_MUTATION_STABILIZER(M) if(holder) var/message diff --git a/code/datums/mutations/_mutations.dm b/code/datums/mutations/_mutations.dm index 4913a057e011a..95f59ade38c39 100644 --- a/code/datums/mutations/_mutations.dm +++ b/code/datums/mutations/_mutations.dm @@ -1,3 +1,23 @@ + +/// Negatives that are virtually harmless and mostly just funny (language) +// Set to 0 because munchkinning via miscommunication = bad +#define NEGATIVE_STABILITY_MINI 0 +/// Negatives that are slightly annoying (unused) +#define NEGATIVE_STABILITY_MINOR -20 +/// Negatives that present an uncommon or weak, consistent hindrance to gameplay (cough, paranoia) +#define NEGATIVE_STABILITY_MODERATE -30 +/// Negatives that present a major consistent hindrance to gameplay (deaf, mute, acid flesh) +#define NEGATIVE_STABILITY_MAJOR -40 + +/// Positives that provide basically no benefit (glowy) +#define POSITIVE_INSTABILITY_MINI 5 +/// Positives that are niche in application or useful in rare circumstances (parlor tricks, geladikinesis, autotomy) +#define POSITIVE_INSTABILITY_MINOR 10 +/// Positives that provide a new ability that's roughly par with station equipment (insulated, cryokinesis) +#define POSITIVE_INSTABILITY_MODERATE 25 +/// Positives that are unique, very powerful, and noticeably change combat/gameplay (hulk, tk) +#define POSITIVE_INSTABILITY_MAJOR 35 + /datum/mutation var/name diff --git a/code/datums/mutations/adaptation.dm b/code/datums/mutations/adaptation.dm index 1c183f9367d3a..2cac87dd4b4c4 100644 --- a/code/datums/mutations/adaptation.dm +++ b/code/datums/mutations/adaptation.dm @@ -4,7 +4,7 @@ quality = POSITIVE difficulty = 16 text_gain_indication = "Your body feels warm!" - instability = 25 + instability = POSITIVE_INSTABILITY_MAJOR conflicts = list(/datum/mutation/human/pressure_adaptation) /datum/mutation/human/temperature_adaptation/New(class_ = MUT_OTHER, timer, datum/mutation/human/copymut) @@ -31,7 +31,7 @@ quality = POSITIVE difficulty = 16 text_gain_indication = "Your body feels numb!" - instability = 25 + instability = POSITIVE_INSTABILITY_MAJOR conflicts = list(/datum/mutation/human/temperature_adaptation) /datum/mutation/human/pressure_adaptation/New(class_ = MUT_OTHER, timer, datum/mutation/human/copymut) diff --git a/code/datums/mutations/antenna.dm b/code/datums/mutations/antenna.dm index 80edceea1e5ed..fc1a94276f702 100644 --- a/code/datums/mutations/antenna.dm +++ b/code/datums/mutations/antenna.dm @@ -4,7 +4,7 @@ quality = POSITIVE text_gain_indication = "You feel an antenna sprout from your forehead." text_lose_indication = "Your antenna shrinks back down." - instability = 5 + instability = POSITIVE_INSTABILITY_MINOR difficulty = 8 var/datum/weakref/radio_weakref @@ -47,7 +47,7 @@ text_gain_indication = "You hear distant voices at the corners of your mind." text_lose_indication = "The distant voices fade." power_path = /datum/action/cooldown/spell/pointed/mindread - instability = 40 + instability = POSITIVE_INSTABILITY_MINOR difficulty = 8 locked = TRUE diff --git a/code/datums/mutations/autotomy.dm b/code/datums/mutations/autotomy.dm index 5a70455db5fb8..bb78ceb08dcf7 100644 --- a/code/datums/mutations/autotomy.dm +++ b/code/datums/mutations/autotomy.dm @@ -3,7 +3,7 @@ desc = "Allows a creature to voluntary discard a random appendage." quality = POSITIVE text_gain_indication = span_notice("Your joints feel loose.") - instability = 30 + instability = POSITIVE_INSTABILITY_MINOR power_path = /datum/action/cooldown/spell/self_amputation energy_coeff = 1 diff --git a/code/datums/mutations/body.dm b/code/datums/mutations/body.dm index 896820746d61d..eaa1ba1f5cafa 100644 --- a/code/datums/mutations/body.dm +++ b/code/datums/mutations/body.dm @@ -4,6 +4,7 @@ /datum/mutation/human/epilepsy name = "Epilepsy" desc = "A genetic defect that sporadically causes seizures." + instability = NEGATIVE_STABILITY_MODERATE quality = NEGATIVE text_gain_indication = "You get a headache." synchronizer_coeff = 1 @@ -50,6 +51,7 @@ /datum/mutation/human/bad_dna name = "Unstable DNA" desc = "Strange mutation that causes the holder to randomly mutate." + instability = NEGATIVE_STABILITY_MAJOR quality = NEGATIVE text_gain_indication = "You feel strange." locked = TRUE @@ -79,6 +81,7 @@ /datum/mutation/human/cough name = "Cough" desc = "A chronic cough." + instability = NEGATIVE_STABILITY_MODERATE quality = MINOR_NEGATIVE text_gain_indication = "You start coughing." synchronizer_coeff = 1 @@ -96,6 +99,7 @@ /datum/mutation/human/paranoia name = "Paranoia" desc = "Subject is easily terrified, and may suffer from hallucinations." + instability = NEGATIVE_STABILITY_MODERATE quality = NEGATIVE text_gain_indication = "You feel screams echo through your mind..." text_lose_indication = "The screaming in your mind fades." @@ -112,8 +116,8 @@ desc = "A mutation believed to be the cause of dwarfism." quality = POSITIVE difficulty = 16 - instability = 5 - conflicts = list(/datum/mutation/human/gigantism) + instability = POSITIVE_INSTABILITY_MINOR + conflicts = list(/datum/mutation/human/gigantism, /datum/mutation/human/acromegaly) locked = TRUE // Default intert species for now, so locked from regular pool. /datum/mutation/human/dwarfism/on_acquiring(mob/living/carbon/human/owner) @@ -128,10 +132,71 @@ REMOVE_TRAIT(owner, TRAIT_DWARF, GENETIC_MUTATION) owner.visible_message(span_danger("[owner] suddenly grows!"), span_notice("Everything around you seems to shrink..")) +/datum/mutation/human/acromegaly + name = "Acromegaly" + desc = "A mutation believed to be the cause of acromegaly, or 'being unusually tall'." + quality = MINOR_NEGATIVE + difficulty = 16 + instability = NEGATIVE_STABILITY_MODERATE + synchronizer_coeff = 1 + conflicts = list(/datum/mutation/human/dwarfism) + +/datum/mutation/human/acromegaly/on_acquiring(mob/living/carbon/human/owner) + if(..()) + return + ADD_TRAIT(owner, TRAIT_TOO_TALL, GENETIC_MUTATION) + owner.visible_message(span_danger("[owner] suddenly grows tall!"), span_notice("You feel a small strange urge to fight small men with slingshots. Or maybe play some basketball.")) + RegisterSignal(owner, COMSIG_MOVABLE_MOVED, PROC_REF(head_bonk)) + owner.regenerate_icons() + +/datum/mutation/human/acromegaly/on_losing(mob/living/carbon/human/owner) + if(..()) + return + REMOVE_TRAIT(owner, TRAIT_TOO_TALL, GENETIC_MUTATION) + owner.visible_message(span_danger("[owner] suddenly shrinks!"), span_notice("You return to your usual height.")) + UnregisterSignal(owner, COMSIG_MOVABLE_MOVED, PROC_REF(head_bonk)) + owner.regenerate_icons() + +// This is specifically happening because they're not used to their new height and are stumbling around into machinery made for normal humans +/datum/mutation/human/acromegaly/proc/head_bonk(mob/living/parent) + SIGNAL_HANDLER + var/turf/airlock_turf = get_turf(parent) + var/atom/movable/whacked_by = locate(/obj/machinery/door/airlock) in airlock_turf || locate(/obj/machinery/door/firedoor) in airlock_turf || locate(/obj/structure/mineral_door) in airlock_turf + if(!whacked_by || prob(100 - (8 * GET_MUTATION_SYNCHRONIZER(src)))) + return + to_chat(parent, span_danger("You hit your head on \the [whacked_by]'s header!")) + var/dmg = HAS_TRAIT(parent, TRAIT_HEAD_INJURY_BLOCKED) ? rand(1,4) : rand(2,9) + parent.apply_damage(dmg, BRUTE, BODY_ZONE_HEAD) + parent.do_attack_animation(whacked_by, ATTACK_EFFECT_PUNCH) + playsound(whacked_by, 'sound/effects/bang.ogg', 10, TRUE) + parent.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH, 10 SECONDS) + +/datum/mutation/human/gigantism + name = "Gigantism" //negative version of dwarfism + desc = "The cells within the subject spread out to cover more area, making the subject appear larger." + quality = MINOR_NEGATIVE + difficulty = 12 + conflicts = list(/datum/mutation/human/dwarfism) + +/datum/mutation/human/gigantism/on_acquiring(mob/living/carbon/human/owner) + if(..()) + return + ADD_TRAIT(owner, TRAIT_GIANT, GENETIC_MUTATION) + owner.update_transform(1.25) + owner.visible_message(span_danger("[owner] suddenly grows!"), span_notice("Everything around you seems to shrink..")) + +/datum/mutation/human/gigantism/on_losing(mob/living/carbon/human/owner) + if(..()) + return + REMOVE_TRAIT(owner, TRAIT_GIANT, GENETIC_MUTATION) + owner.update_transform(0.8) + owner.visible_message(span_danger("[owner] suddenly shrinks!"), span_notice("Everything around you seems to grow..")) + //Clumsiness has a very large amount of small drawbacks depending on item. /datum/mutation/human/clumsy name = "Clumsiness" desc = "A genome that inhibits certain brain functions, causing the holder to appear clumsy. Honk!" + instability = NEGATIVE_STABILITY_MAJOR quality = MINOR_NEGATIVE text_gain_indication = "You feel lightheaded." @@ -151,6 +216,7 @@ name = "Tourette's Syndrome" desc = "A chronic twitch that forces the user to scream bad words." //definitely needs rewriting quality = NEGATIVE + instability = 0 text_gain_indication = "You twitch." synchronizer_coeff = 1 @@ -173,6 +239,7 @@ /datum/mutation/human/deaf name = "Deafness" desc = "The holder of this genome is completely deaf." + instability = NEGATIVE_STABILITY_MAJOR quality = NEGATIVE text_gain_indication = "You can't seem to hear anything." @@ -194,6 +261,7 @@ text_gain_indication = "You feel unusually monkey-like." text_lose_indication = "You feel like your old self." quality = NEGATIVE + instability = NEGATIVE_STABILITY_MAJOR // mmmonky remove_on_aheal = FALSE locked = TRUE //Species specific, keep out of actual gene pool mutadone_proof = TRUE @@ -219,7 +287,7 @@ desc = "You permanently emit a light with a random color and intensity." quality = POSITIVE text_gain_indication = "Your skin begins to glow softly." - instability = 5 + instability = POSITIVE_INSTABILITY_MINI power_coeff = 1 conflicts = list(/datum/mutation/human/glow/anti) var/glow_power = 2 @@ -257,6 +325,7 @@ desc = "Your skin seems to attract and absorb nearby light creating 'darkness' around you." text_gain_indication = "The light around you seems to disappear." conflicts = list(/datum/mutation/human/glow) + instability = POSITIVE_INSTABILITY_MINOR locked = TRUE glow_power = -1.5 @@ -265,10 +334,10 @@ /datum/mutation/human/strong name = "Strength" - desc = "The user's muscles slightly expand." + desc = "The user's muscles slightly expand. Commonly seen in top-ranking boxers." quality = POSITIVE text_gain_indication = "You feel strong." - instability = 5 + instability = POSITIVE_INSTABILITY_MINI difficulty = 16 /datum/mutation/human/strong/on_acquiring(mob/living/carbon/human/owner) @@ -286,10 +355,11 @@ /datum/mutation/human/stimmed name = "Stimmed" - desc = "The user's chemical balance is more robust." + desc = "The user's chemical balance is more robust. This mutation is known to slightly improve workout efficiency." quality = POSITIVE + instability = POSITIVE_INSTABILITY_MINI text_gain_indication = "You feel stimmed." - instability = 5 + instability = 15 difficulty = 16 /datum/mutation/human/stimmed/on_acquiring(mob/living/carbon/human/owner) @@ -311,7 +381,7 @@ text_gain_indication = "Your fingertips go numb." text_lose_indication = "Your fingertips regain feeling." difficulty = 16 - instability = 25 + instability = POSITIVE_INSTABILITY_MODERATE /datum/mutation/human/insulated/on_acquiring(mob/living/carbon/human/owner) if(..()) @@ -355,7 +425,7 @@ text_gain_indication = "The space around you twists sickeningly." text_lose_indication = "The space around you settles back to normal." difficulty = 18//high so it's hard to unlock and abuse - instability = 10 + instability = NEGATIVE_STABILITY_MODERATE synchronizer_coeff = 1 energy_coeff = 1 power_coeff = 1 @@ -381,6 +451,7 @@ /datum/mutation/human/acidflesh name = "Acidic Flesh" desc = "Subject has acidic chemicals building up underneath the skin. This is often lethal." + instability = NEGATIVE_STABILITY_MAJOR quality = NEGATIVE text_gain_indication = "A horrible burning sensation envelops you as your flesh turns to acid!" text_lose_indication = "A feeling of relief fills you as your flesh goes back to normal." @@ -398,30 +469,10 @@ owner.visible_message(span_warning("[owner]'s skin bubbles and pops."), span_userdanger("Your bubbling flesh pops! It burns!")) playsound(owner,'sound/weapons/sear.ogg', 50, TRUE) -/datum/mutation/human/gigantism - name = "Gigantism"//negative version of dwarfism - desc = "The cells within the subject spread out to cover more area, making the subject appear larger." - quality = MINOR_NEGATIVE - difficulty = 12 - conflicts = list(/datum/mutation/human/dwarfism) - -/datum/mutation/human/gigantism/on_acquiring(mob/living/carbon/human/owner) - if(..()) - return - ADD_TRAIT(owner, TRAIT_GIANT, GENETIC_MUTATION) - owner.update_transform(1.25) - owner.visible_message(span_danger("[owner] suddenly grows!"), span_notice("Everything around you seems to shrink..")) - -/datum/mutation/human/gigantism/on_losing(mob/living/carbon/human/owner) - if(..()) - return - REMOVE_TRAIT(owner, TRAIT_GIANT, GENETIC_MUTATION) - owner.update_transform(0.8) - owner.visible_message(span_danger("[owner] suddenly shrinks!"), span_notice("Everything around you seems to grow..")) - /datum/mutation/human/spastic name = "Spastic" desc = "Subject suffers from muscle spasms." + instability = NEGATIVE_STABILITY_MODERATE quality = NEGATIVE text_gain_indication = "You flinch." text_lose_indication = "Your flinching subsides." @@ -440,6 +491,7 @@ /datum/mutation/human/extrastun name = "Two Left Feet" desc = "A mutation that replaces the right foot with another left foot. Symptoms include kissing the floor when taking a step." + instability = NEGATIVE_STABILITY_MODERATE quality = NEGATIVE text_gain_indication = "Your right foot feels... left." text_lose_indication = "Your right foot feels alright." @@ -471,6 +523,7 @@ /datum/mutation/human/martyrdom name = "Internal Martyrdom" desc = "A mutation that makes the body destruct when near death. Not damaging, but very, VERY disorienting." + instability = NEGATIVE_STABILITY_MAJOR // free stability >:) locked = TRUE quality = POSITIVE //not that cloning will be an option a lot but generally lets keep this around i guess? text_gain_indication = "You get an intense feeling of heartburn." @@ -518,6 +571,7 @@ /datum/mutation/human/headless name = "H.A.R.S." desc = "A mutation that makes the body reject the head, the brain receding into the chest. Stands for Head Allergic Rejection Syndrome. Warning: Removing this mutation is very dangerous, though it will regenerate non-vital head organs." + instability = NEGATIVE_STABILITY_MAJOR difficulty = 12 //pretty good for traitors quality = NEGATIVE //holy shit no eyes or tongue or ears text_gain_indication = "Something feels off." diff --git a/code/datums/mutations/chameleon.dm b/code/datums/mutations/chameleon.dm index d5cbc36d20a1f..e3ce8826a9438 100644 --- a/code/datums/mutations/chameleon.dm +++ b/code/datums/mutations/chameleon.dm @@ -6,7 +6,7 @@ difficulty = 16 text_gain_indication = "You feel one with your surroundings." text_lose_indication = "You feel oddly exposed." - instability = 25 + instability = POSITIVE_INSTABILITY_MAJOR power_coeff = 1 /datum/mutation/human/chameleon/on_acquiring(mob/living/carbon/human/owner) diff --git a/code/datums/mutations/cold.dm b/code/datums/mutations/cold.dm index 57c4f854fc7a2..32e162bf7d3a0 100644 --- a/code/datums/mutations/cold.dm +++ b/code/datums/mutations/cold.dm @@ -3,7 +3,7 @@ desc = "Allows the user to concentrate moisture and sub-zero forces into snow." quality = POSITIVE text_gain_indication = "Your hand feels cold." - instability = 10 + instability = POSITIVE_INSTABILITY_MINOR difficulty = 10 synchronizer_coeff = 1 power_path = /datum/action/cooldown/spell/conjure_item/snow @@ -25,7 +25,7 @@ desc = "Draws negative energy from the sub-zero void to freeze surrounding temperatures at subject's will." quality = POSITIVE //upsides and downsides text_gain_indication = "Your hand feels cold." - instability = 30 + instability = POSITIVE_INSTABILITY_MODERATE difficulty = 12 synchronizer_coeff = 1 energy_coeff = 1 diff --git a/code/datums/mutations/fire_breath.dm b/code/datums/mutations/fire_breath.dm index f8631761ba202..5836997729456 100644 --- a/code/datums/mutations/fire_breath.dm +++ b/code/datums/mutations/fire_breath.dm @@ -7,7 +7,7 @@ text_gain_indication = "Your throat is burning!" text_lose_indication = "Your throat is cooling down." power_path = /datum/action/cooldown/spell/cone/staggered/fire_breath - instability = 30 + instability = POSITIVE_INSTABILITY_MODERATE energy_coeff = 1 power_coeff = 1 diff --git a/code/datums/mutations/hulk.dm b/code/datums/mutations/hulk.dm index 63e0abc22a33f..3fdc5de52ce2b 100644 --- a/code/datums/mutations/hulk.dm +++ b/code/datums/mutations/hulk.dm @@ -8,7 +8,7 @@ text_gain_indication = "Your muscles hurt!" species_allowed = list(SPECIES_HUMAN) //no skeleton/lizard hulk health_req = 25 - instability = 40 + instability = POSITIVE_INSTABILITY_MAJOR var/scream_delay = 50 var/last_scream = 0 /// List of traits to add/remove when someone gets this mutation. diff --git a/code/datums/mutations/olfaction.dm b/code/datums/mutations/olfaction.dm index 6328345f1c4b3..f487702a3c6c8 100644 --- a/code/datums/mutations/olfaction.dm +++ b/code/datums/mutations/olfaction.dm @@ -6,7 +6,7 @@ text_gain_indication = "Smells begin to make more sense..." text_lose_indication = "Your sense of smell goes back to normal." power_path = /datum/action/cooldown/spell/olfaction - instability = 30 + instability = POSITIVE_INSTABILITY_MODERATE synchronizer_coeff = 1 /datum/mutation/human/olfaction/modify() diff --git a/code/datums/mutations/passive.dm b/code/datums/mutations/passive.dm index 9d694aaf1ebbb..14135fe426ea4 100644 --- a/code/datums/mutations/passive.dm +++ b/code/datums/mutations/passive.dm @@ -2,7 +2,7 @@ name = "Biotech Compatibility" desc = "Subject is more compatibile with biotechnology such as skillchips." quality = POSITIVE - instability = 5 + instability = POSITIVE_INSTABILITY_MINI /datum/mutation/human/biotechcompat/on_acquiring(mob/living/carbon/human/owner) . = ..() @@ -16,7 +16,7 @@ name = "Clever" desc = "Causes the subject to feel just a little bit smarter. Most effective in specimens with low levels of intelligence." quality = POSITIVE - instability = 20 + instability = POSITIVE_INSTABILITY_MODERATE // literally makes you on par with station equipment text_gain_indication = "You feel a little bit smarter." text_lose_indication = "Your mind feels a little bit foggy." diff --git a/code/datums/mutations/radioactive.dm b/code/datums/mutations/radioactive.dm index 8f710bfa497a4..8700e405662a6 100644 --- a/code/datums/mutations/radioactive.dm +++ b/code/datums/mutations/radioactive.dm @@ -3,7 +3,7 @@ desc = "A volatile mutation that causes the host to sent out deadly beta radiation. This affects both the hosts and their surroundings." quality = NEGATIVE text_gain_indication = "You can feel it in your bones!" - instability = 5 + instability = NEGATIVE_STABILITY_MAJOR difficulty = 8 power_coeff = 1 /// Weakref to our radiation emitter component diff --git a/code/datums/mutations/sight.dm b/code/datums/mutations/sight.dm index 8b26f6ca268f0..66e307c247846 100644 --- a/code/datums/mutations/sight.dm +++ b/code/datums/mutations/sight.dm @@ -2,6 +2,7 @@ /datum/mutation/human/nearsight name = "Near Sightness" desc = "The holder of this mutation has poor eyesight." + instability = NEGATIVE_STABILITY_MODERATE quality = MINOR_NEGATIVE text_gain_indication = "You can't see very well." @@ -19,6 +20,7 @@ /datum/mutation/human/blind name = "Blindness" desc = "Renders the subject completely blind." + instability = NEGATIVE_STABILITY_MAJOR quality = NEGATIVE text_gain_indication = "You can't seem to see anything." @@ -40,7 +42,7 @@ difficulty = 18 text_gain_indication = "You can see the heat rising off of your skin..." text_lose_indication = "You can no longer see the heat rising off of your skin..." - instability = 25 + instability = POSITIVE_INSTABILITY_MAJOR // thermals aren't station equipment synchronizer_coeff = 1 power_coeff = 1 energy_coeff = 1 @@ -110,7 +112,7 @@ name = "X Ray Vision" desc = "A strange genome that allows the user to see between the spaces of walls." //actual x-ray would mean you'd constantly be blasting rads, wich might be fun for later //hmb text_gain_indication = "The walls suddenly disappear!" - instability = 35 + instability = POSITIVE_INSTABILITY_MAJOR locked = TRUE /datum/mutation/human/xray/on_acquiring(mob/living/carbon/human/owner) @@ -182,6 +184,7 @@ /datum/mutation/human/illiterate name = "Illiterate" desc = "Causes a severe case of Aphasia that prevents reading or writing." + instability = NEGATIVE_STABILITY_MAJOR quality = NEGATIVE text_gain_indication = "You feel unable to read or write." text_lose_indication = "You feel able to read and write again." diff --git a/code/datums/mutations/speech.dm b/code/datums/mutations/speech.dm index 4c78c19610439..1400503dfc45d 100644 --- a/code/datums/mutations/speech.dm +++ b/code/datums/mutations/speech.dm @@ -4,6 +4,7 @@ /datum/mutation/human/nervousness name = "Nervousness" desc = "Causes the holder to stutter." + instability = NEGATIVE_STABILITY_MINI quality = MINOR_NEGATIVE text_gain_indication = "You feel nervous." @@ -14,6 +15,7 @@ /datum/mutation/human/wacky name = "Wacky" desc = "You are not a clown. You are the entire circus." + instability = NEGATIVE_STABILITY_MINI quality = MINOR_NEGATIVE text_gain_indication = "You feel an off sensation in your voicebox." text_lose_indication = "The off sensation passes." @@ -36,6 +38,7 @@ /datum/mutation/human/mute name = "Mute" desc = "Completely inhibits the vocal section of the brain." + instability = NEGATIVE_STABILITY_MAJOR quality = NEGATIVE text_gain_indication = "You feel unable to express yourself at all." text_lose_indication = "You feel able to speak freely again." @@ -53,6 +56,7 @@ /datum/mutation/human/unintelligible name = "Unintelligible" desc = "Partially inhibits the vocal center of the brain, severely distorting speech." + instability = NEGATIVE_STABILITY_MODERATE quality = NEGATIVE text_gain_indication = "You can't seem to form any coherent thoughts!" text_lose_indication = "Your mind feels more clear." @@ -70,6 +74,7 @@ /datum/mutation/human/swedish name = "Swedish" desc = "A horrible mutation originating from the distant past. Thought to be eradicated after the incident in 2037." + instability = NEGATIVE_STABILITY_MINI quality = MINOR_NEGATIVE text_gain_indication = "You feel Swedish, however that works." text_lose_indication = "The feeling of Swedishness passes." @@ -101,6 +106,7 @@ /datum/mutation/human/chav name = "Chav" desc = "Unknown" + instability = NEGATIVE_STABILITY_MINI quality = MINOR_NEGATIVE text_gain_indication = "Ye feel like a reet prat like, innit?" text_lose_indication = "You no longer feel like being rude and sassy." @@ -138,6 +144,7 @@ /datum/mutation/human/elvis name = "Elvis" desc = "A terrifying mutation named after its 'patient-zero'." + instability = NEGATIVE_STABILITY_MINI quality = MINOR_NEGATIVE locked = TRUE text_gain_indication = "You feel pretty good, honeydoll." @@ -203,6 +210,7 @@ /datum/mutation/human/medieval name = "Medieval" desc = "A horrible mutation originating from the distant past, thought to have once been a common gene in all of old world Europe." + instability = NEGATIVE_STABILITY_MINI quality = MINOR_NEGATIVE text_gain_indication = "You feel like seeking the holy grail!" text_lose_indication = "You no longer feel like seeking anything." @@ -243,6 +251,7 @@ /datum/mutation/human/piglatin name = "Pig Latin" desc = "Historians say back in the 2020's humanity spoke entirely in this mystical language." + instability = NEGATIVE_STABILITY_MINI quality = MINOR_NEGATIVE text_gain_indication = span_notice("Omethingsay eelsfay offyay.") text_lose_indication = span_notice("The off sensation passes.") diff --git a/code/datums/mutations/telekinesis.dm b/code/datums/mutations/telekinesis.dm index 53d8beb56ff50..bd6ba13070df3 100644 --- a/code/datums/mutations/telekinesis.dm +++ b/code/datums/mutations/telekinesis.dm @@ -6,7 +6,7 @@ difficulty = 18 text_gain_indication = "You feel smarter!" limb_req = BODY_ZONE_HEAD - instability = 30 + instability = POSITIVE_INSTABILITY_MAJOR ///Typecache of atoms that TK shouldn't interact with var/static/list/blacklisted_atoms = typecacheof(list(/atom/movable/screen)) diff --git a/code/datums/mutations/telepathy.dm b/code/datums/mutations/telepathy.dm index 8619c2bddc476..0e3dffb48b4a4 100644 --- a/code/datums/mutations/telepathy.dm +++ b/code/datums/mutations/telepathy.dm @@ -6,5 +6,5 @@ text_lose_indication = "You don't hear your mind echo anymore." difficulty = 12 power_path = /datum/action/cooldown/spell/list_target/telepathy - instability = 10 + instability = POSITIVE_INSTABILITY_MINOR // basically a mediocre PDA messager energy_coeff = 1 diff --git a/code/datums/mutations/tongue_spike.dm b/code/datums/mutations/tongue_spike.dm index e6249041250b8..9e25ad6f4f296 100644 --- a/code/datums/mutations/tongue_spike.dm +++ b/code/datums/mutations/tongue_spike.dm @@ -3,7 +3,7 @@ desc = "Allows a creature to voluntary shoot their tongue out as a deadly weapon." quality = POSITIVE text_gain_indication = span_notice("Your feel like you can throw your voice.") - instability = 15 + instability = POSITIVE_INSTABILITY_MINI // worthless. also serves as a bit of a hint that it's not good power_path = /datum/action/cooldown/spell/tongue_spike energy_coeff = 1 @@ -89,7 +89,7 @@ desc = "Allows a creature to voluntary shoot their tongue out as biomass, allowing a long range transfer of chemicals." quality = POSITIVE text_gain_indication = span_notice("Your feel like you can really connect with people by throwing your voice.") - instability = 15 + instability = POSITIVE_INSTABILITY_MINOR // slightly less worthless. slightly. locked = TRUE power_path = /datum/action/cooldown/spell/tongue_spike/chem energy_coeff = 1 diff --git a/code/datums/mutations/touch.dm b/code/datums/mutations/touch.dm index ca94f109ac664..eaa4909703525 100644 --- a/code/datums/mutations/touch.dm +++ b/code/datums/mutations/touch.dm @@ -7,7 +7,7 @@ text_gain_indication = "You feel power flow through your hands." text_lose_indication = "The energy in your hands subsides." power_path = /datum/action/cooldown/spell/touch/shock - instability = 35 + instability = POSITIVE_INSTABILITY_MODERATE // bad stun baton energy_coeff = 1 power_coeff = 1 diff --git a/code/datums/mutations/void_magnet.dm b/code/datums/mutations/void_magnet.dm index 48f04eda636a7..b5c893e32c547 100644 --- a/code/datums/mutations/void_magnet.dm +++ b/code/datums/mutations/void_magnet.dm @@ -3,7 +3,7 @@ desc = "A rare genome that attracts odd forces not usually observed." quality = MINOR_NEGATIVE //upsides and downsides text_gain_indication = span_notice("You feel a heavy, dull force just beyond the walls watching you.") - instability = 30 + instability = POSITIVE_INSTABILITY_MODERATE // useful, but has large drawbacks power_path = /datum/action/cooldown/spell/void/cursed energy_coeff = 1 synchronizer_coeff = 1 diff --git a/code/datums/mutations/webbing.dm b/code/datums/mutations/webbing.dm index 0fda118d0ed60..002687d55be0f 100644 --- a/code/datums/mutations/webbing.dm +++ b/code/datums/mutations/webbing.dm @@ -4,7 +4,7 @@ desc = "Allows the user to lay webbing, and travel through it." quality = POSITIVE text_gain_indication = "Your skin feels webby." - instability = 15 + instability = POSITIVE_INSTABILITY_MODERATE // useful until you're lynched power_path = /datum/action/cooldown/mob_cooldown/lay_web/genetic energy_coeff = 1 diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm index f0d7b2e30eb52..9028d6d367d91 100644 --- a/code/game/machinery/computer/dna_console.dm +++ b/code/game/machinery/computer/dna_console.dm @@ -1,5 +1,20 @@ -/// Base timeout for creating mutation activators and other injectors -#define INJECTOR_TIMEOUT 100 +/// Base timeout for creating mutation activators +#define MIN_ACTIVATOR_TIMEOUT 5 SECONDS +/// Base cooldown multiplier for activator upgrades +#define ACTIVATOR_COOLDOWN_MULTIPLIER 0.25 +/// Base timeout for creating mutation injectors +#define MIN_INJECTOR_TIMEOUT 10 SECONDS +/// Base cooldown multiplier for injecotr upgrades +#define INJECTOR_COOLDOWN_MULTIPLIER 0.15 + +/// Base timeout for creating advanced injectors +#define MIN_ADVANCED_TIMEOUT 15 SECONDS +/// Base cooldown multiplier for advanced injector upgrades +#define ADVANCED_COOLDOWN_MULTIPLIER 0.1 + +/// Used for other things like UI/UE/Initial CD +#define MISC_INJECTOR_TIMEOUT 60 SECONDS + /// Maximum number of genetic makeup storage slots in DNA Console #define NUMBER_OF_BUFFERS 3 /// Timeout for DNA Scramble in DNA Consoles @@ -221,7 +236,7 @@ connect_to_scanner() // Set appropriate ready timers and limits for machines functions - injector_ready = world.time + INJECTOR_TIMEOUT + injector_ready = world.time + MISC_INJECTOR_TIMEOUT scramble_ready = world.time + SCRAMBLE_TIMEOUT joker_ready = world.time + JOKER_TIMEOUT COOLDOWN_START(src, enzyme_copy_timer, ENZYME_COPY_BASE_COOLDOWN) @@ -816,21 +831,33 @@ I.research = TRUE // If there's an operational connected scanner, we can use its upgrades // to improve our injector's genetic damage generation + var/cd_reduction_mult = 1 + ACTIVATOR_COOLDOWN_MULTIPLIER + var/base_cd_time = max(MIN_ACTIVATOR_TIMEOUT, abs(HM.instability) SECONDS) + if(scanner_operational()) I.damage_coeff = connected_scanner.damage_coeff*4 - injector_ready = world.time + INJECTOR_TIMEOUT * (1 - 0.1 * connected_scanner.precision_coeff) - else - injector_ready = world.time + INJECTOR_TIMEOUT + // T1: 1.25 - 0.25: 1: 100% + // T4: 1.25 - 1: 0.25 = 25% + // 25% reduction per tier + cd_reduction_mult -= ACTIVATOR_COOLDOWN_MULTIPLIER * (connected_scanner.precision_coeff) + + injector_ready = world.time + (base_cd_time * cd_reduction_mult) else I.name = "[HM.name] mutator" - I.doitanyway = TRUE + I.force_mutate = TRUE // If there's an operational connected scanner, we can use its upgrades // to improve our injector's genetic damage generation + var/cd_reduction_mult = 1 + INJECTOR_COOLDOWN_MULTIPLIER + var/base_cd_time = max(MIN_INJECTOR_TIMEOUT, abs(HM.instability) * 1 SECONDS) + if(scanner_operational()) - I.damage_coeff = connected_scanner.damage_coeff - injector_ready = world.time + INJECTOR_TIMEOUT * 5 * (1 - 0.1 * connected_scanner.precision_coeff) - else - injector_ready = world.time + INJECTOR_TIMEOUT * 5 + I.damage_coeff = connected_scanner.damage_coeff*4 + // T1: 1.15 - 0.15: 1: 100% + // T4: 1.15 - 0.60: 0.55: 55% + // 15% reduction per tier + cd_reduction_mult -= (INJECTOR_COOLDOWN_MULTIPLIER * connected_scanner.precision_coeff) + + injector_ready = world.time + (base_cd_time * cd_reduction_mult) if(connected_scanner) connected_scanner.use_energy(connected_scanner.active_power_usage) else @@ -1349,7 +1376,7 @@ // If we successfully created an injector, don't forget to set the new // ready timer. if(I) - injector_ready = world.time + INJECTOR_TIMEOUT + injector_ready = world.time + MISC_INJECTOR_TIMEOUT if(connected_scanner) connected_scanner.use_energy(connected_scanner.active_power_usage) else @@ -1538,22 +1565,29 @@ // Run through each mutation in our Advanced Injector and add them to a // new injector + var/total_stability for(var/A in injector) var/datum/mutation/human/HM = A I.add_mutations += new HM.type(copymut=HM) + total_stability += HM.instability // Force apply any mutations, this is functionality similar to mutators - I.doitanyway = TRUE + I.force_mutate = TRUE I.name = "Advanced [inj_name] injector" // If there's an operational connected scanner, we can use its upgrades // to improve our injector's genetic damage generation + var/cd_reduction_mult = 1 + ADVANCED_COOLDOWN_MULTIPLIER + var/base_cd_time = max(MIN_ADVANCED_TIMEOUT, abs(total_stability) SECONDS) + if(scanner_operational()) - I.damage_coeff = connected_scanner.damage_coeff - injector_ready = world.time + INJECTOR_TIMEOUT * 8 * (1 - 0.1 * connected_scanner.precision_coeff) - else - injector_ready = world.time + INJECTOR_TIMEOUT * 8 + I.damage_coeff = connected_scanner.damage_coeff*4 + // T1: 1.1 - 0.1: 1: 100% + // T4: 1.1 - 0.4: 0.7 = 70% + // 10% reduction per tier + cd_reduction_mult -= ADVANCED_COOLDOWN_MULTIPLIER * (connected_scanner.precision_coeff) + injector_ready = world.time + (base_cd_time * cd_reduction_mult) return // Adds a mutation to an advanced injector @@ -2299,11 +2333,20 @@ SIGNAL_HANDLER set_connected_scanner(null) +#undef MIN_ACTIVATOR_TIMEOUT +#undef ACTIVATOR_COOLDOWN_MULTIPLIER +#undef MIN_INJECTOR_TIMEOUT +#undef INJECTOR_COOLDOWN_MULTIPLIER + +#undef MIN_ADVANCED_TIMEOUT +#undef ADVANCED_COOLDOWN_MULTIPLIER + +#undef MISC_INJECTOR_TIMEOUT + #undef GENETIC_DAMAGE_PULSE_UNIQUE_IDENTITY #undef GENETIC_DAMAGE_PULSE_UNIQUE_FEATURES #undef ENZYME_COPY_BASE_COOLDOWN -#undef INJECTOR_TIMEOUT #undef NUMBER_OF_BUFFERS #undef SCRAMBLE_TIMEOUT #undef JOKER_TIMEOUT diff --git a/code/game/machinery/dna_scanner.dm b/code/game/machinery/dna_scanner.dm index 4775642881fcc..cb0ab9900d5cc 100644 --- a/code/game/machinery/dna_scanner.dm +++ b/code/game/machinery/dna_scanner.dm @@ -11,9 +11,9 @@ circuit = /obj/item/circuitboard/machine/dnascanner var/locked = FALSE - var/damage_coeff + var/damage_coeff = 1 var/scan_level - var/precision_coeff + var/precision_coeff = 1 var/message_cooldown var/breakout_time = 1200 var/obj/machinery/computer/scan_consolenew/linked_console = null diff --git a/code/game/objects/items/dna_injector.dm b/code/game/objects/items/dna_injector.dm index 0dc20c6dbb4d9..8fee497a4f9ee 100644 --- a/code/game/objects/items/dna_injector.dm +++ b/code/game/objects/items/dna_injector.dm @@ -163,7 +163,7 @@ /obj/item/dnainjector/activator name = "\improper DNA activator" desc = "Activates the current mutation on injection, if the subject has it." - var/doitanyway = FALSE + var/force_mutate = FALSE var/research = FALSE //Set to true to get expended and filled injectors for chromosomes var/filled = FALSE var/crispr_charge = FALSE // Look for viruses, look at symptoms, if research and Dormant DNA Activator or Viral Evolutionary Acceleration, set to true @@ -176,7 +176,7 @@ if(istype(added_mutation, /datum/mutation/human)) mutation = added_mutation.type if(!target.dna.activate_mutation(added_mutation)) - if(doitanyway) + if(force_mutate) target.dna.add_mutation(added_mutation, MUT_EXTRA) else if(research && target.client) filled = TRUE @@ -184,7 +184,7 @@ for(var/datum/symptom/symp in disease.symptoms) if((symp.type == /datum/symptom/genetic_mutation) || (symp.type == /datum/symptom/viralevolution)) crispr_charge = TRUE - log_combat(user, target, "[!doitanyway ? "failed to inject" : "injected"]", "[src] ([mutation])[crispr_charge ? " with CRISPR charge" : ""]") + log_combat(user, target, "[!force_mutate ? "failed to inject" : "injected"]", "[src] ([mutation])[crispr_charge ? " with CRISPR charge" : ""]") return TRUE /// DNA INJECTORS diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index e588485aedc75..52ffe51bfe68b 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -293,6 +293,11 @@ return MONKEY_HEIGHT_DWARF else return HUMAN_HEIGHT_DWARF + if(HAS_TRAIT(src, TRAIT_TOO_TALL)) + if(ismonkey(src)) + return MONKEY_HEIGHT_TALL + else + return HUMAN_HEIGHT_TALLEST else if(ismonkey(src)) return MONKEY_HEIGHT_MEDIUM diff --git a/code/modules/mob/living/carbon/human/human_update_icons.dm b/code/modules/mob/living/carbon/human/human_update_icons.dm index bd320079b65d5..fe5817eab2780 100644 --- a/code/modules/mob/living/carbon/human/human_update_icons.dm +++ b/code/modules/mob/living/carbon/human/human_update_icons.dm @@ -864,20 +864,34 @@ generate/load female uniform sprites matching all previously decided variables "params" = displacement_map_filter(cut_legs_mask, x = 0, y = 0, size = 4), ), )) + if(HUMAN_HEIGHT_DWARF) // tall monkeys and dwarves use the same value + if(ismonkey(src)) + appearance.add_filters(list( + list( + "name" = "Monkey_Torso", + "priority" = 1, + "params" = displacement_map_filter(cut_torso_mask, x = 0, y = 0, size = 1), + ), + list( + "name" = "Monkey_Legs", + "priority" = 1, + "params" = displacement_map_filter(cut_legs_mask, x = 0, y = 0, size = 1), + ), + )) + else + appearance.add_filters(list( + list( + "name" = "Gnome_Cut_Torso", + "priority" = 1, + "params" = displacement_map_filter(cut_torso_mask, x = 0, y = 0, size = 2), + ), + list( + "name" = "Gnome_Cut_Legs", + "priority" = 1, + "params" = displacement_map_filter(cut_legs_mask, x = 0, y = 0, size = 3), + ), + )) // Don't set this one directly, use TRAIT_DWARF - if(HUMAN_HEIGHT_DWARF) - appearance.add_filters(list( - list( - "name" = "Gnome_Cut_Torso", - "priority" = 1, - "params" = displacement_map_filter(cut_torso_mask, x = 0, y = 0, size = 2), - ), - list( - "name" = "Gnome_Cut_Legs", - "priority" = 1, - "params" = displacement_map_filter(cut_legs_mask, x = 0, y = 0, size = 3), - ), - )) if(HUMAN_HEIGHT_SHORTEST) appearance.add_filters(list( list( From 92b25950fe11e8abc2bf9e6c3277d05423bfbf86 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Tue, 18 Jun 2024 16:46:02 +1200 Subject: [PATCH 044/172] Automatic changelog for PR #83439 [ci skip] --- html/changelogs/AutoChangeLog-pr-83439.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83439.yml diff --git a/html/changelogs/AutoChangeLog-pr-83439.yml b/html/changelogs/AutoChangeLog-pr-83439.yml new file mode 100644 index 0000000000000..9e721ae4ba0a4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83439.yml @@ -0,0 +1,8 @@ +author: "carlarctg" +delete-after: True +changes: + - balance: "Negative mutations now allow you to have more positive mutations, via reducing your instability!" + - code_imp: "All mutations have been overall standardized via defines on their instability values. Many mediocre positive mutations have had their cost reduced significantly!" + - rscadd: "Added a new height mutation: Acromegaly! It's the opposite of Dwarfism and makes you uncannily tall. It also makes you hit your head 8% or 4% (with synch) of the time you pass through airlocks. Wear a helmet!" + - rscadd: "Gigantism is now a recipe mutation, mix Acromegaly with Strength to get it." + - qol: "Injectors and activators' duration is now dependent on the in/stability (absolute value) of the mutations to be injected! With a minimum of 5-10-15 seconds for each type of injector. Also changed up a bit how part upgrade cooldowns work, by making each tier reduce cooldowns by 25-15-10% for each injector type." \ No newline at end of file From f3f50dd7b5f5696e33c714011737e240e4ceff5d Mon Sep 17 00:00:00 2001 From: Jeremiah <42397676+jlsnow301@users.noreply.github.com> Date: Tue, 18 Jun 2024 00:38:00 -0700 Subject: [PATCH 045/172] [no gbp] tgui-say: fixes emotes getting their contents glorfed (#84053) ## About The Pull Request When read by an innocent bystander, what possibly could this PR title mean TGUI Say was, for some reason that I totally don't remember, just sending all forced messages to say. This now will properly cut out /me contents if you get attacked during. It also fixes an issue where the channel color would get stuck if you were attacked as well ## Why It's Good For The Game Fixes #84018 ## Changelog :cl: fix: TGUI say will no longer spill your /me contents when you get attacked /:cl: --- tgui/packages/tgui-say/TguiSay.tsx | 3 ++- tgui/packages/tgui-say/timers.ts | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tgui/packages/tgui-say/TguiSay.tsx b/tgui/packages/tgui-say/TguiSay.tsx index 7bc459c7f2e84..fbee44f00f9e2 100644 --- a/tgui/packages/tgui-say/TguiSay.tsx +++ b/tgui/packages/tgui-say/TguiSay.tsx @@ -162,7 +162,7 @@ export class TguiSay extends Component<{}, State> { ? prefix + currentValue : currentValue; - this.messages.forceSayMsg(grunt); + this.messages.forceSayMsg(grunt, this.channelIterator.current()); this.reset(); } @@ -274,6 +274,7 @@ export class TguiSay extends Component<{}, State> { }; reset() { + this.currentPrefix = null; this.setValue(''); this.setSize(); this.setState({ diff --git a/tgui/packages/tgui-say/timers.ts b/tgui/packages/tgui-say/timers.ts index 85c58f7424ae9..d1388487c07c6 100644 --- a/tgui/packages/tgui-say/timers.ts +++ b/tgui/packages/tgui-say/timers.ts @@ -1,5 +1,7 @@ import { debounce, throttle } from 'common/timer'; +import { Channel } from './ChannelIterator'; + const SECONDS = 1000; /** Timers: Prevents overloading the server, throttles messages */ @@ -10,7 +12,8 @@ export const byondMessages = { 0.4 * SECONDS, ), forceSayMsg: debounce( - (entry: string) => Byond.sendMessage('force', { entry, channel: 'Say' }), + (entry: string, channel: Channel) => + Byond.sendMessage('force', { entry, channel }), 1 * SECONDS, true, ), From 225b64077cc3e2aaa878a07a4bcf3bace509fb37 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Tue, 18 Jun 2024 08:40:41 +0100 Subject: [PATCH 046/172] Gorillas have big fingers (#83999) ## About The Pull Request Gives gorillas the big fingers trait ## Why It's Good For The Game because gorillas have big fingers this doesnt actually have a lot of effects because Gorillas already can't use guns for unrelated reasons, but as gorillas have hands it might come up some day as we expand the number of items which interact with this trait currently this stops gorillas from using stun batons, and laser pointers gorillas dont need to use stun batons because they can just beat you to death with their fists ## Changelog :cl: balance: Gorillas have big fingers, which mostly just prevents them from using laser pointers and stun batons /:cl: --- code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm index b2aff7371a426..ce363af236465 100644 --- a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm @@ -55,7 +55,7 @@ /mob/living/basic/gorilla/Initialize(mapload) . = ..() - add_traits(list(TRAIT_ADVANCEDTOOLUSER, TRAIT_CAN_STRIP), ROUNDSTART_TRAIT) + add_traits(list(TRAIT_ADVANCEDTOOLUSER, TRAIT_CAN_STRIP, TRAIT_CHUNKYFINGERS), ROUNDSTART_TRAIT) AddElement(/datum/element/wall_tearer, allow_reinforced = FALSE) AddElement(/datum/element/dextrous) AddElement(/datum/element/footstep, FOOTSTEP_MOB_BAREFOOT) From a6167706e052e5faaa39b6ec444a53d6c1048759 Mon Sep 17 00:00:00 2001 From: GPeckman <21979502+GPeckman@users.noreply.github.com> Date: Tue, 18 Jun 2024 03:42:14 -0400 Subject: [PATCH 047/172] Airlock fireman carry fix (#83952) ## About The Pull Request You know how airlocks still look closed sometimes when you walk into them while carrying someone else? Yeah, that shouldn't happen anymore. I tried to use flick animations like someone in the issue report suggested, but it left some lights floating in the air while the airlock opened so it didn't really work. Fixes #56420 ## Why It's Good For The Game Bug fix good. ## Changelog :cl: fix: Airlocks should no longer appear closed sometimes when fireman carrying someone into them. /:cl: --- code/game/machinery/doors/airlock.dm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index ae37691f1c1a1..37310e2aceb49 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -601,7 +601,11 @@ if(!machine_stat) update_icon(ALL, AIRLOCK_DENY) playsound(src,doorDeni,50,FALSE,3) - addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon), ALL, AIRLOCK_CLOSED), AIRLOCK_DENY_ANIMATION_TIME) + addtimer(CALLBACK(src, PROC_REF(handle_deny_end)), AIRLOCK_DENY_ANIMATION_TIME) + +/obj/machinery/door/airlock/proc/handle_deny_end() + if(airlock_state == AIRLOCK_DENY) + update_icon(ALL, AIRLOCK_CLOSED) /obj/machinery/door/airlock/examine(mob/user) . = ..() From 03bc74a39cb75bb26191969b3209132dc28a3394 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Tue, 18 Jun 2024 19:47:58 +1200 Subject: [PATCH 048/172] Automatic changelog for PR #84053 [ci skip] --- html/changelogs/AutoChangeLog-pr-84053.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84053.yml diff --git a/html/changelogs/AutoChangeLog-pr-84053.yml b/html/changelogs/AutoChangeLog-pr-84053.yml new file mode 100644 index 0000000000000..6aebdbc471f5f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84053.yml @@ -0,0 +1,4 @@ +author: "jlsnow301" +delete-after: True +changes: + - bugfix: "TGUI say will no longer spill your /me contents when you get attacked" \ No newline at end of file From 2e828d70612aa618f899356e3c55720267e73681 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Tue, 18 Jun 2024 19:48:16 +1200 Subject: [PATCH 049/172] Automatic changelog for PR #83999 [ci skip] --- html/changelogs/AutoChangeLog-pr-83999.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83999.yml diff --git a/html/changelogs/AutoChangeLog-pr-83999.yml b/html/changelogs/AutoChangeLog-pr-83999.yml new file mode 100644 index 0000000000000..a04af9580bdf3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83999.yml @@ -0,0 +1,4 @@ +author: "Jacquerel" +delete-after: True +changes: + - balance: "Gorillas have big fingers, which mostly just prevents them from using laser pointers and stun batons" \ No newline at end of file From 353eaa42d695b3d6590ce2134f9b5c9bf0cdbd5a Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Tue, 18 Jun 2024 19:48:21 +1200 Subject: [PATCH 050/172] Automatic changelog for PR #83952 [ci skip] --- html/changelogs/AutoChangeLog-pr-83952.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83952.yml diff --git a/html/changelogs/AutoChangeLog-pr-83952.yml b/html/changelogs/AutoChangeLog-pr-83952.yml new file mode 100644 index 0000000000000..431aaa759582e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83952.yml @@ -0,0 +1,4 @@ +author: "GPeckman" +delete-after: True +changes: + - bugfix: "Airlocks should no longer appear closed sometimes when fireman carrying someone into them." \ No newline at end of file From a3872f96033f8d96a0458c521ba301aa0ea5a1ec Mon Sep 17 00:00:00 2001 From: TheRyeGuyWhoWillNowDie <70169560+TheRyeGuyWhoWillNowDie@users.noreply.github.com> Date: Tue, 18 Jun 2024 03:53:31 -0400 Subject: [PATCH 051/172] the omnitool upgrade for medical cyborgs makes their syringes faster too (#83792) ## About The Pull Request gives medborgs upgraded with the omnitool upgrade TRAIT_FASTMED which makes use of syringes quicker ## Why It's Good For The Game encourages medical cyborgs to use a variety of chemicals with different effects they've crafted themselves through the beaker apparatus instead of just relying on their infinite hypospray for everything ## Changelog :cl: balance: the advanced omnitool upgrade now hastens the mediborg's syringe too /:cl: --- code/game/objects/items/robot/robot_upgrades.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 2d886163a50ba..1a695442d8a76 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -425,6 +425,7 @@ . = ..() if(!.) return . + ADD_TRAIT(cyborg, TRAIT_FASTMED, REF(src)) for(var/obj/item/borg/cyborg_omnitool/medical/omnitool_upgrade in cyborg.model.modules) if(omnitool_upgrade.upgraded) to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) @@ -436,6 +437,7 @@ . = ..() if(!.) return . + REMOVE_TRAIT(cyborg, TRAIT_FASTMED, REF(src)) for(var/obj/item/borg/cyborg_omnitool/omnitool in cyborg.model.modules) omnitool.downgrade_omnitool() From 71428d5bf6eeeec32d16d41c42aa39a856af4df6 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Tue, 18 Jun 2024 19:57:53 +1200 Subject: [PATCH 052/172] Automatic changelog for PR #83792 [ci skip] --- html/changelogs/AutoChangeLog-pr-83792.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83792.yml diff --git a/html/changelogs/AutoChangeLog-pr-83792.yml b/html/changelogs/AutoChangeLog-pr-83792.yml new file mode 100644 index 0000000000000..c856d7586a8ce --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83792.yml @@ -0,0 +1,4 @@ +author: "TheRyeGuyWhoWillNowDie" +delete-after: True +changes: + - rscadd: "the advanced omnitool upgrade now hastens the mediborg's syringe too" \ No newline at end of file From 4fd0e28f42fe3fd3ebe0e13775444c3e75466aed Mon Sep 17 00:00:00 2001 From: Time-Green <7501474+Time-Green@users.noreply.github.com> Date: Tue, 18 Jun 2024 14:07:47 +0200 Subject: [PATCH 053/172] Refactors body markings into bodypart overlays (#83744) ## About The Pull Request Refactors body markings (lizard and moths) into the bodypart overlays system I've also renamed the icon states for lizard bodymarkings (downstreams with lots of lizard body markings might have problems with this) ## Why It's Good For The Game Gives us better controle over /human appearances. I didn't add any means of actually changing them on the person (aside from genetics. how would that even work? with a waterproof marker?), but makes it easy for when/if I do. Also unloads mutant_bodyparts more, moving is yet closer to full species dedatumization ## Changelog :cl: refactor: Lizard and moth markings now use the bodypart overlay system /:cl: --- code/__DEFINES/traits/declarations.dm | 2 - code/_globalvars/traits/_traits.dm | 1 - code/_globalvars/traits/admin_tooling.dm | 1 - .../subsystem/sprite_accessories.dm | 4 +- .../markings_bodypart_overlay.dm | 31 ++++++ code/datums/dna.dm | 16 ++- code/datums/sprite_accessories.dm | 12 +-- .../modules/client/preferences/_preference.dm | 5 + .../preferences/species_features/lizard.dm | 10 +- .../preferences/species_features/moth.dm | 2 +- .../modules/mining/lavaland/megafauna_loot.dm | 2 +- .../mob/living/carbon/human/_species.dm | 93 ++++++++++-------- code/modules/mob/living/carbon/human/dummy.dm | 2 +- .../human/species_types/lizardpeople.dm | 5 +- .../carbon/human/species_types/mothmen.dm | 3 +- code/modules/unit_tests/changeling.dm | 2 +- .../human/species/lizard/lizard_markings.dmi | Bin 0 -> 977 bytes .../mob/human/species/lizard/lizard_misc.dmi | Bin 5152 -> 2737 bytes tgstation.dme | 1 + 19 files changed, 118 insertions(+), 74 deletions(-) create mode 100644 code/datums/bodypart_overlays/markings_bodypart_overlay.dm create mode 100644 icons/mob/human/species/lizard/lizard_markings.dmi diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 93cba187da449..8f1c58bc96684 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -138,8 +138,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_AGENDER "agender" /// Species with this trait have a blood clan mechanic #define TRAIT_BLOOD_CLANS "blood_clans" -/// Species with this trait have markings (this SUCKS, remove this later in favor of bodypart overlays) -#define TRAIT_HAS_MARKINGS "has_markings" /// Species with this trait use skin tones for coloration #define TRAIT_USES_SKINTONES "uses_skintones" /// Species with this trait use mutant colors for coloration diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 3bb59817ec489..9175b86dc3589 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -248,7 +248,6 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_HARDLY_WOUNDED" = TRAIT_HARDLY_WOUNDED, "TRAIT_HAS_BEEN_KIDNAPPED" = TRAIT_HAS_BEEN_KIDNAPPED, "TRAIT_HAS_CRANIAL_FISSURE" = TRAIT_HAS_CRANIAL_FISSURE, - "TRAIT_HAS_MARKINGS" = TRAIT_HAS_MARKINGS, "TRAIT_HATED_BY_DOGS" = TRAIT_HATED_BY_DOGS, "TRAIT_HEAD_INJURY_BLOCKED" = TRAIT_HEAD_INJURY_BLOCKED, "TRAIT_HEALS_FROM_CARP_RIFTS" = TRAIT_HEALS_FROM_CARP_RIFTS, diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm index d9f6350a07480..150a10c108494 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -94,7 +94,6 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_GUNFLIP" = TRAIT_GUNFLIP, "TRAIT_HANDS_BLOCKED" = TRAIT_HANDS_BLOCKED, "TRAIT_HARDLY_WOUNDED" = TRAIT_HARDLY_WOUNDED, - "TRAIT_HAS_MARKINGS" = TRAIT_HAS_MARKINGS, "TRAIT_HEAVY_SLEEPER" = TRAIT_HEAVY_SLEEPER, "TRAIT_HIDE_EXTERNAL_ORGANS" = TRAIT_HIDE_EXTERNAL_ORGANS, "TRAIT_HOLY" = TRAIT_HOLY, diff --git a/code/controllers/subsystem/sprite_accessories.dm b/code/controllers/subsystem/sprite_accessories.dm index ec5934ac8e8d4..f381df80df6da 100644 --- a/code/controllers/subsystem/sprite_accessories.dm +++ b/code/controllers/subsystem/sprite_accessories.dm @@ -35,7 +35,7 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity var/list/socks_list //! stores /datum/sprite_accessory/socks indexed by name //Lizard Bits (all datum lists indexed by name) - var/list/body_markings_list + var/list/lizard_markings_list var/list/snouts_list var/list/horns_list var/list/frills_list @@ -87,7 +87,7 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity socks_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/socks)[DEFAULT_SPRITE_LIST] - body_markings_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings)[DEFAULT_SPRITE_LIST] + lizard_markings_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/lizard_markings)[DEFAULT_SPRITE_LIST] tails_list_human = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, add_blank = TRUE)[DEFAULT_SPRITE_LIST] tails_list_lizard = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard, add_blank = TRUE)[DEFAULT_SPRITE_LIST] tails_list_monkey = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/monkey, add_blank = TRUE)[DEFAULT_SPRITE_LIST] diff --git a/code/datums/bodypart_overlays/markings_bodypart_overlay.dm b/code/datums/bodypart_overlays/markings_bodypart_overlay.dm new file mode 100644 index 0000000000000..c2c6f54d861d3 --- /dev/null +++ b/code/datums/bodypart_overlays/markings_bodypart_overlay.dm @@ -0,0 +1,31 @@ +/// For body markings applied on the species, which need some extra code +/datum/bodypart_overlay/simple/body_marking + layers = EXTERNAL_ADJACENT + /// Listen to the gendercode, if the limb is bimorphic + var/use_gender = FALSE + /// 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) + +/// 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/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 image(icon, gender_string + icon_state + "_" + limb.body_zone, layer = layer) + +/datum/bodypart_overlay/simple/body_marking/moth + dna_feature_key = "moth_markings" + +/datum/bodypart_overlay/simple/body_marking/moth/get_accessory(name) + return SSaccessories.moth_markings_list[name] + +/datum/bodypart_overlay/simple/body_marking/lizard + dna_feature_key = "lizard_markings" + applies_to = list(/obj/item/bodypart/chest) + +/datum/bodypart_overlay/simple/body_marking/lizard/get_accessory(name) + return SSaccessories.lizard_markings_list[name] diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 02773e375f3a3..d5677dad7ca61 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -207,8 +207,8 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) L[DNA_MUTANT_COLOR_BLOCK] = sanitize_hexcolor(features["mcolor"], include_crunch = FALSE) if(features["ethcolor"]) L[DNA_ETHEREAL_COLOR_BLOCK] = sanitize_hexcolor(features["ethcolor"], include_crunch = FALSE) - if(features["body_markings"]) - L[DNA_LIZARD_MARKINGS_BLOCK] = construct_block(SSaccessories.body_markings_list.Find(features["body_markings"]), length(SSaccessories.body_markings_list)) + if(features["lizard_markings"]) + L[DNA_LIZARD_MARKINGS_BLOCK] = construct_block(SSaccessories.lizard_markings_list.Find(features["lizard_markings"]), length(SSaccessories.lizard_markings_list)) if(features["tail_cat"]) L[DNA_TAIL_BLOCK] = construct_block(SSaccessories.tails_list_human.Find(features["tail_cat"]), length(SSaccessories.tails_list_human)) if(features["tail_lizard"]) @@ -354,7 +354,7 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) if(DNA_ETHEREAL_COLOR_BLOCK) set_uni_feature_block(blocknumber, sanitize_hexcolor(features["ethcolor"], include_crunch = FALSE)) if(DNA_LIZARD_MARKINGS_BLOCK) - set_uni_feature_block(blocknumber, construct_block(SSaccessories.body_markings_list.Find(features["body_markings"]), length(SSaccessories.body_markings_list))) + set_uni_feature_block(blocknumber, construct_block(SSaccessories.lizard_markings_list.Find(features["lizard_markings"]), length(SSaccessories.lizard_markings_list))) if(DNA_TAIL_BLOCK) set_uni_feature_block(blocknumber, construct_block(SSaccessories.tails_list_human.Find(features["tail_cat"]), length(SSaccessories.tails_list_human))) if(DNA_LIZARD_TAIL_BLOCK) @@ -649,8 +649,8 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) dna.features["mcolor"] = sanitize_hexcolor(get_uni_feature_block(features, DNA_MUTANT_COLOR_BLOCK)) if(dna.features["ethcolor"]) dna.features["ethcolor"] = sanitize_hexcolor(get_uni_feature_block(features, DNA_ETHEREAL_COLOR_BLOCK)) - if(dna.features["body_markings"]) - dna.features["body_markings"] = SSaccessories.body_markings_list[deconstruct_block(get_uni_feature_block(features, DNA_LIZARD_MARKINGS_BLOCK), length(SSaccessories.body_markings_list))] + if(dna.features["lizard_markings"]) + dna.features["lizard_markings"] = SSaccessories.lizard_markings_list[deconstruct_block(get_uni_feature_block(features, DNA_LIZARD_MARKINGS_BLOCK), length(SSaccessories.lizard_markings_list))] if(dna.features["snout"]) dna.features["snout"] = SSaccessories.snouts_list[deconstruct_block(get_uni_feature_block(features, DNA_SNOUT_BLOCK), length(SSaccessories.snouts_list))] if(dna.features["horns"]) @@ -686,14 +686,10 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) external_organ.mutate_feature(features, src) if(icon_update) - if(mutcolor_update) - update_body(is_creating = TRUE) - else - update_body() + update_body(is_creating = mutcolor_update) if(mutations_overlay_update) update_mutations_overlay() - /mob/proc/domutcheck() return diff --git a/code/datums/sprite_accessories.dm b/code/datums/sprite_accessories.dm index e6e8b956e6568..e5cf49475e22e 100644 --- a/code/datums/sprite_accessories.dm +++ b/code/datums/sprite_accessories.dm @@ -1700,24 +1700,24 @@ // MutantParts Definitions // ///////////////////////////// -/datum/sprite_accessory/body_markings - icon = 'icons/mob/human/species/lizard/lizard_misc.dmi' +/datum/sprite_accessory/lizard_markings + icon = 'icons/mob/human/species/lizard/lizard_markings.dmi' -/datum/sprite_accessory/body_markings/none +/datum/sprite_accessory/lizard_markings/none name = "None" icon_state = "none" -/datum/sprite_accessory/body_markings/dtiger +/datum/sprite_accessory/lizard_markings/dtiger name = "Dark Tiger Body" icon_state = "dtiger" gender_specific = TRUE -/datum/sprite_accessory/body_markings/ltiger +/datum/sprite_accessory/lizard_markings/ltiger name = "Light Tiger Body" icon_state = "ltiger" gender_specific = TRUE -/datum/sprite_accessory/body_markings/lbelly +/datum/sprite_accessory/lizard_markings/lbelly name = "Light Belly" icon_state = "lbelly" gender_specific = TRUE diff --git a/code/modules/client/preferences/_preference.dm b/code/modules/client/preferences/_preference.dm index 6c62ed1d054c2..485276b4ade2a 100644 --- a/code/modules/client/preferences/_preference.dm +++ b/code/modules/client/preferences/_preference.dm @@ -112,6 +112,10 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key()) /// will show the feature as selectable. var/relevant_mutant_bodypart = null + /// If the selected species has this in its /datum/species/body_markings, + /// will show the feature as selectable. + var/relevant_body_markings = null + /// If the selected species has this in its /datum/species/inherent_traits, /// will show the feature as selectable. var/relevant_inherent_trait = null @@ -333,6 +337,7 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key()) || !isnull(relevant_inherent_trait) \ || !isnull(relevant_external_organ) \ || !isnull(relevant_head_flag) \ + || !isnull(relevant_body_markings) \ ) var/species_type = preferences.read_preference(/datum/preference/choiced/species) diff --git a/code/modules/client/preferences/species_features/lizard.dm b/code/modules/client/preferences/species_features/lizard.dm index bee57300ec4a4..38c83690b3b5e 100644 --- a/code/modules/client/preferences/species_features/lizard.dm +++ b/code/modules/client/preferences/species_features/lizard.dm @@ -29,20 +29,20 @@ category = PREFERENCE_CATEGORY_FEATURES main_feature_name = "Body markings" should_generate_icons = TRUE - relevant_mutant_bodypart = "body_markings" + relevant_body_markings = /datum/bodypart_overlay/simple/body_marking/lizard /datum/preference/choiced/lizard_body_markings/init_possible_values() - return assoc_to_keys_features(SSaccessories.body_markings_list) + return assoc_to_keys_features(SSaccessories.lizard_markings_list) /datum/preference/choiced/lizard_body_markings/icon_for(value) - var/datum/sprite_accessory/sprite_accessory = SSaccessories.body_markings_list[value] + var/datum/sprite_accessory/sprite_accessory = SSaccessories.lizard_markings_list[value] var/icon/final_icon = icon('icons/mob/human/species/lizard/bodyparts.dmi', "lizard_chest_m") if (sprite_accessory.icon_state != "none") var/icon/body_markings_icon = icon( 'icons/mob/human/species/lizard/lizard_misc.dmi', - "m_body_markings_[sprite_accessory.icon_state]_ADJ", + "male_[sprite_accessory.icon_state]_chest", ) final_icon.Blend(body_markings_icon, ICON_OVERLAY) @@ -55,7 +55,7 @@ return final_icon /datum/preference/choiced/lizard_body_markings/apply_to_human(mob/living/carbon/human/target, value) - target.dna.features["body_markings"] = value + target.dna.features["lizard_markings"] = value /datum/preference/choiced/lizard_frills savefile_key = "feature_lizard_frills" diff --git a/code/modules/client/preferences/species_features/moth.dm b/code/modules/client/preferences/species_features/moth.dm index 745e6fb917b8f..f697d857d4fc4 100644 --- a/code/modules/client/preferences/species_features/moth.dm +++ b/code/modules/client/preferences/species_features/moth.dm @@ -34,7 +34,7 @@ category = PREFERENCE_CATEGORY_FEATURES main_feature_name = "Body markings" should_generate_icons = TRUE - relevant_mutant_bodypart = "moth_markings" + relevant_body_markings = /datum/bodypart_overlay/simple/body_marking/moth /datum/preference/choiced/moth_markings/init_possible_values() return assoc_to_keys_features(SSaccessories.moth_markings_list) diff --git a/code/modules/mining/lavaland/megafauna_loot.dm b/code/modules/mining/lavaland/megafauna_loot.dm index f4ae3548fa659..0bbf15352318d 100644 --- a/code/modules/mining/lavaland/megafauna_loot.dm +++ b/code/modules/mining/lavaland/megafauna_loot.dm @@ -755,7 +755,7 @@ "wings" = "None", "frills" = "None", "spines" = "Long", - "body_markings" = "Dark Tiger Body", + "lizard_markings" = "Dark Tiger Body", "legs" = DIGITIGRADE_LEGS, ) consumer.eye_color_left = "#FEE5A3" diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index b9dca314b5189..d5d048a33f844 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -102,6 +102,9 @@ GLOBAL_LIST_EMPTY(features_by_species) ///Replaces default appendix with a different organ. var/obj/item/organ/internal/appendix/mutantappendix = /obj/item/organ/internal/appendix + /// Store body marking defines. See mobs.dm for bitflags + var/list/body_markings = list() + /// Flat modifier on all damage taken via [apply_damage][/mob/living/proc/apply_damage] (so being punched, shot, etc.) /// IE: 10 = 10% less damage taken. var/damage_modifier = 0 @@ -466,7 +469,7 @@ GLOBAL_LIST_EMPTY(features_by_species) var/obj/item/organ/external/new_organ = SSwardrobe.provide_type(organ_path) new_organ.Insert(human, special=TRUE, movement_flags = DELETE_IF_REPLACED) - + add_body_markings(human_who_gained_species) if(length(inherent_traits)) human_who_gained_species.add_traits(inherent_traits, SPECIES_TRAIT) @@ -526,6 +529,8 @@ GLOBAL_LIST_EMPTY(features_by_species) clear_tail_moodlets(C) + remove_body_markings(C) + // Removes all languages previously associated with [LANGUAGE_SPECIES], gaining our new species will add new ones back var/datum/language_holder/losing_holder = GLOB.prototype_language_holders[species_language_holder] for(var/language in losing_holder.understood_languages) @@ -560,42 +565,6 @@ GLOBAL_LIST_EMPTY(features_by_species) eye_organ.refresh(call_update = FALSE) standing += eye_organ.generate_body_overlay(species_human) - // organic body markings (oh my god this is terrible please rework this to be done on the limbs themselves i beg you) - if(HAS_TRAIT(species_human, TRAIT_HAS_MARKINGS)) - var/obj/item/bodypart/chest/chest = species_human.get_bodypart(BODY_ZONE_CHEST) - var/obj/item/bodypart/arm/right/right_arm = species_human.get_bodypart(BODY_ZONE_R_ARM) - var/obj/item/bodypart/arm/left/left_arm = species_human.get_bodypart(BODY_ZONE_L_ARM) - var/obj/item/bodypart/leg/right/right_leg = species_human.get_bodypart(BODY_ZONE_R_LEG) - var/obj/item/bodypart/leg/left/left_leg = species_human.get_bodypart(BODY_ZONE_L_LEG) - var/datum/sprite_accessory/markings = SSaccessories.moth_markings_list[species_human.dna.features["moth_markings"]] - var/mutable_appearance/marking = mutable_appearance(layer = -BODY_LAYER, appearance_flags = KEEP_TOGETHER) - - if(noggin && (IS_ORGANIC_LIMB(noggin))) - var/mutable_appearance/markings_head_overlay = mutable_appearance(markings.icon, "[markings.icon_state]_head") - marking.overlays += markings_head_overlay - - if(chest && (IS_ORGANIC_LIMB(chest))) - var/mutable_appearance/markings_chest_overlay = mutable_appearance(markings.icon, "[markings.icon_state]_chest") - marking.overlays += markings_chest_overlay - - if(right_arm && (IS_ORGANIC_LIMB(right_arm))) - var/mutable_appearance/markings_r_arm_overlay = mutable_appearance(markings.icon, "[markings.icon_state]_r_arm") - marking.overlays += markings_r_arm_overlay - - if(left_arm && (IS_ORGANIC_LIMB(left_arm))) - var/mutable_appearance/markings_l_arm_overlay = mutable_appearance(markings.icon, "[markings.icon_state]_l_arm") - marking.overlays += markings_l_arm_overlay - - if(right_leg && (IS_ORGANIC_LIMB(right_leg))) - var/mutable_appearance/markings_r_leg_overlay = mutable_appearance(markings.icon, "[markings.icon_state]_r_leg") - marking.overlays += markings_r_leg_overlay - - if(left_leg && (IS_ORGANIC_LIMB(left_leg))) - var/mutable_appearance/markings_l_leg_overlay = mutable_appearance(markings.icon, "[markings.icon_state]_l_leg") - marking.overlays += markings_l_leg_overlay - - standing += marking - //Underwear, Undershirts & Socks if(!HAS_TRAIT(species_human, TRAIT_NO_UNDERWEAR)) if(species_human.underwear) @@ -672,8 +641,6 @@ GLOBAL_LIST_EMPTY(features_by_species) switch(bodypart) if("ears") accessory = SSaccessories.ears_list[source.dna.features["ears"]] - if("body_markings") - accessory = SSaccessories.body_markings_list[source.dna.features["body_markings"]] if("legs") accessory = SSaccessories.legs_list[source.dna.features["legs"]] @@ -727,6 +694,8 @@ GLOBAL_LIST_EMPTY(features_by_species) source.apply_overlay(BODY_ADJ_LAYER) source.apply_overlay(BODY_FRONT_LAYER) + update_body_markings(source) + //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. /datum/species/proc/mutant_bodyparts_layertext(layer) @@ -1519,6 +1488,7 @@ GLOBAL_LIST_EMPTY(features_by_species) || (preference.relevant_inherent_trait in inherent_traits) \ || (preference.relevant_external_organ in external_organs) \ || (preference.relevant_head_flag && check_head_flags(preference.relevant_head_flag)) \ + || (preference.relevant_body_markings in body_markings) \ ) features += preference.savefile_key @@ -2110,3 +2080,48 @@ GLOBAL_LIST_EMPTY(features_by_species) return fixed_mut_color return null + +/// Add species appropriate body markings +/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!") + + 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) + 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 + + people_part.add_bodypart_overlay(overlay) + +/// 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) + 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/dummy.dm b/code/modules/mob/living/carbon/human/dummy.dm index 627745cba929e..8d62ed5907948 100644 --- a/code/modules/mob/living/carbon/human/dummy.dm +++ b/code/modules/mob/living/carbon/human/dummy.dm @@ -103,7 +103,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) /proc/create_consistent_human_dna(mob/living/carbon/human/target) target.dna.features["mcolor"] = COLOR_VIBRANT_LIME target.dna.features["ethcolor"] = COLOR_WHITE - target.dna.features["body_markings"] = get_consistent_feature_entry(SSaccessories.body_markings_list) + target.dna.features["lizard_markings"] = get_consistent_feature_entry(SSaccessories.lizard_markings_list) target.dna.features["ears"] = get_consistent_feature_entry(SSaccessories.ears_list) target.dna.features["frills"] = get_consistent_feature_entry(SSaccessories.frills_list) target.dna.features["horns"] = get_consistent_feature_entry(SSaccessories.horns_list) 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 b2a036a9d6d71..ba813901b3e87 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -8,7 +8,8 @@ TRAIT_TACKLING_TAILED_DEFENDER, ) inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_REPTILE - mutant_bodyparts = list("body_markings" = "None", "legs" = "Normal Legs") + mutant_bodyparts = list("legs" = "Normal Legs") + body_markings = list(/datum/bodypart_overlay/simple/body_marking/lizard = "None") external_organs = list( /obj/item/organ/external/horns = "None", /obj/item/organ/external/frills = "None", @@ -49,7 +50,7 @@ /datum/species/lizard/randomize_features() var/list/features = ..() - features["body_markings"] = pick(SSaccessories.body_markings_list) + features["lizard_markings"] = pick(SSaccessories.lizard_markings_list) return features /datum/species/lizard/get_scream_sound(mob/living/carbon/human/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 e2458563b038c..26efe358221fc 100644 --- a/code/modules/mob/living/carbon/human/species_types/mothmen.dm +++ b/code/modules/mob/living/carbon/human/species_types/mothmen.dm @@ -3,12 +3,11 @@ plural_form = "Mothmen" id = SPECIES_MOTH inherent_traits = list( - TRAIT_HAS_MARKINGS, TRAIT_TACKLING_WINGED_ATTACKER, TRAIT_ANTENNAE, ) inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG - mutant_bodyparts = list("moth_markings" = "None") + body_markings = list(/datum/bodypart_overlay/simple/body_marking/moth = "None") external_organs = list(/obj/item/organ/external/wings/moth = "Plain", /obj/item/organ/external/antennae = "Plain") meat = /obj/item/food/meat/slab/human/mutant/moth mutanttongue = /obj/item/organ/internal/tongue/moth diff --git a/code/modules/unit_tests/changeling.dm b/code/modules/unit_tests/changeling.dm index 9749d760ea91c..7f86510fd62d1 100644 --- a/code/modules/unit_tests/changeling.dm +++ b/code/modules/unit_tests/changeling.dm @@ -80,7 +80,7 @@ ling.dna.features["horns"] = "Curled" ling.dna.features["frills"] = "Short" ling.dna.features["spines"] = "Long + Membrane" - ling.dna.features["body_markings"] = "Light Belly" + ling.dna.features["lizard_markings"] = "Light Belly" ling.dna.features["legs"] = DIGITIGRADE_LEGS ling.eye_color_left = COLOR_WHITE ling.eye_color_right = COLOR_WHITE diff --git a/icons/mob/human/species/lizard/lizard_markings.dmi b/icons/mob/human/species/lizard/lizard_markings.dmi new file mode 100644 index 0000000000000000000000000000000000000000..7cc8f2fa1b8a5a25df59837bd1084b07db998763 GIT binary patch literal 977 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 Kvn=|}Gwx5O?YX%C literal 5152 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 diff --git a/tgstation.dme b/tgstation.dme index e5e577755cb8a..5c2702885460a 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -989,6 +989,7 @@ #include "code\datums\atmosphere\planetary.dm" #include "code\datums\bodypart_overlays\bodypart_overlay.dm" #include "code\datums\bodypart_overlays\emote_bodypart_overlay.dm" +#include "code\datums\bodypart_overlays\markings_bodypart_overlay.dm" #include "code\datums\bodypart_overlays\mutant_bodypart_overlay.dm" #include "code\datums\bodypart_overlays\simple_bodypart_overlay.dm" #include "code\datums\brain_damage\brain_trauma.dm" From 3a8f794dcbd1e113c06b9f741dcadaccb62943f8 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Wed, 19 Jun 2024 00:08:20 +1200 Subject: [PATCH 054/172] Automatic changelog for PR #83744 [ci skip] --- html/changelogs/AutoChangeLog-pr-83744.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83744.yml diff --git a/html/changelogs/AutoChangeLog-pr-83744.yml b/html/changelogs/AutoChangeLog-pr-83744.yml new file mode 100644 index 0000000000000..8425dfbfccd62 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83744.yml @@ -0,0 +1,4 @@ +author: "Time-Green" +delete-after: True +changes: + - refactor: "Lizard and moth markings now use the bodypart overlay system" \ No newline at end of file From d10d790f6765ff8197460d6210f6f9cf0e4a9e73 Mon Sep 17 00:00:00 2001 From: Joshua Kidder <49173900+Metekillot@users.noreply.github.com> Date: Tue, 18 Jun 2024 09:34:28 -0400 Subject: [PATCH 055/172] Sparks ignite flammable things (including people), welding fuel pools now ignite in response to more things logically (#83673) ## About The Pull Request Currently, sparks only ignite the air in rooms with plasma/tritium/hydrogen in them. This PR changes sparks to ignite flammable things they touch, including mobs covered in flammable liquids. They also marginally heat containers (40K temp increase from a broken light bulb). The initial purpose was to make welding fuel pools more responsive to flaming things being thrown into them. I have also done that. They now respond to hot objects (including flaming mobs) entering their space or being thrown onto them. They are also ignited by sparks. This PR makes sparks a fire hazard. Keep a fire extinguisher handy. ## Why It's Good For The Game Safety hazards are fun. Sparks should, logically, set flammable things on fire, including YOU. Welding fuel pools should be more hazardous. ## Changelog :cl: Bisar add: Sparks now ignite flammable things. Including you. Keep a fire extinguisher handy or stop dousing yourself in welding fuel! fix: Fixed a few oversights with welding fuel pools not igniting when you throw lit/hot things into them or when you walk into them while on fire. /:cl: --- .../objects/effects/decals/cleanable/misc.dm | 25 ++++++++ .../effects/effect_system/effects_sparks.dm | 59 ++++++++++++++++--- code/game/objects/items/grenades/_grenade.dm | 1 - 3 files changed, 75 insertions(+), 10 deletions(-) diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm index d977605b2436f..b99c8000c58a4 100644 --- a/code/game/objects/effects/decals/cleanable/misc.dm +++ b/code/game/objects/effects/decals/cleanable/misc.dm @@ -444,6 +444,7 @@ beauty = -50 clean_type = CLEAN_TYPE_BLOOD mouse_opacity = MOUSE_OPACITY_OPAQUE + resistance_flags = UNACIDABLE | ACID_PROOF | FIRE_PROOF | FLAMMABLE //gross way of doing this but would need to disassemble fire_act call stack otherwise /// Maximum amount of hotspots this pool can create before deleting itself var/burn_amount = 3 /// Is this fuel pool currently burning? @@ -453,6 +454,10 @@ /obj/effect/decal/cleanable/fuel_pool/Initialize(mapload, burn_stacks) . = ..() + var/static/list/ignition_trigger_connections = list( + COMSIG_TURF_MOVABLE_THROW_LANDED = PROC_REF(ignition_trigger), + ) + AddElement(/datum/element/connect_loc, ignition_trigger_connections) for(var/obj/effect/decal/cleanable/fuel_pool/pool in get_turf(src)) //Can't use locate because we also belong to that turf if(pool == src) continue @@ -509,6 +514,26 @@ ignite() return ..() +/obj/effect/decal/cleanable/fuel_pool/on_entered(datum/source, atom/movable/entered_atom) + . = ..() + if(entered_atom.throwing) // don't light from things being thrown over us, we handle that somewhere else + return + ignition_trigger(source = src, enflammable_atom = entered_atom) + +/obj/effect/decal/cleanable/fuel_pool/proc/ignition_trigger(datum/source, atom/movable/enflammable_atom) + SIGNAL_HANDLER + + if(isitem(enflammable_atom)) + var/obj/item/enflamed_item = enflammable_atom + if(enflamed_item.get_temperature() > FIRE_MINIMUM_TEMPERATURE_TO_EXIST) + ignite() + return + else if(isliving(enflammable_atom)) + var/mob/living/enflamed_liver = enflammable_atom + if(enflamed_liver.on_fire) + ignite() + + /obj/effect/decal/cleanable/fuel_pool/hivis icon_state = "fuel_pool_hivis" diff --git a/code/game/objects/effects/effect_system/effects_sparks.dm b/code/game/objects/effects/effect_system/effects_sparks.dm index 874c53fa83c7d..f9bb819fd42a1 100644 --- a/code/game/objects/effects/effect_system/effects_sparks.dm +++ b/code/game/objects/effects/effect_system/effects_sparks.dm @@ -26,24 +26,65 @@ return INITIALIZE_HINT_LATELOAD /obj/effect/particle_effect/sparks/LateInitialize() + RegisterSignals(src, list(COMSIG_MOVABLE_CROSS, COMSIG_MOVABLE_CROSS_OVER), PROC_REF(sparks_touched)) flick(icon_state, src) playsound(src, SFX_SPARKS, 100, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - var/turf/T = loc - if(isturf(T)) - T.hotspot_expose(1000,100) + var/turf/location = loc + if(isturf(location)) + affect_location(location, just_initialized = TRUE) QDEL_IN(src, 20) /obj/effect/particle_effect/sparks/Destroy() - var/turf/T = loc - if(isturf(T)) - T.hotspot_expose(1000,100) + var/turf/location = loc + if(isturf(location)) + affect_location(location) return ..() /obj/effect/particle_effect/sparks/Move() ..() - var/turf/T = loc - if(isturf(T)) - T.hotspot_expose(1000,100) + var/turf/location = loc + if(isturf(location)) + affect_location(location) + +/* +* Apply the effects of this spark to its location. +* +* When the spark is first created, Cross() and Crossed() don't get called, +* so for the first initialization, we make sure to specifically invoke the +* behavior of the spark on all the mobs and objects in the location. +* turf/location - The place the spark is affectiong +* just_initialized - If the spark is just being created, and we need to manually affect everything in the location +*/ +/obj/effect/particle_effect/sparks/proc/affect_location(turf/location, just_initialized = FALSE) + location.hotspot_expose(1000,100) + if(just_initialized) + for(var/atom/movable/singed in location) + sparks_touched(src, singed) + +/* +* This is called when anything passes through the same tiles as a spark, or when a spark passes through something's tile. +* +* This is invoked by the signals sent by every atom when they're crossed or crossing something. It +* signifies that something has been touched by sparks, and should be affected by possible pyrotechnic affects.. +* datum/source - Can either be the spark itself or an object that just walked into it +* mob/living/singed_mob - The mob that was touched by the spark +*/ +/obj/effect/particle_effect/sparks/proc/sparks_touched(datum/source, atom/movable/singed) + SIGNAL_HANDLER + + if(isobj(singed)) + var/obj/singed_obj = singed + if(singed_obj.resistance_flags & FLAMMABLE && !(singed_obj.resistance_flags & ON_FIRE)) //only fire_act flammable objects instead of burning EVERYTHING + singed_obj.fire_act(1,100) + if(singed_obj.reagents) + var/datum/reagents/reagents = singed_obj.reagents + reagents?.expose_temperature(1000) + return + if(isliving(singed)) + var/mob/living/singed_living = singed + if(singed_living.fire_stacks) + singed_living.ignite_mob(FALSE) //ignite the mob, silent = FALSE (You're set on fire!) + return /datum/effect_system/spark_spread effect_type = /obj/effect/particle_effect/sparks diff --git a/code/game/objects/items/grenades/_grenade.dm b/code/game/objects/items/grenades/_grenade.dm index 5deb833b1f234..ec16b4c22fe95 100644 --- a/code/game/objects/items/grenades/_grenade.dm +++ b/code/game/objects/items/grenades/_grenade.dm @@ -16,7 +16,6 @@ flags_1 = PREVENT_CONTENTS_EXPLOSION_1 // We detonate upon being exploded. obj_flags = CONDUCTS_ELECTRICITY slot_flags = ITEM_SLOT_BELT - resistance_flags = FLAMMABLE max_integrity = 40 /// Bitfields which prevent the grenade from detonating if set. Includes ([GRENADE_DUD]|[GRENADE_USED]) var/dud_flags = NONE From 4366fe5aa2da34a86ae30a5c44b51cc139d1ae41 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Wed, 19 Jun 2024 01:34:50 +1200 Subject: [PATCH 056/172] Automatic changelog for PR #83673 [ci skip] --- html/changelogs/AutoChangeLog-pr-83673.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83673.yml diff --git a/html/changelogs/AutoChangeLog-pr-83673.yml b/html/changelogs/AutoChangeLog-pr-83673.yml new file mode 100644 index 0000000000000..0211d4508cf97 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83673.yml @@ -0,0 +1,5 @@ +author: "Bisar" +delete-after: True +changes: + - rscadd: "Sparks now ignite flammable things. Including you. Keep a fire extinguisher handy or stop dousing yourself in welding fuel!" + - bugfix: "Fixed a few oversights with welding fuel pools not igniting when you throw lit/hot things into them or when you walk into them while on fire." \ No newline at end of file From 7df9a07ddab49be346544240d3a2e03eeffb0131 Mon Sep 17 00:00:00 2001 From: oranges Date: Wed, 19 Jun 2024 09:18:09 +1200 Subject: [PATCH 057/172] Revert "remove human requirement for invisible_wall" (#84096) Reverts tgstation/tgstation#83751 The person who added this has been abusing the shit out of it relentlessly, so they fail the vibe check. --- code/modules/spells/spell_types/conjure/invisible_wall.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/spells/spell_types/conjure/invisible_wall.dm b/code/modules/spells/spell_types/conjure/invisible_wall.dm index d2812912f0fc2..a61db7cf74e19 100644 --- a/code/modules/spells/spell_types/conjure/invisible_wall.dm +++ b/code/modules/spells/spell_types/conjure/invisible_wall.dm @@ -15,7 +15,7 @@ invocation_self_message = span_notice("You form a wall in front of yourself.") invocation_type = INVOCATION_EMOTE - spell_requirements = SPELL_REQUIRES_MIME_VOW + spell_requirements = SPELL_REQUIRES_HUMAN|SPELL_REQUIRES_MIME_VOW antimagic_flags = NONE spell_max_level = 1 From 48acfd680f0a592971ef825bd83083d4791c0524 Mon Sep 17 00:00:00 2001 From: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Date: Tue, 18 Jun 2024 18:14:13 -0500 Subject: [PATCH 058/172] Fix ambience pref not being toggleable in game (#84087) ## About The Pull Request The only time people were added to the ambience SS's list is when you log in, meaning if you toggle the preference on/off mid game, it does nothing. Fixes #61495 ## Changelog :cl: Melbert fix: Enabling or disabling ambience mid round will properly enable or disable ambience qol: Added descriptions differentiating "Ship ambience" from "ambience" /:cl: --- code/datums/mocking/client.dm | 3 +++ code/modules/client/preferences/sounds.dm | 3 +++ .../preferences/features/game_preferences/sounds.tsx | 2 ++ 3 files changed, 8 insertions(+) diff --git a/code/datums/mocking/client.dm b/code/datums/mocking/client.dm index dc1db213f34be..4b724ef705e82 100644 --- a/code/datums/mocking/client.dm +++ b/code/datums/mocking/client.dm @@ -48,3 +48,6 @@ /datum/client_interface/proc/set_macros() return + +/datum/client_interface/proc/update_ambience_pref() + return diff --git a/code/modules/client/preferences/sounds.dm b/code/modules/client/preferences/sounds.dm index f56430b53638a..3ace1b64326cc 100644 --- a/code/modules/client/preferences/sounds.dm +++ b/code/modules/client/preferences/sounds.dm @@ -4,6 +4,9 @@ savefile_key = "sound_ambience" savefile_identifier = PREFERENCE_PLAYER +/datum/preference/toggle/sound_ambience/apply_to_client(client/client, value) + client.update_ambience_pref() + /// Controls hearing announcement sounds /datum/preference/toggle/sound_announcements category = PREFERENCE_CATEGORY_GAME_PREFERENCES diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sounds.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sounds.tsx index 8516823a5587f..3f1c50c16f9f1 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sounds.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sounds.tsx @@ -10,6 +10,7 @@ import { FeatureDropdownInput } from '../dropdowns'; export const sound_ambience: FeatureToggle = { name: 'Enable ambience', category: 'SOUND', + description: `Ambience refers to the more noticeable ambient sounds that play on occasion.`, component: CheckboxInput, }; @@ -81,6 +82,7 @@ export const sound_midi: FeatureToggle = { export const sound_ship_ambience: FeatureToggle = { name: 'Enable ship ambience', category: 'SOUND', + description: `Ship ambience refers to the low ambient buzz that plays on loop.`, component: CheckboxInput, }; From 751bf0bc9baf6f3da8ac4290b39ae62a4cbc98c2 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Wed, 19 Jun 2024 11:15:07 +1200 Subject: [PATCH 059/172] Automatic changelog for PR #84087 [ci skip] --- html/changelogs/AutoChangeLog-pr-84087.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84087.yml diff --git a/html/changelogs/AutoChangeLog-pr-84087.yml b/html/changelogs/AutoChangeLog-pr-84087.yml new file mode 100644 index 0000000000000..09cfa195999e8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84087.yml @@ -0,0 +1,5 @@ +author: "Melbert" +delete-after: True +changes: + - bugfix: "Enabling or disabling ambience mid round will properly enable or disable ambience" + - qol: "Added descriptions differentiating \"Ship ambience\" from \"ambience\"" \ No newline at end of file From d5ab01b3da8d703b554cfccb10d3b4a1f47f2402 Mon Sep 17 00:00:00 2001 From: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Date: Tue, 18 Jun 2024 18:15:37 -0500 Subject: [PATCH 060/172] Hand Tele Fix (#84078) ## About The Pull Request Fixes #84077 Self explanatory ## Changelog :cl: Melbert fix: Fixed hand tele portals being forever /:cl: --- code/game/objects/effects/portals.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm index a7aabee6f4d2a..255f34eff51dd 100644 --- a/code/game/objects/effects/portals.dm +++ b/code/game/objects/effects/portals.dm @@ -101,7 +101,7 @@ . = INITIALIZE_HINT_QDEL CRASH("Somebody fucked up.") if(_lifespan > 0) - addtimer(src, PROC_REF(expire), _lifespan, TIMER_DELETE_ME) + addtimer(CALLBACK(src, PROC_REF(expire)), _lifespan, TIMER_DELETE_ME) link_portal(_linked) hardlinked = automatic_link if(isturf(hard_target_override)) From 4a75fa7dfde1a550a5e21daf1c1e1cad8c124547 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Wed, 19 Jun 2024 11:16:14 +1200 Subject: [PATCH 061/172] Automatic changelog for PR #84078 [ci skip] --- html/changelogs/AutoChangeLog-pr-84078.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84078.yml diff --git a/html/changelogs/AutoChangeLog-pr-84078.yml b/html/changelogs/AutoChangeLog-pr-84078.yml new file mode 100644 index 0000000000000..03f520a71d41b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84078.yml @@ -0,0 +1,4 @@ +author: "Melbert" +delete-after: True +changes: + - bugfix: "Fixed hand tele portals being forever" \ No newline at end of file From 0af50d0ca857b19c0632f8b0563588f2e9d6e25c Mon Sep 17 00:00:00 2001 From: Joshua Kidder <49173900+Metekillot@users.noreply.github.com> Date: Tue, 18 Jun 2024 19:17:07 -0400 Subject: [PATCH 062/172] Activating a lighter or match while covered in flammable liquids now ignites you, even if you're really, really, really ridiculously good looking (#84085) ## About The Pull Request This pull request adds a couple of lines to the code for matches and lighters that has it check to see if its location (which would also be its user) is a living mob with flammable liquid on them. If so, they get lit on fire. ## Why It's Good For The Game It adds a goofy interaction for people unfortunate enough to get splashed with flammable liquid. Beyond a possible way of making a half-assed attempt to assassinate a smoker, it's also a good safety lesson. Just look at these poor young men below... https://github.com/tgstation/tgstation/assets/49173900/f073f71f-6b37-46ce-8ea3-eb30ec2378a1 ## Changelog :cl: Bisar add: The Nanotrasen safety commission reminds employees to properly clean themselves of all flammable material before going on smoke breaks. /:cl: --- code/game/objects/items/cigs_lighters.dm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index 6ca951d262a67..be5d0b8ec2b1c 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -55,6 +55,10 @@ CIGARETTE PACKETS ARE IN FANCY.DM desc = "A [initial(name)]. This one is lit." attack_verb_continuous = string_list(list("burns", "singes")) attack_verb_simple = string_list(list("burn", "singe")) + if(isliving(loc)) + var/mob/living/male_model = loc + if(male_model.fire_stacks && !(male_model.on_fire)) + male_model.ignite_mob() START_PROCESSING(SSobj, src) update_appearance() @@ -876,6 +880,10 @@ CIGARETTE PACKETS ARE IN FANCY.DM attack_verb_continuous = string_list(list("burns", "singes")) attack_verb_simple = string_list(list("burn", "singe")) START_PROCESSING(SSobj, src) + if(isliving(loc)) + var/mob/living/male_model = loc + if(male_model.fire_stacks && !(male_model.on_fire)) + male_model.ignite_mob() else hitsound = SFX_SWING_HIT force = 0 From 4eb696095172bf4f1d457153384c7b15afe8c363 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Wed, 19 Jun 2024 11:18:40 +1200 Subject: [PATCH 063/172] Automatic changelog for PR #84085 [ci skip] --- html/changelogs/AutoChangeLog-pr-84085.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84085.yml diff --git a/html/changelogs/AutoChangeLog-pr-84085.yml b/html/changelogs/AutoChangeLog-pr-84085.yml new file mode 100644 index 0000000000000..995c311e4ef3f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84085.yml @@ -0,0 +1,4 @@ +author: "Bisar" +delete-after: True +changes: + - rscadd: "The Nanotrasen safety commission reminds employees to properly clean themselves of all flammable material before going on smoke breaks." \ No newline at end of file From e8157f4dfc2da8a6b92b935eff191c478846f2d1 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Wed, 19 Jun 2024 01:15:27 +0100 Subject: [PATCH 064/172] Items in your hands can catch fire (#83867) ## About The Pull Request Recently we allowed items held in your hands to catch fire if you catch fire. This makes sense but the code had a few oversights, then we reverted it. This PR reintroduces the feature, but with a few refinements. The basic feature is simple: If you are on fire then items you are holding will also catch fire, in the same vein as items you are wearing on your head or hands. There are also a few caveats we forgot about the first time we added this: - If your gloves cannot catch fire, your held items will not catch fire (because your hands aren't on fire). - If you are extinguished, your held items will also be extinguished. - Stopping, Dropping, and Rolling on top of any items will also extinguish those items. As part of this change, after an argument about whether or not this is an oversight in coding-general, I've made the proc `get_equipped_items` take a bitflag instead of a series of booleans as an argument and added a new one for "include held items", so that we need no longer argue about whether holding something counts as "equipping" it (in all other parts of the game than this proc, it does). This is what gives the PR most of its code footprint, don't be scared. ## Why It's Good For The Game Items you are holding in your hands _should_ catch fire if everything else on your person is on fire, and taking an item off of your body to put it in your hands shouldn't protect it from fire, because those things don't make intuitive sense. If we want an item to be able to catch fire when worn, then it should do so. This might expose some issues where we were improperly setting the flammability flags on items, but any weapon which will burn in your hands now would also have burned if you were wearing it on your belt or back, so making those issues more visible should be a bonus (we'll also stop them from burning on your back or belt). If you see someone holding a piece of paper that you really don't want them to read you can now set them on fire to stop them from reading it, whereas previously they would deftly hold the very flammable object out of reach of their flaming body. ## Changelog :cl: balance: Items held in your hands can catch fire. balance: Items you are holding won't catch fire if your hands cannot catch fire. balance: When you stop being on fire so will items you are holding. balance: If you roll around on your burning items they will stop being on fire. /:cl: --- code/__DEFINES/obj_flags.dm | 5 ++++ code/datums/diseases/transformation.dm | 2 +- code/datums/elements/skill_reward.dm | 2 +- .../status_effects/buffs/stop_drop_roll.dm | 3 +++ .../status_effects/debuffs/fire_stacks.dm | 2 +- code/game/objects/items/tanks/tanks.dm | 2 +- code/modules/admin/verbs/ert.dm | 2 +- code/modules/admin/verbs/selectequipment.dm | 3 ++- code/modules/antagonists/obsessed/obsessed.dm | 2 +- code/modules/bitrunning/server/util.dm | 2 +- code/modules/buildmode/submodes/outfit.dm | 4 ++-- code/modules/clothing/outfits/standard.dm | 2 +- code/modules/mafia/outfits.dm | 2 +- code/modules/mob/inventory.dm | 23 +++++++++---------- .../mob/living/carbon/human/_species.dm | 2 +- code/modules/mob/living/carbon/human/dummy.dm | 2 +- .../mob/living/carbon/human/human_defense.dm | 6 ++++- .../mob/living/carbon/human/inventory.dm | 2 +- code/modules/mob/living/ventcrawling.dm | 2 +- code/modules/mob/transform_procs.dm | 2 +- code/modules/unit_tests/outfit_sanity.dm | 2 +- 21 files changed, 43 insertions(+), 31 deletions(-) diff --git a/code/__DEFINES/obj_flags.dm b/code/__DEFINES/obj_flags.dm index 9e38eada92313..62ae5a7394a0a 100644 --- a/code/__DEFINES/obj_flags.dm +++ b/code/__DEFINES/obj_flags.dm @@ -106,3 +106,8 @@ /// Flags for sharpness in obj/item #define SHARP_EDGED (1<<0) #define SHARP_POINTY (1<<1) + +/// Flags for specifically what kind of items to get in get_equipped_items +#define INCLUDE_POCKETS (1<<0) +#define INCLUDE_ACCESSORIES (1<<1) +#define INCLUDE_HELD (1<<2) diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm index e672a86d72083..966987828bd54 100644 --- a/code/datums/diseases/transformation.dm +++ b/code/datums/diseases/transformation.dm @@ -62,7 +62,7 @@ if(HAS_TRAIT_FROM(affected_mob, TRAIT_NO_TRANSFORM, REF(src))) return ADD_TRAIT(affected_mob, TRAIT_NO_TRANSFORM, REF(src)) - for(var/obj/item/W in affected_mob.get_equipped_items(include_pockets = TRUE)) + for(var/obj/item/W in affected_mob.get_equipped_items(INCLUDE_POCKETS)) affected_mob.dropItemToGround(W) for(var/obj/item/I in affected_mob.held_items) affected_mob.dropItemToGround(I) diff --git a/code/datums/elements/skill_reward.dm b/code/datums/elements/skill_reward.dm index 7809eea85f715..891f933793ea0 100644 --- a/code/datums/elements/skill_reward.dm +++ b/code/datums/elements/skill_reward.dm @@ -29,7 +29,7 @@ ///We check if the item can be equipped, otherwise we drop it. /datum/element/skill_reward/proc/drop_if_unworthy(datum/source, mob/living/user) SIGNAL_HANDLER - if(check_equippable(user) || !(source in user.get_equipped_items(include_pockets = TRUE, include_accessories = TRUE))) + if(check_equippable(user) || !(source in user.get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES))) return NONE to_chat(user, span_warning("You feel completely and utterly unworthy to even touch \the [source].")) user.dropItemToGround(source, TRUE) diff --git a/code/datums/status_effects/buffs/stop_drop_roll.dm b/code/datums/status_effects/buffs/stop_drop_roll.dm index 43d37654e6177..17b4d6d768de3 100644 --- a/code/datums/status_effects/buffs/stop_drop_roll.dm +++ b/code/datums/status_effects/buffs/stop_drop_roll.dm @@ -24,6 +24,9 @@ // Start with one weaker roll owner.spin(spintime = actual_interval, speed = actual_interval / 4) owner.adjust_fire_stacks(-0.25) + + for (var/obj/item/dropped in owner.loc) + dropped.extinguish() // Effectively extinguish your items by rolling on them return TRUE /datum/status_effect/stop_drop_roll/on_remove() diff --git a/code/datums/status_effects/debuffs/fire_stacks.dm b/code/datums/status_effects/debuffs/fire_stacks.dm index 62f8c9ca24e32..dd625ab919aca 100644 --- a/code/datums/status_effects/debuffs/fire_stacks.dm +++ b/code/datums/status_effects/debuffs/fire_stacks.dm @@ -247,7 +247,7 @@ owner.clear_mood_event("on_fire") SEND_SIGNAL(owner, COMSIG_LIVING_EXTINGUISHED, owner) cache_stacks() - for(var/obj/item/equipped in owner.get_equipped_items()) + for(var/obj/item/equipped in (owner.get_equipped_items(INCLUDE_HELD))) equipped.extinguish() /datum/status_effect/fire_handler/fire_stacks/on_remove() diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index 72c84c9ee995e..fe15dab29588e 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -445,7 +445,7 @@ balloon_alert(user, "can't reach!") return - if((src in user.get_equipped_items(include_pockets = TRUE, include_accessories = TRUE)) && !user.canUnEquip(src)) + if((src in user.get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES)) && !user.canUnEquip(src)) balloon_alert(user, "it's stuck!") return diff --git a/code/modules/admin/verbs/ert.dm b/code/modules/admin/verbs/ert.dm index c86d08151ee62..2d1ba075a4795 100644 --- a/code/modules/admin/verbs/ert.dm +++ b/code/modules/admin/verbs/ert.dm @@ -25,7 +25,7 @@ /datum/admins/proc/equipAntagOnDummy(mob/living/carbon/human/dummy/mannequin, datum/antagonist/antag) - for(var/I in mannequin.get_equipped_items(include_pockets = TRUE)) + for(var/I in mannequin.get_equipped_items(INCLUDE_POCKETS)) qdel(I) if (ispath(antag, /datum/antagonist/ert)) var/datum/antagonist/ert/ert = antag diff --git a/code/modules/admin/verbs/selectequipment.dm b/code/modules/admin/verbs/selectequipment.dm index b94fd5cb2e455..415130fa1b727 100644 --- a/code/modules/admin/verbs/selectequipment.dm +++ b/code/modules/admin/verbs/selectequipment.dm @@ -209,7 +209,8 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(select_equipment, R_FUN, "Select Equipment", mob/ta delete_pocket = TRUE BLACKBOX_LOG_ADMIN_VERB("Select Equipment") - for(var/obj/item/item in human_target.get_equipped_items(include_pockets = delete_pocket)) + var/includes_flags = delete_pocket ? INCLUDE_POCKETS : NONE + for(var/obj/item/item in human_target.get_equipped_items(includes_flags)) qdel(item) var/obj/item/organ/internal/brain/human_brain = human_target.get_organ_slot(BRAIN) diff --git a/code/modules/antagonists/obsessed/obsessed.dm b/code/modules/antagonists/obsessed/obsessed.dm index 3d0a0063bf709..db934c90df604 100644 --- a/code/modules/antagonists/obsessed/obsessed.dm +++ b/code/modules/antagonists/obsessed/obsessed.dm @@ -66,7 +66,7 @@ shoes = /obj/item/clothing/shoes/sneakers/black /datum/outfit/obsessed/post_equip(mob/living/carbon/human/H) - for(var/obj/item/carried_item in H.get_equipped_items(include_pockets = TRUE, include_accessories = TRUE)) + for(var/obj/item/carried_item in H.get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES)) carried_item.add_mob_blood(H)//Oh yes, there will be blood... H.regenerate_icons() diff --git a/code/modules/bitrunning/server/util.dm b/code/modules/bitrunning/server/util.dm index ac3e60b51ba64..6b5352bde6cb1 100644 --- a/code/modules/bitrunning/server/util.dm +++ b/code/modules/bitrunning/server/util.dm @@ -66,7 +66,7 @@ /// Removes all blacklisted items from a mob and returns them to base state /obj/machinery/quantum_server/proc/reset_equipment(mob/living/carbon/human/person) - for(var/obj/item in person.get_equipped_items(include_pockets = TRUE, include_accessories = TRUE)) + for(var/obj/item in person.get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES)) qdel(item) var/datum/antagonist/bitrunning_glitch/antag_datum = locate() in person.mind?.antag_datums diff --git a/code/modules/buildmode/submodes/outfit.dm b/code/modules/buildmode/submodes/outfit.dm index 5f8e3319cb95d..c3d507bf1e6c7 100644 --- a/code/modules/buildmode/submodes/outfit.dm +++ b/code/modules/buildmode/submodes/outfit.dm @@ -32,11 +32,11 @@ to_chat(c, span_warning("Pick an outfit first.")) return - for (var/item in dollie.get_equipped_items(include_pockets = TRUE)) + for (var/item in dollie.get_equipped_items(INCLUDE_POCKETS)) qdel(item) if(dressuptime != "Naked") dollie.equipOutfit(dressuptime) if(LAZYACCESS(modifiers, RIGHT_CLICK)) - for (var/item in dollie.get_equipped_items(include_pockets = TRUE)) + for (var/item in dollie.get_equipped_items(INCLUDE_POCKETS)) qdel(item) diff --git a/code/modules/clothing/outfits/standard.dm b/code/modules/clothing/outfits/standard.dm index a22691495ccc1..6c088760f07db 100644 --- a/code/modules/clothing/outfits/standard.dm +++ b/code/modules/clothing/outfits/standard.dm @@ -185,7 +185,7 @@ l_hand = /obj/item/fireaxe /datum/outfit/psycho/post_equip(mob/living/carbon/human/H) - for(var/obj/item/carried_item in H.get_equipped_items(include_pockets = TRUE, include_accessories = TRUE)) + for(var/obj/item/carried_item in H.get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES)) carried_item.add_mob_blood(H)//Oh yes, there will be blood... for(var/obj/item/I in H.held_items) I.add_mob_blood(H) diff --git a/code/modules/mafia/outfits.dm b/code/modules/mafia/outfits.dm index dc2d384b263f6..5c6450adb90d2 100644 --- a/code/modules/mafia/outfits.dm +++ b/code/modules/mafia/outfits.dm @@ -155,7 +155,7 @@ suit = /obj/item/clothing/suit/apron /datum/outfit/mafia/obsessed/post_equip(mob/living/carbon/human/H) - for(var/obj/item/carried_item in H.get_equipped_items(include_pockets = TRUE, include_accessories = TRUE)) + for(var/obj/item/carried_item in H.get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES)) carried_item.add_mob_blood(H)//Oh yes, there will be blood... H.regenerate_icons() diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index b118de06f057a..50ab6e82faa4d 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -388,38 +388,37 @@ * Used to return a list of equipped items on a mob; does not include held items (use get_all_gear) * * Argument(s): - * * Optional - include_pockets (TRUE/FALSE), whether or not to include the pockets and suit storage in the returned list - * * Optional - include_accessories (TRUE/FALSE), whether or not to include the accessories in the returned list + * * Optional - include_flags, (see obj.flags.dm) describes which optional things to include or not (pockets, accessories, held items) */ -/mob/living/proc/get_equipped_items(include_pockets = FALSE, include_accessories = FALSE) +/mob/living/proc/get_equipped_items(include_flags = NONE) var/list/items = list() for(var/obj/item/item_contents in contents) if(item_contents.item_flags & IN_INVENTORY) items += item_contents - items -= held_items + if (!(include_flags & INCLUDE_HELD)) + items -= held_items return items /** - * Used to return a list of equipped items on a human mob; does not include held items (use get_all_gear) + * Used to return a list of equipped items on a human mob; does not by default include held items, see include_flags * * Argument(s): - * * Optional - include_pockets (TRUE/FALSE), whether or not to include the pockets and suit storage in the returned list - * * Optional - include_accessories (TRUE/FALSE), whether or not to include the accessories in the returned list + * * Optional - include_flags, (see obj.flags.dm) describes which optional things to include or not (pockets, accessories, held items) */ -/mob/living/carbon/human/get_equipped_items(include_pockets = FALSE, include_accessories = FALSE) +/mob/living/carbon/human/get_equipped_items(include_flags = NONE) var/list/items = ..() - if(!include_pockets) + if(!(include_flags & INCLUDE_POCKETS)) items -= list(l_store, r_store, s_store) - if(include_accessories && w_uniform) + if((include_flags & INCLUDE_ACCESSORIES) && w_uniform) var/obj/item/clothing/under/worn_under = w_uniform items += worn_under.attached_accessories return items /mob/living/proc/unequip_everything() var/list/items = list() - items |= get_equipped_items(include_pockets = TRUE) + items |= get_equipped_items(INCLUDE_POCKETS) for(var/I in items) dropItemToGround(I) drop_all_held_items() @@ -558,7 +557,7 @@ //GetAllContents that is reasonable and not stupid /mob/living/proc/get_all_gear() - var/list/processing_list = get_equipped_items(include_pockets = TRUE, include_accessories = TRUE) + held_items + var/list/processing_list = get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES | INCLUDE_HELD) list_clear_nulls(processing_list) // handles empty hands var/i = 0 while(i < length(processing_list)) diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index d5d048a33f844..1e514ad13cedb 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -403,7 +403,7 @@ GLOBAL_LIST_EMPTY(features_by_species) replacement.Insert(organ_holder, special=TRUE, movement_flags = DELETE_IF_REPLACED) /datum/species/proc/worn_items_fit_body_check(mob/living/carbon/wearer) - for(var/obj/item/equipped_item in wearer.get_equipped_items(include_pockets = TRUE)) + for(var/obj/item/equipped_item in wearer.get_equipped_items(INCLUDE_POCKETS)) var/equipped_item_slot = wearer.get_slot_by_item(equipped_item) if(!equipped_item.mob_can_equip(wearer, equipped_item_slot, bypass_equip_delay_self = TRUE, ignore_equipped = TRUE)) wearer.dropItemToGround(equipped_item, force = TRUE) diff --git a/code/modules/mob/living/carbon/human/dummy.dm b/code/modules/mob/living/carbon/human/dummy.dm index 8d62ed5907948..3340e34064052 100644 --- a/code/modules/mob/living/carbon/human/dummy.dm +++ b/code/modules/mob/living/carbon/human/dummy.dm @@ -41,7 +41,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) //Instead of just deleting our equipment, we save what we can and reinsert it into SSwardrobe's store //Hopefully this makes preference reloading not the worst thing ever /mob/living/carbon/human/dummy/delete_equipment() - var/list/items_to_check = get_equipped_items(include_pockets = TRUE) + held_items + var/list/items_to_check = get_equipped_items(INCLUDE_POCKETS | INCLUDE_HELD) var/list/to_nuke = list() //List of items queued for deletion, can't qdel them before iterating their contents in case they hold something ///Travel to the bottom of the contents chain, expanding it out for(var/i = 1; i <= length(items_to_check); i++) //Needs to be a c style loop since it can expand diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 6e1f9037018b6..aa2daa1675e91 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -93,7 +93,7 @@ return TRUE var/block_chance_modifier = round(damage / -3) - for(var/obj/item/worn_thing in get_equipped_items(include_pockets = FALSE) + held_items) + for(var/obj/item/worn_thing in get_equipped_items(INCLUDE_HELD)) // Things that are supposed to be worn, being held = cannot block if(isclothing(worn_thing)) if(worn_thing in held_items) @@ -796,6 +796,10 @@ if(leg_clothes) burning_items |= leg_clothes + if (!gloves || (!(gloves.resistance_flags & FIRE_PROOF) && (gloves.resistance_flags & FLAMMABLE))) + for(var/obj/item/burnable_item in held_items) + burning_items |= burnable_item + for(var/obj/item/burning in burning_items) burning.fire_act((stacks * 25 * seconds_per_tick)) //damage taken is reduced to 2% of this value by fire_act() diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 32ab7ca1b900a..19e4b7a43deb6 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -347,7 +347,7 @@ //delete all equipment without dropping anything /mob/living/carbon/human/proc/delete_equipment() - for(var/slot in get_equipped_items(include_pockets = TRUE))//order matters, dependant slots go first + for(var/slot in get_equipped_items(INCLUDE_POCKETS))//order matters, dependant slots go first qdel(slot) for(var/obj/item/held_item in held_items) qdel(held_item) diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm index 3d7be3ea47e29..e25a6f9b16e27 100644 --- a/code/modules/mob/living/ventcrawling.dm +++ b/code/modules/mob/living/ventcrawling.dm @@ -31,7 +31,7 @@ to_chat(src, span_warning("You can't vent crawl while buckled!")) return if(iscarbon(src) && required_nudity) - if(length(get_equipped_items(include_pockets = TRUE)) || get_num_held_items()) + if(length(get_equipped_items(INCLUDE_POCKETS)) || get_num_held_items()) if(provide_feedback) to_chat(src, span_warning("You can't crawl around in the ventilation ducts with items!")) return diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index b4fbd713065aa..123fb0de82cd7 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -312,7 +312,7 @@ SSblackbox.record_feedback("amount", "gorillas_created", 1) - var/Itemlist = get_equipped_items(include_pockets = TRUE) + var/Itemlist = get_equipped_items(INCLUDE_POCKETS) Itemlist += held_items for(var/obj/item/W in Itemlist) dropItemToGround(W, TRUE) diff --git a/code/modules/unit_tests/outfit_sanity.dm b/code/modules/unit_tests/outfit_sanity.dm index 18f5e9b8e6141..554d226ed2e72 100644 --- a/code/modules/unit_tests/outfit_sanity.dm +++ b/code/modules/unit_tests/outfit_sanity.dm @@ -49,7 +49,7 @@ for (var/outfit_type in outfits_to_check) // Only make one human and keep undressing it because it's much faster - for (var/obj/item/I in H.get_equipped_items(include_pockets = TRUE)) + for (var/obj/item/I in H.get_equipped_items(INCLUDE_POCKETS)) qdel(I) var/datum/outfit/outfit = new outfit_type From 9e0047f8f470b54e23adabd57123405a0b8b8cbd Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Wed, 19 Jun 2024 12:17:06 +1200 Subject: [PATCH 065/172] Automatic changelog for PR #83867 [ci skip] --- html/changelogs/AutoChangeLog-pr-83867.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83867.yml diff --git a/html/changelogs/AutoChangeLog-pr-83867.yml b/html/changelogs/AutoChangeLog-pr-83867.yml new file mode 100644 index 0000000000000..b34ce8b957e24 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83867.yml @@ -0,0 +1,7 @@ +author: "Jacquerel" +delete-after: True +changes: + - balance: "Items held in your hands can catch fire." + - balance: "Items you are holding won't catch fire if your hands cannot catch fire." + - balance: "When you stop being on fire so will items you are holding." + - balance: "If you roll around on your burning items they will stop being on fire." \ No newline at end of file From 3ad7731897ac9e249562bd8ca414c04287af1ac4 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Wed, 19 Jun 2024 00:26:20 +0000 Subject: [PATCH 066/172] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-83439.yml | 8 ---- html/changelogs/AutoChangeLog-pr-83673.yml | 5 --- html/changelogs/AutoChangeLog-pr-83744.yml | 4 -- html/changelogs/AutoChangeLog-pr-83792.yml | 4 -- html/changelogs/AutoChangeLog-pr-83867.yml | 7 ---- html/changelogs/AutoChangeLog-pr-83952.yml | 4 -- html/changelogs/AutoChangeLog-pr-83999.yml | 4 -- html/changelogs/AutoChangeLog-pr-84053.yml | 4 -- html/changelogs/AutoChangeLog-pr-84078.yml | 4 -- html/changelogs/AutoChangeLog-pr-84085.yml | 4 -- html/changelogs/AutoChangeLog-pr-84087.yml | 5 --- html/changelogs/archive/2024-06.yml | 43 ++++++++++++++++++++++ 12 files changed, 43 insertions(+), 53 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-83439.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83673.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83744.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83792.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83867.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83952.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83999.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84053.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84078.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84085.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84087.yml diff --git a/html/changelogs/AutoChangeLog-pr-83439.yml b/html/changelogs/AutoChangeLog-pr-83439.yml deleted file mode 100644 index 9e721ae4ba0a4..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83439.yml +++ /dev/null @@ -1,8 +0,0 @@ -author: "carlarctg" -delete-after: True -changes: - - balance: "Negative mutations now allow you to have more positive mutations, via reducing your instability!" - - code_imp: "All mutations have been overall standardized via defines on their instability values. Many mediocre positive mutations have had their cost reduced significantly!" - - rscadd: "Added a new height mutation: Acromegaly! It's the opposite of Dwarfism and makes you uncannily tall. It also makes you hit your head 8% or 4% (with synch) of the time you pass through airlocks. Wear a helmet!" - - rscadd: "Gigantism is now a recipe mutation, mix Acromegaly with Strength to get it." - - qol: "Injectors and activators' duration is now dependent on the in/stability (absolute value) of the mutations to be injected! With a minimum of 5-10-15 seconds for each type of injector. Also changed up a bit how part upgrade cooldowns work, by making each tier reduce cooldowns by 25-15-10% for each injector type." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83673.yml b/html/changelogs/AutoChangeLog-pr-83673.yml deleted file mode 100644 index 0211d4508cf97..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83673.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Bisar" -delete-after: True -changes: - - rscadd: "Sparks now ignite flammable things. Including you. Keep a fire extinguisher handy or stop dousing yourself in welding fuel!" - - bugfix: "Fixed a few oversights with welding fuel pools not igniting when you throw lit/hot things into them or when you walk into them while on fire." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83744.yml b/html/changelogs/AutoChangeLog-pr-83744.yml deleted file mode 100644 index 8425dfbfccd62..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83744.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Time-Green" -delete-after: True -changes: - - refactor: "Lizard and moth markings now use the bodypart overlay system" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83792.yml b/html/changelogs/AutoChangeLog-pr-83792.yml deleted file mode 100644 index c856d7586a8ce..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83792.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "TheRyeGuyWhoWillNowDie" -delete-after: True -changes: - - rscadd: "the advanced omnitool upgrade now hastens the mediborg's syringe too" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83867.yml b/html/changelogs/AutoChangeLog-pr-83867.yml deleted file mode 100644 index b34ce8b957e24..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83867.yml +++ /dev/null @@ -1,7 +0,0 @@ -author: "Jacquerel" -delete-after: True -changes: - - balance: "Items held in your hands can catch fire." - - balance: "Items you are holding won't catch fire if your hands cannot catch fire." - - balance: "When you stop being on fire so will items you are holding." - - balance: "If you roll around on your burning items they will stop being on fire." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83952.yml b/html/changelogs/AutoChangeLog-pr-83952.yml deleted file mode 100644 index 431aaa759582e..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83952.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "GPeckman" -delete-after: True -changes: - - bugfix: "Airlocks should no longer appear closed sometimes when fireman carrying someone into them." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83999.yml b/html/changelogs/AutoChangeLog-pr-83999.yml deleted file mode 100644 index a04af9580bdf3..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83999.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Jacquerel" -delete-after: True -changes: - - balance: "Gorillas have big fingers, which mostly just prevents them from using laser pointers and stun batons" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84053.yml b/html/changelogs/AutoChangeLog-pr-84053.yml deleted file mode 100644 index 6aebdbc471f5f..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84053.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "jlsnow301" -delete-after: True -changes: - - bugfix: "TGUI say will no longer spill your /me contents when you get attacked" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84078.yml b/html/changelogs/AutoChangeLog-pr-84078.yml deleted file mode 100644 index 03f520a71d41b..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84078.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Melbert" -delete-after: True -changes: - - bugfix: "Fixed hand tele portals being forever" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84085.yml b/html/changelogs/AutoChangeLog-pr-84085.yml deleted file mode 100644 index 995c311e4ef3f..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84085.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Bisar" -delete-after: True -changes: - - rscadd: "The Nanotrasen safety commission reminds employees to properly clean themselves of all flammable material before going on smoke breaks." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84087.yml b/html/changelogs/AutoChangeLog-pr-84087.yml deleted file mode 100644 index 09cfa195999e8..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84087.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Melbert" -delete-after: True -changes: - - bugfix: "Enabling or disabling ambience mid round will properly enable or disable ambience" - - qol: "Added descriptions differentiating \"Ship ambience\" from \"ambience\"" \ No newline at end of file diff --git a/html/changelogs/archive/2024-06.yml b/html/changelogs/archive/2024-06.yml index 9f757c45df58b..c1c7f194b7758 100644 --- a/html/changelogs/archive/2024-06.yml +++ b/html/changelogs/archive/2024-06.yml @@ -800,3 +800,46 @@ san7890: - qol: A message with a link to publicly accessible logs (if enabled by your server operators) should now be visible far earlier when a world is about to reboot. +2024-06-19: + Bisar: + - rscadd: The Nanotrasen safety commission reminds employees to properly clean themselves + of all flammable material before going on smoke breaks. + - rscadd: Sparks now ignite flammable things. Including you. Keep a fire extinguisher + handy or stop dousing yourself in welding fuel! + - bugfix: Fixed a few oversights with welding fuel pools not igniting when you throw + lit/hot things into them or when you walk into them while on fire. + GPeckman: + - bugfix: Airlocks should no longer appear closed sometimes when fireman carrying + someone into them. + Jacquerel: + - balance: Gorillas have big fingers, which mostly just prevents them from using + laser pointers and stun batons + - balance: Items held in your hands can catch fire. + - balance: Items you are holding won't catch fire if your hands cannot catch fire. + - balance: When you stop being on fire so will items you are holding. + - balance: If you roll around on your burning items they will stop being on fire. + Melbert: + - bugfix: Fixed hand tele portals being forever + - bugfix: Enabling or disabling ambience mid round will properly enable or disable + ambience + - qol: Added descriptions differentiating "Ship ambience" from "ambience" + TheRyeGuyWhoWillNowDie: + - rscadd: the advanced omnitool upgrade now hastens the mediborg's syringe too + Time-Green: + - refactor: Lizard and moth markings now use the bodypart overlay system + carlarctg: + - balance: Negative mutations now allow you to have more positive mutations, via + reducing your instability! + - code_imp: All mutations have been overall standardized via defines on their instability + values. Many mediocre positive mutations have had their cost reduced significantly! + - rscadd: 'Added a new height mutation: Acromegaly! It''s the opposite of Dwarfism + and makes you uncannily tall. It also makes you hit your head 8% or 4% (with + synch) of the time you pass through airlocks. Wear a helmet!' + - rscadd: Gigantism is now a recipe mutation, mix Acromegaly with Strength to get + it. + - qol: Injectors and activators' duration is now dependent on the in/stability (absolute + value) of the mutations to be injected! With a minimum of 5-10-15 seconds for + each type of injector. Also changed up a bit how part upgrade cooldowns work, + by making each tier reduce cooldowns by 25-15-10% for each injector type. + jlsnow301: + - bugfix: TGUI say will no longer spill your /me contents when you get attacked From b984c9d6f0a729c9010c47da3e8f5c9272fa704c Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 19 Jun 2024 15:31:19 +0300 Subject: [PATCH 067/172] APC channel wires (#84099) ## About The Pull Request Added wires for toggling channels between Auto and Off to the APC. ![image](https://github.com/tgstation/tgstation/assets/3625094/b4986bd1-3c10-4200-bc88-405fe6c40d6a) ## Why It's Good For The Game Allows for a few interesting setups, such as: - Connecting signaller to the lights channel to control lights remotely or using proximity sensors/infrared lasers. - Connecting signaller to the machinery channel to automatically disable machine power usage in an area for power saving with signaller or proximity sensors. ## Changelog :cl: qol: APC has wires for machinery/lights/environment channels /:cl: --- code/__DEFINES/wires.dm | 2 ++ code/datums/wires/apc.dm | 42 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/code/__DEFINES/wires.dm b/code/__DEFINES/wires.dm index 2b4c528abc212..4926996f26bd3 100644 --- a/code/__DEFINES/wires.dm +++ b/code/__DEFINES/wires.dm @@ -64,6 +64,8 @@ #define WIRE_ZAP1 "High Voltage Circuit 1" #define WIRE_ZAP2 "High Voltage Circuit 2" #define WIRE_OVERCLOCK "Overclock" +#define WIRE_EQUIPMENT "Equipment" +#define WIRE_ENVIRONMENT "Environment" // Wire states for the AI #define AI_WIRE_NORMAL 0 diff --git a/code/datums/wires/apc.dm b/code/datums/wires/apc.dm index 54d179802a311..50847df994372 100644 --- a/code/datums/wires/apc.dm +++ b/code/datums/wires/apc.dm @@ -4,8 +4,13 @@ /datum/wires/apc/New(atom/holder) wires = list( - WIRE_POWER1, WIRE_POWER2, - WIRE_IDSCAN, WIRE_AI + WIRE_EQUIPMENT, + WIRE_LIGHT, + WIRE_ENVIRONMENT, + WIRE_POWER1, + WIRE_POWER2, + WIRE_INTERFACE, + WIRE_AI ) add_duds(6) ..() @@ -22,17 +27,32 @@ var/list/status = list() status += "The interface light is [A.locked ? "red" : "green"]." status += "The short indicator is [A.shorted ? "lit" : "off"]." + status += "The channel one light is [A.equipment ? "on" : "off"]." + status += "The channel two light is [A.lighting ? "on" : "off"]." + status += "The channel three light is [A.environ ? "on" : "off"]." status += "The AI connection light is [!A.aidisabled ? "on" : "off"]." return status -/datum/wires/apc/on_pulse(wire) +/datum/wires/apc/on_pulse(wire, user) var/obj/machinery/power/apc/A = holder switch(wire) + if(WIRE_EQUIPMENT) + A.equipment = A.equipment > APC_CHANNEL_OFF ? APC_CHANNEL_OFF : APC_CHANNEL_AUTO_ON + A.update_appearance() + A.update() + if(WIRE_LIGHT) + A.lighting = A.lighting > APC_CHANNEL_OFF ? APC_CHANNEL_OFF : APC_CHANNEL_AUTO_ON + A.update_appearance() + A.update() + if(WIRE_ENVIRONMENT) + A.environ = A.environ > APC_CHANNEL_OFF ? APC_CHANNEL_OFF : APC_CHANNEL_AUTO_ON + A.update_appearance() + A.update() if(WIRE_POWER1, WIRE_POWER2) // Short for a long while. if(!A.shorted) A.shorted = TRUE addtimer(CALLBACK(A, TYPE_PROC_REF(/obj/machinery/power/apc, reset), wire), 2 MINUTES) - if(WIRE_IDSCAN) // Unlock for a little while. + if(WIRE_INTERFACE) // Unlock for a little while. A.locked = FALSE addtimer(CALLBACK(A, TYPE_PROC_REF(/obj/machinery/power/apc, reset), wire), 30 SECONDS) if(WIRE_AI) // Disable AI control for a very short time. @@ -43,12 +63,26 @@ /datum/wires/apc/on_cut(wire, mend, source) var/obj/machinery/power/apc/A = holder switch(wire) + if(WIRE_EQUIPMENT) + A.equipment = mend ? APC_CHANNEL_AUTO_ON : APC_CHANNEL_OFF + A.update_appearance() + A.update() + if(WIRE_LIGHT) + A.lighting = mend ? APC_CHANNEL_AUTO_ON : APC_CHANNEL_OFF + A.update_appearance() + A.update() + if(WIRE_ENVIRONMENT) + A.environ = mend ? APC_CHANNEL_AUTO_ON : APC_CHANNEL_OFF + A.update_appearance() + A.update() if(WIRE_POWER1, WIRE_POWER2) // Short out. if(mend && !is_cut(WIRE_POWER1) && !is_cut(WIRE_POWER2)) A.shorted = FALSE else A.shorted = TRUE A.shock(usr, 50) + if(WIRE_INTERFACE) + A.locked = !mend if(WIRE_AI) // Disable AI control. A.aidisabled = !mend From 72ada6b7ae7e0e66570ba6f076010161a198e119 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Thu, 20 Jun 2024 00:31:39 +1200 Subject: [PATCH 068/172] Automatic changelog for PR #84099 [ci skip] --- html/changelogs/AutoChangeLog-pr-84099.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84099.yml diff --git a/html/changelogs/AutoChangeLog-pr-84099.yml b/html/changelogs/AutoChangeLog-pr-84099.yml new file mode 100644 index 0000000000000..da8c2a27966e1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84099.yml @@ -0,0 +1,4 @@ +author: "MTandi" +delete-after: True +changes: + - qol: "APC has wires for machinery/lights/environment channels" \ No newline at end of file From f5f9c5b0de31655f3190edb0e50d567220204cf2 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 19 Jun 2024 15:34:37 +0300 Subject: [PATCH 069/172] Power cell tiers consistency (#84074) ## About The Pull Request Tier 3 had both 20 and 30 MJ cells for some reason, while 10 MJ cell was considered tier 2. Now the scaling is proper: 10 MJ is tier 1, 20 MJ is tier 2, and so on... Also updated plasma crystal sprite, and gave unique sprites to the smallest cells. ![image](https://github.com/tgstation/tgstation/assets/3625094/308a88b2-a834-4256-894d-88743311c0b4) ## Why It's Good For The Game The scaling was off, and the sprites made them look out of place for their tier. ## Changelog :cl: fix: Made 10 MJ & 20 MJ cells properly correspond to tiers 1 & 2 in lathes. image: Updated cell sprites to correspond to other stock parts of their tiers. image: Updated plasma cell, 500KJ cell and 2.5MJ cell sprites /:cl: --- code/modules/power/cell.dm | 10 ++++++++++ .../modules/research/designs/power_designs.dm | 4 ++-- icons/obj/machines/cell_charger.dmi | Bin 3287 -> 3629 bytes 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index dc2b4e9812a03..b55593ec913e7 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -311,19 +311,29 @@ /obj/item/stock_parts/cell/crap name = "\improper Nanotrasen brand rechargeable AA battery" desc = "You can't top the plasma top." //TOTALLY TRADEMARK INFRINGEMENT + icon_state = "aa_cell" maxcharge = STANDARD_CELL_CHARGE * 0.5 custom_materials = list(/datum/material/glass=SMALL_MATERIAL_AMOUNT*0.4) +/obj/item/stock_parts/cell/crap/Initialize(mapload) + AddElement(/datum/element/update_icon_blocker) + return ..() + /obj/item/stock_parts/cell/crap/empty empty = TRUE /obj/item/stock_parts/cell/upgraded name = "upgraded power cell" desc = "A power cell with a slightly higher capacity than normal!" + icon_state = "9v_cell" maxcharge = STANDARD_CELL_CHARGE * 2.5 custom_materials = list(/datum/material/glass=SMALL_MATERIAL_AMOUNT*0.5) chargerate = STANDARD_CELL_RATE * 0.5 +/obj/item/stock_parts/cell/upgraded/Initialize(mapload) + AddElement(/datum/element/update_icon_blocker) + return ..() + /obj/item/stock_parts/cell/upgraded/plus name = "upgraded power cell+" desc = "A power cell with an even higher capacity than the base model!" diff --git a/code/modules/research/designs/power_designs.dm b/code/modules/research/designs/power_designs.dm index 85704c0c5b72e..700f99a643504 100644 --- a/code/modules/research/designs/power_designs.dm +++ b/code/modules/research/designs/power_designs.dm @@ -24,7 +24,7 @@ construction_time = 10 SECONDS build_path = /obj/item/stock_parts/cell/high/empty category = list( - RND_CATEGORY_STOCK_PARTS + RND_SUBCATEGORY_STOCK_PARTS_2 + RND_CATEGORY_STOCK_PARTS + RND_SUBCATEGORY_STOCK_PARTS_1 ) departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING @@ -37,7 +37,7 @@ construction_time = 10 SECONDS build_path = /obj/item/stock_parts/cell/super/empty category = list( - RND_CATEGORY_STOCK_PARTS + RND_SUBCATEGORY_STOCK_PARTS_3 + RND_CATEGORY_STOCK_PARTS + RND_SUBCATEGORY_STOCK_PARTS_2 ) departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING diff --git a/icons/obj/machines/cell_charger.dmi b/icons/obj/machines/cell_charger.dmi index 5ce285fc817826755ca6e66f3593fb9b74c0097a..0c9ca53544286bb1d40e6be608b5cbbf22623c56 100644 GIT binary patch literal 3629 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 literal 3287 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 t( Date: Thu, 20 Jun 2024 00:35:01 +1200 Subject: [PATCH 070/172] Automatic changelog for PR #84074 [ci skip] --- html/changelogs/AutoChangeLog-pr-84074.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84074.yml diff --git a/html/changelogs/AutoChangeLog-pr-84074.yml b/html/changelogs/AutoChangeLog-pr-84074.yml new file mode 100644 index 0000000000000..3ba774dadd0a4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84074.yml @@ -0,0 +1,6 @@ +author: "MTandi" +delete-after: True +changes: + - bugfix: "Made 10 MJ & 20 MJ cells properly correspond to tiers 1 & 2 in lathes." + - image: "Updated cell sprites to correspond to other stock parts of their tiers." + - image: "Updated plasma cell, 500KJ cell and 2.5MJ cell sprites" \ No newline at end of file From c7b27d01e20c0f6b2c5f4e84795854b07a36ed6b Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 19 Jun 2024 15:36:29 +0300 Subject: [PATCH 071/172] Fixed TechWeb app piling designs issue (#84104) ## About The Pull Request Fixes #81478 ## Why It's Good For The Game We had this issue since February. ## Changelog :cl: fix: Fixed techweb app showing wrong designs on Details button click /:cl: --- tgui/packages/tgui/interfaces/Techweb.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tgui/packages/tgui/interfaces/Techweb.jsx b/tgui/packages/tgui/interfaces/Techweb.jsx index c041d646d7d99..dcafea78bf529 100644 --- a/tgui/packages/tgui/interfaces/Techweb.jsx +++ b/tgui/packages/tgui/interfaces/Techweb.jsx @@ -621,7 +621,7 @@ const TechNode = (props) => { {design_ids.map((k, i) => ( - - - - } - > - {!pressure && {'No Pressure Detected'}} - {usingLastData && ( - - {'Tank destroyed. Displaying last recorded data.'} - - )} - - - (value ? value.toFixed(2) : '-') + ' kPa'} - /> - - - - - - = leakPressure} - /> - - - - - = leakPressure && - pressure < fragmentPressure) || - leaking - } - /> - - - = fragmentPressure} - /> - - - - - - - -

- - - - act('change_rate', { target: new_rate }) - } - /> - - - - - -
- - - - -
- {!inputData.total_moles && {'No Gas Present'}} - -
-
- -
- {!outputData.inputData && {'No Gas Present'}} - -
-
- -
- } - > - {!bufferData.total_moles && {'No Gas Present'}} - -
-
-
-
- - ); -}; - -const TankCompressorRecords = (props) => { - const { act, data } = useBackend(); - const { records = [], disk } = data; - const [activeRecordRef, setActiveRecordRef] = useSharedState( - 'recordRef', - records[0]?.ref, - ); - const activeRecord = - !!activeRecordRef && - records.find((record) => activeRecordRef === record.ref); - if (records.length === 0) { - return ( - - No Records - - ); - } - - return ( - - - - - {records.map((record) => ( - setActiveRecordRef(record.ref)} - > - {record.name} - - ))} - - - {activeRecord ? ( - -
{ - act('delete_record', { - ref: activeRecord.ref, - }); - }} - />, -
-
- ) : ( - - No Record Selected - - )} -
-
- ); -}; diff --git a/tgui/packages/tgui/interfaces/TankCompressor.tsx b/tgui/packages/tgui/interfaces/TankCompressor.tsx new file mode 100644 index 0000000000000..3f516e3c01803 --- /dev/null +++ b/tgui/packages/tgui/interfaces/TankCompressor.tsx @@ -0,0 +1,321 @@ +import { toFixed } from 'common/math'; +import { BooleanLike } from 'common/react'; + +import { useBackend, useSharedState } from '../backend'; +import { + Box, + Button, + Knob, + LabeledControls, + LabeledList, + NoticeBox, + RoundGauge, + Section, + Stack, + Tabs, +} from '../components'; +import { formatSiUnit } from '../format'; +import { Window } from '../layouts'; + +type Data = { + // Dynamic + tankPresent: BooleanLike; + tankPressure: number; + leaking: BooleanLike; + active: BooleanLike; + transferRate: number; + lastPressure: number; + disk: string; + storage: string; + records: Record[]; + // Static + maxTransfer: number; + leakPressure: number; + fragmentPressure: number; + ejectPressure: number; +}; + +type Record = { + ref: string; + name: string; + timestamp: string; + source: string; + gases: GasMoles[]; +}; + +type GasMoles = { + [key: string]: number; +}; + +const formatPressure = (value) => { + if (value < 10000) { + return toFixed(value) + ' kPa'; + } + return formatSiUnit(value * 1000, 1, 'Pa'); +}; + +export const TankCompressor = (props) => { + return ( + + + + + + ); +}; + +const TankCompressorContent = (props) => { + const { act, data } = useBackend(); + const { disk, storage } = data; + + return ( + + +
act('eject_disk')} + > + Eject Disk + + } + > + +
+
+
+ ); +}; + +const TankCompressorControls = (props) => { + const { act, data } = useBackend(); + const { + tankPresent, + leaking, + lastPressure, + leakPressure, + fragmentPressure, + tankPressure, + maxTransfer, + active, + transferRate, + ejectPressure, + } = data; + const pressure = tankPresent ? tankPressure : lastPressure; + const usingLastData = !!(lastPressure && !tankPresent); + const notice_color = + usingLastData || leaking || pressure > fragmentPressure + ? 'bad' + : !tankPresent + ? 'blue' + : pressure > leakPressure + ? 'average' + : 'good'; + const notice_text = usingLastData + ? 'Tank destroyed. Displaying last recorded data.' + : !tankPresent + ? 'No Tank Detected' + : leaking + ? 'Tank Leaking' + : !pressure + ? 'No Pressure Detected' + : pressure < leakPressure + ? 'Tank Pressure Nominal' + : pressure < fragmentPressure + ? 'Leak Hazard' + : 'Explosive Hazard'; + + return ( + +
ejectPressure} + onClick={() => act('eject_tank')} + > + {'Eject Tank'} + + } + > + {notice_text} + + + + + + + + act('change_rate', { + target: value, + }) + } + /> + + + +
+
+ ); +}; + +const TankCompressorRecords = (props) => { + const { act, data } = useBackend(); + const { records = [], disk } = data; + const [activeRecordRef, setActiveRecordRef] = useSharedState( + 'recordRef', + records[0]?.ref, + ); + const activeRecord = + !!activeRecordRef && + records.find((record) => activeRecordRef === record.ref); + if (records.length === 0) { + return ( + + No Records + + ); + } + + return ( + + + + + {records.map((record) => ( + setActiveRecordRef(record.ref)} + > + {record.name} + + ))} + + + {activeRecord ? ( + + + + {activeRecord.name} + + + {activeRecord.timestamp} + + + {activeRecord.source} + + + + {Object.keys(activeRecord.gases).map((gas_name) => ( + + {(activeRecord.gases[gas_name] + ? activeRecord.gases[gas_name].toFixed(2) + : '-') + ' moles'} + + ))} + + + + + {!data.content_unlocked && ( Buy BYOND premium for more slots! )} - - @@ -168,9 +197,7 @@ export const CharacterPreferenceWindow = (props) => { - - {pageContents} From c77eeb3205670045549f2172015e302069172bf5 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Thu, 20 Jun 2024 09:48:49 +1200 Subject: [PATCH 103/172] Automatic changelog for PR #83989 [ci skip] --- html/changelogs/AutoChangeLog-pr-83989.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83989.yml diff --git a/html/changelogs/AutoChangeLog-pr-83989.yml b/html/changelogs/AutoChangeLog-pr-83989.yml new file mode 100644 index 0000000000000..f6e4deed9933f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83989.yml @@ -0,0 +1,4 @@ +author: "Vishenka0704" +delete-after: True +changes: + - qol: "Ability to delete characters(yourself)" \ No newline at end of file From daa34b9f192c85c49d410da90119018bbb484c54 Mon Sep 17 00:00:00 2001 From: Joshua Kidder <49173900+Metekillot@users.noreply.github.com> Date: Wed, 19 Jun 2024 18:25:34 -0400 Subject: [PATCH 104/172] [no gbp] Sparks don't ignite furniture (unless you made it out of plasma you fucking lunatic), sparks have a decreasing chance to ignite bigger items, small fix to obj/fire_act() signal (#84111) ## About The Pull Request Even though it's hilarious, sparks currently ignite any flammable thing they touch whatsoever; including gigantic wooden/cloth items, or tables and chairs. Turning areas with wooden furnitures into fields of ash wasn't the intent, so I adjusted sparks to not ignite furniture (you can put welding fuel under them if that's your intent) and items bigger than small items have a steadily decreasing chance to get ignited by sparks (normal is 50%, bulky is 20%, bigger than bulky won't ignite only from sparks) ## Why It's Good For The Game Even in a death trap space station of the future, sparks aren't THAT much of a fire hazard. ## Changelog :cl: fix: Sparks will no longer turn areas with wooden furniture or similar into naught but a field of ashes; they no longer ignite furniture, (unless it's made of plasma(?!)) and have a decreasing chance to ignite items bigger than small size. /:cl: --- .../effects/effect_system/effects_sparks.dm | 25 +++++++++++++++---- code/game/objects/obj_defense.dm | 1 + 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/code/game/objects/effects/effect_system/effects_sparks.dm b/code/game/objects/effects/effect_system/effects_sparks.dm index f9bb819fd42a1..c715cc1d7457d 100644 --- a/code/game/objects/effects/effect_system/effects_sparks.dm +++ b/code/game/objects/effects/effect_system/effects_sparks.dm @@ -74,12 +74,27 @@ if(isobj(singed)) var/obj/singed_obj = singed - if(singed_obj.resistance_flags & FLAMMABLE && !(singed_obj.resistance_flags & ON_FIRE)) //only fire_act flammable objects instead of burning EVERYTHING - singed_obj.fire_act(1,100) if(singed_obj.reagents) - var/datum/reagents/reagents = singed_obj.reagents - reagents?.expose_temperature(1000) - return + var/datum/reagents/reagents = singed_obj.reagents // heat up things that contain reagents before we check to see if they burn + reagents?.expose_temperature(1000) // we set this at 1000 because that's the max reagent temp for a chem heater, higher temps require more than sparks + if(singed_obj.custom_materials && (GET_MATERIAL_REF(/datum/material/plasma) in singed_obj.custom_materials)) + singed_obj.fire_act(FIRE_MINIMUM_TEMPERATURE_TO_SPREAD,100) + return // if it's made of plasma we just start burning no matter what, even furniture (see right below) + if(isstructure(singed_obj) || ismachinery(singed_obj)) // don't ignite furniture even if it's flammable, leave that to actual fires + return + if(singed_obj.resistance_flags & FLAMMABLE && !(singed_obj.resistance_flags & ON_FIRE)) //only fire_act flammable objects instead of burning EVERYTHING + if(isitem(singed_obj)) + var/obj/item/singed_item = singed_obj + var/ignite_chance = 120 // base chance applies to anything under WEIGHT_CLASS_NORMAL, so burn everything flammable that's small/tiny + if(singed_item.w_class > WEIGHT_CLASS_SMALL) + var/ignite_chance_penalty = (singed_item.w_class * 2 + round(singed_item.w_class * 0.5)) * 10 // size penalties to ignite chance: normal = 70, bulky = 100, + ignite_chance -= ignite_chance_penalty // the bigger the item, the less likely it is to ignite + if(prob(ignite_chance)) + singed_item.fire_act(FIRE_MINIMUM_TEMPERATURE_TO_SPREAD,100) + return + else + singed_obj.fire_act(FIRE_MINIMUM_TEMPERATURE_TO_SPREAD,100) + return if(isliving(singed)) var/mob/living/singed_living = singed if(singed_living.fire_stacks) diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 9ebcbb253d20b..d07f7ad21c5f5 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -132,6 +132,7 @@ take_damage(clamp(0.02 * exposed_temperature, 0, 20), BURN, FIRE, 0) if(!(resistance_flags & ON_FIRE) && (resistance_flags & FLAMMABLE) && !(resistance_flags & FIRE_PROOF)) AddComponent(/datum/component/burning, custom_fire_overlay || GLOB.fire_overlay, burning_particles) + SEND_SIGNAL(src, COMSIG_ATOM_FIRE_ACT, exposed_temperature, exposed_volume) return TRUE return ..() From cdf36a55547a476510ceb210f28d8ea2948ed91d Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Thu, 20 Jun 2024 10:40:50 +1200 Subject: [PATCH 105/172] Automatic changelog for PR #84111 [ci skip] --- html/changelogs/AutoChangeLog-pr-84111.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84111.yml diff --git a/html/changelogs/AutoChangeLog-pr-84111.yml b/html/changelogs/AutoChangeLog-pr-84111.yml new file mode 100644 index 0000000000000..4b3d8e92bbd00 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84111.yml @@ -0,0 +1,4 @@ +author: "Metekillot" +delete-after: True +changes: + - bugfix: "Sparks will no longer turn areas with wooden furniture or similar into naught but a field of ashes; they no longer ignite furniture, (unless it's made of plasma(?!)) and have a decreasing chance to ignite items bigger than small size." \ No newline at end of file From bb40b65e5b71e834b82521d32cfa41a305934067 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 20 Jun 2024 01:56:16 +0300 Subject: [PATCH 106/172] Compressor UI fix [NO GBP] (#84157) ## About The Pull Request Hotfix for Compressor UI not showing Tank data. Deleted a tag by accident when cleaning up unused variables. ## Why It's Good For The Game Sorry ## Changelog :cl: fix: Fixed new compressor UI /:cl: --- tgui/packages/tgui/interfaces/TankCompressor.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/tgui/packages/tgui/interfaces/TankCompressor.tsx b/tgui/packages/tgui/interfaces/TankCompressor.tsx index 3f516e3c01803..a0d2acc14fb4b 100644 --- a/tgui/packages/tgui/interfaces/TankCompressor.tsx +++ b/tgui/packages/tgui/interfaces/TankCompressor.tsx @@ -70,6 +70,7 @@ const TankCompressorContent = (props) => { return ( +
Date: Thu, 20 Jun 2024 11:05:25 +1200 Subject: [PATCH 107/172] Automatic changelog for PR #84157 [ci skip] --- html/changelogs/AutoChangeLog-pr-84157.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84157.yml diff --git a/html/changelogs/AutoChangeLog-pr-84157.yml b/html/changelogs/AutoChangeLog-pr-84157.yml new file mode 100644 index 0000000000000..721b7fd36b3ef --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84157.yml @@ -0,0 +1,4 @@ +author: "MTandi" +delete-after: True +changes: + - bugfix: "Fixed new compressor UI" \ No newline at end of file From 6d5e5801c3e81d7f976bd4172adf2c8dd5a29588 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Thu, 20 Jun 2024 00:23:07 +0000 Subject: [PATCH 108/172] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-83695.yml | 5 --- html/changelogs/AutoChangeLog-pr-83866.yml | 4 -- html/changelogs/AutoChangeLog-pr-83925.yml | 4 -- html/changelogs/AutoChangeLog-pr-83986.yml | 4 -- html/changelogs/AutoChangeLog-pr-83988.yml | 8 ---- html/changelogs/AutoChangeLog-pr-83989.yml | 4 -- html/changelogs/AutoChangeLog-pr-84006.yml | 5 --- html/changelogs/AutoChangeLog-pr-84067.yml | 4 -- html/changelogs/AutoChangeLog-pr-84071.yml | 4 -- html/changelogs/AutoChangeLog-pr-84074.yml | 6 --- html/changelogs/AutoChangeLog-pr-84099.yml | 4 -- html/changelogs/AutoChangeLog-pr-84104.yml | 4 -- html/changelogs/AutoChangeLog-pr-84108.yml | 4 -- html/changelogs/AutoChangeLog-pr-84109.yml | 4 -- html/changelogs/AutoChangeLog-pr-84111.yml | 4 -- html/changelogs/AutoChangeLog-pr-84116.yml | 5 --- html/changelogs/AutoChangeLog-pr-84120.yml | 4 -- html/changelogs/AutoChangeLog-pr-84123.yml | 4 -- html/changelogs/AutoChangeLog-pr-84124.yml | 4 -- html/changelogs/AutoChangeLog-pr-84157.yml | 4 -- html/changelogs/archive/2024-06.yml | 49 ++++++++++++++++++++++ 21 files changed, 49 insertions(+), 89 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-83695.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83866.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83925.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83986.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83988.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83989.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84006.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84067.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84071.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84074.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84099.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84104.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84108.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84109.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84111.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84116.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84120.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84123.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84124.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84157.yml diff --git a/html/changelogs/AutoChangeLog-pr-83695.yml b/html/changelogs/AutoChangeLog-pr-83695.yml deleted file mode 100644 index 34b0598a26406..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83695.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Ben10Omintrix" -delete-after: True -changes: - - rscadd: "vendrobes may have mothroaches inside them" - - rscadd: "mothroaches will now seek out clothes to eat them" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83866.yml b/html/changelogs/AutoChangeLog-pr-83866.yml deleted file mode 100644 index 77c38213c9f14..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83866.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Absolucy" -delete-after: True -changes: - - qol: "Prettied up the Chemical Analyzer's output in chat, making it easier to read, especially when scanning multiple things." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83925.yml b/html/changelogs/AutoChangeLog-pr-83925.yml deleted file mode 100644 index 7698097a45a3a..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83925.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Rhials" -delete-after: True -changes: - - bugfix: "Fixes a door in the Fredington Fasting Bear Five Nights and Fnafbears map." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83986.yml b/html/changelogs/AutoChangeLog-pr-83986.yml deleted file mode 100644 index d22b2d9744ab2..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83986.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "GPeckman" -delete-after: True -changes: - - bugfix: "The chaplain altar can once again be buckled to." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83988.yml b/html/changelogs/AutoChangeLog-pr-83988.yml deleted file mode 100644 index 90f0a198682e6..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83988.yml +++ /dev/null @@ -1,8 +0,0 @@ -author: "mc-oofert" -delete-after: True -changes: - - bugfix: "wawa centcom interns may actually leave the stationside dock" - - bugfix: "wawa hop office and cap office get keycard auths" - - bugfix: "wawa disposals blast doors work properly" - - bugfix: "wawa med elevator controls on the bottom floor are accessible" - - bugfix: "sci entrance actually has access restrictions" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83989.yml b/html/changelogs/AutoChangeLog-pr-83989.yml deleted file mode 100644 index f6e4deed9933f..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83989.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Vishenka0704" -delete-after: True -changes: - - qol: "Ability to delete characters(yourself)" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84006.yml b/html/changelogs/AutoChangeLog-pr-84006.yml deleted file mode 100644 index 54a31eda940c7..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84006.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SyncIt21" -delete-after: True -changes: - - bugfix: "no more runtimes when dragging turfs onto other stuff" - - code_imp: "most actions now properly check for recursive locs & better adjacency" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84067.yml b/html/changelogs/AutoChangeLog-pr-84067.yml deleted file mode 100644 index 2ab2ff078df5a..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84067.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SyncIt21" -delete-after: True -changes: - - bugfix: "Techfabs now print 5x cable coil" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84071.yml b/html/changelogs/AutoChangeLog-pr-84071.yml deleted file mode 100644 index 766856faa60c8..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84071.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SyncIt21" -delete-after: True -changes: - - bugfix: "You can move around ui buttons in your action bar" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84074.yml b/html/changelogs/AutoChangeLog-pr-84074.yml deleted file mode 100644 index 3ba774dadd0a4..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84074.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "MTandi" -delete-after: True -changes: - - bugfix: "Made 10 MJ & 20 MJ cells properly correspond to tiers 1 & 2 in lathes." - - image: "Updated cell sprites to correspond to other stock parts of their tiers." - - image: "Updated plasma cell, 500KJ cell and 2.5MJ cell sprites" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84099.yml b/html/changelogs/AutoChangeLog-pr-84099.yml deleted file mode 100644 index da8c2a27966e1..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84099.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "MTandi" -delete-after: True -changes: - - qol: "APC has wires for machinery/lights/environment channels" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84104.yml b/html/changelogs/AutoChangeLog-pr-84104.yml deleted file mode 100644 index 580ba6a7626c3..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84104.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "MTandi" -delete-after: True -changes: - - bugfix: "Fixed techweb app showing wrong designs on Details button click" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84108.yml b/html/changelogs/AutoChangeLog-pr-84108.yml deleted file mode 100644 index f2a3935790775..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84108.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "mc-oofert" -delete-after: True -changes: - - bugfix: "gasping makes sound now" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84109.yml b/html/changelogs/AutoChangeLog-pr-84109.yml deleted file mode 100644 index 8297afe62bb77..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84109.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "grungussuss" -delete-after: True -changes: - - bugfix: "mimes can now break their vow while borged or an MMI" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84111.yml b/html/changelogs/AutoChangeLog-pr-84111.yml deleted file mode 100644 index 4b3d8e92bbd00..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84111.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Metekillot" -delete-after: True -changes: - - bugfix: "Sparks will no longer turn areas with wooden furniture or similar into naught but a field of ashes; they no longer ignite furniture, (unless it's made of plasma(?!)) and have a decreasing chance to ignite items bigger than small size." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84116.yml b/html/changelogs/AutoChangeLog-pr-84116.yml deleted file mode 100644 index e11526c56cf50..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84116.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "MTandi" -delete-after: True -changes: - - refactor: "Compressor UI to TypeScript" - - qol: "Simplified Compressor UI layout" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84120.yml b/html/changelogs/AutoChangeLog-pr-84120.yml deleted file mode 100644 index 9c4bcb7fa60f4..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84120.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Rhials" -delete-after: True -changes: - - balance: "The energy bola slowdown has been (roughly) halved, to allow for more retaliation when used on a criminal." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84123.yml b/html/changelogs/AutoChangeLog-pr-84123.yml deleted file mode 100644 index 3d09db30c03b1..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84123.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "LT3" -delete-after: True -changes: - - spellcheck: "Melon fruit bowl now comes with a side of foreshadowing for people who want to experience an explosion of flavour" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84124.yml b/html/changelogs/AutoChangeLog-pr-84124.yml deleted file mode 100644 index 7743692b30a7a..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84124.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "FlufflesTheDog" -delete-after: True -changes: - - bugfix: "limbs that are both robotic and something else can be repaired properly" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84157.yml b/html/changelogs/AutoChangeLog-pr-84157.yml deleted file mode 100644 index 721b7fd36b3ef..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84157.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "MTandi" -delete-after: True -changes: - - bugfix: "Fixed new compressor UI" \ No newline at end of file diff --git a/html/changelogs/archive/2024-06.yml b/html/changelogs/archive/2024-06.yml index c1c7f194b7758..1c03380f14dee 100644 --- a/html/changelogs/archive/2024-06.yml +++ b/html/changelogs/archive/2024-06.yml @@ -843,3 +843,52 @@ by making each tier reduce cooldowns by 25-15-10% for each injector type. jlsnow301: - bugfix: TGUI say will no longer spill your /me contents when you get attacked +2024-06-20: + Absolucy: + - qol: Prettied up the Chemical Analyzer's output in chat, making it easier to read, + especially when scanning multiple things. + Ben10Omintrix: + - rscadd: vendrobes may have mothroaches inside them + - rscadd: mothroaches will now seek out clothes to eat them + FlufflesTheDog: + - bugfix: limbs that are both robotic and something else can be repaired properly + GPeckman: + - bugfix: The chaplain altar can once again be buckled to. + LT3: + - spellcheck: Melon fruit bowl now comes with a side of foreshadowing for people + who want to experience an explosion of flavour + MTandi: + - bugfix: Fixed techweb app showing wrong designs on Details button click + - bugfix: Fixed new compressor UI + - refactor: Compressor UI to TypeScript + - qol: Simplified Compressor UI layout + - bugfix: Made 10 MJ & 20 MJ cells properly correspond to tiers 1 & 2 in lathes. + - image: Updated cell sprites to correspond to other stock parts of their tiers. + - image: Updated plasma cell, 500KJ cell and 2.5MJ cell sprites + - qol: APC has wires for machinery/lights/environment channels + Metekillot: + - bugfix: Sparks will no longer turn areas with wooden furniture or similar into + naught but a field of ashes; they no longer ignite furniture, (unless it's made + of plasma(?!)) and have a decreasing chance to ignite items bigger than small + size. + Rhials: + - bugfix: Fixes a door in the Fredington Fasting Bear Five Nights and Fnafbears + map. + - balance: The energy bola slowdown has been (roughly) halved, to allow for more + retaliation when used on a criminal. + SyncIt21: + - bugfix: Techfabs now print 5x cable coil + - bugfix: no more runtimes when dragging turfs onto other stuff + - code_imp: most actions now properly check for recursive locs & better adjacency + - bugfix: You can move around ui buttons in your action bar + Vishenka0704: + - qol: Ability to delete characters(yourself) + grungussuss: + - bugfix: mimes can now break their vow while borged or an MMI + mc-oofert: + - bugfix: wawa centcom interns may actually leave the stationside dock + - bugfix: wawa hop office and cap office get keycard auths + - bugfix: wawa disposals blast doors work properly + - bugfix: wawa med elevator controls on the bottom floor are accessible + - bugfix: sci entrance actually has access restrictions + - bugfix: gasping makes sound now From 58d6edd8f3da8eabf9946f11ab4d91e373209eef Mon Sep 17 00:00:00 2001 From: r3dj4ck0424 <51569477+r3dj4ck0424@users.noreply.github.com> Date: Thu, 20 Jun 2024 14:31:45 +1200 Subject: [PATCH 109/172] A few minor edits to wawa (#84036) ## About The Pull Request Closes #84022 by adding two tiles under those doors Closes #84021 by moving the fire alarm a few tiles to the left Adds an extra reinforced glass tile to that walkway so the door from the prison showers upper level doesn't send the security guy crashing to the floor below ![Father's Depot Gamma 2024-06-16 180514](https://github.com/tgstation/tgstation/assets/51569477/269d93db-452e-454c-aeb5-8bcf4ec8fe2e) ![Father's Depot Gamma 2024-06-16 180622](https://github.com/tgstation/tgstation/assets/51569477/df8976b7-ad90-4da5-b35a-934d334bc3cd) ## Why It's Good For The Game Closes #84022 and #84021 Makes that specific prison door more useful ## Changelog :cl: fix: puts tiles under the wawa tool storage doors fix: allows you to access a door and a fire alarm on wawa's prison second floor /:cl: --- _maps/map_files/wawastation/wawastation.dmm | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/_maps/map_files/wawastation/wawastation.dmm b/_maps/map_files/wawastation/wawastation.dmm index c02a4b1de4849..693ec5799e2b9 100644 --- a/_maps/map_files/wawastation/wawastation.dmm +++ b/_maps/map_files/wawastation/wawastation.dmm @@ -9539,6 +9539,7 @@ "duB" = ( /obj/structure/cable, /obj/structure/window/reinforced/spawner/directional/west, +/obj/machinery/firealarm/directional/east, /turf/open/floor/iron/dark, /area/station/security/prison) "duS" = ( @@ -22386,10 +22387,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/wood/tile, /area/station/service/bar) -"hWN" = ( -/obj/machinery/firealarm/directional/south, -/turf/open/openspace, -/area/station/security/prison) "hWW" = ( /obj/structure/cable, /obj/effect/landmark/start/atmospheric_technician, @@ -45703,7 +45700,7 @@ /obj/structure/cable, /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/plating, +/turf/open/floor/iron, /area/station/commons/storage/primary) "qmI" = ( /obj/effect/turf_decal/tile/purple/fourcorners, @@ -46634,6 +46631,10 @@ }, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/aisat/teleporter) +"qFS" = ( +/obj/structure/window/reinforced/spawner/directional/south, +/turf/open/floor/glass/reinforced, +/area/station/security/prison) "qGk" = ( /turf/closed/wall/r_wall, /area/station/hallway/secondary/command) @@ -65281,6 +65282,10 @@ /obj/structure/rack, /turf/open/floor/plating, /area/station/asteroid) +"xbr" = ( +/obj/structure/window/reinforced/spawner/directional/west, +/turf/open/floor/glass/reinforced, +/area/station/security/prison) "xbs" = ( /obj/machinery/airalarm/directional/south, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -68155,7 +68160,7 @@ name = "Primary Tool Storage" }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/plating, +/turf/open/floor/iron, /area/station/commons/storage/primary) "ydC" = ( /obj/effect/decal/cleanable/dirt/dust, @@ -151220,9 +151225,9 @@ hHw uRG oyP dAq +xbr +qFS wSc -rwW -hWN jOV vxX vxX From ba61eb7f79460d8fcc00e97d74221bc716951de9 Mon Sep 17 00:00:00 2001 From: lessthanthree <83487515+lessthnthree@users.noreply.github.com> Date: Wed, 19 Jun 2024 19:32:09 -0700 Subject: [PATCH 110/172] Fixes Icebox NanoDrug airlock access (#84027) ## About The Pull Request Fixes the access for the westmost airlock in the medical hallway (the NanoDrug.) The room should have general med with the inner door being restricted to chemistry, same as the East door. ## Why It's Good For The Game Consistent airlock access into a room. ## Changelog :cl: LT3 fix: Fixed paramedics not having access to the Icebox NanoDrug using the west airlock /:cl: --- _maps/map_files/IceBoxStation/IceBoxStation.dmm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index 984cf0ca1298e..644eea8dea0b3 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -23048,7 +23048,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/effect/mapping_helpers/airlock/access/all/medical/chemistry, +/obj/effect/mapping_helpers/airlock/access/all/medical/general, /obj/effect/turf_decal/tile/yellow/full, /turf/open/floor/iron/large, /area/station/medical/treatment_center) @@ -47295,7 +47295,7 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/mapping_helpers/airlock/access/all/medical/chemistry, +/obj/effect/mapping_helpers/airlock/access/all/medical/general, /turf/open/floor/iron/smooth, /area/station/maintenance/department/medical/central) "oiD" = ( From 9ddbe800c2e027a66dbc94bd2dce0fc92298c999 Mon Sep 17 00:00:00 2001 From: Goat <126099705+Goat-Real@users.noreply.github.com> Date: Wed, 19 Jun 2024 20:32:47 -0600 Subject: [PATCH 111/172] Icebox raptor pen radiation proofing (#84055) ## About The Pull Request The raptor pen was using surface areas instead of the proper underground area tiles ## Why It's Good For The Game Shouldn't be hit by radiation since it's not directly part of the station or surface. fix #83917 ## Changelog :cl: Goat fix: Icebox's raptor den is now lined with asbestos and lead and no longer gets hit with radiation. /:cl: --- .../map_files/IceBoxStation/IceBoxStation.dmm | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index 644eea8dea0b3..5092980f2699b 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -3845,7 +3845,7 @@ "bil" = ( /obj/structure/railing/wooden_fence, /turf/open/misc/hay/icemoon, -/area/icemoon/surface) +/area/icemoon/underground/explored) "bin" = ( /obj/effect/turf_decal/stripes/asteroid/line{ dir = 4 @@ -6355,7 +6355,7 @@ dir = 1 }, /turf/open/misc/hay/icemoon, -/area/icemoon/surface) +/area/icemoon/underground/explored) "bPV" = ( /obj/item/kirbyplants/random/dead, /turf/open/floor/plating/snowed/icemoon, @@ -11342,7 +11342,7 @@ /area/icemoon/surface/outdoors/nospawn) "dlu" = ( /turf/closed/wall/mineral/wood/nonmetal, -/area/icemoon/surface) +/area/icemoon/underground/explored) "dlB" = ( /obj/structure/table/wood, /obj/item/storage/photo_album/chapel, @@ -20638,7 +20638,7 @@ dir = 5 }, /turf/open/misc/hay/icemoon, -/area/icemoon/surface) +/area/icemoon/underground/explored) "ghE" = ( /obj/structure/disposalpipe/segment, /obj/machinery/camera/directional/west{ @@ -26929,7 +26929,7 @@ dir = 6 }, /turf/open/misc/hay/icemoon, -/area/icemoon/surface) +/area/icemoon/underground/explored) "idN" = ( /obj/structure/window/reinforced/spawner/directional/north, /obj/machinery/door/window/brigdoor/left/directional/south{ @@ -30551,7 +30551,7 @@ dir = 9 }, /turf/open/misc/hay/icemoon, -/area/icemoon/surface) +/area/icemoon/underground/explored) "jkN" = ( /obj/effect/spawner/random/entertainment/arcade, /obj/machinery/status_display/ai/directional/north, @@ -36851,7 +36851,7 @@ /obj/structure/table/wood, /obj/item/flashlight/lantern/on, /turf/open/misc/hay/icemoon, -/area/icemoon/surface) +/area/icemoon/underground/explored) "kZa" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -40539,7 +40539,7 @@ dir = 10 }, /turf/open/misc/hay/icemoon, -/area/icemoon/surface) +/area/icemoon/underground/explored) "mhq" = ( /obj/structure/closet, /obj/effect/spawner/random/maintenance, @@ -43322,7 +43322,7 @@ }, /obj/item/soap/deluxe, /turf/open/misc/hay/icemoon, -/area/icemoon/surface) +/area/icemoon/underground/explored) "ncB" = ( /obj/machinery/door/airlock/security/glass{ name = "Brig Walkway" @@ -45443,7 +45443,7 @@ "nEI" = ( /obj/item/flashlight/lantern/on, /turf/open/misc/hay/icemoon, -/area/icemoon/surface) +/area/icemoon/underground/explored) "nEV" = ( /obj/machinery/vending/wardrobe/sec_wardrobe, /obj/structure/cable, @@ -53710,7 +53710,7 @@ "qbM" = ( /obj/structure/ore_container/food_trough/raptor_trough, /turf/open/misc/hay/icemoon, -/area/icemoon/surface) +/area/icemoon/underground/explored) "qbO" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -58945,7 +58945,7 @@ }, /obj/item/raptor_dex, /turf/open/misc/hay/icemoon, -/area/icemoon/surface) +/area/icemoon/underground/explored) "rAr" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -59334,7 +59334,7 @@ dir = 4 }, /turf/open/misc/hay/icemoon, -/area/icemoon/surface) +/area/icemoon/underground/explored) "rEp" = ( /obj/structure/table, /obj/item/hand_labeler, @@ -74902,7 +74902,7 @@ /area/station/service/chapel) "wvu" = ( /turf/open/misc/hay/icemoon, -/area/icemoon/surface) +/area/icemoon/underground/explored) "wvv" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -78456,7 +78456,7 @@ dir = 8 }, /turf/open/misc/hay/icemoon, -/area/icemoon/surface) +/area/icemoon/underground/explored) "xxI" = ( /obj/machinery/airalarm/directional/north, /obj/item/kirbyplants/random, From b229a77f0a8f3cd184bf0699217549c69b9d44ee Mon Sep 17 00:00:00 2001 From: projectkepler-RU <99981766+projectkepler-ru@users.noreply.github.com> Date: Thu, 20 Jun 2024 09:33:24 +0700 Subject: [PATCH 112/172] Fix access in the wawa station bridge and replace the empty medkit (#83778) ## About The Pull Request closes #83772 we really should add a unit test to make sure the access on door or whatever actually exist ## Why It's Good For The Game closes #83772 ## Changelog :cl: fix: Wawastation bridge now has the correct access on their suit storage and medkit now actually starts filled /:cl: --- _maps/map_files/wawastation/wawastation.dmm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_maps/map_files/wawastation/wawastation.dmm b/_maps/map_files/wawastation/wawastation.dmm index 693ec5799e2b9..91877afd2c8e8 100644 --- a/_maps/map_files/wawastation/wawastation.dmm +++ b/_maps/map_files/wawastation/wawastation.dmm @@ -59707,7 +59707,7 @@ /area/station/medical/virology) "vay" = ( /obj/structure/table/reinforced, -/obj/item/storage/medkit, +/obj/item/storage/medkit/regular, /obj/effect/turf_decal/tile/dark_blue/half/contrasted{ dir = 1 }, @@ -61857,7 +61857,7 @@ "vQf" = ( /obj/machinery/suit_storage_unit/standard_unit, /obj/machinery/door/window/brigdoor/right/directional/east{ - req_access = list("bridge") + req_access = list("command") }, /obj/effect/turf_decal/bot, /obj/machinery/light/small/dim/directional/west, From be71922bd0f13c22be727330809b5e2ad3c57808 Mon Sep 17 00:00:00 2001 From: jimmyl <70376633+mc-oofert@users.noreply.github.com> Date: Thu, 20 Jun 2024 04:34:24 +0200 Subject: [PATCH 113/172] every engineering lobby starts with a flatpacked flatpacker and multitool (#84107) ## About The Pull Request every engineering lobby starts with a flatpacked flatpacker and multitool ## Why It's Good For The Game flatpackers should be roundstart and they were already but with the new techtree theyre locked behind exp tools this makes them roundstart as intended but limited in quantity per new tech tree, and something traitors could destroy if they wanted ## Changelog :cl: add: every engineering lobby starts with a flatpacked flatpacker and multitool /:cl: --- _maps/map_files/Birdshot/birdshot.dmm | 17 ++++++++----- .../map_files/Deltastation/DeltaStation2.dmm | 9 +++++++ .../map_files/IceBoxStation/IceBoxStation.dmm | 9 +++++-- _maps/map_files/MetaStation/MetaStation.dmm | 13 +++++++--- _maps/map_files/NorthStar/north_star.dmm | 14 ++++++++++- _maps/map_files/tramstation/tramstation.dmm | 7 ++++++ _maps/map_files/wawastation/wawastation.dmm | 9 ++++++- code/game/machinery/flatpacker.dm | 24 ++++++++++++++----- 8 files changed, 83 insertions(+), 19 deletions(-) diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm index e26e63400333f..86dd2443803c4 100644 --- a/_maps/map_files/Birdshot/birdshot.dmm +++ b/_maps/map_files/Birdshot/birdshot.dmm @@ -12780,6 +12780,9 @@ /area/station/security/checkpoint/science) "fnm" = ( /obj/structure/filingcabinet/chestdrawer, +/obj/item/book/manual/wiki/engineering_guide{ + pixel_y = 6 + }, /turf/open/floor/iron/grimy, /area/station/engineering/main) "fnw" = ( @@ -17534,10 +17537,6 @@ /obj/structure/table/greyscale, /obj/item/clothing/gloves/color/yellow, /obj/item/wrench, -/obj/item/multitool{ - pixel_x = 4; - pixel_y = 5 - }, /turf/open/floor/iron/grimy, /area/station/engineering/main) "gUC" = ( @@ -29651,8 +29650,14 @@ pixel_y = 4 }, /obj/machinery/light/small/directional/south, -/obj/item/book/manual/wiki/engineering_guide{ - pixel_y = 4 +/obj/item/flatpack{ + board = /obj/item/circuitboard/machine/flatpacker; + pixel_x = -6; + pixel_y = 5 + }, +/obj/item/multitool{ + pixel_x = 7; + pixel_y = -2 }, /turf/open/floor/iron/grimy, /area/station/engineering/main) diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 57ff65acf22af..f399c25d3b148 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -78577,6 +78577,15 @@ /obj/structure/cable, /obj/machinery/firealarm/directional/east, /obj/effect/decal/cleanable/dirt, +/obj/item/flatpack{ + board = /obj/item/circuitboard/machine/flatpacker; + pixel_x = -6; + pixel_y = 5 + }, +/obj/item/multitool{ + pixel_x = 8 + }, +/obj/structure/table, /turf/open/floor/iron, /area/station/engineering/storage_shared) "tFG" = ( diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index 5092980f2699b..09525a5fa06ec 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -74888,8 +74888,13 @@ /obj/effect/turf_decal/siding/yellow/corner, /obj/machinery/status_display/evac/directional/south, /obj/structure/table, -/obj/effect/spawner/random/trash/food_packaging, -/obj/effect/spawner/random/trash/cigbutt, +/obj/item/flatpack{ + board = /obj/item/circuitboard/machine/flatpacker; + pixel_x = -5 + }, +/obj/item/multitool{ + pixel_x = 8 + }, /turf/open/floor/iron, /area/station/engineering/lobby) "wve" = ( diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index dc42fb3fe9ce6..24c017ab71bd5 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -9215,6 +9215,9 @@ dir = 4 }, /obj/machinery/light/small/directional/north, +/obj/item/lightreplacer{ + pixel_y = 7 + }, /turf/open/floor/iron/dark/corner{ dir = 1 }, @@ -58915,13 +58918,17 @@ "uJz" = ( /obj/effect/turf_decal/bot, /obj/structure/rack, -/obj/item/lightreplacer{ - pixel_y = 7 - }, /obj/machinery/status_display/evac/directional/east, /obj/effect/turf_decal/tile/yellow{ dir = 4 }, +/obj/item/flatpack{ + board = /obj/item/circuitboard/machine/flatpacker; + pixel_x = -5 + }, +/obj/item/multitool{ + pixel_x = 8 + }, /turf/open/floor/iron/checker, /area/station/engineering/storage_shared) "uJB" = ( diff --git a/_maps/map_files/NorthStar/north_star.dmm b/_maps/map_files/NorthStar/north_star.dmm index 3c8cf0e7cb56c..0f9faf9338b6c 100644 --- a/_maps/map_files/NorthStar/north_star.dmm +++ b/_maps/map_files/NorthStar/north_star.dmm @@ -53022,7 +53022,19 @@ /obj/effect/turf_decal/trimline/yellow/corner{ dir = 4 }, -/obj/item/storage/toolbox/mechanical, +/obj/item/storage/toolbox/mechanical{ + pixel_x = 8; + pixel_y = -4 + }, +/obj/item/flatpack{ + board = /obj/item/circuitboard/machine/flatpacker; + pixel_x = -6; + pixel_y = 5 + }, +/obj/item/multitool{ + pixel_x = 7; + pixel_y = 10 + }, /turf/open/floor/iron/corner{ dir = 4 }, diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index b0c8d17c83315..4015dbf2ad35b 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -49386,6 +49386,13 @@ }, /obj/structure/cable, /obj/structure/table, +/obj/item/multitool{ + pixel_x = 8 + }, +/obj/item/flatpack{ + board = /obj/item/circuitboard/machine/flatpacker; + pixel_x = -5 + }, /turf/open/floor/iron, /area/station/engineering/break_room) "qwq" = ( diff --git a/_maps/map_files/wawastation/wawastation.dmm b/_maps/map_files/wawastation/wawastation.dmm index 91877afd2c8e8..17929ae134bf8 100644 --- a/_maps/map_files/wawastation/wawastation.dmm +++ b/_maps/map_files/wawastation/wawastation.dmm @@ -6901,7 +6901,13 @@ /area/station/cargo/storage) "cAy" = ( /obj/structure/table/glass, -/obj/effect/spawner/random/food_or_drink/refreshing_beverage, +/obj/item/flatpack{ + board = /obj/item/circuitboard/machine/flatpacker; + pixel_x = -5 + }, +/obj/item/multitool{ + pixel_x = 8 + }, /turf/open/floor/iron, /area/station/engineering/lobby) "cAC" = ( @@ -39890,6 +39896,7 @@ "omE" = ( /obj/structure/table/glass, /obj/effect/spawner/random/food_or_drink/snack, +/obj/effect/spawner/random/food_or_drink/refreshing_beverage, /turf/open/floor/iron, /area/station/engineering/lobby) "omL" = ( diff --git a/code/game/machinery/flatpacker.dm b/code/game/machinery/flatpacker.dm index 9468dacc24c56..03382dce8d81e 100644 --- a/code/game/machinery/flatpacker.dm +++ b/code/game/machinery/flatpacker.dm @@ -242,7 +242,7 @@ /obj/item/flatpack name = "flatpack" - desc = "A box containing a compacted packed machine. Use multitool to deploy." + desc = "A box containing a compactly packed machine. Use multitool to deploy." icon = 'icons/obj/devices/circuitry_n_data.dmi' icon_state = "flatpack" w_class = WEIGHT_CLASS_HUGE //cart time @@ -253,13 +253,25 @@ /// The board we deploy var/obj/item/circuitboard/machine/board -/obj/item/flatpack/Initialize(mapload, obj/item/circuitboard/machine/board) +/obj/item/flatpack/Initialize(mapload, obj/item/circuitboard/machine/new_board) . = ..() - if(!isnull(board)) - src.board = board // i got board + var/static/list/tool_behaviors + if(!tool_behaviors) + tool_behaviors = string_assoc_nested_list(list( + TOOL_MULTITOOL = list( + SCREENTIP_CONTEXT_LMB = "Deploy", + ), + )) + AddElement(/datum/element/contextual_screentip_tools, tool_behaviors) + if(isnull(board) && isnull(new_board)) + return INITIALIZE_HINT_QDEL //how + + board = !isnull(new_board) ? new_board : new board(src) // i got board + if(board.loc != src) board.forceMove(src) - var/obj/machinery/build = initial(board.build_path) - name += " ([initial(build.name)])" + var/obj/machinery/build = initial(board.build_path) + name += " ([initial(build.name)])" + /obj/item/flatpack/Destroy() QDEL_NULL(board) From e313ee383f766fb692efe15fb9d8a4972a73cd8f Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Thu, 20 Jun 2024 14:37:36 +1200 Subject: [PATCH 114/172] Automatic changelog for PR #84036 [ci skip] --- html/changelogs/AutoChangeLog-pr-84036.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84036.yml diff --git a/html/changelogs/AutoChangeLog-pr-84036.yml b/html/changelogs/AutoChangeLog-pr-84036.yml new file mode 100644 index 0000000000000..1719aafa28b22 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84036.yml @@ -0,0 +1,5 @@ +author: "r3dj4ck0424" +delete-after: True +changes: + - bugfix: "puts tiles under the wawa tool storage doors" + - bugfix: "allows you to access a door and a fire alarm on wawa's prison second floor" \ No newline at end of file From 09fe8194df4c10fa6fc2e99b909c7c45a10cf9fa Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Thu, 20 Jun 2024 14:37:57 +1200 Subject: [PATCH 115/172] Automatic changelog for PR #84027 [ci skip] --- html/changelogs/AutoChangeLog-pr-84027.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84027.yml diff --git a/html/changelogs/AutoChangeLog-pr-84027.yml b/html/changelogs/AutoChangeLog-pr-84027.yml new file mode 100644 index 0000000000000..9af71299e44b8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84027.yml @@ -0,0 +1,4 @@ +author: "LT3" +delete-after: True +changes: + - bugfix: "Fixed paramedics not having access to the Icebox NanoDrug using the west airlock" \ No newline at end of file From 23c71cffe427d5963508fa5347571b44ce153e91 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Thu, 20 Jun 2024 14:37:58 +1200 Subject: [PATCH 116/172] Automatic changelog for PR #84055 [ci skip] --- html/changelogs/AutoChangeLog-pr-84055.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84055.yml diff --git a/html/changelogs/AutoChangeLog-pr-84055.yml b/html/changelogs/AutoChangeLog-pr-84055.yml new file mode 100644 index 0000000000000..0ae2635f1ca8c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84055.yml @@ -0,0 +1,4 @@ +author: "Goat" +delete-after: True +changes: + - bugfix: "Icebox's raptor den is now lined with asbestos and lead and no longer gets hit with radiation." \ No newline at end of file From 9512265649588c4df9d6f8a53ff5b2627f838770 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Thu, 20 Jun 2024 14:38:17 +1200 Subject: [PATCH 117/172] Automatic changelog for PR #83778 [ci skip] --- html/changelogs/AutoChangeLog-pr-83778.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83778.yml diff --git a/html/changelogs/AutoChangeLog-pr-83778.yml b/html/changelogs/AutoChangeLog-pr-83778.yml new file mode 100644 index 0000000000000..8d8d34e39104f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83778.yml @@ -0,0 +1,4 @@ +author: "projectkepler-ru" +delete-after: True +changes: + - bugfix: "Wawastation bridge now has the correct access on their suit storage and medkit now actually starts filled" \ No newline at end of file From a071f97732438bee73e98a467467b8c1310155e3 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Thu, 20 Jun 2024 14:38:37 +1200 Subject: [PATCH 118/172] Automatic changelog for PR #84107 [ci skip] --- html/changelogs/AutoChangeLog-pr-84107.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84107.yml diff --git a/html/changelogs/AutoChangeLog-pr-84107.yml b/html/changelogs/AutoChangeLog-pr-84107.yml new file mode 100644 index 0000000000000..1dda24aba25b0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84107.yml @@ -0,0 +1,4 @@ +author: "mc-oofert" +delete-after: True +changes: + - rscadd: "every engineering lobby starts with a flatpacked flatpacker and multitool" \ No newline at end of file From 5d413f4bec24ddf1d6ad718e3c40d9e7d3151857 Mon Sep 17 00:00:00 2001 From: Xander3359 <66163761+Xander3359@users.noreply.github.com> Date: Wed, 19 Jun 2024 22:48:19 -0400 Subject: [PATCH 119/172] Fix rust heretic not being able to rust walls/floors (#84041) ## About The Pull Request Fix rust heretic not being able to rust walls/floors --- code/game/turfs/turf.dm | 1 - .../spells/spell_types/touch/_touch.dm | 35 ++++++++++++++----- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 515f1513ac754..565adb22dbc00 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -568,7 +568,6 @@ GLOBAL_LIST_EMPTY(station_turfs) if(EXPLODE_LIGHT) SSexplosions.low_mov_atom += movable_thing - /turf/narsie_act(force, ignore_mobs, probability = 20) . = (prob(probability) || force) for(var/I in src) diff --git a/code/modules/spells/spell_types/touch/_touch.dm b/code/modules/spells/spell_types/touch/_touch.dm index 5045ea6522092..1ed5ce49511dd 100644 --- a/code/modules/spells/spell_types/touch/_touch.dm +++ b/code/modules/spells/spell_types/touch/_touch.dm @@ -127,7 +127,8 @@ /datum/action/cooldown/spell/touch/proc/register_hand_signals() SHOULD_CALL_PARENT(TRUE) - RegisterSignal(attached_hand, COMSIG_ITEM_AFTERATTACK, PROC_REF(on_hand_hit)) + RegisterSignal(attached_hand, COMSIG_ITEM_INTERACTING_WITH_ATOM, PROC_REF(on_hand_hit)) + RegisterSignal(attached_hand, COMSIG_ITEM_INTERACTING_WITH_ATOM_SECONDARY, PROC_REF(on_hand_hit_secondary)) RegisterSignal(attached_hand, COMSIG_ITEM_DROPPED, PROC_REF(on_hand_dropped)) RegisterSignal(attached_hand, COMSIG_QDELETING, PROC_REF(on_hand_deleted)) @@ -140,7 +141,8 @@ SHOULD_CALL_PARENT(TRUE) UnregisterSignal(attached_hand, list( - COMSIG_ITEM_AFTERATTACK, + COMSIG_ITEM_INTERACTING_WITH_ATOM, + COMSIG_ITEM_INTERACTING_WITH_ATOM_SECONDARY, COMSIG_ITEM_DROPPED, COMSIG_QDELETING, COMSIG_ITEM_OFFER_TAKEN, @@ -159,21 +161,34 @@ return ..() /** - * Signal proc for [COMSIG_ITEM_AFTERATTACK] from our attached hand. + * Signal proc for [COMSIG_ITEM_INTERACTING_WITH_ATOM] from our attached hand. * * When our hand hits an atom, we can cast do_hand_hit() on them. */ -/datum/action/cooldown/spell/touch/proc/on_hand_hit(datum/source, atom/victim, mob/caster, click_parameters) +/datum/action/cooldown/spell/touch/proc/on_hand_hit(datum/source, mob/living/caster, atom/target, click_parameters) SIGNAL_HANDLER SHOULD_NOT_OVERRIDE(TRUE) // DEFINITELY don't put effects here, put them in cast_on_hand_hit - if(!can_hit_with_hand(victim, caster)) + if(!can_hit_with_hand(target, caster)) return - if(LAZYACCESS(params2list(click_parameters), RIGHT_CLICK)) - INVOKE_ASYNC(src, PROC_REF(do_secondary_hand_hit), source, victim, caster) - else - INVOKE_ASYNC(src, PROC_REF(do_hand_hit), source, victim, caster) + INVOKE_ASYNC(src, PROC_REF(do_hand_hit), source, target, caster) + return ITEM_INTERACT_SUCCESS + +/** + * Signal proc for [COMSIG_ITEM_INTERACTING_WITH_ATOM_SECONDARY] from our attached hand. + * + * When our hand hits an atom, we can cast do_hand_hit() on them. + */ +/datum/action/cooldown/spell/touch/proc/on_hand_hit_secondary(datum/source, mob/living/caster, atom/target, click_parameters) + SIGNAL_HANDLER + SHOULD_NOT_OVERRIDE(TRUE) + + if(!can_hit_with_hand(target, caster)) + return + + INVOKE_ASYNC(src, PROC_REF(do_secondary_hand_hit), source, target, caster) + return ITEM_INTERACT_SUCCESS /// Checks if the passed victim can be cast on by the caster. /datum/action/cooldown/spell/touch/proc/can_hit_with_hand(atom/victim, mob/caster) @@ -206,6 +221,7 @@ log_combat(caster, victim, "cast the touch spell [name] on", hand) spell_feedback(caster) + caster.do_attack_animation(victim) remove_hand(caster) /** @@ -223,6 +239,7 @@ if(SECONDARY_ATTACK_CONTINUE_CHAIN) log_combat(caster, victim, "cast the touch spell [name] on", hand, "(secondary / alt cast)") spell_feedback(caster) + caster.do_attack_animation(victim) remove_hand(caster) // Call normal will call the normal cast proc From b55d3fc87de65137f37fd1ea228581fcb9f7a842 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Thu, 20 Jun 2024 14:48:54 +1200 Subject: [PATCH 120/172] Automatic changelog for PR #84041 [ci skip] --- html/changelogs/AutoChangeLog-pr-84041.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84041.yml diff --git a/html/changelogs/AutoChangeLog-pr-84041.yml b/html/changelogs/AutoChangeLog-pr-84041.yml new file mode 100644 index 0000000000000..f2f0bed84127c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84041.yml @@ -0,0 +1,4 @@ +author: "Xander3359" +delete-after: True +changes: + - bugfix: "Fix rust heretic being unable to rust walls or floors" \ No newline at end of file From 63a31c92468cc59d5c80c2b45a7469df3e2509a8 Mon Sep 17 00:00:00 2001 From: jimmyl <70376633+mc-oofert@users.noreply.github.com> Date: Thu, 20 Jun 2024 07:01:46 +0200 Subject: [PATCH 121/172] [no gbp] wawa floor lights on elevators no longer get destroyed + allows paramed to enter the protolathe room (#83913) ## About The Pull Request wawa floor lights on elevators no longer get destroyed + fixes engi entry wrong access on door ![image](https://github.com/tgstation/tgstation/assets/70376633/bdea7bbe-59ac-4db7-92f4-7066a39ca871) ## Why It's Good For The Game fixes #83888 fixes #83889 ( i think?) ## Changelog :cl: fix: fixed wrong access on one door on wawastation and also made lights on elevators not break (On Wawastation) /:cl: --- _maps/map_files/wawastation/wawastation.dmm | 22 ++++++++------------- code/modules/power/lighting/light.dm | 13 +++++++++--- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/_maps/map_files/wawastation/wawastation.dmm b/_maps/map_files/wawastation/wawastation.dmm index 17929ae134bf8..8bec8ecfae0fd 100644 --- a/_maps/map_files/wawastation/wawastation.dmm +++ b/_maps/map_files/wawastation/wawastation.dmm @@ -9214,7 +9214,7 @@ /area/station/medical/virology) "dpf" = ( /obj/structure/transport/linear/public, -/obj/machinery/light/floor, +/obj/machinery/light/floor/transport, /turf/open/floor/plating/elevatorshaft, /area/station/medical/treatment_center) "dpj" = ( @@ -16057,9 +16057,7 @@ /area/station/security/breakroom) "fLM" = ( /obj/structure/transport/linear/public, -/obj/machinery/light/floor{ - _status_traits = list("underfloor" = list("innate")) - }, +/obj/machinery/light/floor/transport, /turf/open/floor/plating/elevatorshaft, /area/station/cargo/storage) "fLU" = ( @@ -35473,6 +35471,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/effect/mapping_helpers/airlock/access/any/engineering/construction, /turf/open/floor/iron, /area/station/engineering/lobby) "mBY" = ( @@ -49264,7 +49263,6 @@ /turf/open/floor/iron/white, /area/station/medical/treatment_center) "ryG" = ( -/obj/effect/mapping_helpers/airlock/access/any/engineering/maintenance/departmental, /obj/structure/cable, /obj/machinery/door/airlock/engineering/glass{ name = "Break Room" @@ -49273,6 +49271,8 @@ /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/mapping_helpers/airlock/access/any/engineering/general, +/obj/effect/mapping_helpers/airlock/access/any/engineering/construction, /turf/open/floor/iron, /area/station/engineering/break_room) "ryP" = ( @@ -60993,13 +60993,6 @@ /obj/effect/turf_decal/box, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/aisat/foyer) -"vBA" = ( -/obj/machinery/light/floor{ - _status_traits = list("underfloor" = list("innate")) - }, -/obj/structure/transport/linear/public, -/turf/open/floor/plating/elevatorshaft, -/area/station/cargo/storage) "vBD" = ( /obj/structure/chair/office/light{ dir = 1 @@ -61606,6 +61599,7 @@ /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/mapping_helpers/airlock/access/any/engineering/construction, /turf/open/floor/iron, /area/station/engineering/break_room) "vMN" = ( @@ -82693,8 +82687,8 @@ dgR uPg bui yit -yit dpf +yit dKw miD dFY @@ -83678,7 +83672,7 @@ uDB uDB uDB sdc -vBA +fLM soZ jCX jCX diff --git a/code/modules/power/lighting/light.dm b/code/modules/power/lighting/light.dm index 43713cc49ae0c..9d3eb222fb843 100644 --- a/code/modules/power/lighting/light.dm +++ b/code/modules/power/lighting/light.dm @@ -77,12 +77,13 @@ var/fire_power = 0.5 ///The Light colour to use when working in fire alarm status var/fire_colour = COLOR_FIRE_LIGHT_RED - ///Power usage - W per unit of luminosity var/power_consumption_rate = 20 + ///break if moved, if false also makes it ignore if the wall its on breaks + var/break_if_moved = TRUE /obj/machinery/light/Move() - if(status != LIGHT_BROKEN) + if(status != LIGHT_BROKEN && break_if_moved) break_light_tube(TRUE) return ..() @@ -117,7 +118,8 @@ RegisterSignal(src, COMSIG_LIGHT_EATER_ACT, PROC_REF(on_light_eater)) RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) AddElement(/datum/element/atmos_sensitive, mapload) - find_and_hang_on_wall(custom_drop_callback = CALLBACK(src, PROC_REF(knock_down))) + if(break_if_moved) + find_and_hang_on_wall(custom_drop_callback = CALLBACK(src, PROC_REF(knock_down))) /obj/machinery/light/post_machine_initialize() . = ..() @@ -733,3 +735,8 @@ /obj/machinery/light/floor/broken status = LIGHT_BROKEN icon_state = "floor-broken" + +/obj/machinery/light/floor/transport + name = "transport light" + break_if_moved = FALSE + layer = BELOW_OPEN_DOOR_LAYER From 4945059b0472f3a8edc2649b6d86f474806ef6e7 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Thu, 20 Jun 2024 17:02:03 +1200 Subject: [PATCH 122/172] Automatic changelog for PR #83913 [ci skip] --- html/changelogs/AutoChangeLog-pr-83913.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83913.yml diff --git a/html/changelogs/AutoChangeLog-pr-83913.yml b/html/changelogs/AutoChangeLog-pr-83913.yml new file mode 100644 index 0000000000000..e080f9e5aeb4f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83913.yml @@ -0,0 +1,4 @@ +author: "mc-oofert" +delete-after: True +changes: + - bugfix: "fixed wrong access on one door on wawastation and also made lights on elevators not break (On Wawastation)" \ No newline at end of file From 4799324416c8ce9a0061efc6132b70ceab27a5c7 Mon Sep 17 00:00:00 2001 From: ArcaneMusic <41715314+ArcaneMusic@users.noreply.github.com> Date: Thu, 20 Jun 2024 01:12:05 -0400 Subject: [PATCH 123/172] Mild QOL updates to vending machine-cargo interactions. (#83933) ## About The Pull Request This Pull makes a few minor improvements to the features I added with vendor cargo (#81582). Changes are as follows: * Vending machines, when restocked with a refill pack and while containing a number of credits, will play a cash register sound to alert you that there's a payout associated with the action. * The Vending Restock app now works on all modular computer platforms, as opposed to just laptops and tablets. * This is actually hilarious because I even made a screen icon for modular consoles, and it's just been unused ever since merge. * The "cargochat" cargo modular console now has the vendor refill app pre-installed. * Vending machines, when determining their missing inventory during the associated station trait, now adds from 1-5 credits per missing item, up from 0-1. The original number was far too low to feel like a strong incentive based on feedback I'd received, and while still lower than providing a flat percentage of the missing item specifically (we ran some numbers on this a few months back), it should at least incentivize players to keep the station better stocked during regular rounds. Also, the UI now shows a difference between if all vending machines are stocked or not. ![image](https://github.com/tgstation/tgstation/assets/41715314/7ea762a6-25d0-4119-87cc-91c1691ba01d) ## Why It's Good For The Game Most of these are just interfacing and ease of use improvements, as having the app pre-installed in a place where players can actually make some use of it's contents should help to improve it's versatility with regards to the restocking app. Audio feedback is always good. In terms of the balance tweak on the stored value on vending machines, basically it's a way to better incentivize it as an option on the station and to better encourage players to do these kinds of minor upkeep tasks for the crew. ## Changelog :cl: qol: Vending machines now give audio feedback when you restock a vending refill and get a payout. qol: The Restock tracker NTOS app for tracking vending machine contents now works on all consoles, and comes pre-installed on the cargochat cargo computers. balance: Vending machines now offer a bit more credits when missing contents at the start of a round after getting restocked. /:cl: --------- Co-authored-by: Jacquerel Co-authored-by: Jeremiah <42397676+jlsnow301@users.noreply.github.com> --- .../computers/machinery/console_presets.dm | 1 + .../file_system/programs/restock_tracker.dm | 2 +- code/modules/vending/_vending.dm | 3 ++- tgui/packages/tgui/interfaces/RestockTracker.jsx | 10 ++++++++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/code/modules/modular_computers/computers/machinery/console_presets.dm b/code/modules/modular_computers/computers/machinery/console_presets.dm index 0ec80da4bbb29..ad87960603c35 100644 --- a/code/modules/modular_computers/computers/machinery/console_presets.dm +++ b/code/modules/modular_computers/computers/machinery/console_presets.dm @@ -137,6 +137,7 @@ starting_programs += /datum/computer_file/program/bounty_board starting_programs += /datum/computer_file/program/budgetorders starting_programs += /datum/computer_file/program/shipping + starting_programs += /datum/computer_file/program/restock_tracker /obj/machinery/modular_computer/preset/cargochat/cargo/setup_starting_software() var/datum/computer_file/program/chatclient/chatprogram = cpu.find_file_by_name("ntnrc_client") diff --git a/code/modules/modular_computers/file_system/programs/restock_tracker.dm b/code/modules/modular_computers/file_system/programs/restock_tracker.dm index 46462c0c6b531..8f2174ce97bbd 100644 --- a/code/modules/modular_computers/file_system/programs/restock_tracker.dm +++ b/code/modules/modular_computers/file_system/programs/restock_tracker.dm @@ -5,7 +5,7 @@ program_open_overlay = "restock" extended_desc = "Nanotrasen IoT network listing all the vending machines found on station, and how well stocked they are each. Profitable!" program_flags = PROGRAM_ON_NTNET_STORE | PROGRAM_REQUIRES_NTNET - can_run_on_flags = PROGRAM_LAPTOP | PROGRAM_PDA + can_run_on_flags = PROGRAM_ALL size = 4 program_icon = "cash-register" tgui_id = "NtosRestock" diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index 76d193c80e87f..ed6d085abe593 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -271,7 +271,7 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock) */ var/max_amount = rand(CEILING(product_record.amount * 0.5, 1), product_record.amount) product_record.amount = rand(0, max_amount) - credits_contained += rand(0, 1) //randomly add a few credits to the machine to make it look like it's been used, proportional to the amount missing. + credits_contained += rand(1, 5) //randomly add a few credits to the machine to make it look like it's been used, proportional to the amount missing. if(tiltable && prob(6)) // 1 in 17 chance to start tilted (as an additional hint to the station trait behind it) INVOKE_ASYNC(src, PROC_REF(tilt), loc) credits_contained = 0 // If it's tilted, it's been looted, so no credits for you. @@ -1652,6 +1652,7 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock) return var/credits_to_remove = min(CREDITS_DUMP_THRESHOLD, round(credits_contained)) var/obj/item/holochip/holochip = new(loc, credits_to_remove) + playsound(src, 'sound/effects/cashregister.ogg', 40, TRUE) credits_contained = max(0, credits_contained - credits_to_remove) SSblackbox.record_feedback("amount", "vending machine looted", holochip.credits) diff --git a/tgui/packages/tgui/interfaces/RestockTracker.jsx b/tgui/packages/tgui/interfaces/RestockTracker.jsx index 7df606adffcd3..ab6f1d012edf0 100644 --- a/tgui/packages/tgui/interfaces/RestockTracker.jsx +++ b/tgui/packages/tgui/interfaces/RestockTracker.jsx @@ -81,7 +81,17 @@ export const RestockTracker = (props) => { ))} + {vending_list.length === 0 && }
); }; + +export const RestockTrackerFull = (props) => { + const { data } = useBackend(); + return ( +
+ All vending machines stocked! +
+ ); +}; From d184dfaf0b5f984ed455f9ae563a50824c5a9fa1 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Thu, 20 Jun 2024 17:28:12 +1200 Subject: [PATCH 124/172] Automatic changelog for PR #83933 [ci skip] --- html/changelogs/AutoChangeLog-pr-83933.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83933.yml diff --git a/html/changelogs/AutoChangeLog-pr-83933.yml b/html/changelogs/AutoChangeLog-pr-83933.yml new file mode 100644 index 0000000000000..d64620d533ad1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83933.yml @@ -0,0 +1,6 @@ +author: "ArcaneMusic" +delete-after: True +changes: + - qol: "Vending machines now give audio feedback when you restock a vending refill and get a payout." + - qol: "The Restock tracker NTOS app for tracking vending machine contents now works on all consoles, and comes pre-installed on the cargochat cargo computers." + - balance: "Vending machines now offer a bit more credits when missing contents at the start of a round after getting restocked." \ No newline at end of file From 4739cedebc850752cef6add1d60ec2ade7e53d49 Mon Sep 17 00:00:00 2001 From: necromanceranne <40847847+necromanceranne@users.noreply.github.com> Date: Thu, 20 Jun 2024 22:58:21 +1000 Subject: [PATCH 125/172] Event Horizon Anti-Existential Beam Rifle. The ultimate conclusion to the arms race and the sniper's art. (#83934) ## About The Pull Request Replaces the Particle Acceleration Rifle, or the Beam Marksman Rifle, with the Event Horizon Anti-Existential Beam Rifle. In short, it shoots black holes. It takes five cores to make. It pretty much kills everything you point it at and their immediate bystanders as well. You can do this from the relative safety of a whole four screens away thanks to it having a scope. There can only ever be one vortex anomaly made in the round. The recipe, however, always requires the maximum number of cores that can be made in a round. If the number goes up for some reason (maybe someone wants to add more vortex items), so does the total number of cores needed to make an AEBR. ## Why It's Good For The Game Firstly; the beam rifle? Awful. Jank code. Bad performance. Ancient balancing considerations. Just too strong to bring out regularly against specifically blobs, but completely fucking useless against anyone else. So I'm hitting all these problems at once. I reduced a 600 line file to less than 60. I've removed all that bad code. I've also made it specifically unable to combat blobs at all because singularities send blobs off to safety. Secondly; this is maybe the first example of 'more cores = bigger power'. The rifle was already utterly trash to have around, and I just didn't think the way it worked currently could really excite anyone enough to go on a big ol' quest to get it. Solution? You will cause a shuttle call if you get this weapon. ## Changelog :cl: add: Replaces the Particle Acceleration Rifle with the Event Horizon anti-existential beam rifle. It shoots black holes. You can make this in-game. That's right, YOU! balance: Only one vortex anomaly can be made in a round. /:cl: --------- Co-authored-by: Jacquerel --- _maps/deathmatch/arena_station.dmm | 2 +- _maps/virtual_domains/xeno_nest.dmm | 2 +- code/__DEFINES/research/anomalies.dm | 2 +- .../datums/components/crafting/guncrafting.dm | 4 +- .../components/crafting/ranged_weapon.dm | 15 +- .../datums/storage/subtypes/bag_of_holding.dm | 2 +- code/modules/power/cell.dm | 15 - .../{boh_tear.dm => reality_tear.dm} | 35 +- code/modules/projectiles/guns/energy.dm | 17 +- .../projectiles/guns/energy/beam_rifle.dm | 584 +----------------- .../research/designs/weapon_designs.dm | 5 +- tgstation.dme | 2 +- 12 files changed, 86 insertions(+), 599 deletions(-) rename code/modules/power/singularity/{boh_tear.dm => reality_tear.dm} (59%) diff --git a/_maps/deathmatch/arena_station.dmm b/_maps/deathmatch/arena_station.dmm index c7654810360e1..50089df45e8a0 100644 --- a/_maps/deathmatch/arena_station.dmm +++ b/_maps/deathmatch/arena_station.dmm @@ -930,7 +930,7 @@ /area/deathmatch) "LY" = ( /obj/structure/closet/secure_closet, -/obj/item/gun/energy/beam_rifle, +/obj/item/gun/energy/xray, /turf/open/indestructible/vault, /area/deathmatch) "Mc" = ( diff --git a/_maps/virtual_domains/xeno_nest.dmm b/_maps/virtual_domains/xeno_nest.dmm index 907436758c781..65f183d69c401 100644 --- a/_maps/virtual_domains/xeno_nest.dmm +++ b/_maps/virtual_domains/xeno_nest.dmm @@ -140,7 +140,7 @@ /area/ruin/space/has_grav/powered/virtual_domain) "F" = ( /obj/structure/table/greyscale, -/obj/item/gun/energy/beam_rifle, +/obj/item/gun/energy/xray, /obj/item/gun/energy/laser{ pixel_x = 4; pixel_y = -6 diff --git a/code/__DEFINES/research/anomalies.dm b/code/__DEFINES/research/anomalies.dm index db605431c610c..a1e30cd142f00 100644 --- a/code/__DEFINES/research/anomalies.dm +++ b/code/__DEFINES/research/anomalies.dm @@ -2,7 +2,7 @@ #define MAX_CORES_BLUESPACE 3 #define MAX_CORES_GRAVITATIONAL 8 #define MAX_CORES_FLUX 8 -#define MAX_CORES_VORTEX 8 +#define MAX_CORES_VORTEX 1 #define MAX_CORES_PYRO 8 #define MAX_CORES_HALLUCINATION 8 #define MAX_CORES_BIOSCRAMBLER 8 diff --git a/code/datums/components/crafting/guncrafting.dm b/code/datums/components/crafting/guncrafting.dm index 6d4f4713f8bb1..dcf42ee47b1a5 100644 --- a/code/datums/components/crafting/guncrafting.dm +++ b/code/datums/components/crafting/guncrafting.dm @@ -84,8 +84,8 @@ desc = "A suitcase containing the necessary gun parts to tranform a standard energy gun into a temperature gun. Fantastic at birthday parties and killing indigenious populations of lizardpeople." /obj/item/weaponcrafting/gunkit/beam_rifle - name = "particle acceleration rifle part kit (lethal)" - desc = "The coup de grace of guncrafting. This suitcase contains the highly experimental rig for a particle acceleration rifle. Requires an energy gun, a stabilized flux anomaly and a stabilized gravity anomaly." + name = "\improper Event Horizon anti-existential beam rifle part kit (DOOMSDAY DEVICE, DO NOT CONSTRUCT)" + desc = "What fevered minds wrought this terrible construction kit? To create a frame to harness the strange energies that flow through the Spinward Sector towards such horrible acts of violence?" /obj/item/weaponcrafting/gunkit/ebow name = "energy crossbow part kit (less lethal)" diff --git a/code/datums/components/crafting/ranged_weapon.dm b/code/datums/components/crafting/ranged_weapon.dm index b646c4472ed98..666e84964c553 100644 --- a/code/datums/components/crafting/ranged_weapon.dm +++ b/code/datums/components/crafting/ranged_weapon.dm @@ -72,21 +72,18 @@ blacklist += subtypesof(/obj/item/gun/energy/e_gun) /datum/crafting_recipe/beam_rifle - name = "Particle Acceleration Rifle" - result = /obj/item/gun/energy/beam_rifle + name = "Event Horizon Anti-Existential Beam Rifle" + result = /obj/item/gun/energy/event_horizon reqs = list( - /obj/item/gun/energy/e_gun = 1, - /obj/item/assembly/signaler/anomaly/flux = 1, + /obj/item/assembly/signaler/anomaly/flux = 2, /obj/item/assembly/signaler/anomaly/grav = 1, + /obj/item/assembly/signaler/anomaly/vortex = MAX_CORES_VORTEX, + /obj/item/assembly/signaler/anomaly/bluespace = 1, /obj/item/weaponcrafting/gunkit/beam_rifle = 1, ) - time = 10 SECONDS + time = 30 SECONDS //Maybe the delay will make you reconsider your choices category = CAT_WEAPON_RANGED -/datum/crafting_recipe/beam_rifle/New() - ..() - blacklist += subtypesof(/obj/item/gun/energy/e_gun) - /datum/crafting_recipe/ebow name = "Energy Crossbow" result = /obj/item/gun/energy/recharge/ebow/large diff --git a/code/datums/storage/subtypes/bag_of_holding.dm b/code/datums/storage/subtypes/bag_of_holding.dm index a4ea699e42e21..aa812f5d1e007 100644 --- a/code/datums/storage/subtypes/bag_of_holding.dm +++ b/code/datums/storage/subtypes/bag_of_holding.dm @@ -38,7 +38,7 @@ user.investigate_log("has been gibbed by a bag of holding recursive insertion.", INVESTIGATE_DEATHS) user.gib() - var/obj/boh_tear/tear = new(rift_loc) + var/obj/reality_tear/tear = new(rift_loc) tear.start_disaster() qdel(to_insert) qdel(parent) diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index b55593ec913e7..74352134f59f4 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -480,21 +480,6 @@ charge_light_type = null connector_type = "slimecore" -/obj/item/stock_parts/cell/beam_rifle - name = "beam rifle capacitor" - desc = "A high powered capacitor that can provide huge amounts of energy in an instant." - maxcharge = STANDARD_CELL_CHARGE * 50 - chargerate = STANDARD_CELL_RATE * 2.5 //Extremely energy intensive - -/obj/item/stock_parts/cell/beam_rifle/corrupt() - return - -/obj/item/stock_parts/cell/beam_rifle/emp_act(severity) - . = ..() - if(. & EMP_PROTECT_SELF) - return - charge = clamp((charge-(10000/severity)),0,maxcharge) - /obj/item/stock_parts/cell/emergency_light name = "miniature power cell" desc = "A tiny power cell with a very low power capacity. Used in light fixtures to power them in the event of an outage." diff --git a/code/modules/power/singularity/boh_tear.dm b/code/modules/power/singularity/reality_tear.dm similarity index 59% rename from code/modules/power/singularity/boh_tear.dm rename to code/modules/power/singularity/reality_tear.dm index a0089a7c94b35..e43301541a08f 100644 --- a/code/modules/power/singularity/boh_tear.dm +++ b/code/modules/power/singularity/reality_tear.dm @@ -1,4 +1,7 @@ -/obj/boh_tear +/// Tear in the Fabric of Reality /// +// Typically spawned by placing two bags of holding into one another, collapsing into a wandering singularity after a brief period as a stationary singularity. + +/obj/reality_tear name = "tear in the fabric of reality" desc = "As you gaze into the abyss, the only thing you can think is... \"Should I really be this close to it?\"" anchored = TRUE @@ -15,30 +18,36 @@ pixel_y = -32 resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF flags_1 = SUPERMATTER_IGNORES_1 + /// Range that our singularity component consumes objects + var/singularity_consume_range = 1 + /// Ranges that the singularity pulls objects + var/singularity_grav_pull = 21 + /// Time before we begin our bagulo spawn + var/collapse_spawn_time = 9 SECONDS -/obj/boh_tear/proc/start_disaster() +/obj/reality_tear/proc/start_disaster() apply_wibbly_filters(src) playsound(loc, 'sound/effects/clockcult_gateway_disrupted.ogg', vary = 200, extrarange = 3, falloff_exponent = 1, frequency = 0.33, pressure_affected = FALSE, ignore_walls = TRUE, falloff_distance = 7) AddComponent( /datum/component/singularity, \ - consume_range = 1, \ - grav_pull = 21, \ + consume_range = singularity_consume_range, \ + grav_pull = singularity_grav_pull, \ roaming = FALSE, \ singularity_size = STAGE_SIX, \ ) - addtimer(CALLBACK(src, PROC_REF(bagulo_time)), 9 SECONDS, TIMER_DELETE_ME) + addtimer(CALLBACK(src, PROC_REF(reality_collapse)), collapse_spawn_time, TIMER_DELETE_ME) animate(src, time = 7.5 SECONDS, transform = transform.Scale(2), flags = ANIMATION_PARALLEL) animate(time = 2 SECONDS, transform = transform.Scale(0.25), easing = ELASTIC_EASING) animate(time = 0.5 SECONDS, alpha = 0) -/obj/boh_tear/proc/bagulo_time() +/obj/reality_tear/proc/reality_collapse() playsound(loc, 'sound/effects/supermatter.ogg', 200, vary = TRUE, extrarange = 3, falloff_exponent = 1, frequency = 0.5, pressure_affected = FALSE, ignore_walls = TRUE, falloff_distance = 7) var/obj/singularity/bagulo = new(loc) bagulo.expand(STAGE_TWO) bagulo.energy = 400 qdel(src) -/obj/boh_tear/attack_tk(mob/user) +/obj/reality_tear/attack_tk(mob/user) if(!isliving(user)) return var/mob/living/jedi = user @@ -47,3 +56,15 @@ jedi.spawn_dust() addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, attack_hand), jedi), 0.5 SECONDS) return COMPONENT_CANCEL_ATTACK_CHAIN + +//The temporary tears in reality. Collapses into nothing, and has a significantly lower gravity pull range, but consumes more widely. + +/obj/reality_tear/temporary + name = "puncture in the fabric of reality" + desc = "Count your lucky stars that this wasn't anywhere near you." + singularity_consume_range = 2 + singularity_grav_pull = 3 + collapse_spawn_time = 2 SECONDS + +/obj/reality_tear/temporary/reality_collapse() + qdel(src) diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 4c00e83b0bbc6..b977441e9ae11 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -26,14 +26,23 @@ var/single_shot_type_overlay = TRUE ///Should we give an overlay to empty guns? var/display_empty = TRUE - var/selfcharge = 0 - var/charge_timer = 0 - var/charge_delay = 8 + ///whether the gun's cell drains the cyborg user's cell to recharge var/use_cyborg_cell = FALSE ///set to true so the gun is given an empty cell var/dead_cell = FALSE + // Self charging vars + + /// Whether or not our gun charges its own cell on a timer. + var/selfcharge = 0 + /// The amount of time between instances of cell self recharge + var/charge_timer = 0 + /// The amount of seconds_per_tick during process() before the gun charges itself + var/charge_delay = 8 + /// The amount restored by the gun to the cell per self charge tick + var/self_charge_amount = STANDARD_ENERGY_GUN_SELF_CHARGE_RATE + /obj/item/gun/energy/fire_sounds() // What frequency the energy gun's sound will make var/pitch_to_use = 1 @@ -153,7 +162,7 @@ if(charge_timer < charge_delay) return charge_timer = 0 - cell.give(STANDARD_ENERGY_GUN_SELF_CHARGE_RATE * seconds_per_tick) + cell.give(self_charge_amount * seconds_per_tick) if(!chambered) //if empty chamber we try to charge a new shot recharge_newshot(TRUE) update_appearance() diff --git a/code/modules/projectiles/guns/energy/beam_rifle.dm b/code/modules/projectiles/guns/energy/beam_rifle.dm index e29e1ef4878be..0bda1930c6260 100644 --- a/code/modules/projectiles/guns/energy/beam_rifle.dm +++ b/code/modules/projectiles/guns/energy/beam_rifle.dm @@ -1,588 +1,64 @@ - -#define ZOOM_LOCK_AUTOZOOM_FREEMOVE 0 -#define ZOOM_LOCK_AUTOZOOM_ANGLELOCK 1 -#define ZOOM_LOCK_CENTER_VIEW 2 -#define ZOOM_LOCK_OFF 3 - -#define AUTOZOOM_PIXEL_STEP_FACTOR 48 - -#define AIMING_BEAM_ANGLE_CHANGE_THRESHOLD 0.1 - -/obj/item/gun/energy/beam_rifle - name = "particle acceleration rifle" - desc = "An energy-based anti material marksman rifle that uses highly charged particle beams moving at extreme velocities to decimate whatever is unfortunate enough to be targeted by one." - desc_controls = "Hold down left click while scoped to aim, when weapon is fully aimed (Tracer goes from red to green as it charges), release to fire. Moving while aiming or changing where you're pointing at while aiming will delay the aiming process depending on how much you changed." +/obj/item/gun/energy/event_horizon + name = "\improper Event Horizon anti-existential beam rifle" + desc = "The deranged minds of Nanotrasen, in their great hubris and spite, have birthed forth the definitive conclusion to the arms race. Weaponized black holes, and a platform to deliver them.\ + To look upon this existential maleficence is to know that the pursuit of profit has consigned all life to this pathetic conclusion; the destruction of reality itself." icon = 'icons/obj/weapons/guns/energy.dmi' icon_state = "esniper" inhand_icon_state = null worn_icon_state = null fire_sound = 'sound/weapons/beam_sniper.ogg' slot_flags = ITEM_SLOT_BACK - force = 15 + force = 20 //This is maybe the sanest part of this weapon. custom_materials = null - recoil = 4 + recoil = 2 ammo_x_offset = 3 ammo_y_offset = 3 modifystate = FALSE charge_sections = 1 weapon_weight = WEAPON_HEAVY w_class = WEIGHT_CLASS_BULKY - ammo_type = list(/obj/item/ammo_casing/energy/beam_rifle/hitscan) - actions_types = list(/datum/action/item_action/zoom_lock_action) - cell_type = /obj/item/stock_parts/cell/beam_rifle - var/aiming = FALSE - var/aiming_time = 12 - var/aiming_time_fire_threshold = 5 - var/aiming_time_left = 12 - var/aiming_time_increase_user_movement = 3 - var/scoped_slow = 1 - var/aiming_time_increase_angle_multiplier = 0.3 - var/last_process = 0 - - var/lastangle = 0 - var/aiming_lastangle = 0 - var/mob/current_user = null - var/list/obj/effect/projectile/tracer/current_tracers - - var/structure_piercing = 2 //Amount * 2. For some reason structures aren't respecting this unless you have it doubled. Probably with the objects in question's Bump() code instead of this but I'll deal with this later. - var/structure_bleed_coeff = 0.7 - var/wall_pierce_amount = 0 - var/wall_devastate = 0 - var/aoe_structure_range = 1 - var/aoe_structure_damage = 50 - var/aoe_fire_range = 2 - var/aoe_fire_chance = 40 - var/aoe_mob_range = 1 - var/aoe_mob_damage = 30 - var/impact_structure_damage = 60 - var/projectile_damage = 30 - var/projectile_stun = 0 - var/projectile_setting_pierce = TRUE - var/delay = 25 - var/lastfire = 0 - - //ZOOMING - var/zoom_current_view_increase = 0 - ///The radius you want to zoom by - var/zoom_target_view_increase = 9.5 - var/zooming = FALSE - var/zoom_lock = ZOOM_LOCK_OFF - var/zooming_angle - var/current_zoom_x = 0 - var/current_zoom_y = 0 - - var/obj/projectile/beam/beam_rifle/hitscan/aiming_beam/trace = null - -/obj/item/gun/energy/beam_rifle/apply_fantasy_bonuses(bonus) - . = ..() - delay = modify_fantasy_variable("delay", delay, -bonus * 2) - aiming_time = modify_fantasy_variable("aiming_time", aiming_time, -bonus * 2) - recoil = modify_fantasy_variable("recoil", recoil, round(-bonus / 2)) - -/obj/item/gun/energy/beam_rifle/remove_fantasy_bonuses(bonus) - delay = reset_fantasy_variable("delay", delay) - aiming_time = reset_fantasy_variable("aiming_time", aiming_time) - recoil = reset_fantasy_variable("recoil", recoil) - return ..() - -/obj/item/gun/energy/beam_rifle/debug - delay = 0 - cell_type = /obj/item/stock_parts/cell/infinite - aiming_time = 0 - recoil = 0 - pin = /obj/item/firing_pin - -/obj/item/gun/energy/beam_rifle/equipped(mob/user) - set_user(user) - return ..() - -/obj/item/gun/energy/beam_rifle/pickup(mob/user) - set_user(user) - return ..() - -/obj/item/gun/energy/beam_rifle/dropped(mob/user) - set_user() - return ..() - -/obj/item/gun/energy/beam_rifle/ui_action_click(mob/user, actiontype) - if(istype(actiontype, /datum/action/item_action/zoom_lock_action)) - zoom_lock++ - if(zoom_lock > 3) - zoom_lock = 0 - switch(zoom_lock) - if(ZOOM_LOCK_AUTOZOOM_FREEMOVE) - to_chat(user, span_boldnotice("You switch [src]'s zooming processor to free directional.")) - if(ZOOM_LOCK_AUTOZOOM_ANGLELOCK) - to_chat(user, span_boldnotice("You switch [src]'s zooming processor to locked directional.")) - if(ZOOM_LOCK_CENTER_VIEW) - to_chat(user, span_boldnotice("You switch [src]'s zooming processor to center mode.")) - if(ZOOM_LOCK_OFF) - to_chat(user, span_boldnotice("You disable [src]'s zooming system.")) - reset_zooming() - return - - return ..() + ammo_type = list(/obj/item/ammo_casing/energy/event_horizon) + selfcharge = TRUE + self_charge_amount = STANDARD_ENERGY_GUN_SELF_CHARGE_RATE * 10 -/obj/item/gun/energy/beam_rifle/proc/set_autozoom_pixel_offsets_immediate(current_angle) - if(zoom_lock == ZOOM_LOCK_CENTER_VIEW || zoom_lock == ZOOM_LOCK_OFF) - return - current_zoom_x = sin(current_angle) + sin(current_angle) * AUTOZOOM_PIXEL_STEP_FACTOR * zoom_current_view_increase - current_zoom_y = cos(current_angle) + cos(current_angle) * AUTOZOOM_PIXEL_STEP_FACTOR * zoom_current_view_increase - -/obj/item/gun/energy/beam_rifle/proc/handle_zooming() - if(!zooming || !check_user()) - return - current_user.client.view_size.setTo(zoom_target_view_increase) - zoom_current_view_increase = zoom_target_view_increase - set_autozoom_pixel_offsets_immediate(zooming_angle) - -/obj/item/gun/energy/beam_rifle/proc/start_zooming() - if(zoom_lock == ZOOM_LOCK_OFF) - return - zooming = TRUE - -/obj/item/gun/energy/beam_rifle/proc/stop_zooming(mob/user) - if(zooming) - zooming = FALSE - reset_zooming(user) - -/obj/item/gun/energy/beam_rifle/proc/reset_zooming(mob/user) - if(!user) - user = current_user - if(!user || !user.client) - return FALSE - user.client.view_size.zoomIn() - zoom_current_view_increase = 0 - zooming_angle = 0 - current_zoom_x = 0 - current_zoom_y = 0 - -/obj/item/gun/energy/beam_rifle/attack_self(mob/user) - projectile_setting_pierce = !projectile_setting_pierce - balloon_alert(user, "switched to [projectile_setting_pierce ? "pierce":"impact"] mode") - aiming_beam() - -/obj/item/gun/energy/beam_rifle/proc/update_slowdown() - if(aiming) - slowdown = scoped_slow - else - slowdown = initial(slowdown) - -/obj/item/gun/energy/beam_rifle/Initialize(mapload) +/obj/item/gun/energy/event_horizon/Initialize(mapload) . = ..() - fire_delay = delay - current_tracers = list() - START_PROCESSING(SSfastprocess, src) - -/obj/item/gun/energy/beam_rifle/Destroy() - STOP_PROCESSING(SSfastprocess, src) - set_user(null) - QDEL_LIST(current_tracers) - return ..() - -/obj/item/gun/energy/beam_rifle/emp_act(severity) - . = ..() - if(. & EMP_PROTECT_SELF) - return - chambered = null - recharge_newshot() - -/obj/item/gun/energy/beam_rifle/proc/aiming_beam(force_update = FALSE) - var/diff = abs(aiming_lastangle - lastangle) - if(!check_user()) - return - if(diff < AIMING_BEAM_ANGLE_CHANGE_THRESHOLD && !force_update) - return - aiming_lastangle = lastangle - // ONLY ONE at once (since fire can sleep) - if(trace) - QDEL_NULL(trace) - trace = new - trace.gun = src - trace.wall_pierce_amount = wall_pierce_amount - trace.structure_pierce_amount = structure_piercing - trace.do_pierce = projectile_setting_pierce - if(aiming_time) - var/percent = ((100/aiming_time)*aiming_time_left) - trace.color = rgb(255 * percent,255 * ((100 - percent) / 100),0) - else - trace.color = rgb(0, 255, 0) - var/turf/curloc = get_turf(src) - - var/atom/target_atom = current_user.client.mouse_object_ref?.resolve() - var/turf/targloc = get_turf(target_atom) - if(!istype(targloc)) - if(!istype(curloc)) - return - targloc = get_turf_in_angle(lastangle, curloc, 10) - var/mouse_modifiers = params2list(current_user.client.mouseParams) - trace.preparePixelProjectile(targloc, current_user, mouse_modifiers, 0) - trace.fire(lastangle) - trace = null + AddComponent(/datum/component/scope, range_modifier = 4) -/obj/item/gun/energy/beam_rifle/process() - if(!aiming) - last_process = world.time - return - check_user() - handle_zooming() - aiming_time_left = max(0, aiming_time_left - (world.time - last_process)) - aiming_beam(TRUE) - last_process = world.time - -/obj/item/gun/energy/beam_rifle/proc/check_user(automatic_cleanup = TRUE) - if(!istype(current_user) || !isturf(current_user.loc) || !(src in current_user.held_items) || current_user.incapacitated()) //Doesn't work if you're not holding it! - if(automatic_cleanup) - stop_aiming() - return FALSE - return TRUE - -/obj/item/gun/energy/beam_rifle/proc/process_aim(params) - var/angle = mouse_angle_from_client(current_user?.client, params) - current_user.setDir(angle2dir_cardinal(angle)) - var/difference = abs(closer_angle_difference(lastangle, angle)) - delay_penalty(difference * aiming_time_increase_angle_multiplier) - lastangle = angle - -/obj/item/gun/energy/beam_rifle/proc/on_mob_move() - SIGNAL_HANDLER - check_user() - if(aiming) - delay_penalty(aiming_time_increase_user_movement) - process_aim(current_user?.client?.mouseParams) - INVOKE_ASYNC(src, PROC_REF(aiming_beam), TRUE) - -/obj/item/gun/energy/beam_rifle/proc/start_aiming(params) - aiming_time_left = aiming_time - aiming = TRUE - process_aim(params) - aiming_beam(TRUE) - zooming_angle = lastangle - start_zooming() - -/obj/item/gun/energy/beam_rifle/proc/stop_aiming(mob/user) - set waitfor = FALSE - aiming_time_left = aiming_time - aiming = FALSE - QDEL_LIST(current_tracers) - QDEL_NULL(trace) - stop_zooming(user) - -/obj/item/gun/energy/beam_rifle/proc/set_user(mob/user) - if(user == current_user) - return - stop_aiming(current_user) - if(istype(current_user)) - unregister_client_signals(current_user) - UnregisterSignal(current_user, list(COMSIG_MOVABLE_MOVED, COMSIG_MOB_LOGIN, COMSIG_MOB_LOGOUT)) - current_user = null - if(!istype(user)) - return - current_user = user - RegisterSignal(user, COMSIG_MOVABLE_MOVED, PROC_REF(on_mob_move)) - RegisterSignal(user, COMSIG_MOB_LOGIN, PROC_REF(register_client_signals)) - RegisterSignal(user, COMSIG_MOB_LOGOUT, PROC_REF(unregister_client_signals)) - if(user.client) - register_client_signals(user) +/obj/item/gun/energy/event_horizon/process_fire(atom/target, mob/living/user, message, params, zone_override, bonus_spread) -/obj/item/gun/energy/beam_rifle/proc/register_client_signals(mob/source) - SIGNAL_HANDLER - RegisterSignal(source.client, COMSIG_CLIENT_MOUSEDOWN, PROC_REF(on_mouse_down)) - -/obj/item/gun/energy/beam_rifle/proc/unregister_client_signals(mob/source) - SIGNAL_HANDLER - stop_aiming() - if(QDELETED(source.client)) - return - UnregisterSignal(source.client, list(COMSIG_CLIENT_MOUSEDOWN, COMSIG_CLIENT_MOUSEUP, COMSIG_CLIENT_MOUSEDRAG)) - -///change the aiming beam angle to that of the mouse cursor. -/obj/item/gun/energy/beam_rifle/proc/on_mouse_drag(client/source, src_object, over_object, src_location, over_location, src_control, over_control, params) - SIGNAL_HANDLER - if(aiming) - process_aim(params) - INVOKE_ASYNC(src, PROC_REF(aiming_beam)) - if(zoom_lock == ZOOM_LOCK_AUTOZOOM_FREEMOVE) - zooming_angle = lastangle - set_autozoom_pixel_offsets_immediate(zooming_angle) - -///Start aiming and charging the beam -/obj/item/gun/energy/beam_rifle/proc/on_mouse_down(client/source, atom/movable/object, location, control, params) - SIGNAL_HANDLER - if(source.mob.get_active_held_item() != src) - return - if(!object.IsAutoclickable() || (object in source.mob.contents) || (object == source.mob)) + if(!HAS_TRAIT(user, TRAIT_USER_SCOPED)) + balloon_alert(user, "must be scoped!") return - INVOKE_ASYNC(src, PROC_REF(start_aiming), params) - RegisterSignal(source, COMSIG_CLIENT_MOUSEDRAG, PROC_REF(on_mouse_drag)) - RegisterSignal(source, COMSIG_CLIENT_MOUSEUP, PROC_REF(on_mouse_up)) - -///Stop aiming and fire the beam if charged enough -/obj/item/gun/energy/beam_rifle/proc/on_mouse_up(client/source, atom/movable/object, location, control, params) - SIGNAL_HANDLER - if(!object.IsAutoclickable()) - return - process_aim(params) - UnregisterSignal(source, list(COMSIG_CLIENT_MOUSEDRAG, COMSIG_CLIENT_MOUSEUP)) - if(aiming_time_left <= aiming_time_fire_threshold && check_user()) - sync_ammo() - var/atom/target = source.mouse_object_ref?.resolve() - if(target) - INVOKE_ASYNC(src, PROC_REF(try_fire_gun), target, source.mob, source.mouseParams, TRUE) - stop_aiming() - QDEL_LIST(current_tracers) - -/obj/item/gun/energy/beam_rifle/try_fire_gun(atom/target, mob/living/user, params, passthrough = FALSE) - if(user.Adjacent(target)) //It's adjacent, is the user, or is on the user's person - if(target in user.contents) //can't shoot stuff inside us. - return FALSE - if(!ismob(target) || user.combat_mode) //melee attack - return FALSE - if(target == user && user.zone_selected != BODY_ZONE_PRECISE_MOUTH) //so we can't shoot ourselves (unless mouth selected) - return FALSE - if(!passthrough && (aiming_time > aiming_time_fire_threshold)) - return FALSE - if(lastfire > world.time + delay) - return FALSE - if(!..()) - return FALSE - lastfire = world.time - stop_aiming() - return TRUE - -/obj/item/gun/energy/beam_rifle/proc/sync_ammo() - for(var/obj/item/ammo_casing/energy/beam_rifle/AC in contents) - AC.sync_stats() -/obj/item/gun/energy/beam_rifle/proc/delay_penalty(amount) - aiming_time_left = clamp(aiming_time_left + amount, 0, aiming_time) - -/obj/item/ammo_casing/energy/beam_rifle - name = "particle acceleration lens" - desc = "Don't look into barrel!" - var/wall_pierce_amount = 0 - var/wall_devastate = 0 - var/aoe_structure_range = 1 - var/aoe_structure_damage = 30 - var/aoe_fire_range = 2 - var/aoe_fire_chance = 66 - var/aoe_mob_range = 1 - var/aoe_mob_damage = 20 - var/impact_structure_damage = 50 - var/projectile_damage = 40 - var/projectile_stun = 0 - var/structure_piercing = 2 - var/structure_bleed_coeff = 0.7 - var/do_pierce = TRUE - var/obj/item/gun/energy/beam_rifle/host - -/obj/item/ammo_casing/energy/beam_rifle/proc/sync_stats() - var/obj/item/gun/energy/beam_rifle/BR = loc - if(!istype(BR)) - stack_trace("Beam rifle syncing error") - host = BR - do_pierce = BR.projectile_setting_pierce - wall_pierce_amount = BR.wall_pierce_amount - wall_devastate = BR.wall_devastate - aoe_structure_range = BR.aoe_structure_range - aoe_structure_damage = BR.aoe_structure_damage - aoe_fire_range = BR.aoe_fire_range - aoe_fire_chance = BR.aoe_fire_chance - aoe_mob_range = BR.aoe_mob_range - aoe_mob_damage = BR.aoe_mob_damage - impact_structure_damage = BR.impact_structure_damage - projectile_damage = BR.projectile_damage - projectile_stun = BR.projectile_stun - delay = BR.delay - structure_piercing = BR.structure_piercing - structure_bleed_coeff = BR.structure_bleed_coeff - -/obj/item/ammo_casing/energy/beam_rifle/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") . = ..() - var/obj/projectile/beam/beam_rifle/hitscan/HS_BB = loaded_projectile - if(!istype(HS_BB)) - return - HS_BB.impact_direct_damage = projectile_damage - HS_BB.stun = projectile_stun - HS_BB.impact_structure_damage = impact_structure_damage - HS_BB.aoe_mob_damage = aoe_mob_damage - HS_BB.aoe_mob_range = clamp(aoe_mob_range, 0, 15) //Badmin safety lock - HS_BB.aoe_fire_chance = aoe_fire_chance - HS_BB.aoe_fire_range = aoe_fire_range - HS_BB.aoe_structure_damage = aoe_structure_damage - HS_BB.aoe_structure_range = clamp(aoe_structure_range, 0, 15) //Badmin safety lock - HS_BB.wall_devastate = wall_devastate - HS_BB.wall_pierce_amount = wall_pierce_amount - HS_BB.structure_pierce_amount = structure_piercing - HS_BB.structure_bleed_coeff = structure_bleed_coeff - HS_BB.do_pierce = do_pierce - HS_BB.gun = host - -/obj/item/ammo_casing/energy/beam_rifle/throw_proj(atom/target, turf/targloc, mob/living/user, params, spread, atom/fired_from) - var/turf/curloc = get_turf(user) - if(!istype(curloc) || !loaded_projectile) - return FALSE - var/obj/item/gun/energy/beam_rifle/gun = loc - if(!targloc && gun) - targloc = get_turf_in_angle(gun.lastangle, curloc, 10) - else if(!targloc) - return FALSE - var/firing_dir - if(loaded_projectile.firer) - firing_dir = loaded_projectile.firer.dir - if(!loaded_projectile.suppressed && firing_effect_type) - new firing_effect_type(get_turf(src), firing_dir) - var/modifiers = params2list(params) - loaded_projectile.preparePixelProjectile(target, user, modifiers, spread) - loaded_projectile.fire(gun? gun.lastangle : null, null) - loaded_projectile = null - return TRUE + message_admins("[ADMIN_LOOKUPFLW(user)] has fired an anti-existential beam at [ADMIN_VERBOSEJMP(user)].") -/obj/item/ammo_casing/energy/beam_rifle/hitscan - projectile_type = /obj/projectile/beam/beam_rifle/hitscan - select_name = "beam" - e_cost = LASER_SHOTS(5, 50000) // Beam rifle has a custom cell +/obj/item/ammo_casing/energy/event_horizon + projectile_type = /obj/projectile/beam/event_horizon + select_name = "doomsday" + e_cost = LASER_SHOTS(1, STANDARD_CELL_CHARGE) fire_sound = 'sound/weapons/beam_sniper.ogg' -/obj/projectile/beam/beam_rifle - name = "particle beam" +/obj/projectile/beam/event_horizon + name = "anti-existential beam" icon = null hitsound = 'sound/effects/explosion3.ogg' - damage = 0 //Handled manually. + damage = 100 // Does it matter? damage_type = BURN armor_flag = ENERGY range = 150 jitter = 20 SECONDS - var/obj/item/gun/energy/beam_rifle/gun - var/structure_pierce_amount = 0 //All set to 0 so the gun can manually set them during firing. - var/structure_bleed_coeff = 0 - var/structure_pierce = 0 - var/do_pierce = TRUE - var/wall_pierce_amount = 0 - var/wall_pierce = 0 - var/wall_devastate = 0 - var/aoe_structure_range = 0 - var/aoe_structure_damage = 0 - var/aoe_fire_range = 0 - var/aoe_fire_chance = 0 - var/aoe_mob_range = 0 - var/aoe_mob_damage = 0 - var/impact_structure_damage = 0 - var/impact_direct_damage = 0 - var/list/pierced = list() - -/obj/projectile/beam/beam_rifle/proc/AOE(turf/epicenter) - if(!epicenter) - return - new /obj/effect/temp_visual/explosion/fast(epicenter) - for(var/mob/living/L in range(aoe_mob_range, epicenter)) //handle aoe mob damage - L.adjustFireLoss(aoe_mob_damage) - to_chat(L, span_userdanger("\The [src] sears you!")) - for(var/turf/T in RANGE_TURFS(aoe_fire_range, epicenter)) //handle aoe fire - if(prob(aoe_fire_chance)) - new /obj/effect/hotspot(T) - for(var/obj/O in range(aoe_structure_range, epicenter)) - if(!isitem(O)) - O.take_damage(aoe_structure_damage * get_damage_coeff(O), BURN, LASER, FALSE) - -/obj/projectile/beam/beam_rifle/prehit_pierce(atom/A) - if(isclosedturf(A) && (wall_pierce < wall_pierce_amount)) - if(prob(wall_devastate)) - if(iswallturf(A)) - var/turf/closed/wall/W = A - W.dismantle_wall(TRUE, TRUE) - else - SSexplosions.medturf += A - ++wall_pierce - return PROJECTILE_PIERCE_PHASE // yeah this gun is a snowflakey piece of garbage - if(isobj(A) && (structure_pierce < structure_pierce_amount)) - ++structure_pierce - var/obj/O = A - O.take_damage((impact_structure_damage + aoe_structure_damage) * structure_bleed_coeff * get_damage_coeff(A), BURN, ENERGY, FALSE) - return PROJECTILE_PIERCE_PHASE // ditto and this could be refactored to on_hit honestly - return ..() - -/obj/projectile/beam/beam_rifle/proc/get_damage_coeff(atom/target) - if(istype(target, /obj/machinery/door)) - return 0.4 - if(istype(target, /obj/structure/window)) - return 0.5 - return 1 - -/obj/projectile/beam/beam_rifle/proc/handle_impact(atom/target) - if(isobj(target)) - var/obj/O = target - O.take_damage(impact_structure_damage * get_damage_coeff(target), BURN, LASER, FALSE) - if(isliving(target)) - var/mob/living/L = target - L.adjustFireLoss(impact_direct_damage) - L.emote("scream") - -/obj/projectile/beam/beam_rifle/proc/handle_hit(atom/target, piercing_hit = FALSE) - set waitfor = FALSE - if(!is_hostile_projectile()) - return FALSE - playsound(src, 'sound/effects/explosion3.ogg', 100, TRUE) - if(!do_pierce) - AOE(get_turf(target) || get_turf(src)) - if(!QDELETED(target)) - handle_impact(target) - -/obj/projectile/beam/beam_rifle/on_hit(atom/target, blocked = 0, pierce_hit) - handle_hit(target, pierce_hit) - return ..() - -/obj/projectile/beam/beam_rifle/is_hostile_projectile() - return TRUE // on hit = boom fire - -/obj/projectile/beam/beam_rifle/hitscan - icon_state = "" hitscan = TRUE tracer_type = /obj/effect/projectile/tracer/tracer/beam_rifle - var/constant_tracer = FALSE -/obj/projectile/beam/beam_rifle/hitscan/generate_hitscan_tracers(cleanup = TRUE, duration = 5, impacting = TRUE, highlander) - set waitfor = FALSE - if(isnull(highlander)) - highlander = constant_tracer - if(highlander && istype(gun)) - QDEL_LIST(gun.current_tracers) - for(var/datum/point/p in beam_segments) - gun.current_tracers += generate_tracer_between_points(p, beam_segments[p], tracer_type, color, 0, hitscan_light_range, hitscan_light_color_override, hitscan_light_intensity) - else - for(var/datum/point/p in beam_segments) - generate_tracer_between_points(p, beam_segments[p], tracer_type, color, duration, hitscan_light_range, hitscan_light_color_override, hitscan_light_intensity) - if(cleanup) - QDEL_LIST(beam_segments) - beam_segments = null - QDEL_NULL(beam_index) - -/obj/projectile/beam/beam_rifle/hitscan/aiming_beam - tracer_type = /obj/effect/projectile/tracer/tracer/aiming - name = "aiming beam" - hitsound = null - hitsound_wall = null - damage = 0 - constant_tracer = TRUE - hitscan_light_range = 0 - hitscan_light_intensity = 0 - hitscan_light_color_override = "#99ff99" - reflectable = REFLECT_FAKEPROJECTILE - -/obj/projectile/beam/beam_rifle/hitscan/aiming_beam/is_hostile_projectile() - return FALSE // just an aiming reticle - -/obj/projectile/beam/beam_rifle/hitscan/aiming_beam/prehit_pierce(atom/target) - return PROJECTILE_DELETE_WITHOUT_HITTING +/obj/projectile/beam/event_horizon/on_hit(atom/target, blocked, pierce_hit) + . = ..() -/obj/projectile/beam/beam_rifle/hitscan/aiming_beam/on_hit(atom/target, blocked = 0, pierce_hit) - SHOULD_CALL_PARENT(FALSE) // This is some snowflake stuff so whatever - qdel(src) - return BULLET_ACT_BLOCK + // Where we droppin' boys? + var/turf/rift_loc = get_turf(target) -#undef AIMING_BEAM_ANGLE_CHANGE_THRESHOLD -#undef AUTOZOOM_PIXEL_STEP_FACTOR -#undef ZOOM_LOCK_AUTOZOOM_ANGLELOCK -#undef ZOOM_LOCK_AUTOZOOM_FREEMOVE -#undef ZOOM_LOCK_CENTER_VIEW -#undef ZOOM_LOCK_OFF + // Spawn our temporary rift, then activate it. + var/obj/reality_tear/temporary/tear = new(rift_loc) + tear.start_disaster() + message_admins("[ADMIN_LOOKUPFLW(target)] has been hit by an anti-existential beam at [ADMIN_VERBOSEJMP(rift_loc)], creating a singularity.") diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index 00c7dba3946bd..35d95d82d3047 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -218,8 +218,8 @@ autolathe_exportable = FALSE /datum/design/beamrifle - name = "Beam Marksman Rifle Part Kit (Lethal)" - desc = "The gunkit for a powerful long ranged anti-material rifle that fires charged particle beams to obliterate targets." + name = "Event Horizon Anti-Existential Beam Rifle Part Kit (DOOMSDAY DEVICE)" + desc = "The kit that produces a weapon made to end your foes on an existential level. Why the fuck can you make this?" id = "beamrifle" build_type = PROTOLATHE | AWAY_LATHE materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 5, /datum/material/glass =SHEET_MATERIAL_AMOUNT * 2.5, /datum/material/diamond =SHEET_MATERIAL_AMOUNT * 2.5, /datum/material/uranium = SHEET_MATERIAL_AMOUNT * 4, /datum/material/silver = SHEET_MATERIAL_AMOUNT * 2.25, /datum/material/gold =SHEET_MATERIAL_AMOUNT * 2.5) @@ -230,7 +230,6 @@ departmental_flags = DEPARTMENT_BITFLAG_SECURITY autolathe_exportable = FALSE - /datum/design/rapidsyringe name = "Rapid Syringe Gun" desc = "A gun that fires many syringes." diff --git a/tgstation.dme b/tgstation.dme index f3bdadf367d85..94efbba308232 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -5364,12 +5364,12 @@ #include "code\modules\power\lighting\light_items.dm" #include "code\modules\power\lighting\light_mapping_helpers.dm" #include "code\modules\power\lighting\light_wallframes.dm" -#include "code\modules\power\singularity\boh_tear.dm" #include "code\modules\power\singularity\containment_field.dm" #include "code\modules\power\singularity\dark_matter_singularity.dm" #include "code\modules\power\singularity\emitter.dm" #include "code\modules\power\singularity\field_generator.dm" #include "code\modules\power\singularity\narsie.dm" +#include "code\modules\power\singularity\reality_tear.dm" #include "code\modules\power\singularity\singularity.dm" #include "code\modules\power\supermatter\supermatter.dm" #include "code\modules\power\supermatter\supermatter_extra_effects.dm" From 0ecbf899ecf9ded02740c5e86c99ab01bc55ac8c Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Fri, 21 Jun 2024 00:58:41 +1200 Subject: [PATCH 126/172] Automatic changelog for PR #83934 [ci skip] --- html/changelogs/AutoChangeLog-pr-83934.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83934.yml diff --git a/html/changelogs/AutoChangeLog-pr-83934.yml b/html/changelogs/AutoChangeLog-pr-83934.yml new file mode 100644 index 0000000000000..ad3574f8f8cb2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83934.yml @@ -0,0 +1,5 @@ +author: "necromanceranne" +delete-after: True +changes: + - rscadd: "Replaces the Particle Acceleration Rifle with the Event Horizon anti-existential beam rifle. It shoots black holes. You can make this in-game. That's right, YOU!" + - balance: "Only one vortex anomaly can be made in a round." \ No newline at end of file From 24908564f1fd5cae2135ec3775c5344c7f8c4d8b Mon Sep 17 00:00:00 2001 From: _0Steven <42909981+00-Steven@users.noreply.github.com> Date: Thu, 20 Jun 2024 18:48:40 +0200 Subject: [PATCH 127/172] Refactors card attackby chains into item_interaction (#84106) ## About The Pull Request Funnily enough I was already working on this before shit broke, but here we go. This is mostly just the same behaviour but ported to `item_interaction(...)`. Primary changes include splitting off ID recoloring into its own method for clarity, adding more sanity checks when using tgui windows, and slightly improving the comprehensibility of genpop prisoner id interactions (proper time text instead of seconds, actual usage descs). ## Why It's Good For The Game Better to use `item_interaction(...)` than `attackby(...)`. Fixes an interaction bug introduced by the recent afterattack refactor. Nice to have a better idea of how to use genpop. ## Changelog :cl: refactor: Updated cards/ids to use the proper item interaction system instead of attackby, please report any issues. fix: You can no longer recolour an ID at any point if you open the menu but then don't select anything until later. fix: ID cards can be recoloured using crayons/spraycans again. qol: Prisoner IDs show genpop sentence time in hours/minutes/seconds instead of seconds. qol: Prisoner IDs have genpop usage tips in their examine. /:cl: --- code/game/objects/items/cards_ids.dm | 123 +++++++++++++++++---------- 1 file changed, 80 insertions(+), 43 deletions(-) diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index c43f32daacbdf..5dc826e8fd51e 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -552,26 +552,26 @@ if(ispath(trim)) SSid_access.apply_trim_to_card(src, trim) -/obj/item/card/id/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/rupee)) +/obj/item/card/id/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(istype(tool, /obj/item/rupee)) to_chat(user, span_warning("Your ID smartly rejects the strange shard of glass. Who knew, apparently it's not ACTUALLY valuable!")) - return - else if(iscash(W)) - insert_money(W, user) - return - else if(istype(W, /obj/item/storage/bag/money)) - var/obj/item/storage/bag/money/money_bag = W + return ITEM_INTERACT_BLOCKING + else if(iscash(tool)) + return insert_money(tool, user) ? ITEM_INTERACT_SUCCESS : ITEM_INTERACT_BLOCKING + else if(istype(tool, /obj/item/storage/bag/money)) + var/obj/item/storage/bag/money/money_bag = tool var/list/money_contained = money_bag.contents var/money_added = mass_insert_money(money_contained, user) - if (money_added) - to_chat(user, span_notice("You stuff the contents into the card! They disappear in a puff of bluespace smoke, adding [money_added] worth of credits to the linked account.")) - return - else - return ..() + if(!money_added) + return ITEM_INTERACT_BLOCKING + to_chat(user, span_notice("You stuff the contents into the card! They disappear in a puff of bluespace smoke, adding [money_added] worth of credits to the linked account.")) + return ITEM_INTERACT_SUCCESS + return NONE /** * Insert credits or coins into the ID card and add their value to the associated bank account. * + * Returns TRUE if the money was successfully inserted, FALSE otherwise. * Arguments: * money - The item to attempt to convert to credits and insert into the card. * user - The user inserting the item. @@ -584,11 +584,11 @@ if(!registered_account) to_chat(user, span_warning("[src] doesn't have a linked account to deposit [money] into!")) - return + return FALSE var/cash_money = money.get_item_credit_value() if(!cash_money) to_chat(user, span_warning("[money] doesn't seem to be worth anything!")) - return + return FALSE registered_account.adjust_money(cash_money, "System: Deposit") SSblackbox.record_feedback("amount", "credits_inserted", cash_money) log_econ("[cash_money] credits were inserted into [src] owned by [src.registered_name]") @@ -599,6 +599,7 @@ to_chat(user, span_notice("The linked account now reports a balance of [registered_account.account_balance] cr.")) qdel(money) + return TRUE /** * Insert multiple money or money-equivalent items at once. @@ -953,20 +954,41 @@ return ..() - -/obj/item/card/id/advanced/attackby(obj/item/W, mob/user, params) +/obj/item/card/id/advanced/item_interaction(mob/living/user, obj/item/tool, list/modifiers) . = ..() - if(istype(W, /obj/item/toy/crayon)) - var/obj/item/toy/crayon/our_crayon = W - if(tgui_alert(usr, "Recolor Department or Subdepartment?", "Recoloring ID...", list("Department", "Subdepartment")) == "Department") - if(!do_after(user, 2 SECONDS)) // Doesn't technically require a spraycan's cap to be off but shhh - return + if(.) + return . + + if(istype(tool, /obj/item/toy/crayon)) + return recolor_id(user, tool) + +/obj/item/card/id/advanced/proc/recolor_id(mob/living/user, obj/item/toy/crayon/our_crayon) + if(our_crayon.is_capped) + balloon_alert(user, "take the cap off first!") + return ITEM_INTERACT_BLOCKING + var/choice = tgui_alert(usr, "Recolor Department or Subdepartment?", "Recoloring ID...", list("Department", "Subdepartment")) + if(isnull(choice) \ + || QDELETED(user) \ + || QDELETED(src) \ + || QDELETED(our_crayon) \ + || !usr.can_perform_action(src, ALLOW_RESTING) \ + || !usr.can_perform_action(our_crayon, ALLOW_RESTING) \ + ) + return ITEM_INTERACT_BLOCKING + + switch(choice) + if("Department") + if(!do_after(user, 2 SECONDS)) + return ITEM_INTERACT_BLOCKING department_color_override = our_crayon.paint_color balloon_alert(user, "recolored") - else if(do_after(user, 1 SECONDS)) + if("Subdepartment") + if(!do_after(user, 1 SECONDS)) + return ITEM_INTERACT_BLOCKING subdepartment_color_override = our_crayon.paint_color balloon_alert(user, "recolored") - update_icon() + update_icon() + return ITEM_INTERACT_SUCCESS /obj/item/card/id/advanced/proc/update_intern_status(datum/source, mob/user, slot) SIGNAL_HANDLER @@ -1275,27 +1297,38 @@ /// Time left on a card till they can leave. var/time_left = 0 -/obj/item/card/id/advanced/prisoner/attackby(obj/item/card/id/C, mob/user) - ..() - var/list/id_access = C.GetAccess() +/obj/item/card/id/advanced/prisoner/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + . = ..() + if(.) + return . + + if(isidcard(tool)) + return set_sentence_time(user, tool) + +/obj/item/card/id/advanced/prisoner/proc/set_sentence_time(mob/living/user, obj/item/card/id/our_card) + var/list/id_access = our_card.GetAccess() if(!(ACCESS_BRIG in id_access)) - return FALSE - if(loc != user) + balloon_alert(user, "access denied!") + return ITEM_INTERACT_BLOCKING + if(!user.is_holding(src)) to_chat(user, span_warning("You must be holding the ID to continue!")) - return FALSE - if(timed) + return ITEM_INTERACT_BLOCKING + + if(timed) // If we already have a time set, reset the card timed = FALSE time_to_assign = initial(time_to_assign) registered_name = initial(registered_name) STOP_PROCESSING(SSobj, src) - to_chat(user, "Restating prisoner ID to default parameters.") - return + to_chat(user, "Resetting prisoner ID to default parameters.") + return ITEM_INTERACT_SUCCESS + var/choice = tgui_input_number(user, "Sentence time in seconds", "Sentencing") - if(!choice || QDELETED(user) || QDELETED(src) || !usr.can_perform_action(src, FORBID_TELEKINESIS_REACH) || loc != user) - return FALSE + if(isnull(choice) || QDELETED(user) || QDELETED(src) || !user.can_perform_action(src, FORBID_TELEKINESIS_REACH) || !user.is_holding(src)) + return ITEM_INTERACT_BLOCKING time_to_assign = choice - to_chat(user, "You set the sentence time to [time_to_assign] seconds.") + to_chat(user, "You set the sentence time to [DisplayTimeText(time_to_assign * 10)].") timed = TRUE + return ITEM_INTERACT_SUCCESS /obj/item/card/id/advanced/prisoner/proc/start_timer() say("Sentence started, welcome to the corporate rehabilitation center!") @@ -1307,10 +1340,15 @@ return if(timed) - if(time_left <= 0) + if(time_to_assign > 0) + . += span_notice("The digital timer on the card is set to [DisplayTimeText(time_to_assign * 10)]. The timer will start once the prisoner passes through the prison gate scanners.") + else if(time_left <= 0) . += span_notice("The digital timer on the card has zero seconds remaining. You leave a changed man, but a free man nonetheless.") else - . += span_notice("The digital timer on the card has [time_left] seconds remaining. Don't do the crime if you can't do the time.") + . += span_notice("The digital timer on the card has [DisplayTimeText(time_left * 10)] remaining. Don't do the crime if you can't do the time.") + + . += span_notice("[EXAMINE_HINT("Swipe")] a security ID on the card to [timed ? "re" : ""]set the genpop sentence time.") + . += span_notice("Remember to [EXAMINE_HINT("swipe")] the card on a genpop locker to link it.") /obj/item/card/id/advanced/prisoner/process(seconds_per_tick) if(!timed) @@ -1761,11 +1799,10 @@ voice_name += " (as [scribbled_name])" stored_name[NAME_PART_INDEX] = voice_name -/obj/item/card/cardboard/attackby(obj/item/item, mob/living/user, params) - if(user.can_write(item, TRUE)) - INVOKE_ASYNC(src, PROC_REF(modify_card), user, item) - return TRUE - return ..() +/obj/item/card/cardboard/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(user.can_write(tool, TRUE)) + INVOKE_ASYNC(src, PROC_REF(modify_card), user, tool) + return ITEM_INTERACT_SUCCESS ///Lets the user write a name, assignment or trim on the card, or reset it. Only the name is important for the component. /obj/item/card/cardboard/proc/modify_card(mob/living/user, obj/item/item) From d8865327e8d208f183036f20ccac7d35411ef1fb Mon Sep 17 00:00:00 2001 From: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Date: Thu, 20 Jun 2024 22:21:26 +0530 Subject: [PATCH 128/172] Broken APC's turn off area power (#84136) ## About The Pull Request - Fixes #84064 - Closes #83392(doesn't occur upstream but should help downstream if they have the problem) ## Changelog :cl: fix: breaking an APC will depower the area /:cl: --- code/modules/power/apc/apc_attack.dm | 18 +--------- code/modules/power/apc/apc_main.dm | 50 +++++++++++++++++++--------- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/code/modules/power/apc/apc_attack.dm b/code/modules/power/apc/apc_attack.dm index 8c9715f1dcb1c..50f10c47e33c1 100644 --- a/code/modules/power/apc/apc_attack.dm +++ b/code/modules/power/apc/apc_attack.dm @@ -85,7 +85,7 @@ return /obj/machinery/power/apc/blob_act(obj/structure/blob/B) - set_broken() + atom_break() /obj/machinery/power/apc/take_damage(damage_amount, damage_type = BRUTE, damage_flag = "", sound_effect = TRUE, attack_dir, armor_penetration = 0) // APC being at 0 integrity doesnt delete it outright. Combined with take_damage this might cause runtimes. @@ -100,11 +100,6 @@ return damage_amount . = ..() -/obj/machinery/power/apc/atom_break(damage_flag) - . = ..() - if(.) - set_broken() - /obj/machinery/power/apc/proc/can_use(mob/user, loud = 0) //used by attack_hand() and Topic() if(isAdminGhostAI(user)) return TRUE @@ -120,17 +115,6 @@ balloon_alert(user, "it's disabled!") return . -/obj/machinery/power/apc/proc/set_broken() - if(machine_stat & BROKEN) - return - if(malfai && operating) - malfai.malf_picker.processing_time = clamp(malfai.malf_picker.processing_time - 10,0,1000) - operating = FALSE - atom_break() - if(occupier) - malfvacate(TRUE) - update() - /obj/machinery/power/apc/proc/shock(mob/user, prb) if(!prob(prb)) return FALSE diff --git a/code/modules/power/apc/apc_main.dm b/code/modules/power/apc/apc_main.dm index 7e63aff7cbe1b..69732c69b97ac 100644 --- a/code/modules/power/apc/apc_main.dm +++ b/code/modules/power/apc/apc_main.dm @@ -250,38 +250,51 @@ /obj/machinery/power/apc/proc/on_saboteur(datum/source, disrupt_duration) SIGNAL_HANDLER + disrupt_duration *= 0.1 // so, turns out, failure timer is in seconds, not deciseconds; without this, disruptions last 10 times as long as they probably should energy_fail(disrupt_duration) return COMSIG_SABOTEUR_SUCCESS +/obj/machinery/power/apc/on_set_is_operational(old_value) + update_area_power_usage(!old_value) + +/obj/machinery/power/apc/update_name(updates) + . = ..() + if(auto_name) + name = "\improper [get_area_name(area, TRUE)] APC" + /obj/machinery/power/apc/proc/assign_to_area(area/target_area = get_area(src)) if(area == target_area) return disconnect_from_area() area = target_area - area.power_light = TRUE - area.power_equip = TRUE - area.power_environ = TRUE - area.power_change() + update_area_power_usage(TRUE) area.apc = src auto_name = TRUE update_appearance(UPDATE_NAME) -/obj/machinery/power/apc/update_name(updates) - . = ..() - if(auto_name) - name = "\improper [get_area_name(area, TRUE)] APC" +/obj/machinery/power/apc/proc/update_area_power_usage(state) + //apc is non functional so force disable + if(state && (has_electronics != APC_ELECTRONICS_SECURED || (machine_stat & (BROKEN | MAINT)) || QDELETED(cell))) + state = FALSE + + //no change in value + if(state == area.power_light && state == area.power_equip && state == area.power_environ) + return + + area.power_light = state + area.power_equip = state + area.power_environ = state + + area.power_change() /obj/machinery/power/apc/proc/disconnect_from_area() if(isnull(area)) return - area.power_light = FALSE - area.power_equip = FALSE - area.power_environ = FALSE - area.power_change() + update_area_power_usage(FALSE) area.apc = null area = null @@ -318,9 +331,16 @@ else . += "The cover is closed." -/obj/machinery/power/apc/on_deconstruction(disassembled = TRUE) - if(!(machine_stat & BROKEN)) - set_broken() +/obj/machinery/power/apc/atom_break(damage_flag) + . = ..() + if(.) + if(malfai && operating) + malfai.malf_picker.processing_time = clamp(malfai.malf_picker.processing_time - 10, 0, 1000) + operating = FALSE + if(occupier) + malfvacate(TRUE) + update() + if(opened != APC_COVER_REMOVED) opened = APC_COVER_REMOVED coverlocked = FALSE From f92a08642b08f87f0f61e3c5261e8dc46d8a643b Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Fri, 21 Jun 2024 04:52:32 +1200 Subject: [PATCH 129/172] Automatic changelog for PR #84106 [ci skip] --- html/changelogs/AutoChangeLog-pr-84106.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84106.yml diff --git a/html/changelogs/AutoChangeLog-pr-84106.yml b/html/changelogs/AutoChangeLog-pr-84106.yml new file mode 100644 index 0000000000000..dc33240181e5f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84106.yml @@ -0,0 +1,8 @@ +author: "00-Steven" +delete-after: True +changes: + - refactor: "Updated cards/ids to use the proper item interaction system instead of attackby, please report any issues." + - bugfix: "You can no longer recolour an ID at any point if you open the menu but then don't select anything until later." + - bugfix: "ID cards can be recoloured using crayons/spraycans again." + - qol: "Prisoner IDs show genpop sentence time in hours/minutes/seconds instead of seconds." + - qol: "Prisoner IDs have genpop usage tips in their examine." \ No newline at end of file From fcaadffa78f988c9f6bb0d664a9f7ec1a779d8ac Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Fri, 21 Jun 2024 04:52:43 +1200 Subject: [PATCH 130/172] Automatic changelog for PR #84136 [ci skip] --- html/changelogs/AutoChangeLog-pr-84136.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84136.yml diff --git a/html/changelogs/AutoChangeLog-pr-84136.yml b/html/changelogs/AutoChangeLog-pr-84136.yml new file mode 100644 index 0000000000000..a81b14d088658 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84136.yml @@ -0,0 +1,4 @@ +author: "SyncIt21" +delete-after: True +changes: + - bugfix: "breaking an APC will depower the area" \ No newline at end of file From 24deefde7ee76481802a80f954246f31c2b8ad77 Mon Sep 17 00:00:00 2001 From: Rex9001 <120136161+Rex9001@users.noreply.github.com> Date: Thu, 20 Jun 2024 19:18:14 +0200 Subject: [PATCH 131/172] Lunatics now get their objectives properly and get their hud (and updated look for the heretic master) (#83977) ## About The Pull Request Fixes lunatics getting no obectives by adding the objective before the info panel is generated. The ascended moon heretic now gets a Lunatic Master antag datum so lunatics should no have an easier time seeing their master at a glance. Lunatics should now also get their hud properly fixes https://github.com/tgstation/tgstation/issues/83959 and https://github.com/tgstation/tgstation/issues/82835 ## Why It's Good For The Game All of these issues made moon ascension very buggy and now it should play better. ## Changelog :cl: fix: lunatics now get their hud properly fix: lunatics now get objectives qol: ascended moon heretics are now labelled as ringleaders and are easier for lunatics to spot /:cl: --- .../heretic/knowledge/moon_lore.dm | 4 +- .../antagonists/heretic/moon_lunatic.dm | 41 +++++++++++++++--- icons/mob/huds/antag_hud.dmi | Bin 5381 -> 5607 bytes 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/code/modules/antagonists/heretic/knowledge/moon_lore.dm b/code/modules/antagonists/heretic/knowledge/moon_lore.dm index e2af5390ba810..4b61648329214 100644 --- a/code/modules/antagonists/heretic/knowledge/moon_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/moon_lore.dm @@ -188,7 +188,6 @@ /datum/heretic_knowledge/ultimate/moon_final/on_finished_recipe(mob/living/user, list/selected_atoms, turf/loc) . = ..() - var/datum/antagonist/heretic/heretic_datum = IS_HERETIC(user) priority_announce( text = "[generate_heretic_text()] Laugh, for the ringleader [user.real_name] has ascended! \ The truth shall finally devour the lie! [generate_heretic_text()]", @@ -199,8 +198,7 @@ user.client?.give_award(/datum/award/achievement/misc/moon_ascension, user) ADD_TRAIT(user, TRAIT_MADNESS_IMMUNE, REF(src)) - heretic_datum.add_team_hud(user, /datum/antagonist/lunatic) - + user.mind.add_antag_datum(/datum/antagonist/lunatic/master) RegisterSignal(user, COMSIG_LIVING_LIFE, PROC_REF(on_life)) // Roughly 1/5th of the station will rise up as lunatics to the heretic diff --git a/code/modules/antagonists/heretic/moon_lunatic.dm b/code/modules/antagonists/heretic/moon_lunatic.dm index dbc07a6b5054b..3d877ee962c11 100644 --- a/code/modules/antagonists/heretic/moon_lunatic.dm +++ b/code/modules/antagonists/heretic/moon_lunatic.dm @@ -13,16 +13,27 @@ var/datum/mind/ascended_heretic // The body of the ascended heretic who created us var/mob/living/carbon/human/ascended_body + // Our objective + var/datum/objective/lunatic/lunatic_obj + +/datum/antagonist/lunatic/on_gain() + // Masters gain an objective before so we dont want duplicates + for(var/objective in objectives) + if(!istype(objective, /datum/objective/lunatic)) + continue + return ..() + var/datum/objective/lunatic/loony = new() + objectives += loony + lunatic_obj = loony + return ..() /// Runs when the moon heretic creates us, used to give the lunatic a master /datum/antagonist/lunatic/proc/set_master(datum/mind/heretic_master, mob/living/carbon/human/heretic_body) src.ascended_heretic = heretic_master src.ascended_body = heretic_body - var/datum/objective/lunatic/lunatic_obj = new() lunatic_obj.master = heretic_master lunatic_obj.update_explanation_text() - objectives += lunatic_obj to_chat(owner, span_boldnotice("Ruin the lie, save the truth through obeying [heretic_master] the ringleader!")) @@ -30,8 +41,7 @@ var/mob/living/our_mob = mob_override || owner.current handle_clown_mutation(our_mob, "Ancient knowledge from the moon has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") our_mob.faction |= FACTION_HERETIC - add_team_hud(our_mob) - add_team_hud(our_mob, /datum/antagonist/heretic) + add_team_hud(our_mob, /datum/antagonist/lunatic) ADD_TRAIT(our_mob, TRAIT_MADNESS_IMMUNE, REF(src)) var/datum/action/cooldown/lunatic_track/moon_track = new /datum/action/cooldown/lunatic_track() @@ -52,7 +62,28 @@ /datum/objective/lunatic explanation_text = "Assist your ringleader. If you are seeing this, scroll up in chat for who that is and report this" var/datum/mind/master + // If the person with this objective is a lunatic master + var/is_master = FALSE /datum/objective/lunatic/update_explanation_text() . = ..() - explanation_text = "Assist your ringleader [master]" + if(is_master) + explanation_text = "Lead your lunatics to further your own goals!" + return + explanation_text = "Assist your ringleader [master], do not harm fellow lunatics" + +// Lunatic master +/datum/antagonist/lunatic/master + name = "\improper Ringleader" + antag_hud_name = "lunatic_master" + +/datum/antagonist/lunatic/master/on_gain() + var/datum/objective/lunatic/loony = new() + objectives += loony + loony.is_master = TRUE + loony.update_explanation_text() + return ..() + +/datum/antagonist/lunatic/master/apply_innate_effects(mob/living/mob_override) + var/mob/living/our_mob = mob_override || owner.current + add_team_hud(our_mob, /datum/antagonist/lunatic) diff --git a/icons/mob/huds/antag_hud.dmi b/icons/mob/huds/antag_hud.dmi index c51fcc5baa8c66c7e63ba22bea8ed94a097d3362..2a916d01d95530e75894a589470372842030b7b9 100644 GIT binary patch literal 5607 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 SqDddPfQf;beuJ)i!v6q?Acdd+ literal 5381 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 Date: Fri, 21 Jun 2024 05:18:33 +1200 Subject: [PATCH 132/172] Automatic changelog for PR #83977 [ci skip] --- html/changelogs/AutoChangeLog-pr-83977.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83977.yml diff --git a/html/changelogs/AutoChangeLog-pr-83977.yml b/html/changelogs/AutoChangeLog-pr-83977.yml new file mode 100644 index 0000000000000..d25e543431a43 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83977.yml @@ -0,0 +1,6 @@ +author: "Rex9001" +delete-after: True +changes: + - bugfix: "lunatics now get their hud properly" + - bugfix: "lunatics now get objectives" + - qol: "ascended moon heretics are now labelled as ringleaders and are easier for lunatics to spot" \ No newline at end of file From 7b1a0daad211339240dc552b00dc2f7d730211cc Mon Sep 17 00:00:00 2001 From: Rhials <28870487+Rhials@users.noreply.github.com> Date: Thu, 20 Jun 2024 13:19:30 -0400 Subject: [PATCH 133/172] DRAGnet snares now use a dedicated beacon instead of the station teleporter (#84118) ## About The Pull Request This sets up an alternative to the DRAGnet snares using the teleporter to determine the destination of their snare teleport -- The DRAGnet beacon. ![drag net](https://github.com/tgstation/tgstation/assets/28870487/0084d4d9-378f-4896-bc88-0685d6407999) Rather than using a convoluted system that routes via the teleporter, DRAGnets can now by synced with a DRAGnet beacon. When snare rounds are fired and successfully teleport a target, they will instead be sent to the synced beacon. Syncing can be done by either pressing the gun to the beacon or vice-versa. These beacons can be wrenched into place, then swiped with a security ID to block them from being unwrenched. An emag will unlock and unwrench the beacon, and fry its access control. To facilitate this change, roundstart DRAGnet armory spawns are now done through spawners (like the other weapons), which includes a single beacon to be used by the two guns. You can print more with basic sec tech, and one is included in the DRAGnet crate from cargo. The teleport is also slightly more accurate, to make it more consistent. As usual, if not synced to a beacon, DRAGnets will just teleport your target willy-nilly. ## Why It's Good For The Game The current system is both clunky and prone to mishaps, dissuading players from engaging with it. The "active" teleporter concept has always been a bit of a mystery to players, and when a system for properly using the DRAGnet teleport is set up, it's incredibly easy to break even on accident. Every time you teleport a prisoner you have to pray that no bumbling space explorer decided to reroute the teleporter to the abandoned satellite. This system is much more clear and reliable. It's also more versatile, allowing for multiple teleport networks to be set up simultaneously. Security is starved for creativity at times. They deserve to be able to do some wacky dynamic stuff with their tools. ## Changelog :cl: Rhials balance: DRAGnets now come with a beacon they can be synced to, which will set the destination for the snare round's teleport ability. /:cl: --- _maps/map_files/Birdshot/birdshot.dmm | 2 +- .../map_files/Deltastation/DeltaStation2.dmm | 5 +- .../map_files/IceBoxStation/IceBoxStation.dmm | 5 +- _maps/map_files/MetaStation/MetaStation.dmm | 3 +- _maps/map_files/NorthStar/north_star.dmm | 2 +- _maps/map_files/tramstation/tramstation.dmm | 3 +- _maps/map_files/wawastation/wawastation.dmm | 3 +- .../objects/effects/spawners/random/armory.dm | 10 ++ code/modules/cargo/packs/security.dm | 7 +- .../projectiles/guns/energy/energy_gun.dm | 27 +++++- .../projectile/energy/net_snare.dm | 87 +++++++++++++++--- code/modules/research/designs/misc_designs.dm | 13 +++ .../research/techweb/nodes/security_nodes.dm | 1 + icons/effects/random_spawners.dmi | Bin 95426 -> 95835 bytes icons/obj/devices/tracker.dmi | Bin 11771 -> 11967 bytes 15 files changed, 134 insertions(+), 34 deletions(-) diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm index 86dd2443803c4..ef02944be5751 100644 --- a/_maps/map_files/Birdshot/birdshot.dmm +++ b/_maps/map_files/Birdshot/birdshot.dmm @@ -45122,7 +45122,7 @@ /obj/structure/rack, /obj/effect/spawner/random/armory/riot_helmet, /obj/effect/spawner/random/armory/bulletproof_helmet, -/obj/item/gun/energy/e_gun/dragnet, +/obj/effect/spawner/random/armory/dragnet, /turf/open/floor/iron/dark/small, /area/station/ai_monitored/security/armory) "qaV" = ( diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index f399c25d3b148..9f1a266b18575 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -882,11 +882,8 @@ pixel_x = 3 }, /obj/structure/window/reinforced/spawner/directional/north, -/obj/item/gun/energy/e_gun/dragnet{ - pixel_y = 4 - }, -/obj/item/gun/energy/e_gun/dragnet, /obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/spawner/random/armory/dragnet, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) "alG" = ( diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index 09525a5fa06ec..9e5ecd8c0486f 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -30518,15 +30518,12 @@ "jko" = ( /obj/structure/railing, /obj/structure/rack, -/obj/item/gun/energy/e_gun/dragnet{ - pixel_y = 4 - }, -/obj/item/gun/energy/e_gun/dragnet, /obj/structure/cable, /obj/machinery/door/firedoor/border_only, /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 1 }, +/obj/effect/spawner/random/armory/dragnet, /turf/open/floor/iron/dark/textured, /area/station/ai_monitored/security/armory/upper) "jkx" = ( diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 24c017ab71bd5..6cd01a35c9daf 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -32130,12 +32130,11 @@ /area/station/maintenance/fore) "loY" = ( /obj/structure/rack, -/obj/item/gun/energy/e_gun/dragnet, -/obj/item/gun/energy/e_gun/dragnet, /obj/effect/turf_decal/tile/blue/half/contrasted{ dir = 4 }, /obj/machinery/light/small/directional/west, +/obj/effect/spawner/random/armory/dragnet, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) "lpo" = ( diff --git a/_maps/map_files/NorthStar/north_star.dmm b/_maps/map_files/NorthStar/north_star.dmm index 0f9faf9338b6c..7ce411f102fc1 100644 --- a/_maps/map_files/NorthStar/north_star.dmm +++ b/_maps/map_files/NorthStar/north_star.dmm @@ -57668,7 +57668,7 @@ /area/station/science/lower) "oOW" = ( /obj/structure/rack, -/obj/item/gun/energy/e_gun/dragnet, +/obj/effect/spawner/random/armory/dragnet, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) "oOY" = ( diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index 4015dbf2ad35b..a8b81413f9cb6 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -28696,10 +28696,9 @@ /area/station/cargo/storage) "jlQ" = ( /obj/structure/rack, -/obj/item/gun/energy/e_gun/dragnet, -/obj/item/gun/energy/e_gun/dragnet, /obj/item/radio/intercom/directional/north, /obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/spawner/random/armory/dragnet, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) "jlX" = ( diff --git a/_maps/map_files/wawastation/wawastation.dmm b/_maps/map_files/wawastation/wawastation.dmm index 8bec8ecfae0fd..f06276d3e9fa2 100644 --- a/_maps/map_files/wawastation/wawastation.dmm +++ b/_maps/map_files/wawastation/wawastation.dmm @@ -13544,12 +13544,11 @@ /area/station/maintenance/department/medical) "eQJ" = ( /obj/structure/rack, -/obj/item/gun/energy/e_gun/dragnet, -/obj/item/gun/energy/e_gun/dragnet, /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 1 }, /obj/item/radio/intercom/directional/south, +/obj/effect/spawner/random/armory/dragnet, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) "eQQ" = ( diff --git a/code/game/objects/effects/spawners/random/armory.dm b/code/game/objects/effects/spawners/random/armory.dm index 5292ca6ad0986..dfb71ff10d54b 100644 --- a/code/game/objects/effects/spawners/random/armory.dm +++ b/code/game/objects/effects/spawners/random/armory.dm @@ -45,6 +45,16 @@ icon_state = "shotgun" loot = list(/obj/item/gun/ballistic/shotgun/riot) +/obj/effect/spawner/random/armory/dragnet + name = "DRAGnet spawner" + icon_state = "dragnet" + loot = list(/obj/item/gun/energy/e_gun/dragnet) + spawn_loot_count = 2 + +/obj/effect/spawner/random/armory/dragnet/spawn_loot(lootcount_override) + . = ..() + new /obj/item/dragnet_beacon(get_turf(src)) //And give them a beacon too! + // Armor /obj/effect/spawner/random/armory/bulletproof_helmet name = "bulletproof helmet spawner" diff --git a/code/modules/cargo/packs/security.dm b/code/modules/cargo/packs/security.dm index e36f9f84cacf1..05360fe913f0a 100644 --- a/code/modules/cargo/packs/security.dm +++ b/code/modules/cargo/packs/security.dm @@ -214,9 +214,12 @@ /datum/supply_pack/security/armory/dragnet name = "DRAGnet Crate" desc = "Contains three \"Dynamic Rapid-Apprehension of the Guilty\" netting devices, \ - a recent breakthrough in law enforcement prisoner management technology." + a recent breakthrough in law enforcement prisoner management technology. Includes a DRAGnet beacon." cost = CARGO_CRATE_VALUE * 5 - contains = list(/obj/item/gun/energy/e_gun/dragnet = 3) + contains = list( + /obj/item/gun/energy/e_gun/dragnet = 3, + /obj/item/dragnet_beacon = 1 + ) crate_name = "\improper DRAGnet crate" /datum/supply_pack/security/armory/energy diff --git a/code/modules/projectiles/guns/energy/energy_gun.dm b/code/modules/projectiles/guns/energy/energy_gun.dm index fec816b1e765f..78e75d1f30665 100644 --- a/code/modules/projectiles/guns/energy/energy_gun.dm +++ b/code/modules/projectiles/guns/energy/energy_gun.dm @@ -86,7 +86,7 @@ /obj/item/gun/energy/e_gun/dragnet name = "\improper DRAGnet" - desc = "The \"Dynamic Rapid-Apprehension of the Guilty\" net is a revolution in law enforcement technology." + desc = "The \"Dynamic Rapid-Apprehension of the Guilty\" net is a revolution in law enforcement technology. Can by synced with a DRAGnet beacon to set a teleport destination for snare rounds." icon_state = "dragnet" inhand_icon_state = "dragnet" lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' @@ -95,10 +95,35 @@ modifystate = FALSE w_class = WEIGHT_CLASS_NORMAL ammo_x_offset = 1 + ///A dragnet beacon set to be the teleport destination for snare teleport rounds. + var/obj/item/dragnet_beacon/linked_beacon /obj/item/gun/energy/e_gun/dragnet/add_seclight_point() return +/obj/item/gun/energy/e_gun/dragnet/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(istype(tool, /obj/item/dragnet_beacon)) + link_beacon(user, tool) + +///Sets the linked_beacon var on the dragnet, which becomes the snare round's teleport destination. +/obj/item/gun/energy/e_gun/dragnet/proc/link_beacon(mob/living/user, obj/item/dragnet_beacon/our_beacon) + if(linked_beacon) + if(our_beacon == linked_beacon) + balloon_alert(user, "already synced!") + return + else + UnregisterSignal(linked_beacon, COMSIG_QDELETING) //You're getting overridden dude. + + linked_beacon = our_beacon + balloon_alert(user, "beacon synced") + RegisterSignal(our_beacon, COMSIG_QDELETING, PROC_REF(handle_beacon_disable)) + +///Handles clearing the linked_beacon reference in the event that it is deleted. +/obj/item/gun/energy/e_gun/dragnet/proc/handle_beacon_disable(datum/source) + SIGNAL_HANDLER + visible_message(span_warning("A light on the [src] flashes, indicating that it is no longer linked with a DRAGnet beacon!")) + linked_beacon = null + /obj/item/gun/energy/e_gun/dragnet/snare name = "Energy Snare Launcher" desc = "Fires an energy snare that slows the target down." diff --git a/code/modules/projectiles/projectile/energy/net_snare.dm b/code/modules/projectiles/projectile/energy/net_snare.dm index 1bb7988e4bae4..ac35fb5503e68 100644 --- a/code/modules/projectiles/projectile/energy/net_snare.dm +++ b/code/modules/projectiles/projectile/energy/net_snare.dm @@ -11,10 +11,15 @@ SpinAnimation() /obj/projectile/energy/net/on_hit(atom/target, blocked = 0, pierce_hit) + var/obj/item/dragnet_beacon/destination_beacon = null + var/obj/item/gun/energy/e_gun/dragnet/our_dragnet = fired_from + if(our_dragnet && istype(our_dragnet)) + destination_beacon = our_dragnet.linked_beacon + if(isliving(target)) var/turf/Tloc = get_turf(target) if(!locate(/obj/effect/nettingportal) in Tloc) - new /obj/effect/nettingportal(Tloc) + new /obj/effect/nettingportal(Tloc, destination_beacon) . = ..() /obj/projectile/energy/net/on_range() @@ -29,26 +34,18 @@ light_range = 3 anchored = TRUE -/obj/effect/nettingportal/Initialize(mapload) +/obj/effect/nettingportal/Initialize(mapload, destination_beacon) . = ..() - var/obj/item/beacon/teletarget = null - for(var/obj/machinery/computer/teleporter/com as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/computer/teleporter)) - var/atom/target = com.target_ref?.resolve() - if(target) - if(com.power_station && com.power_station.teleporter_hub && com.power_station.engaged) - teletarget = target - else - com.target_ref = null - + var/obj/item/dragnet_beacon/teletarget = destination_beacon addtimer(CALLBACK(src, PROC_REF(pop), teletarget), 3 SECONDS) /obj/effect/nettingportal/proc/pop(teletarget) if(teletarget) - for(var/mob/living/L in get_turf(src)) - do_teleport(L, teletarget, 2, channel = TELEPORT_CHANNEL_BLUESPACE)//teleport what's in the tile to the beacon + for(var/mob/living/living_mob in get_turf(src)) + do_teleport(living_mob, get_turf(teletarget), 1, channel = TELEPORT_CHANNEL_BLUESPACE) //Teleport what's in the tile to the beacon else - for(var/mob/living/L in get_turf(src)) - do_teleport(L, L, 15, channel = TELEPORT_CHANNEL_BLUESPACE) //Otherwise it just warps you off somewhere. + for(var/mob/living/living_mob in get_turf(src)) + do_teleport(living_mob, get_turf(living_mob), 15, channel = TELEPORT_CHANNEL_BLUESPACE) //Otherwise it just warps you off somewhere. qdel(src) @@ -58,6 +55,66 @@ /obj/effect/nettingportal/singularity_pull() return +/obj/item/dragnet_beacon + name = "\improper DRAGnet beacon" + desc = "Can be synced with a DRAGnet to set it as a designated teleporting point." + icon = 'icons/obj/devices/tracker.dmi' + icon_state = "dragnet_beacon" + inhand_icon_state = "beacon" + lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi' + righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi' + ///Has a security ID been used to lock this in place? + var/locked = FALSE + +/obj/item/dragnet_beacon/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(istype(tool, /obj/item/gun/energy/e_gun/dragnet)) + var/obj/item/gun/energy/e_gun/dragnet/dragnet_to_link = tool + dragnet_to_link.link_beacon(user, src) + return + + if(isidcard(tool)) + if(!anchored) + balloon_alert(user, "wrench the beacon first!") + return + + if(obj_flags & EMAGGED) + balloon_alert(user, "the access control is fried!") + return + + var/obj/item/card/id/id_card = tool + if((ACCESS_SECURITY in id_card.GetAccess())) + locked = !locked + balloon_alert(user, "beacon [locked ? "locked" : "unlocked"]") + else + balloon_alert(user, "no access!") + +/obj/item/dragnet_beacon/wrench_act(mob/living/user, obj/item/tool) + if(user.is_holding(src)) + balloon_alert(user, "put it down first!") + return ITEM_INTERACT_BLOCKING + + if(anchored && locked) + balloon_alert(user, "must be unlocked first!") + return ITEM_INTERACT_BLOCKING + + if(isinspace() && !anchored) + balloon_alert(user, "nothing to anchor to!") + return ITEM_INTERACT_BLOCKING + + set_anchored(!anchored) + tool.play_tool_sound(src, 75) + user.balloon_alert_to_viewers("[anchored ? "anchored" : "unanchored"]") + +/obj/item/dragnet_beacon/emag_act(mob/user, obj/item/card/emag/emag_card) + if(obj_flags & EMAGGED) + return FALSE + obj_flags |= EMAGGED + locked = FALSE + set_anchored(FALSE) + do_sparks(3, TRUE, src) + balloon_alert(user, "beacon unlocked") + return TRUE + /obj/projectile/energy/trap name = "energy snare" icon_state = "e_snare" diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index 8ae869220deef..0ea6c41e16448 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -818,6 +818,19 @@ ) departmental_flags = DEPARTMENT_BITFLAG_SECURITY + +/datum/design/dragnet_beacon + name = "DRAGnet Beacon" + desc = "A beacon that can be used as a teleport destination for DRAGnet snare rounds. Remember to sync it with your DRAGnet first!" + id = "dragnet_beacon" + build_type = PROTOLATHE | AWAY_LATHE + materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 5, /datum/material/glass = SHEET_MATERIAL_AMOUNT * 2) + build_path = /obj/item/dragnet_beacon + category = list( + RND_CATEGORY_EQUIPMENT + RND_SUBCATEGORY_EQUIPMENT_SECURITY + ) + departmental_flags = DEPARTMENT_BITFLAG_SECURITY + /datum/design/inspector name = "N-Spect Scanner" desc = "Central Command-issued inspection device. Performs inspections according to Nanotrasen protocols when activated, then prints an encrypted report regarding the maintenance of the station. Definitely not giving you cancer." diff --git a/code/modules/research/techweb/nodes/security_nodes.dm b/code/modules/research/techweb/nodes/security_nodes.dm index 97092f2682a63..8b931fd2273e5 100644 --- a/code/modules/research/techweb/nodes/security_nodes.dm +++ b/code/modules/research/techweb/nodes/security_nodes.dm @@ -32,6 +32,7 @@ "scanner_gate", "turret_control", "pepperspray", + "dragnet_beacon", "inspector", "evidencebag", "handcuffs_s", diff --git a/icons/effects/random_spawners.dmi b/icons/effects/random_spawners.dmi index ddd6fd6f608bd114a92d6210f8bf26e4e9968e71..ed6c0c8702e45438562f6b7aa916f29cd7c1d1b2 100644 GIT binary patch delta 5975 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 diff --git a/icons/obj/devices/tracker.dmi b/icons/obj/devices/tracker.dmi index 59884c0aff8810423f1206e144301f016b54c262..39be63ef4de814e2bfd48b1848367c37cb98b46d 100644 GIT binary patch delta 10423 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 delta 10232 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 From 7299f0d746e997947c9f69d1613e858860caf154 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Fri, 21 Jun 2024 05:20:16 +1200 Subject: [PATCH 134/172] Automatic changelog for PR #84118 [ci skip] --- html/changelogs/AutoChangeLog-pr-84118.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84118.yml diff --git a/html/changelogs/AutoChangeLog-pr-84118.yml b/html/changelogs/AutoChangeLog-pr-84118.yml new file mode 100644 index 0000000000000..f91609e8fe3b9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84118.yml @@ -0,0 +1,4 @@ +author: "Rhials" +delete-after: True +changes: + - balance: "DRAGnets now come with a beacon they can be synced to, which will set the destination for the snare round's teleport ability." \ No newline at end of file From 9adf780b5dc029fb06831ef4de24148bda2808ec Mon Sep 17 00:00:00 2001 From: JackEnoff <166665535+JackEnoff@users.noreply.github.com> Date: Thu, 20 Jun 2024 13:32:16 -0400 Subject: [PATCH 135/172] Repurposed Glands (Adrenals) now show the correct chemical cost and duration (#84088) ## About The Pull Request Adrenals now show the actual chemical cost it inquires and its correct duration in its description in the action button and cellular emporium. Also yeah I did kinda forgot to atomize this while working on the ling balance changes, oopsies! ## Why It's Good For The Game Misiformation in the description = new player bait = bad ## Changelog :cl: fix: Repurposed Glands (Adrenals) now show their correct duration and chemical cost in its description. /:cl: --- code/modules/antagonists/changeling/powers/adrenaline.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/antagonists/changeling/powers/adrenaline.dm b/code/modules/antagonists/changeling/powers/adrenaline.dm index 10c06656b2978..3b6a550b18b0f 100644 --- a/code/modules/antagonists/changeling/powers/adrenaline.dm +++ b/code/modules/antagonists/changeling/powers/adrenaline.dm @@ -1,6 +1,6 @@ /datum/action/changeling/adrenaline name = "Repurposed Glands" - desc = "We shift almost all available muscle mass from the arms to the legs, disabling the former but making us unable to be downed for 15 seconds. Costs 10 chemicals." + desc = "We shift almost all available muscle mass from the arms to the legs, disabling the former but making us unable to be downed for 20 seconds. Costs 25 chemicals." helptext = "Disables your arms and retracts bioweaponry, but regenerates your legs, grants you speed, and wakes you up from any stun." button_icon_state = "adrenaline" chemical_cost = 25 // similar cost to biodegrade, as they serve similar purposes From 6502360c9aebd89df1d6aa9742e13820c235f6f8 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Fri, 21 Jun 2024 05:38:18 +1200 Subject: [PATCH 136/172] Automatic changelog for PR #84088 [ci skip] --- html/changelogs/AutoChangeLog-pr-84088.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84088.yml diff --git a/html/changelogs/AutoChangeLog-pr-84088.yml b/html/changelogs/AutoChangeLog-pr-84088.yml new file mode 100644 index 0000000000000..1dce6075c2695 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84088.yml @@ -0,0 +1,4 @@ +author: "JackEnoff" +delete-after: True +changes: + - bugfix: "Repurposed Glands (Adrenals) now show their correct duration and chemical cost in its description." \ No newline at end of file From 8dee916d5d39cfcf996ec8f510abbf0241019f76 Mon Sep 17 00:00:00 2001 From: GPeckman <21979502+GPeckman@users.noreply.github.com> Date: Thu, 20 Jun 2024 13:38:33 -0400 Subject: [PATCH 137/172] Fixes cleaning spray being blocked by everything (#83941) ## About The Pull Request Fixes #62873, a very old bug. It looks like someone else added code that affected the lifetime of a chemical spray, so I just took the simple option and removed that bit of code. ## Why It's Good For The Game Bug fix. ## Changelog :cl: fix: When on 'stream' mode, the cleaning spray from a bottle of space cleaner should no longer be blocked by just about everything. /:cl: --- code/modules/reagents/reagent_containers/spray.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 387f3b84d4911..bb426436599c0 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -96,7 +96,6 @@ /obj/item/reagent_containers/spray/proc/do_spray(atom/target, wait_step, obj/effect/decal/chempuff/reagent_puff, range, puff_reagent_left, mob/user) reagent_puff.user = user reagent_puff.sprayer = src - reagent_puff.lifetime = puff_reagent_left reagent_puff.stream = stream_mode var/turf/target_turf = get_turf(target) From de13f1ee5ad3e271a07e6ee1ac826881d5bd1188 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Fri, 21 Jun 2024 05:39:13 +1200 Subject: [PATCH 138/172] Automatic changelog for PR #83941 [ci skip] --- html/changelogs/AutoChangeLog-pr-83941.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83941.yml diff --git a/html/changelogs/AutoChangeLog-pr-83941.yml b/html/changelogs/AutoChangeLog-pr-83941.yml new file mode 100644 index 0000000000000..e7aa6d982793b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83941.yml @@ -0,0 +1,4 @@ +author: "GPeckman" +delete-after: True +changes: + - bugfix: "When on 'stream' mode, the cleaning spray from a bottle of space cleaner should no longer be blocked by just about everything." \ No newline at end of file From 10d1740c94ecd714842c66f53f83e2063596aeae Mon Sep 17 00:00:00 2001 From: grungussuss <96586172+Sadboysuss@users.noreply.github.com> Date: Thu, 20 Jun 2024 20:47:33 +0300 Subject: [PATCH 139/172] MODsuit welding module protects flash-sensitives from flashes (#84112) ## About The Pull Request ```php desc = "A module installed into the visor of the suit, this projects a \ polarized, holographic overlay in front of the user's eyes. It's rated high enough for \ immunity against extremities such as spot and arc welding, solar eclipses, and handheld flashlights." ``` ## Why It's Good For The Game This module projects a screen on the inside of the MODsuit, why would it not protect flash-sensitives. ## Changelog :cl: grungussuss fix: Welding protection module for MODsuits protect flash-sensitives from welding arcs /:cl: --------- Co-authored-by: san7890 --- code/__DEFINES/mobs.dm | 2 ++ code/modules/mod/modules/modules_engineering.dm | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 6f6a9d209a10e..a0c40856dace1 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -448,6 +448,8 @@ #define FLASH_PROTECTION_NONE 0 #define FLASH_PROTECTION_FLASH 1 #define FLASH_PROTECTION_WELDER 2 +#define FLASH_PROTECTION_WELDER_PLUS 3 +#define FLASH_PROTECTION_MAXIMUM 4 // AI Toggles #define AI_CAMERA_LUMINOSITY 5 diff --git a/code/modules/mod/modules/modules_engineering.dm b/code/modules/mod/modules/modules_engineering.dm index cb830b2128e7e..e1081d0365a9b 100644 --- a/code/modules/mod/modules/modules_engineering.dm +++ b/code/modules/mod/modules/modules_engineering.dm @@ -15,7 +15,8 @@ /obj/item/mod/module/welding/on_suit_activation() var/obj/item/clothing/head_cover = mod.get_part_from_slot(ITEM_SLOT_HEAD) || mod.get_part_from_slot(ITEM_SLOT_MASK) || mod.get_part_from_slot(ITEM_SLOT_EYES) if(istype(head_cover)) - head_cover.flash_protect = FLASH_PROTECTION_WELDER + //this is a screen that displays an image, so flash sensitives can use this to protect against flashes. + head_cover.flash_protect = FLASH_PROTECTION_MAXIMUM /obj/item/mod/module/welding/on_suit_deactivation(deleting = FALSE) if(deleting) From 565e6bf944b18ebb958108662bd733f1eb351b57 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Fri, 21 Jun 2024 05:48:12 +1200 Subject: [PATCH 140/172] Automatic changelog for PR #84112 [ci skip] --- html/changelogs/AutoChangeLog-pr-84112.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84112.yml diff --git a/html/changelogs/AutoChangeLog-pr-84112.yml b/html/changelogs/AutoChangeLog-pr-84112.yml new file mode 100644 index 0000000000000..9ea4b1d68bf9e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84112.yml @@ -0,0 +1,4 @@ +author: "grungussuss" +delete-after: True +changes: + - bugfix: "Welding protection module for MODsuits protect flash-sensitives from welding arcs" \ No newline at end of file From b68c9677ce7589197ec48171a0089e5b0c34c1ee Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Thu, 20 Jun 2024 21:48:39 +0400 Subject: [PATCH 141/172] Resprited jetpacks (#84126) ## About The Pull Request Resprites absolutely ancient jetpack sprites. ![image](https://github.com/tgstation/tgstation/assets/44720187/9d901fd2-db2a-4fd2-807e-edc5822d0979) ## Why It's Good For The Game Current jetpack sprites are most likely from exadv era and look accordingly, lacking any shading or texture. ## Changelog :cl: image: Resprited all jetpacks /:cl: --- icons/mob/clothing/back.dmi | Bin 128847 -> 111960 bytes .../inhands/equipment/jetpacks_lefthand.dmi | Bin 3182 -> 3664 bytes .../inhands/equipment/jetpacks_righthand.dmi | Bin 3456 -> 3616 bytes icons/obj/canisters.dmi | Bin 17680 -> 15809 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/mob/clothing/back.dmi b/icons/mob/clothing/back.dmi index 52be2d07923e506a1aea2e7d2fb789c654701c5c..eb3f87d9c71f0a0300d7e8ae7be24743f96319d3 100644 GIT binary patch literal 111960 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
{ft#HnWqvy=XHSE?aryLk`3W3C}m&Q)

qsGg~-!SZ$~M7W+w~A3=5IJ&4<# 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 Hr-UW|shL2@ literal 128847 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%0D~fRk!7 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�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 PFbXlL8U~007|R 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 diff --git a/icons/obj/canisters.dmi b/icons/obj/canisters.dmi index 277833976adbb709736e378dd08b7ab814ea2b36..436467648880b3583883cb9bff4075f62a486bb8 100644 GIT binary patch literal 15809 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

y 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 N002ovPDHLkV1j-Oly?9C From 92d1623c32b563aafddc5e8e06f315a435325dec Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Fri, 21 Jun 2024 05:48:59 +1200 Subject: [PATCH 142/172] Automatic changelog for PR #84126 [ci skip] --- html/changelogs/AutoChangeLog-pr-84126.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84126.yml diff --git a/html/changelogs/AutoChangeLog-pr-84126.yml b/html/changelogs/AutoChangeLog-pr-84126.yml new file mode 100644 index 0000000000000..633e7a1a2870b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84126.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - image: "Resprited all jetpacks" \ No newline at end of file From 8a8fac1d078b99c7829d3d2575b7100ff275ff68 Mon Sep 17 00:00:00 2001 From: Djiq <42111655+EdgeLordExe@users.noreply.github.com> Date: Thu, 20 Jun 2024 20:13:13 +0200 Subject: [PATCH 143/172] Feast of Owls Heretic Ritual : Forsake your ascension (#83769) ## About The Pull Request This adds a simple ritual that let's a heretic forsake their ascension for immediate power - 5 knowledge points. ## Why It's Good For The Game Heretic suffers from lack of gimmicks and it's not really because of lack of tools that could support them, but rather due to heretics going straight for ascension (who can blame them), this ritual allows a heretic to restrict themself from ascending and in exchange gain a sizeable amount of research points. Not only that, but this will also help with people learning heretic, as it allows a new player to jump immediately into heretic without the struggle of early game (the struggle of early-game justifies late-game power, by rejecting late-game power heretic gets a jump-start with points.) ## Changelog :cl: add: Adds Feast of Owls ritual to heretic which allows one to forsake their ascension in exchange for immediate power. /:cl: --------- Co-authored-by: carlarctg <53100513+carlarctg@users.noreply.github.com> --- .../antagonists/heretic/heretic_antag.dm | 7 +++++- .../heretic/knowledge/starting_lore.dm | 25 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/code/modules/antagonists/heretic/heretic_antag.dm b/code/modules/antagonists/heretic/heretic_antag.dm index 9c41c54e84e09..416dbe390e16f 100644 --- a/code/modules/antagonists/heretic/heretic_antag.dm +++ b/code/modules/antagonists/heretic/heretic_antag.dm @@ -56,6 +56,8 @@ var/static/list/blacklisted_rune_turfs = typecacheof(list(/turf/open/space, /turf/open/openspace, /turf/open/lava, /turf/open/chasm)) /// Controls what types of turf we can spread rust to, increases as we unlock more powerful rust abilites var/rust_strength = 0 + /// Wether we are allowed to ascend + var/feast_of_owls = FALSE /// Static list of what each path converts to in the UI (colors are TGUI colors) var/static/list/path_to_ui_color = list( PATH_START = "grey", @@ -478,7 +480,8 @@ succeeded = FALSE parts += "Objective #[count]: [objective.explanation_text] [objective.get_roundend_success_suffix()]" count++ - + if(feast_of_owls) + parts += span_greentext("Ascension Forsaken") if(ascended) parts += span_greentext(span_big("THE HERETIC ASCENDED!")) @@ -695,6 +698,8 @@ /datum/antagonist/heretic/proc/can_ascend() if(!can_assign_self_objectives) return FALSE // We spurned the offer of the Mansus :( + if(feast_of_owls) + return FALSE // We sold our ambition for immediate power :/ for(var/datum/objective/must_be_done as anything in objectives) if(!must_be_done.check_completion()) return FALSE diff --git a/code/modules/antagonists/heretic/knowledge/starting_lore.dm b/code/modules/antagonists/heretic/knowledge/starting_lore.dm index f1b5f7f55ea19..50b57fd9e96b4 100644 --- a/code/modules/antagonists/heretic/knowledge/starting_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/starting_lore.dm @@ -293,3 +293,28 @@ GLOBAL_LIST_INIT(heretic_start_knowledge, initialize_starting_knowledge()) body.do_jitter_animation() body.visible_message(span_danger("An awful ripping sound is heard as [ripped_thing]'s [exterior_text] is ripped straight out, wrapping around [le_book || "the book"], turning into an eldritch shade of blue!")) return ..() + +/datum/heretic_knowledge/feast_of_owls + name = "Feast of Owls" + desc = "Allows you to undergo a ritual that gives you 5 knowledge points but locks you out of ascension. This can only be done once and cannot be reverted." + gain_text = "Under the soft glow of unreason there is a beast that stalks the night. I shall bring it forth and let it enter my presence. It will feast upon my amibitions and leave knowledge in its wake." + route = PATH_START + required_atoms = list() + +/datum/heretic_knowledge/feast_of_owls/can_be_invoked(datum/antagonist/heretic/invoker) + return !invoker.feast_of_owls + +/datum/heretic_knowledge/feast_of_owls/on_finished_recipe(mob/living/user, list/selected_atoms, turf/loc) + var/alert = tgui_alert(user,"Do you really want to forsake your ascension? This action cannot be reverted.", "Feast of Owls", list("Yes I'm sure", "No"), 30 SECONDS) + if( alert != "Yes I'm sure") + return FALSE + user.set_temp_blindness(5 SECONDS) + user.AdjustParalyzed(5 SECONDS) + var/datum/antagonist/heretic/heretic_datum = IS_HERETIC(user) + for(var/i in 0 to 4) + user.emote("scream") + playsound(loc, 'sound/items/eatfood.ogg', 100, TRUE) + heretic_datum.knowledge_points++ + sleep(1 SECONDS) + to_chat(user,span_danger("You feel different...")) + heretic_datum.feast_of_owls = TRUE From 881dd195f15f50f789bd690babb556958bd60e57 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 20 Jun 2024 21:15:30 +0300 Subject: [PATCH 144/172] Techweb tweaks [NO GBP] (#84086) ## About The Pull Request PR for collecting techweb feedback post merge and address valid issues of #84024. People seem to dislike the abundance of new experiments in the middle of the tree, so reducing some requirements for those for now. Also updated NT frontier app a bit, as people are confused with the shell experiments. ![image](https://github.com/tgstation/tgstation/assets/3625094/8ce91935-c374-443c-84b4-ebee14d6bac1) ## Why It's Good For The Game Balancing out the new tree. ## Changelog :cl: balance: Added ordnance to extra access of geneticists and roboticists balance: Reduced parts scanning tests' machine count to 4 from 8 balance: Reduced augmented organs scanning tests mob count to 1 from 2 balance: Reduced equipped mech scanning test count to 1 from 2 balance: Added polycrystal option to bluespace crystal scan test fix: Allowed NTNet relay in away circuit imprinter for NT Frontier app qol: NT Frontier app installed on RD and Scientists` PDAs by default qol: Updated NT Frontier app to be more user-friendly /:cl: --------- Co-authored-by: Jeremiah <42397676+jlsnow301@users.noreply.github.com> --- code/datums/id_trim/jobs.dm | 6 +- .../experisci/experiment/experiments.dm | 15 +- .../computers/item/role_tablet_presets.dm | 2 + .../file_system/programs/frontier.dm | 2 +- .../research/designs/machine_designs.dm | 1 - .../research/techweb/nodes/biology_nodes.dm | 2 +- .../research/techweb/nodes/research_nodes.dm | 2 +- .../packages/tgui/interfaces/NtosScipaper.jsx | 255 +++++++++--------- 8 files changed, 148 insertions(+), 137 deletions(-) diff --git a/code/datums/id_trim/jobs.dm b/code/datums/id_trim/jobs.dm index cfa608011bdf9..4d4c44138e0c2 100644 --- a/code/datums/id_trim/jobs.dm +++ b/code/datums/id_trim/jobs.dm @@ -545,11 +545,13 @@ ACCESS_MORGUE, ACCESS_RESEARCH, ACCESS_SCIENCE, + ACCESS_XENOBIOLOGY, ) extra_access = list( ACCESS_ROBOTICS, ACCESS_TECH_STORAGE, - ACCESS_XENOBIOLOGY, + ACCESS_ORDNANCE, + ACCESS_ORDNANCE_STORAGE, ) template_access = list( ACCESS_CAPTAIN, @@ -960,6 +962,8 @@ ACCESS_GENETICS, ACCESS_XENOBIOLOGY, ACCESS_MORGUE_SECURE, + ACCESS_ORDNANCE, + ACCESS_ORDNANCE_STORAGE, ) template_access = list( ACCESS_CAPTAIN, diff --git a/code/modules/experisci/experiment/experiments.dm b/code/modules/experisci/experiment/experiments.dm index f0915bdbf77cd..7a7c073b75a6a 100644 --- a/code/modules/experisci/experiment/experiments.dm +++ b/code/modules/experisci/experiment/experiments.dm @@ -335,7 +335,7 @@ name = "Exosuit Materials: Load Strain Test" description = "Exosuit equipment places unique strain upon the structure of the vehicle. Scan exosuits you have assembled from your exosuit fabricator and fully equipped to accelerate our structural stress simulations." possible_types = list(/obj/vehicle/sealed/mecha) - total_requirement = 2 + total_requirement = 1 /// Scan for organs you didn't start the round with /datum/experiment/scanning/people/novel_organs @@ -383,6 +383,7 @@ description = "We need to gather data on how cybernetic vital organs integrate with human biology. Conduct a scan on a human with these implants to help us understand their compatibility" performance_hint = "Perform an organ manipulation surgery to replace one of the vital organs with a cybernetic variant." required_traits_desc = "augmented vital organs" + required_count = 1 /datum/experiment/scanning/people/augmented_organs/is_valid_scan_target(mob/living/carbon/human/check) . = ..() @@ -431,15 +432,19 @@ required_reagent = /datum/reagent/cryostylane min_purity = 0.99 -/datum/experiment/scanning/bluespace_crystal +/datum/experiment/scanning/points/bluespace_crystal name = "Bluespace Crystal Sampling" description = "Investigate the properties of bluespace crystals by scanning either an artificial or naturally occurring variant. This will help us deepen our understanding of bluespace phenomena." - required_atoms = list(/obj/item/stack/ore/bluespace_crystal = 1) + required_points = 1 + required_atoms = list( + /obj/item/stack/ore/bluespace_crystal = 1, + /obj/item/stack/sheet/bluespace_crystal = 1 + ) /datum/experiment/scanning/points/machinery_tiered_scan/tier2_any name = "Upgraded Stock Parts Benchmark" description = "Our newly-designed machinery components require practical application tests for hints at possible further advancements, as well as a general confirmation that we didn't actually design worse parts somehow. Scan any machinery with Upgraded Parts and report the results." - required_points = 8 + required_points = 4 required_atoms = list( /obj/machinery = 1 ) @@ -448,7 +453,7 @@ /datum/experiment/scanning/points/machinery_tiered_scan/tier3_any name = "Advanced Stock Parts Benchmark" description = "Our newly-designed machinery components require practical application tests for hints at possible further advancements, as well as a general confirmation that we didn't actually design worse parts somehow. Scan any machinery with Advanced Parts and report the results." - required_points = 8 + required_points = 4 required_atoms = list( /obj/machinery = 1 ) diff --git a/code/modules/modular_computers/computers/item/role_tablet_presets.dm b/code/modules/modular_computers/computers/item/role_tablet_presets.dm index ee6c9ee68f0af..44392c8c62de9 100644 --- a/code/modules/modular_computers/computers/item/role_tablet_presets.dm +++ b/code/modules/modular_computers/computers/item/role_tablet_presets.dm @@ -97,6 +97,7 @@ /datum/computer_file/program/crew_manifest, /datum/computer_file/program/robocontrol, /datum/computer_file/program/science, + /datum/computer_file/program/scipaper_program, /datum/computer_file/program/status, /datum/computer_file/program/signal_commander, ) @@ -187,6 +188,7 @@ starting_programs = list( /datum/computer_file/program/atmosscan, /datum/computer_file/program/science, + /datum/computer_file/program/scipaper_program, /datum/computer_file/program/signal_commander, ) diff --git a/code/modules/modular_computers/file_system/programs/frontier.dm b/code/modules/modular_computers/file_system/programs/frontier.dm index c41cf642ffb55..7a65513508d3e 100644 --- a/code/modules/modular_computers/file_system/programs/frontier.dm +++ b/code/modules/modular_computers/file_system/programs/frontier.dm @@ -8,7 +8,7 @@ program_open_overlay = "research" tgui_id = "NtosScipaper" program_icon = "paper-plane" - download_access = list(ACCESS_ORDNANCE) + download_access = list(ACCESS_ORDNANCE, ACCESS_SCIENCE, ACCESS_AWAY_SCIENCE) var/datum/techweb/linked_techweb /// Unpublished, temporary paper datum. diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index 7d4f613f05478..ef6c65d183175 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -747,7 +747,6 @@ name = "NTNet Relay Board" desc = "The circuit board for a wireless network relay." id = "ntnet_relay" - build_type = IMPRINTER build_path = /obj/item/circuitboard/machine/ntnet_relay category = list( RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_TELECOMMS diff --git a/code/modules/research/techweb/nodes/biology_nodes.dm b/code/modules/research/techweb/nodes/biology_nodes.dm index 6a14d7d517c8f..4adc78691835a 100644 --- a/code/modules/research/techweb/nodes/biology_nodes.dm +++ b/code/modules/research/techweb/nodes/biology_nodes.dm @@ -6,6 +6,7 @@ design_ids = list( "healthanalyzer", "autopsyscanner", + "genescanner", "medical_kiosk", "chem_master", "ph_meter", @@ -54,7 +55,6 @@ "scan_console", "dna_disk", "dnainfuser", - "genescanner", "mod_dna_lock", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) diff --git a/code/modules/research/techweb/nodes/research_nodes.dm b/code/modules/research/techweb/nodes/research_nodes.dm index b3af62c72e994..f68086ab5abdd 100644 --- a/code/modules/research/techweb/nodes/research_nodes.dm +++ b/code/modules/research/techweb/nodes/research_nodes.dm @@ -48,7 +48,7 @@ "bluespacebodybag", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) - required_experiments = list(/datum/experiment/scanning/bluespace_crystal) + required_experiments = list(/datum/experiment/scanning/points/bluespace_crystal) /datum/techweb_node/bluespace_travel id = "bluespace_travel" diff --git a/tgui/packages/tgui/interfaces/NtosScipaper.jsx b/tgui/packages/tgui/interfaces/NtosScipaper.jsx index 2af2cd12f43f9..4d12fdc638931 100644 --- a/tgui/packages/tgui/interfaces/NtosScipaper.jsx +++ b/tgui/packages/tgui/interfaces/NtosScipaper.jsx @@ -5,7 +5,6 @@ import { Button, Collapsible, Dropdown, - Icon, Input, LabeledList, NoticeBox, @@ -13,14 +12,13 @@ import { Stack, Table, Tabs, - Tooltip, } from '../components'; import { TableCell, TableRow } from '../components/Table'; import { NtosWindow } from '../layouts'; export const NtosScipaper = (props) => { return ( - + @@ -50,31 +48,132 @@ const PaperPublishing = (props) => { return ( <>

- - + {fileList.length === 0 && ( + + Use the File Manager app to download files from a disk. + + )} + + + } + > + + + act('select_file', { + selected_uid: fileList[ordfile_name], + }) + } + /> + + + + } + > + + + act('select_experiment', { + selected_expath: expList[experiment_name], + }) + } + /> + + + + } + > + + String(number))} + selected={String(tier)} + onSelected={(new_tier) => + act('select_tier', { + selected_tier: Number(new_tier), + }) + } + /> + + + + } + > + + + act('select_partner', { + selected_partner: allowedPartners[new_partner], + }) + } + /> + + + act('et_alia')} + /> + } + > act('rewrite', { - title: value, + author: value, }) } /> - + act('rewrite', { - author: value, + title: value, }) } /> - { } /> - - - - - act('select_file', { - selected_uid: fileList[ordfile_name], - }) - } - /> - - - - - - - - - - - - - act('select_experiment', { - selected_expath: expList[experiment_name], - }) - } - /> - - - - - - - - - - - - String(number))} - selected={String(tier)} - onSelected={(new_tier) => - act('select_tier', { - selected_tier: Number(new_tier), - }) - } - /> - - - - - - - - - - - - - act('select_partner', { - selected_partner: allowedPartners[new_partner], - }) - } - /> - - - - - - - -
- - - +
); @@ -366,7 +367,7 @@ export const NtosScipaperContent = (props) => { Please sync this application to a valid techweb to upload progress! )} - + @@ -385,7 +386,7 @@ export const NtosScipaperContent = (props) => { }) } > - {'View Previous Publications'} + {'Publications'} { }) } > - {'View Available Experiments'} + {'Experiments'} { }) } > - {'View Scientific Partners'} + {'Scientific Partners'} {currentTab === 1 && } From bd5c045acb183c58c1b54d44ef671e1a14fc2302 Mon Sep 17 00:00:00 2001 From: BeagleGaming1 <56142455+BeagleGaming1@users.noreply.github.com> Date: Thu, 20 Jun 2024 14:16:18 -0400 Subject: [PATCH 145/172] Adds proto-kinetic accelerator modkit and proto-kinetic crusher trophy disks to the bitrunning vendor (#83825) ## About The Pull Request Adds disks to the bitrunning vendor that give the pka and pkc additional parts. I have no idea if any of these numbers are balanced, I am not good at balance, and these are just random numbers I came up with. If anyone has any recommendations on how to better order or price it, I would love to know. ## Why It's Good For The Game It gives people a way to test fights against megafauna using unique combinations of accelerator modkits and crusher trophies with less risks. ## Changelog :cl: add: Added disks for accelerator modkits and crusher trophies to the bitrunning vendor /:cl: --- code/modules/bitrunning/objects/disks.dm | 43 ++++++++++++++++++++++++ code/modules/bitrunning/orders/tech.dm | 20 +++++++++++ 2 files changed, 63 insertions(+) diff --git a/code/modules/bitrunning/objects/disks.dm b/code/modules/bitrunning/objects/disks.dm index 6e166d5eb7fdb..17b768c54d08f 100644 --- a/code/modules/bitrunning/objects/disks.dm +++ b/code/modules/bitrunning/objects/disks.dm @@ -142,3 +142,46 @@ /obj/item/dualsaber/green, /obj/item/grenade/syndieminibomb, ) + +///proto-kinetic accelerator mods, to be applied to pka's given inside domains +/obj/item/bitrunning_disk/item/pka_mods + name = "bitrunning gear: proto-kinetic accelerator mods" + selectable_items = list( + /obj/item/borg/upgrade/modkit/range, + /obj/item/borg/upgrade/modkit/damage, + /obj/item/borg/upgrade/modkit/cooldown, + /obj/item/borg/upgrade/modkit/aoe/mobs, + /obj/item/borg/upgrade/modkit/human_passthrough, + ) + +/obj/item/bitrunning_disk/item/pka_mods/premium + name = "bitrunning gear: premium proto-kinetic accelerator mods" + selectable_items = list( + /obj/item/borg/upgrade/modkit/cooldown/repeater, + /obj/item/borg/upgrade/modkit/lifesteal, + /obj/item/borg/upgrade/modkit/resonator_blasts, + /obj/item/borg/upgrade/modkit/bounty, + /obj/item/borg/upgrade/modkit/indoors, + ) + +///proto-kinetic crusher trophies, to be applied to pkc's given inside domains +/obj/item/bitrunning_disk/item/pkc_mods + name = "bitrunning gear: proto-kinetic crusher mods" + selectable_items = list( + /obj/item/crusher_trophy/watcher_wing, + /obj/item/crusher_trophy/blaster_tubes/magma_wing, + /obj/item/crusher_trophy/legion_skull, + /obj/item/crusher_trophy/wolf_ear, + ) + +/obj/item/bitrunning_disk/item/pkc_mods/premium + name = "bitrunning gear: premium proto-kinetic crusher mods" + selectable_items = list( + /obj/item/crusher_trophy/watcher_wing/ice_wing, + /obj/item/crusher_trophy/blaster_tubes, + /obj/item/crusher_trophy/miner_eye, + /obj/item/crusher_trophy/tail_spike, + /obj/item/crusher_trophy/demon_claws, + /obj/item/crusher_trophy/vortex_talisman, + /obj/item/crusher_trophy/ice_demon_cube, + ) diff --git a/code/modules/bitrunning/orders/tech.dm b/code/modules/bitrunning/orders/tech.dm index a4bf59ce18dec..7e987e4818104 100644 --- a/code/modules/bitrunning/orders/tech.dm +++ b/code/modules/bitrunning/orders/tech.dm @@ -34,3 +34,23 @@ /datum/orderable_item/bitrunning_tech/flip_skillchip item_path = /obj/item/skillchip/matrix_flip cost_per_order = 2000 + +/datum/orderable_item/bitrunning_tech/pka_mod + item_path = /obj/item/bitrunning_disk/item/pka_mods + cost_per_order = 750 + desc = "This disk contains a program that lets you equip modkits for the proto-kinetic accelerator. Proto-kinetic accelerator not included." + +/datum/orderable_item/bitrunning_tech/pka_mod/premium + item_path = /obj/item/bitrunning_disk/item/pka_mods/premium + cost_per_order = 1800 + desc = "This disk contains a program that lets you equip stronger modkits for the proto-kinetic accelerator. Proto-kinetic accelerator not included." + +/datum/orderable_item/bitrunning_tech/pkc_mod + item_path = /obj/item/bitrunning_disk/item/pkc_mods + cost_per_order = 750 + desc = "This disk contains a program that lets you equip trophies for the proto-kinetic crusher. Proto-kinetic crusher no included." + +/datum/orderable_item/bitrunning_tech/pkc_mod/premium + item_path = /obj/item/bitrunning_disk/item/pkc_mods/premium + cost_per_order = 1800 + desc = "This disk contains a program that lets you equip stronger trophies for the proto-kinetic crusher. Proto-kinetic crusher not included." From 8da4e142bc0e38ce53e814851705ebd86366640e Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Fri, 21 Jun 2024 06:18:13 +1200 Subject: [PATCH 146/172] Automatic changelog for PR #83769 [ci skip] --- html/changelogs/AutoChangeLog-pr-83769.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83769.yml diff --git a/html/changelogs/AutoChangeLog-pr-83769.yml b/html/changelogs/AutoChangeLog-pr-83769.yml new file mode 100644 index 0000000000000..919aa6eb4a078 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83769.yml @@ -0,0 +1,4 @@ +author: "EdgeLordExe" +delete-after: True +changes: + - rscadd: "Adds Feast of Owls ritual to heretic which allows one to forsake their ascension in exchange for immediate power." \ No newline at end of file From d33a66ef7f5765b86c9b466a853502f5a76542ea Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Fri, 21 Jun 2024 06:18:26 +1200 Subject: [PATCH 147/172] Automatic changelog for PR #84086 [ci skip] --- html/changelogs/AutoChangeLog-pr-84086.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84086.yml diff --git a/html/changelogs/AutoChangeLog-pr-84086.yml b/html/changelogs/AutoChangeLog-pr-84086.yml new file mode 100644 index 0000000000000..50d8eaac49554 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84086.yml @@ -0,0 +1,11 @@ +author: "MTandi" +delete-after: True +changes: + - balance: "Added ordnance to extra access of geneticists and roboticists" + - balance: "Reduced parts scanning tests' machine count to 4 from 8" + - balance: "Reduced augmented organs scanning tests mob count to 1 from 2" + - balance: "Reduced equipped mech scanning test count to 1 from 2" + - balance: "Added polycrystal option to bluespace crystal scan test" + - bugfix: "Allowed NTNet relay in away circuit imprinter for NT Frontier app" + - qol: "NT Frontier app installed on RD and Scientists` PDAs by default" + - qol: "Updated NT Frontier app to be more user-friendly" \ No newline at end of file From 3d2f82b315c70cb2959e41232ffef09b711f0bc6 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Fri, 21 Jun 2024 06:18:31 +1200 Subject: [PATCH 148/172] Automatic changelog for PR #83825 [ci skip] --- html/changelogs/AutoChangeLog-pr-83825.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-83825.yml diff --git a/html/changelogs/AutoChangeLog-pr-83825.yml b/html/changelogs/AutoChangeLog-pr-83825.yml new file mode 100644 index 0000000000000..4a2fb94912a65 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83825.yml @@ -0,0 +1,4 @@ +author: "BeagleGaming1" +delete-after: True +changes: + - rscadd: "Added disks for accelerator modkits and crusher trophies to the bitrunning vendor" \ No newline at end of file From 94cf89f2d73e05535504423848ea06466e167684 Mon Sep 17 00:00:00 2001 From: Joshua Kidder <49173900+Metekillot@users.noreply.github.com> Date: Thu, 20 Jun 2024 15:10:08 -0400 Subject: [PATCH 149/172] Settler partially atomized into traits, ashwalkers given some settler traits (#84090) ## About The Pull Request So my previous PR was to give ashwalker the settler trait so they'd get some of the benefits of settler (better riding, fishing, and taming) but it was suggested that Settler be atomized into different traits instead. I've done that here. Ashwalkers now get TRAIT_ROUGHRIDER TRAIT_BEAST_EMPATHY TRAIT_EXPERT_FISHER which will, respectively, make them better riders, better tamers, and better at fishing. I also made a small change to the riding code that references riding speed boosts for people with the ROUGHRIDER trait (would, at the moment, only be ashwalkers and settlers) that gives ashwalkers the maximum bonus, to represent their primal connection with the beasts in the area. ## Why It's Good For The Game Ashwalkers are described in the lore as being denizens of lavaland, the same as all the other messed up shit down there. This change brings them in line with that. The improvements to the handling of the settler trait will also open up avenues for expanding or improving on related systems ## Changelog :cl: Bisar add: Ashwalkers are now better at riding, taming animals, and fishing. code: Behavior for the settler trait has been partially atomized into several traits instead. /:cl: --------- Co-authored-by: necromanceranne <40847847+necromanceranne@users.noreply.github.com> Co-authored-by: Jacquerel --- code/__DEFINES/fish.dm | 4 ++-- code/__DEFINES/traits/declarations.dm | 8 ++++++++ code/_globalvars/traits/_traits.dm | 5 +++++ code/_globalvars/traits/admin_tooling.dm | 5 +++++ code/datums/components/riding/riding_mob.dm | 11 ++++++++--- code/datums/components/tameable.dm | 4 ++-- code/datums/elements/climbable.dm | 2 +- code/datums/quirks/positive_quirks/settler.dm | 12 +++++++++++- code/modules/fishing/sources/_fish_source.dm | 4 ++-- code/modules/mob/living/brain/brain_item.dm | 10 +++++++++- .../carbon/human/species_types/lizardpeople.dm | 1 - code/modules/mob/mob.dm | 4 ++-- 12 files changed, 55 insertions(+), 15 deletions(-) diff --git a/code/__DEFINES/fish.dm b/code/__DEFINES/fish.dm index 24242699e3d01..8e03c920d248d 100644 --- a/code/__DEFINES/fish.dm +++ b/code/__DEFINES/fish.dm @@ -9,8 +9,8 @@ #define FAV_BAIT_DIFFICULTY_MOD -5 /// Difficulty modifier when bait is fish's disliked #define DISLIKED_BAIT_DIFFICULTY_MOD 15 -/// Difficulty modifier when our fisherman has the trait TRAIT_SETTLER -#define SETTLER_DIFFICULTY_MOD -5 +/// Difficulty modifier when our fisherman has the trait TRAIT_EXPERT_FISHER +#define EXPERT_FISHER_DIFFICULTY_MOD -5 #define FISH_TRAIT_MINOR_DIFFICULTY_BOOST 5 diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 8f1c58bc96684..c34e0f2925e9f 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -1151,6 +1151,14 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// Does this item bypass ranged armor checks? #define TRAIT_BYPASS_RANGED_ARMOR "bypass_ranged_armor" +/// Traits given by settler, each with their own specific effects for cases where someone would have that trait, but not the other settler effects + +#define TRAIT_EXPERT_FISHER "expert_fisher" // fishing is easier +#define TRAIT_ROUGHRIDER "roughrider" // you can improve speed on mounted animals with a good mood +#define TRAIT_STUBBY_BODY "stubby_body" // you have a stubby body that lessens your agility +#define TRAIT_BEAST_EMPATHY "beast_empathy" // you're good with animals, such as with taming them +#define TRAIT_STURDY_FRAME "sturdy_frame" // you suffer much lesser effects from equipment that slows you down + /// This item cannot be selected for or used by a theft objective (Spies, Traitors, etc.) #define TRAIT_ITEM_OBJECTIVE_BLOCKED "item_objective_blocked" /// This trait lets you attach limbs to any player without surgery. diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 9175b86dc3589..66f32028c6b9c 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -138,6 +138,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_BALD" = TRAIT_BALD, "TRAIT_BALLOON_SUTRA" = TRAIT_BALLOON_SUTRA, "TRAIT_BATON_RESISTANCE" = TRAIT_BATON_RESISTANCE, + "TRAIT_BEAST_EMPATHY" = TRAIT_BEAST_EMPATHY, "TRAIT_BEING_BLADE_SHIELDED" = TRAIT_BEING_BLADE_SHIELDED, "TRAIT_BLOB_ALLY" = TRAIT_BLOB_ALLY, "TRAIT_BLOCK_SHUTTLE_MOVEMENT" = TRAIT_BLOCK_SHUTTLE_MOVEMENT, @@ -208,6 +209,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_EXAMINE_FISHING_SPOT" = TRAIT_EXAMINE_FISHING_SPOT, "TRAIT_EXAMINE_FITNESS" = TRAIT_EXAMINE_FITNESS, "TRAIT_EXPANDED_FOV" = TRAIT_EXPANDED_FOV, + "TRAIT_EXPERT_FISHER" = TRAIT_EXPERT_FISHER, "TRAIT_EXTROVERT" = TRAIT_EXTROVERT, "TRAIT_FAKEDEATH" = TRAIT_FAKEDEATH, "TRAIT_FASTMED" = TRAIT_FASTMED, @@ -414,6 +416,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_ROCK_METAMORPHIC" = TRAIT_ROCK_METAMORPHIC, "TRAIT_ROCK_STONER" = TRAIT_ROCK_STONER, "TRAIT_ROD_SUPLEX" = TRAIT_ROD_SUPLEX, + "TRAIT_ROUGHRIDER" = TRAIT_ROUGHRIDER, "TRAIT_SABRAGE_PRO" = TRAIT_SABRAGE_PRO, "TRAIT_SECURITY_HUD" = TRAIT_SECURITY_HUD, "TRAIT_SEE_GLASS_COLORS" = TRAIT_SEE_GLASS_COLORS, @@ -445,7 +448,9 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_STIMULATED" = TRAIT_STIMULATED, "TRAIT_STRONG_GRABBER" = TRAIT_STRONG_GRABBER, "TRAIT_STRONG_STOMACH" = TRAIT_STRONG_STOMACH, + "TRAIT_STUBBY_BODY" = TRAIT_STUBBY_BODY, "TRAIT_STUNIMMUNE" = TRAIT_STUNIMMUNE, + "TRAIT_STURDY_FRAME" = TRAIT_STURDY_FRAME, "TRAIT_SUCCUMB_OVERRIDE" = TRAIT_SUCCUMB_OVERRIDE, "TRAIT_SUICIDED" = TRAIT_SUICIDED, "TRAIT_SUPERMATTER_SOOTHER" = TRAIT_SUPERMATTER_SOOTHER, diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm index 150a10c108494..d709113d2b175 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -36,6 +36,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_BADTOUCH" = TRAIT_BADTOUCH, "TRAIT_BALD" = TRAIT_BALD, "TRAIT_BATON_RESISTANCE" = TRAIT_BATON_RESISTANCE, + "TRAIT_BEAST_EMPATHY" = TRAIT_BEAST_EMPATHY, "TRAIT_BLOCK_SHUTTLE_MOVEMENT" = TRAIT_BLOCK_SHUTTLE_MOVEMENT, "TRAIT_BLOOD_CLANS" = TRAIT_BLOOD_CLANS, "TRAIT_BLOODSHOT_EYES" = TRAIT_BLOODSHOT_EYES, @@ -72,6 +73,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_EMPATH" = TRAIT_EMPATH, "TRAIT_EXAMINE_FITNESS" = TRAIT_EXAMINE_FITNESS, "TRAIT_EXPANDED_FOV" = TRAIT_EXPANDED_FOV, + "TRAIT_EXPERT_FISHER" = TRAIT_EXPERT_FISHER, "TRAIT_FAKEDEATH" = TRAIT_FAKEDEATH, "TRAIT_FAST_CUFFING" = TRAIT_FAST_CUFFING, "TRAIT_FAT" = TRAIT_FAT, @@ -188,6 +190,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_RESISTHIGHPRESSURE" = TRAIT_RESISTHIGHPRESSURE, "TRAIT_RESISTLOWPRESSURE" = TRAIT_RESISTLOWPRESSURE, "TRAIT_RESTRAINED" = TRAIT_RESTRAINED, + "TRAIT_ROUGHRIDER" = TRAIT_ROUGHRIDER, "TRAIT_SECURITY_HUD" = TRAIT_SECURITY_HUD, "TRAIT_SELF_AWARE" = TRAIT_SELF_AWARE, "TRAIT_SETTLER" = TRAIT_SETTLER, @@ -208,7 +211,9 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_STABLELIVER" = TRAIT_STABLELIVER, "TRAIT_STRONG_GRABBER" = TRAIT_STRONG_GRABBER, "TRAIT_STRONG_STOMACH" = TRAIT_STRONG_STOMACH, + "TRAIT_STUBBY_BODY" = TRAIT_STUBBY_BODY, "TRAIT_STUNIMMUNE" = TRAIT_STUNIMMUNE, + "TRAIT_STURDY_FRAME" = TRAIT_STURDY_FRAME, "TRAIT_SURGEON" = TRAIT_SURGEON, "TRAIT_SURGICALLY_ANALYZED" = TRAIT_SURGICALLY_ANALYZED, "TRAIT_TAGGER" = TRAIT_TAGGER, diff --git a/code/datums/components/riding/riding_mob.dm b/code/datums/components/riding/riding_mob.dm index a808784b815ec..78158c55e8eb7 100644 --- a/code/datums/components/riding/riding_mob.dm +++ b/code/datums/components/riding/riding_mob.dm @@ -110,9 +110,14 @@ last_move_diagonal = ((direction & (direction - 1)) && (living_parent.loc == next)) var/modified_move_cooldown = vehicle_move_cooldown var/modified_move_delay = vehicle_move_delay - if(ishuman(user) && HAS_TRAIT(user, TRAIT_SETTLER)) - var/mob/living/carbon/human/settler_rider = user - switch(settler_rider.mob_mood.sanity_level) + if(ishuman(user) && HAS_TRAIT(user, TRAIT_ROUGHRIDER)) // YEEHAW! + var/mob/living/carbon/human/rough_rider = user + var/ride_benefit = null + if(HAS_TRAIT(rough_rider, TRAIT_PRIMITIVE)) // closer to a beast than a man; you don't need to think to ride! + ride_benefit = SANITY_LEVEL_GREAT + else + ride_benefit = rough_rider.mob_mood.sanity_level + switch(ride_benefit) if(SANITY_LEVEL_GREAT) modified_move_cooldown *= 0.5 modified_move_delay *= 0.5 diff --git a/code/datums/components/tameable.dm b/code/datums/components/tameable.dm index 43f48005bf89e..0d77688a22e7a 100644 --- a/code/datums/components/tameable.dm +++ b/code/datums/components/tameable.dm @@ -42,7 +42,7 @@ var/inform_tamer = FALSE atom_parent.balloon_alert(attacker, "fed") var/modified_tame_chance = current_tame_chance - if(HAS_TRAIT(attacker, TRAIT_SETTLER)) + if(HAS_TRAIT(attacker, TRAIT_BEAST_EMPATHY)) modified_tame_chance += 50 inform_tamer = TRUE if(unique || !already_friends(attacker)) @@ -71,7 +71,7 @@ if(inform_tamer) source.balloon_alert(tamer, "tamed") - if(HAS_TRAIT(tamer, TRAIT_SETTLER)) + if(HAS_TRAIT(tamer, TRAIT_BEAST_EMPATHY)) INVOKE_ASYNC(src, PROC_REF(rename_pet), source, tamer) if(unique) qdel(src) diff --git a/code/datums/elements/climbable.dm b/code/datums/elements/climbable.dm index 533facf709a92..a2c67742a357e 100644 --- a/code/datums/elements/climbable.dm +++ b/code/datums/elements/climbable.dm @@ -69,7 +69,7 @@ if(HAS_TRAIT(user, TRAIT_FREERUNNING)) //do you have any idea how fast I am??? adjusted_climb_time *= 0.8 adjusted_climb_stun *= 0.8 - if(HAS_TRAIT(user, TRAIT_SETTLER)) //hold on, gimme a moment, my tiny legs can't get over the goshdamn table + if(HAS_TRAIT(user, TRAIT_STUBBY_BODY)) //hold on, gimme a moment, my tiny legs can't get over the goshdamn table adjusted_climb_time *= 1.5 adjusted_climb_stun *= 1.5 LAZYADDASSOCLIST(current_climbers, climbed_thing, user) diff --git a/code/datums/quirks/positive_quirks/settler.dm b/code/datums/quirks/positive_quirks/settler.dm index 9b52403404b12..3b4084242b811 100644 --- a/code/datums/quirks/positive_quirks/settler.dm +++ b/code/datums/quirks/positive_quirks/settler.dm @@ -9,17 +9,26 @@ value = 4 mob_trait = TRAIT_SETTLER quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE - medical_record_text = "Patient appears to be abnormally stout." + medical_record_text = "Patient has been exposed to planetary conditions for extended periods, resulting in an excessively stout build." mail_goodies = list( /obj/item/clothing/shoes/workboots/mining, /obj/item/gps, ) + /// Most of the behavior of settler is from these traits, rather than exclusively the quirk + var/list/settler_traits = list( + TRAIT_EXPERT_FISHER, + TRAIT_ROUGHRIDER, + TRAIT_STUBBY_BODY, + TRAIT_BEAST_EMPATHY, + TRAIT_STURDY_FRAME, + ) /datum/quirk/item_quirk/settler/add(client/client_source) var/mob/living/carbon/human/human_quirkholder = quirk_holder human_quirkholder.set_mob_height(HUMAN_HEIGHT_SHORTEST) human_quirkholder.add_movespeed_modifier(/datum/movespeed_modifier/settler) human_quirkholder.physiology.hunger_mod *= 0.5 //good for you, shortass, you don't get hungry nearly as often + human_quirkholder.add_traits(settler_traits, QUIRK_TRAIT) /datum/quirk/item_quirk/settler/add_unique(client/client_source) give_item_to_holder(/obj/item/storage/box/papersack/wheat, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS)) @@ -32,3 +41,4 @@ human_quirkholder.set_mob_height(HUMAN_HEIGHT_MEDIUM) human_quirkholder.remove_movespeed_modifier(/datum/movespeed_modifier/settler) human_quirkholder.physiology.hunger_mod *= 2 + human_quirkholder.remove_traits(settler_traits, QUIRK_TRAIT) diff --git a/code/modules/fishing/sources/_fish_source.dm b/code/modules/fishing/sources/_fish_source.dm index eb681dc16cbfd..66d2bf0a880e3 100644 --- a/code/modules/fishing/sources/_fish_source.dm +++ b/code/modules/fishing/sources/_fish_source.dm @@ -85,8 +85,8 @@ GLOBAL_LIST_INIT(specific_fish_icons, zebra_typecacheof(list( . = fishing_difficulty // Difficulty modifier added by having the Settler quirk - if(HAS_TRAIT(fisherman, TRAIT_SETTLER)) - . += SETTLER_DIFFICULTY_MOD + if(HAS_TRAIT(fisherman, TRAIT_EXPERT_FISHER)) + . += EXPERT_FISHER_DIFFICULTY_MOD // Difficulty modifier added by the fisher's skill level if(!challenge || !(challenge.special_effects & FISHING_MINIGAME_RULE_NO_EXP)) diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 1ef72fd18e600..b0a747ff51d88 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -394,7 +394,15 @@ /obj/item/organ/internal/brain/primitive //No like books and stompy metal men name = "primitive brain" desc = "This juicy piece of meat has a clearly underdeveloped frontal lobe." - organ_traits = list(TRAIT_ADVANCEDTOOLUSER, TRAIT_CAN_STRIP, TRAIT_PRIMITIVE) // No literacy + organ_traits = list( + TRAIT_ADVANCEDTOOLUSER, + TRAIT_CAN_STRIP, + TRAIT_PRIMITIVE, // No literacy + TRAIT_FORBID_MINING_SHUTTLE_CONSOLE_OUTSIDE_STATION, + TRAIT_EXPERT_FISHER, // live off land, fish from river + TRAIT_ROUGHRIDER, // ride beast, chase down prey, flee from danger + TRAIT_BEAST_EMPATHY, // know the way of beast, calm with food + ) /obj/item/organ/internal/brain/golem name = "crystalline matrix" 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 ba813901b3e87..71a5c4c026193 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -157,7 +157,6 @@ Lizard subspecies: ASHWALKERS inherent_traits = list( TRAIT_MUTANT_COLORS, TRAIT_VIRUSIMMUNE, - TRAIT_FORBID_MINING_SHUTTLE_CONSOLE_OUTSIDE_STATION, ) species_language_holder = /datum/language_holder/lizard/ash digitigrade_customization = DIGITIGRADE_FORCED diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 80f1b2dfb484d..7dd1cf0d2880f 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1537,8 +1537,8 @@ else speedies += thing.slowdown - //if our movespeed mod is in the negatives, we don't modify it since that's a benefit - if(speedies > 0 && HAS_TRAIT(src, TRAIT_SETTLER)) + //if we have TRAIT_STURDY_FRAME, we reduce our overall speed penalty UNLESS that penalty would be a negative value, and therefore a speed boost. + if(speedies > 0 && HAS_TRAIT(src, TRAIT_STURDY_FRAME)) speedies *= 0.2 if(immutable_speedies) From caa8c1b07b477f464dd1e6ed2d3f8f1addc335b6 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Fri, 21 Jun 2024 07:13:17 +1200 Subject: [PATCH 150/172] Automatic changelog for PR #84090 [ci skip] --- html/changelogs/AutoChangeLog-pr-84090.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84090.yml diff --git a/html/changelogs/AutoChangeLog-pr-84090.yml b/html/changelogs/AutoChangeLog-pr-84090.yml new file mode 100644 index 0000000000000..bde4fd47b9183 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84090.yml @@ -0,0 +1,5 @@ +author: "Bisar" +delete-after: True +changes: + - rscadd: "Ashwalkers are now better at riding, taming animals, and fishing." + - code_imp: "Behavior for the settler trait has been partially atomized into several traits instead." \ No newline at end of file From fd693a067dd66a2e52a5aa20c42017ffad8f1dac Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 20 Jun 2024 23:01:36 +0300 Subject: [PATCH 151/172] New gibber and food/slime processor sprites (#84149) --- .../food_and_drinks/machinery/gibber.dm | 31 +++++++++++++----- .../food_and_drinks/machinery/processor.dm | 9 +++-- .../chemistry/machinery/reagentgrinder.dm | 4 +-- icons/obj/machines/kitchen.dmi | Bin 15911 -> 17083 bytes 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/code/modules/food_and_drinks/machinery/gibber.dm b/code/modules/food_and_drinks/machinery/gibber.dm index e0002817f782e..cd50f29ffe478 100644 --- a/code/modules/food_and_drinks/machinery/gibber.dm +++ b/code/modules/food_and_drinks/machinery/gibber.dm @@ -5,6 +5,7 @@ icon_state = "grinder" density = TRUE circuit = /obj/item/circuitboard/machine/gibber + anchored_tabletop_offset = 8 var/operating = FALSE //Is it on? var/dirty = FALSE // Does it need cleaning? @@ -15,13 +16,15 @@ /obj/machinery/gibber/Initialize(mapload) . = ..() + RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, PROC_REF(on_cleaned)) if(prob(5)) name = "meat grinder" desc = "Okay, if I... if I chop you up in a meat grinder, and the only thing that comes out, that's left of you, is your eyeball, \ you'r- you're PROBABLY DEAD! You're probably going to - not you, I'm just sayin', like, if you- if somebody were to, like, \ push you into a meat grinder, and, like, your- one of your finger bones is still intact, they're not gonna pick it up and go, \ Well see, yeah it wasn't deadly, it wasn't an instant kill move! You still got, like, this part of your finger left!" - add_overlay("grjam") + dirty = TRUE + update_appearance(UPDATE_OVERLAYS) /obj/machinery/gibber/RefreshParts() . = ..() @@ -45,16 +48,23 @@ /obj/machinery/gibber/update_overlays() . = ..() if(dirty) - . +="grbloody" - if(machine_stat & (NOPOWER|BROKEN)) + . += "grinder_bloody" + if(machine_stat & (NOPOWER|BROKEN) || panel_open) return if(!occupant) - . += "grjam" + . += "grinder_empty" + . += emissive_appearance(icon, "grinder_empty", src, alpha = src.alpha) return if(operating) - . += "gruse" + . += "grinder_active" + . += emissive_appearance(icon, "grinder_active", src, alpha = src.alpha) + . += "grinder_jaws_active" return - . += "gridle" + . += "grinder_loaded" + . += emissive_appearance(icon, "grinder_loaded", src, alpha = src.alpha) + +/obj/machinery/gibber/on_set_panel_open(old_value) + update_appearance(UPDATE_OVERLAYS) /obj/machinery/gibber/attack_paw(mob/user, list/modifiers) return attack_hand(user, modifiers) @@ -160,8 +170,7 @@ operating = TRUE update_appearance() - var/offset = prob(50) ? -2 : 2 - animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 200) //start shaking + Shake(pixelshiftx = 1, pixelshifty = 0, duration = gibtime) var/mob/living/mob_occupant = occupant var/sourcename = mob_occupant.real_name var/sourcejob @@ -223,6 +232,8 @@ /obj/machinery/gibber/proc/make_meat(obj/item/stack/sheet/animalhide/skin, list/obj/item/food/meat/slab/allmeat, meat_produced, gibtype, list/datum/disease/diseases) playsound(src.loc, 'sound/effects/splat.ogg', 50, TRUE) operating = FALSE + if (!dirty && prob(50)) + dirty = TRUE var/turf/T = get_turf(src) var/list/turf/nearby_turfs = RANGE_TURFS(3,T) - T if(skin) @@ -265,3 +276,7 @@ if(victim.loc == input) victim.forceMove(src) victim.gib(DROP_ALL_REMAINS) + +/obj/machinery/gibber/proc/on_cleaned(obj/source_component, obj/source) + dirty = FALSE + update_appearance(UPDATE_OVERLAYS) diff --git a/code/modules/food_and_drinks/machinery/processor.dm b/code/modules/food_and_drinks/machinery/processor.dm index 4a60cdbc26592..78dd71df128d9 100644 --- a/code/modules/food_and_drinks/machinery/processor.dm +++ b/code/modules/food_and_drinks/machinery/processor.dm @@ -4,7 +4,8 @@ name = "food processor" desc = "An industrial grinder used to process meat and other foods. Keep hands clear of intake area while operating." icon = 'icons/obj/machines/kitchen.dmi' - icon_state = "processor1" + base_icon_state = "processor" + icon_state = "processor" layer = BELOW_OBJ_LAYER density = TRUE pass_flags = PASSTABLE @@ -91,7 +92,7 @@ if(processing) to_chat(user, span_warning("[src] is in the process of processing!")) return TRUE - if(default_deconstruction_screwdriver(user, "processor", "processor1", attacking_item) || default_pry_open(attacking_item, close_after_pry = TRUE) || default_deconstruction_crowbar(attacking_item)) + if(default_deconstruction_screwdriver(user, base_icon_state + "_open", base_icon_state, attacking_item) || default_pry_open(attacking_item, close_after_pry = TRUE) || default_deconstruction_crowbar(attacking_item)) return if(istype(attacking_item, /obj/item/storage/bag/tray)) @@ -157,7 +158,7 @@ total_time += recipe.time var/duration = (total_time / rating_speed) - INVOKE_ASYNC(src, TYPE_PROC_REF(/atom, Shake), 2, 2, duration, max(duration*0.02, 0.01)) //initial values work out to duration 4 seconds, interval 0.8 + INVOKE_ASYNC(src, TYPE_PROC_REF(/atom, Shake), 1, 0, duration) sleep(duration) for(var/atom/movable/content_item in processor_contents) var/datum/food_processor_process/recipe = PROCESSOR_SELECT_RECIPE(content_item) @@ -189,6 +190,8 @@ /obj/machinery/processor/slime name = "slime processor" + base_icon_state = "processor_slime" + icon_state = "processor_slime" desc = "An industrial grinder with a sticker saying appropriated for science department. Keep hands clear of intake area while operating." circuit = /obj/item/circuitboard/machine/processor/slime diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index e206ffebbc9f8..a4fa10cb88c63 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -422,7 +422,7 @@ var/duration = time / speed - Shake(duration = duration) + Shake(pixelshiftx = 1, pixelshifty = 0, duration = duration) operating = TRUE if(!juicing) playsound(src, 'sound/machines/blender.ogg', 50, TRUE) @@ -490,7 +490,7 @@ var/duration = time / speed - Shake(duration = duration) + Shake(pixelshiftx = 1, pixelshifty = 0, duration = duration) operating = TRUE playsound(src, 'sound/machines/juicer.ogg', 20, TRUE) diff --git a/icons/obj/machines/kitchen.dmi b/icons/obj/machines/kitchen.dmi index c94afb8d78ad6a8440aa8ef79b477109bbe64574..2142125c5aa5cd1fe87cdd07c01da8825d30d915 100644 GIT binary patch literal 17083 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 P4tgu6DqAZ3A@KhIn6bjB From d104b8021cf373a751695c2897399a82196497d8 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Fri, 21 Jun 2024 08:01:56 +1200 Subject: [PATCH 152/172] Automatic changelog for PR #84149 [ci skip] --- html/changelogs/AutoChangeLog-pr-84149.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84149.yml diff --git a/html/changelogs/AutoChangeLog-pr-84149.yml b/html/changelogs/AutoChangeLog-pr-84149.yml new file mode 100644 index 0000000000000..babdfdbcddbde --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84149.yml @@ -0,0 +1,5 @@ +author: "MTandi" +delete-after: True +changes: + - image: "New gibber sprite" + - image: "New food/slime processor sprite" \ No newline at end of file From f6c44181cea46839d205848ff4ed4f5c6d093b1a Mon Sep 17 00:00:00 2001 From: Changelogs Date: Fri, 21 Jun 2024 00:21:28 +0000 Subject: [PATCH 153/172] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-83769.yml | 4 -- html/changelogs/AutoChangeLog-pr-83778.yml | 4 -- html/changelogs/AutoChangeLog-pr-83825.yml | 4 -- html/changelogs/AutoChangeLog-pr-83913.yml | 4 -- html/changelogs/AutoChangeLog-pr-83933.yml | 6 -- html/changelogs/AutoChangeLog-pr-83934.yml | 5 -- html/changelogs/AutoChangeLog-pr-83941.yml | 4 -- html/changelogs/AutoChangeLog-pr-83977.yml | 6 -- html/changelogs/AutoChangeLog-pr-84027.yml | 4 -- html/changelogs/AutoChangeLog-pr-84036.yml | 5 -- html/changelogs/AutoChangeLog-pr-84041.yml | 4 -- html/changelogs/AutoChangeLog-pr-84055.yml | 4 -- html/changelogs/AutoChangeLog-pr-84086.yml | 11 --- html/changelogs/AutoChangeLog-pr-84088.yml | 4 -- html/changelogs/AutoChangeLog-pr-84090.yml | 5 -- html/changelogs/AutoChangeLog-pr-84106.yml | 8 --- html/changelogs/AutoChangeLog-pr-84107.yml | 4 -- html/changelogs/AutoChangeLog-pr-84112.yml | 4 -- html/changelogs/AutoChangeLog-pr-84118.yml | 4 -- html/changelogs/AutoChangeLog-pr-84126.yml | 4 -- html/changelogs/AutoChangeLog-pr-84136.yml | 4 -- html/changelogs/AutoChangeLog-pr-84149.yml | 5 -- html/changelogs/archive/2024-06.yml | 82 ++++++++++++++++++++++ 23 files changed, 82 insertions(+), 107 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-83769.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83778.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83825.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83913.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83933.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83934.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83941.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-83977.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84027.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84036.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84041.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84055.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84086.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84088.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84090.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84106.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84107.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84112.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84118.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84126.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84136.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84149.yml diff --git a/html/changelogs/AutoChangeLog-pr-83769.yml b/html/changelogs/AutoChangeLog-pr-83769.yml deleted file mode 100644 index 919aa6eb4a078..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83769.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "EdgeLordExe" -delete-after: True -changes: - - rscadd: "Adds Feast of Owls ritual to heretic which allows one to forsake their ascension in exchange for immediate power." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83778.yml b/html/changelogs/AutoChangeLog-pr-83778.yml deleted file mode 100644 index 8d8d34e39104f..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83778.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "projectkepler-ru" -delete-after: True -changes: - - bugfix: "Wawastation bridge now has the correct access on their suit storage and medkit now actually starts filled" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83825.yml b/html/changelogs/AutoChangeLog-pr-83825.yml deleted file mode 100644 index 4a2fb94912a65..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83825.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "BeagleGaming1" -delete-after: True -changes: - - rscadd: "Added disks for accelerator modkits and crusher trophies to the bitrunning vendor" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83913.yml b/html/changelogs/AutoChangeLog-pr-83913.yml deleted file mode 100644 index e080f9e5aeb4f..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83913.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "mc-oofert" -delete-after: True -changes: - - bugfix: "fixed wrong access on one door on wawastation and also made lights on elevators not break (On Wawastation)" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83933.yml b/html/changelogs/AutoChangeLog-pr-83933.yml deleted file mode 100644 index d64620d533ad1..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83933.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "ArcaneMusic" -delete-after: True -changes: - - qol: "Vending machines now give audio feedback when you restock a vending refill and get a payout." - - qol: "The Restock tracker NTOS app for tracking vending machine contents now works on all consoles, and comes pre-installed on the cargochat cargo computers." - - balance: "Vending machines now offer a bit more credits when missing contents at the start of a round after getting restocked." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83934.yml b/html/changelogs/AutoChangeLog-pr-83934.yml deleted file mode 100644 index ad3574f8f8cb2..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83934.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "necromanceranne" -delete-after: True -changes: - - rscadd: "Replaces the Particle Acceleration Rifle with the Event Horizon anti-existential beam rifle. It shoots black holes. You can make this in-game. That's right, YOU!" - - balance: "Only one vortex anomaly can be made in a round." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83941.yml b/html/changelogs/AutoChangeLog-pr-83941.yml deleted file mode 100644 index e7aa6d982793b..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83941.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "GPeckman" -delete-after: True -changes: - - bugfix: "When on 'stream' mode, the cleaning spray from a bottle of space cleaner should no longer be blocked by just about everything." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83977.yml b/html/changelogs/AutoChangeLog-pr-83977.yml deleted file mode 100644 index d25e543431a43..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83977.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "Rex9001" -delete-after: True -changes: - - bugfix: "lunatics now get their hud properly" - - bugfix: "lunatics now get objectives" - - qol: "ascended moon heretics are now labelled as ringleaders and are easier for lunatics to spot" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84027.yml b/html/changelogs/AutoChangeLog-pr-84027.yml deleted file mode 100644 index 9af71299e44b8..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84027.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "LT3" -delete-after: True -changes: - - bugfix: "Fixed paramedics not having access to the Icebox NanoDrug using the west airlock" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84036.yml b/html/changelogs/AutoChangeLog-pr-84036.yml deleted file mode 100644 index 1719aafa28b22..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84036.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "r3dj4ck0424" -delete-after: True -changes: - - bugfix: "puts tiles under the wawa tool storage doors" - - bugfix: "allows you to access a door and a fire alarm on wawa's prison second floor" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84041.yml b/html/changelogs/AutoChangeLog-pr-84041.yml deleted file mode 100644 index f2f0bed84127c..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84041.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Xander3359" -delete-after: True -changes: - - bugfix: "Fix rust heretic being unable to rust walls or floors" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84055.yml b/html/changelogs/AutoChangeLog-pr-84055.yml deleted file mode 100644 index 0ae2635f1ca8c..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84055.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Goat" -delete-after: True -changes: - - bugfix: "Icebox's raptor den is now lined with asbestos and lead and no longer gets hit with radiation." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84086.yml b/html/changelogs/AutoChangeLog-pr-84086.yml deleted file mode 100644 index 50d8eaac49554..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84086.yml +++ /dev/null @@ -1,11 +0,0 @@ -author: "MTandi" -delete-after: True -changes: - - balance: "Added ordnance to extra access of geneticists and roboticists" - - balance: "Reduced parts scanning tests' machine count to 4 from 8" - - balance: "Reduced augmented organs scanning tests mob count to 1 from 2" - - balance: "Reduced equipped mech scanning test count to 1 from 2" - - balance: "Added polycrystal option to bluespace crystal scan test" - - bugfix: "Allowed NTNet relay in away circuit imprinter for NT Frontier app" - - qol: "NT Frontier app installed on RD and Scientists` PDAs by default" - - qol: "Updated NT Frontier app to be more user-friendly" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84088.yml b/html/changelogs/AutoChangeLog-pr-84088.yml deleted file mode 100644 index 1dce6075c2695..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84088.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "JackEnoff" -delete-after: True -changes: - - bugfix: "Repurposed Glands (Adrenals) now show their correct duration and chemical cost in its description." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84090.yml b/html/changelogs/AutoChangeLog-pr-84090.yml deleted file mode 100644 index bde4fd47b9183..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84090.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Bisar" -delete-after: True -changes: - - rscadd: "Ashwalkers are now better at riding, taming animals, and fishing." - - code_imp: "Behavior for the settler trait has been partially atomized into several traits instead." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84106.yml b/html/changelogs/AutoChangeLog-pr-84106.yml deleted file mode 100644 index dc33240181e5f..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84106.yml +++ /dev/null @@ -1,8 +0,0 @@ -author: "00-Steven" -delete-after: True -changes: - - refactor: "Updated cards/ids to use the proper item interaction system instead of attackby, please report any issues." - - bugfix: "You can no longer recolour an ID at any point if you open the menu but then don't select anything until later." - - bugfix: "ID cards can be recoloured using crayons/spraycans again." - - qol: "Prisoner IDs show genpop sentence time in hours/minutes/seconds instead of seconds." - - qol: "Prisoner IDs have genpop usage tips in their examine." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84107.yml b/html/changelogs/AutoChangeLog-pr-84107.yml deleted file mode 100644 index 1dda24aba25b0..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84107.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "mc-oofert" -delete-after: True -changes: - - rscadd: "every engineering lobby starts with a flatpacked flatpacker and multitool" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84112.yml b/html/changelogs/AutoChangeLog-pr-84112.yml deleted file mode 100644 index 9ea4b1d68bf9e..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84112.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "grungussuss" -delete-after: True -changes: - - bugfix: "Welding protection module for MODsuits protect flash-sensitives from welding arcs" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84118.yml b/html/changelogs/AutoChangeLog-pr-84118.yml deleted file mode 100644 index f91609e8fe3b9..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84118.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Rhials" -delete-after: True -changes: - - balance: "DRAGnets now come with a beacon they can be synced to, which will set the destination for the snare round's teleport ability." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84126.yml b/html/changelogs/AutoChangeLog-pr-84126.yml deleted file mode 100644 index 633e7a1a2870b..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84126.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - image: "Resprited all jetpacks" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84136.yml b/html/changelogs/AutoChangeLog-pr-84136.yml deleted file mode 100644 index a81b14d088658..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84136.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SyncIt21" -delete-after: True -changes: - - bugfix: "breaking an APC will depower the area" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84149.yml b/html/changelogs/AutoChangeLog-pr-84149.yml deleted file mode 100644 index babdfdbcddbde..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84149.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "MTandi" -delete-after: True -changes: - - image: "New gibber sprite" - - image: "New food/slime processor sprite" \ No newline at end of file diff --git a/html/changelogs/archive/2024-06.yml b/html/changelogs/archive/2024-06.yml index 1c03380f14dee..b77aab2bd31f1 100644 --- a/html/changelogs/archive/2024-06.yml +++ b/html/changelogs/archive/2024-06.yml @@ -892,3 +892,85 @@ - bugfix: wawa med elevator controls on the bottom floor are accessible - bugfix: sci entrance actually has access restrictions - bugfix: gasping makes sound now +2024-06-21: + 00-Steven: + - refactor: Updated cards/ids to use the proper item interaction system instead + of attackby, please report any issues. + - bugfix: You can no longer recolour an ID at any point if you open the menu but + then don't select anything until later. + - bugfix: ID cards can be recoloured using crayons/spraycans again. + - qol: Prisoner IDs show genpop sentence time in hours/minutes/seconds instead of + seconds. + - qol: Prisoner IDs have genpop usage tips in their examine. + ArcaneMusic: + - qol: Vending machines now give audio feedback when you restock a vending refill + and get a payout. + - qol: The Restock tracker NTOS app for tracking vending machine contents now works + on all consoles, and comes pre-installed on the cargochat cargo computers. + - balance: Vending machines now offer a bit more credits when missing contents at + the start of a round after getting restocked. + BeagleGaming1: + - rscadd: Added disks for accelerator modkits and crusher trophies to the bitrunning + vendor + Bisar: + - rscadd: Ashwalkers are now better at riding, taming animals, and fishing. + - code_imp: Behavior for the settler trait has been partially atomized into several + traits instead. + EdgeLordExe: + - rscadd: Adds Feast of Owls ritual to heretic which allows one to forsake their + ascension in exchange for immediate power. + GPeckman: + - bugfix: When on 'stream' mode, the cleaning spray from a bottle of space cleaner + should no longer be blocked by just about everything. + Goat: + - bugfix: Icebox's raptor den is now lined with asbestos and lead and no longer + gets hit with radiation. + JackEnoff: + - bugfix: Repurposed Glands (Adrenals) now show their correct duration and chemical + cost in its description. + LT3: + - bugfix: Fixed paramedics not having access to the Icebox NanoDrug using the west + airlock + MTandi: + - image: New gibber sprite + - image: New food/slime processor sprite + - balance: Added ordnance to extra access of geneticists and roboticists + - balance: Reduced parts scanning tests' machine count to 4 from 8 + - balance: Reduced augmented organs scanning tests mob count to 1 from 2 + - balance: Reduced equipped mech scanning test count to 1 from 2 + - balance: Added polycrystal option to bluespace crystal scan test + - bugfix: Allowed NTNet relay in away circuit imprinter for NT Frontier app + - qol: NT Frontier app installed on RD and Scientists` PDAs by default + - qol: Updated NT Frontier app to be more user-friendly + Rex9001: + - bugfix: lunatics now get their hud properly + - bugfix: lunatics now get objectives + - qol: ascended moon heretics are now labelled as ringleaders and are easier for + lunatics to spot + Rhials: + - balance: DRAGnets now come with a beacon they can be synced to, which will set + the destination for the snare round's teleport ability. + SmArtKar: + - image: Resprited all jetpacks + SyncIt21: + - bugfix: breaking an APC will depower the area + Xander3359: + - bugfix: Fix rust heretic being unable to rust walls or floors + grungussuss: + - bugfix: Welding protection module for MODsuits protect flash-sensitives from welding + arcs + mc-oofert: + - rscadd: every engineering lobby starts with a flatpacked flatpacker and multitool + - bugfix: fixed wrong access on one door on wawastation and also made lights on + elevators not break (On Wawastation) + necromanceranne: + - rscadd: Replaces the Particle Acceleration Rifle with the Event Horizon anti-existential + beam rifle. It shoots black holes. You can make this in-game. That's right, + YOU! + - balance: Only one vortex anomaly can be made in a round. + projectkepler-ru: + - bugfix: Wawastation bridge now has the correct access on their suit storage and + medkit now actually starts filled + r3dj4ck0424: + - bugfix: puts tiles under the wawa tool storage doors + - bugfix: allows you to access a door and a fire alarm on wawa's prison second floor From 7b1b4ec22970f3f2aac75b71711b3733e5a5e637 Mon Sep 17 00:00:00 2001 From: Mothblocks <35135081+Mothblocks@users.noreply.github.com> Date: Thu, 20 Jun 2024 19:10:38 -0700 Subject: [PATCH 154/172] Better delete character ux (#84158) I didn't see https://github.com/tgstation/tgstation/pull/83989 and that is on me. The UX of it is not suitable enough for preferences menu. - New row with only one entry makes the UI look much worse and adds too much blank space - The deleting confirmation prompt is a weird amount of work and also doesn't tell you when you get it wrong - A weird amount was being handled in JavaScript This reverts the PR and just starts over. You can see the UX here. https://github.com/tgstation/tgstation/assets/35135081/8106bca7-8c01-41da-8ede-e33a5a548583 ## Changelog :cl: qol: Dramatically improves delete character UI and UX. /:cl: --- code/modules/client/preferences.dm | 34 ++--------- code/modules/client/preferences_savefile.dm | 43 +++++++++++--- .../CharacterPreferenceWindow.tsx | 32 ----------- .../PreferencesMenu/DeleteCharacterPopup.tsx | 57 +++++++++++++++++++ .../interfaces/PreferencesMenu/MainPage.tsx | 30 +++++++++- 5 files changed, 124 insertions(+), 72 deletions(-) create mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/DeleteCharacterPopup.tsx diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 9877fe8869eb5..7cd3965718e60 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -211,37 +211,11 @@ GLOBAL_LIST_EMPTY(preferences_datums) if ("change_slot") // Save existing character save_character() - - // SAFETY: `load_character` performs sanitization the slot number - if (!load_character(params["slot"])) - tainted_character_profiles = TRUE - randomise_appearance_prefs() - save_character() - - for (var/datum/preference_middleware/preference_middleware as anything in middleware) - preference_middleware.on_new_character(usr) - - character_preview_view.update_body() - + // SAFETY: `switch_to_slot` performs sanitization on the slot number + switch_to_slot(params["slot"]) return TRUE - if ("remove_slot") - var/picked_slot = params["slot"] - var/confidence_check = tgui_input_text(usr, "To confirm the deletion of a character, type the name of the character.", "Character Deletion") - if(confidence_check != params["name"]) - return FALSE - - if(!remove_character(picked_slot)) - return FALSE - - if (!load_character(params["slotToJump"])) - randomise_appearance_prefs() - save_character() - - for (var/datum/preference_middleware/preference_middleware as anything in middleware) - preference_middleware.on_new_character(usr) - - tainted_character_profiles = TRUE - character_preview_view.update_body(); + if ("remove_current_slot") + remove_current_slot() return TRUE if ("rotate") character_preview_view.setDir(turn(character_preview_view.dir, -90)) diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 5750e296a80bc..9a6448e2e6d54 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -368,15 +368,42 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car return TRUE -/datum/preferences/proc/remove_character(slot) - SHOULD_NOT_SLEEP(TRUE) - if(!slot) - return FALSE - slot = sanitize_integer(slot, 1, max_save_slots, initial(default_slot)) +/datum/preferences/proc/switch_to_slot(new_slot) + // SAFETY: `load_character` performs sanitization on the slot number + if (!load_character(new_slot)) + tainted_character_profiles = TRUE + randomise_appearance_prefs() + save_character() + + for (var/datum/preference_middleware/preference_middleware as anything in middleware) + preference_middleware.on_new_character(usr) + + character_preview_view.update_body() + +/datum/preferences/proc/remove_current_slot() + PRIVATE_PROC(TRUE) + + var/closest_slot + for (var/other_slot in default_slot - 1 to 1 step -1) + var/save_data = savefile.get_entry("character[other_slot]") + if (!isnull(save_data)) + closest_slot = other_slot + break + + if (isnull(closest_slot)) + for (var/other_slot in default_slot + 1 to max_save_slots) + var/save_data = savefile.get_entry("character[other_slot]") + if (!isnull(save_data)) + closest_slot = other_slot + break - var/tree_key = "character[slot]" - savefile.remove_entry(tree_key) - return TRUE + if (isnull(closest_slot)) + stack_trace("remove_current_slot() being called when there are no slots to go to, the client should prevent this") + return + + savefile.remove_entry("character[default_slot]") + tainted_character_profiles = TRUE + switch_to_slot(closest_slot) /datum/preferences/proc/sanitize_be_special(list/input_be_special) var/list/output = list() diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx index 435d7c441d08d..8193384e6ae88 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx @@ -101,38 +101,6 @@ export const CharacterPreferenceWindow = (props) => { profiles={data.character_profiles} /> - - - {!data.content_unlocked && ( Buy BYOND premium for more slots! diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/DeleteCharacterPopup.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/DeleteCharacterPopup.tsx new file mode 100644 index 0000000000000..3656465677b21 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/DeleteCharacterPopup.tsx @@ -0,0 +1,57 @@ +import { useEffect, useState } from 'react'; + +import { useBackend } from '../../backend'; +import { Box, Button, Modal, Stack } from '../../components'; +import { PreferencesMenuData } from './data'; + +export const DeleteCharacterPopup = (props: { close: () => void }) => { + const { data, act } = useBackend(); + const [secondsLeft, setSecondsLeft] = useState(3); + + const { close } = props; + + useEffect(() => { + const interval = setInterval(() => { + setSecondsLeft((current) => current - 1); + }, 1000); + + return () => clearInterval(interval); + }); + + return ( + + + + Wait! + + + + {`You're about to delete ${data.character_preferences.names[data.name_to_use]} forever. Are you sure you want to do this?`} + + + + + + {/* Explicit width so that the layout doesn't shift */} + + + + + + + + + + + ); +}; diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/MainPage.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/MainPage.tsx index c79827d2abe74..35ddf9d2a7326 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/MainPage.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/MainPage.tsx @@ -1,7 +1,7 @@ import { filter, map, sortBy } from 'common/collections'; import { classes } from 'common/react'; import { createSearch } from 'common/string'; -import { useState } from 'react'; +import { ReactNode, useState } from 'react'; import { sendAct, useBackend } from '../../backend'; import { @@ -21,6 +21,7 @@ import { RandomSetting, ServerData, } from './data'; +import { DeleteCharacterPopup } from './DeleteCharacterPopup'; import { MultiNameInput, NameInput } from './names'; import features from './preferences/features'; import { @@ -383,6 +384,7 @@ export const PreferenceList = (props: { preferences: Record; randomizations: Record; maxHeight: string; + children?: ReactNode; }) => { return ( + + {props.children} ); }; @@ -478,6 +482,8 @@ export const MainPage = (props: { openSpecies: () => void }) => { const [currentClothingMenu, setCurrentClothingMenu] = useState( null, ); + const [deleteCharacterPopupOpen, setDeleteCharacterPopupOpen] = + useState(false); const [multiNameInputOpen, setMultiNameInputOpen] = useState(false); const [randomToggleEnabled] = useRandomToggleState(); @@ -549,6 +555,12 @@ export const MainPage = (props: { openSpecies: () => void }) => { /> )} + {deleteCharacterPopupOpen && ( + setDeleteCharacterPopupOpen(false)} + /> + )} + @@ -648,7 +660,21 @@ export const MainPage = (props: { openSpecies: () => void }) => { )} preferences={nonContextualPreferences} maxHeight="auto" - /> + > + + + + From e2efec3e66a71e1dd5ac438682718bff1057de0c Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Fri, 21 Jun 2024 14:10:55 +1200 Subject: [PATCH 155/172] Automatic changelog for PR #84158 [ci skip] --- html/changelogs/AutoChangeLog-pr-84158.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84158.yml diff --git a/html/changelogs/AutoChangeLog-pr-84158.yml b/html/changelogs/AutoChangeLog-pr-84158.yml new file mode 100644 index 0000000000000..90e914ceb5428 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84158.yml @@ -0,0 +1,4 @@ +author: "Mothblocks" +delete-after: True +changes: + - qol: "Dramatically improves delete character UI and UX." \ No newline at end of file From a4683217983615fe26b6546ecb23a10d908aae8d Mon Sep 17 00:00:00 2001 From: jimmyl <70376633+mc-oofert@users.noreply.github.com> Date: Fri, 21 Jun 2024 04:19:10 +0200 Subject: [PATCH 156/172] borg factory gives you your preference borg name (#84147) ## About The Pull Request borg factory gives you your preference borg name ## Why It's Good For The Game fixes #82880 ## Changelog :cl: fix: borg factory gives you your preference borg name /:cl: --- code/modules/mob/transform_procs.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 123fb0de82cd7..d186661d87fae 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -140,8 +140,8 @@ new_borg.gender = gender new_borg.SetInvisibility(INVISIBILITY_NONE) - if(client) - new_borg.updatename(client) + if(client?.prefs.read_preference(/datum/preference/name/cyborg) != DEFAULT_CYBORG_NAME) + new_borg.apply_pref_name(/datum/preference/name/cyborg, client) if(mind) //TODO //TODO WHAT if(!transfer_after) From a3204178a354f708851fad635f80406b657bced0 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Fri, 21 Jun 2024 14:19:47 +1200 Subject: [PATCH 157/172] Automatic changelog for PR #84147 [ci skip] --- html/changelogs/AutoChangeLog-pr-84147.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84147.yml diff --git a/html/changelogs/AutoChangeLog-pr-84147.yml b/html/changelogs/AutoChangeLog-pr-84147.yml new file mode 100644 index 0000000000000..d8500ff079b4d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84147.yml @@ -0,0 +1,4 @@ +author: "mc-oofert" +delete-after: True +changes: + - bugfix: "borg factory gives you your preference borg name" \ No newline at end of file From 18298332e6c97698bd2a40c9a018b6aad3a01ff1 Mon Sep 17 00:00:00 2001 From: Joshua Kidder <49173900+Metekillot@users.noreply.github.com> Date: Thu, 20 Jun 2024 22:20:01 -0400 Subject: [PATCH 158/172] Felinids no longer get negative moodlets roundstart about their tail (#84163) ## About The Pull Request Felinids receive their tail during creation of their character; the code wasn't accounting for special cases like this and always giving them negative mood events when they received a tail, even if they hadn't lost it yet. This no longer happens. ## Why It's Good For The Game Nanotrasen re-education programs guarantee memory loss for felinid employees from the Tail Wars of 2277, and this bring the code in line with that. Fixes #84048 ## Changelog :cl: Bisar fix: Felinids no longer remember losing their tail and regaining it roundstart; you need to do it during the round to get that mood event. /:cl: --- code/modules/surgery/organs/external/tails.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/modules/surgery/organs/external/tails.dm b/code/modules/surgery/organs/external/tails.dm index 977597f90f52f..e4cd3f50a4997 100644 --- a/code/modules/surgery/organs/external/tails.dm +++ b/code/modules/surgery/organs/external/tails.dm @@ -23,11 +23,12 @@ /obj/item/organ/external/tail/Insert(mob/living/carbon/receiver, special, movement_flags) . = ..() if(.) - original_owner ||= WEAKREF(receiver) - receiver.clear_mood_event("tail_lost") receiver.clear_mood_event("tail_balance_lost") + if(!special) // if some admin wants to give someone tail moodles for tail shenanigans, they can spawn it and do it by hand + original_owner ||= WEAKREF(receiver) + // If it's your tail, an infinite debuff is replaced with a timed one // If it's not your tail but of same species, I guess it works, but we are more sad // If it's not your tail AND of different species, we are horrified From 1eab8bdae9b581a65f2dedad17dcb05fcf220425 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Fri, 21 Jun 2024 14:20:24 +1200 Subject: [PATCH 159/172] Automatic changelog for PR #84163 [ci skip] --- html/changelogs/AutoChangeLog-pr-84163.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84163.yml diff --git a/html/changelogs/AutoChangeLog-pr-84163.yml b/html/changelogs/AutoChangeLog-pr-84163.yml new file mode 100644 index 0000000000000..6dbfc565dcbd0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84163.yml @@ -0,0 +1,4 @@ +author: "Bisar" +delete-after: True +changes: + - bugfix: "Felinids no longer remember losing their tail and regaining it roundstart; you need to do it during the round to get that mood event." \ No newline at end of file From 1e74f4b74011f0d246a84305c20ed9164ec5a4ee Mon Sep 17 00:00:00 2001 From: JupiterJaeden <48777952+JupiterJaeden@users.noreply.github.com> Date: Thu, 20 Jun 2024 22:21:09 -0400 Subject: [PATCH 160/172] Fixes conga lines breaking when going up/down stairs. (#84156) ## About The Pull Request Last PR I fixed ladders and no-grav conga lines, but I couldn't figure out stairs. I have returned to it and after several fucking hours I figured it out. Fixes conga lines of more than 2 breaking when pulling them up and down stairs. You can now go up and down stairs with conga lines of arbitrary length! ## Why It's Good For The Game Bug fix good. ## Changelog :cl: fix: Conga lines of more than 2 no longer break when going up and down stairs. /:cl: --- code/game/atoms_movable.dm | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index d8ae957994794..8135a3af59346 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -595,7 +595,7 @@ stop_pulling() else if(pulling.anchored || pulling.move_resist > move_force) stop_pulling() - if(!only_pulling && pulledby && moving_diagonally != FIRST_DIAG_STEP && (get_dist(src, pulledby) > 1 || z != pulledby.z)) //separated from our puller and not in the middle of a diagonal move. + if(!only_pulling && pulledby && moving_diagonally != FIRST_DIAG_STEP && (get_dist(src, pulledby) > 1 || (z != pulledby.z && !z_allowed))) //separated from our puller and not in the middle of a diagonal move. pulledby.stop_pulling() /atom/movable/proc/set_glide_size(target = 8) @@ -792,7 +792,14 @@ if(target_turf != current_turf || (moving_diagonally != SECOND_DIAG_STEP && ISDIAGONALDIR(pull_dir)) || get_dist(src, pulling) > 1) pulling.move_from_pull(src, target_turf, glide_size) - check_pulling() + if (pulledby) + if (pulledby.currently_z_moving) + check_pulling(z_allowed = TRUE) + //dont call check_pulling() here at all if there is a pulledby that is not currently z moving + //because it breaks stair conga lines, for some fucking reason. + //it's fine because the pull will be checked when this whole proc is called by the mob doing the pulling anyways + else + check_pulling() //glide_size strangely enough can change mid movement animation and update correctly while the animation is playing //This means that if you don't override it late like this, it will just be set back by the movement update that's called when you move turfs. From d621cfd46cf78e2c9bdac9d0628b9f75aee69900 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Fri, 21 Jun 2024 14:21:37 +1200 Subject: [PATCH 161/172] Automatic changelog for PR #84156 [ci skip] --- html/changelogs/AutoChangeLog-pr-84156.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84156.yml diff --git a/html/changelogs/AutoChangeLog-pr-84156.yml b/html/changelogs/AutoChangeLog-pr-84156.yml new file mode 100644 index 0000000000000..95d9e31986fb6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84156.yml @@ -0,0 +1,4 @@ +author: "JupiterJaeden" +delete-after: True +changes: + - bugfix: "Conga lines of more than 2 no longer break when going up and down stairs." \ No newline at end of file From ebfd39179dc1b8ff0f15ffcf95b22eedfaac07de Mon Sep 17 00:00:00 2001 From: FlufflesTheDog Date: Thu, 20 Jun 2024 19:22:57 -0700 Subject: [PATCH 162/172] Fix missing sanitization for citation pda alerts (#84091) ## About The Pull Request Sanitizes input sent to pdas when a citation is issued. The text length is +very+ limited so it'd be hard to abuse, but better safe than sorry. ## Why It's Good For The Game be clean... ## Changelog :cl: fix: sanitization on citation pda alerts /:cl: --- code/game/machinery/computer/records/security.dm | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/code/game/machinery/computer/records/security.dm b/code/game/machinery/computer/records/security.dm index c41779e7384ec..dac62612a4c74 100644 --- a/code/game/machinery/computer/records/security.dm +++ b/code/game/machinery/computer/records/security.dm @@ -176,7 +176,7 @@ return TRUE if("set_note") - var/note = trim(params["note"], MAX_MESSAGE_LEN) + var/note = strip_html_full(params["note"], MAX_MESSAGE_LEN) investigate_log("[user] has changed the security note of record: \"[target]\" from \"[target.security_note]\" to \"[note]\".") target.security_note = note return TRUE @@ -199,7 +199,7 @@ /// Handles adding a crime to a particular record. /obj/machinery/computer/records/security/proc/add_crime(mob/user, datum/record/crew/target, list/params) - var/input_name = trim(params["name"], MAX_CRIME_NAME_LEN) + var/input_name = strip_html_full(params["name"], MAX_CRIME_NAME_LEN) if(!input_name) to_chat(usr, span_warning("You must enter a name for the crime.")) playsound(src, 'sound/machines/terminal_error.ogg', 75, TRUE) @@ -213,7 +213,7 @@ var/input_details if(params["details"]) - input_details = trim(params["details"], MAX_MESSAGE_LEN) + input_details = strip_html_full(params["details"], MAX_MESSAGE_LEN) if(params["fine"] == 0) var/datum/crime/new_crime = new(name = input_name, details = input_details, author = usr) @@ -245,13 +245,13 @@ return FALSE if(params["name"] && length(params["name"]) > 2 && params["name"] != editing_crime.name) - var/new_name = trim(params["name"], MAX_CRIME_NAME_LEN) + var/new_name = strip_html_full(params["name"], MAX_CRIME_NAME_LEN) investigate_log("[user] edited crime: \"[editing_crime.name]\" for target: \"[target.name]\", changing the name to: \"[new_name]\".", INVESTIGATE_RECORDS) editing_crime.name = new_name return TRUE if(params["details"] && length(params["description"]) > 2 && params["name"] != editing_crime.name) - var/new_details = trim(params["details"], MAX_MESSAGE_LEN) + var/new_details = strip_html_full(params["details"], MAX_MESSAGE_LEN) investigate_log("[user] edited crime \"[editing_crime.name]\" for target: \"[target.name]\", changing the details to: \"[new_details]\" from: \"[editing_crime.details]\".", INVESTIGATE_RECORDS) editing_crime.details = new_details return TRUE @@ -327,9 +327,9 @@ playsound(src, 'sound/machines/printer.ogg', 100, TRUE) var/obj/item/printable - var/input_alias = trim(params["alias"], MAX_NAME_LEN) || target.name - var/input_description = trim(params["desc"], MAX_BROADCAST_LEN) || "No further details." - var/input_header = trim(params["head"], 8) || capitalize(params["type"]) + var/input_alias = strip_html_full(params["alias"], MAX_NAME_LEN) || target.name + var/input_description = strip_html_full(params["desc"], MAX_BROADCAST_LEN) || "No further details." + var/input_header = strip_html_full(params["head"], 8) || capitalize(params["type"]) switch(params["type"]) if("missing") From 23cfbd3987139d5d35140ec9155eefc975915625 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Fri, 21 Jun 2024 14:23:16 +1200 Subject: [PATCH 163/172] Automatic changelog for PR #84091 [ci skip] --- html/changelogs/AutoChangeLog-pr-84091.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84091.yml diff --git a/html/changelogs/AutoChangeLog-pr-84091.yml b/html/changelogs/AutoChangeLog-pr-84091.yml new file mode 100644 index 0000000000000..58059ae4af9d8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84091.yml @@ -0,0 +1,4 @@ +author: "FlufflesTheDog" +delete-after: True +changes: + - bugfix: "sanitization on citation pda alerts" \ No newline at end of file From b02ff6e94637763bf79836a13b67a85c20efedba Mon Sep 17 00:00:00 2001 From: Aylong <69762909+AyIong@users.noreply.github.com> Date: Fri, 21 Jun 2024 05:45:38 +0300 Subject: [PATCH 164/172] Fullscreen QoL (#84066) ## About The Pull Request Add hotkey for toggling fullscreen (F11) Add toggle fullscreen button to the skin buttons Also, fix little padding on the left and right, maybe that was the intention, so please tell me if this needs to be returned, screenshots bellow | Before | After(With padding) | After(Without padding/final result) | | - | - | - | | ![image](https://github.com/tgstation/tgstation/assets/69762909/3c8863dc-94cf-40e9-9eec-24fe548f1474) | ![image](https://github.com/tgstation/tgstation/assets/69762909/ae167f4d-02e3-4b6d-874f-3b5c38d77bc8) | ![image](https://github.com/tgstation/tgstation/assets/69762909/30a4ed6c-fc0f-468c-ab01-7c4b66551d0f) | ## Why It's Good For The Game It is a little bit not convenient to search for the Toggle Fullscreen button in any of the tabs, I think no one will argue that the hotkey is more convenient ## Changelog :cl: qol: Fullscreen mode can now be toggled by pressing F11 or the button at the top right /:cl: --- code/__DEFINES/keybinding.dm | 1 + code/datums/keybinding/client.dm | 14 +++++++ interface/skin.dmf | 61 +++++++++++++++++------------- tgui/packages/tgui-panel/themes.ts | 4 ++ 4 files changed, 54 insertions(+), 26 deletions(-) diff --git a/code/__DEFINES/keybinding.dm b/code/__DEFINES/keybinding.dm index 2a2a092c6d05b..5f025ad99cffb 100644 --- a/code/__DEFINES/keybinding.dm +++ b/code/__DEFINES/keybinding.dm @@ -26,6 +26,7 @@ //Client #define COMSIG_KB_CLIENT_GETHELP_DOWN "keybinding_client_gethelp_down" #define COMSIG_KB_CLIENT_SCREENSHOT_DOWN "keybinding_client_screenshot_down" +#define COMSIG_KB_CLIENT_FULLSCREEN_DOWN "keybinding_client_fullscreen_down" #define COMSIG_KB_CLIENT_MINIMALHUD_DOWN "keybinding_client_minimalhud_down" //Communication diff --git a/code/datums/keybinding/client.dm b/code/datums/keybinding/client.dm index 81b9bb6c287a3..f36645692c992 100644 --- a/code/datums/keybinding/client.dm +++ b/code/datums/keybinding/client.dm @@ -32,6 +32,20 @@ winset(user, null, "command=.auto") return TRUE +/datum/keybinding/client/toggle_fullscreen + hotkey_keys = list("F11") + name = "toggle_fullscreen" + full_name = "Toggle Fullscreen" + description = "Makes the game window fullscreen." + keybind_signal = COMSIG_KB_CLIENT_FULLSCREEN_DOWN + +/datum/keybinding/client/toggle_fullscreen/down(client/user) + . = ..() + if(.) + return + user.toggle_fullscreen() + return TRUE + /datum/keybinding/client/minimal_hud hotkey_keys = list("F12") name = "minimal_hud" diff --git a/interface/skin.dmf b/interface/skin.dmf index b8d1d82f17558..8388f5107b64c 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -70,8 +70,8 @@ window "mainwindow" menu = "menu" elem "split" type = CHILD - pos = 3,0 - size = 634x440 + pos = 0,0 + size = 640x440 anchor1 = 0,0 anchor2 = 100,100 saved-params = "splitter" @@ -159,58 +159,67 @@ window "infowindow" is-vert = false elem "changelog" type = BUTTON - pos = 16,5 - size = 104x20 - anchor1 = 3,0 - anchor2 = 19,0 + pos = 5,5 + size = 90x20 + anchor1 = 1,0 + anchor2 = 15,0 saved-params = "is-checked" text = "Changelog" command = "changelog" elem "rules" type = BUTTON - pos = 120,5 - size = 100x20 - anchor1 = 19,0 - anchor2 = 34,0 + pos = 95,5 + size = 90x20 + anchor1 = 15,0 + anchor2 = 29,0 saved-params = "is-checked" text = "Rules" command = "rules" elem "wiki" type = BUTTON - pos = 220,5 - size = 100x20 - anchor1 = 34,0 - anchor2 = 50,0 + pos = 185,5 + size = 90x20 + anchor1 = 29,0 + anchor2 = 43,0 saved-params = "is-checked" text = "Wiki" command = "wiki" elem "forum" type = BUTTON - pos = 320,5 - size = 100x20 - anchor1 = 50,0 - anchor2 = 66,0 + pos = 275,5 + size = 90x20 + anchor1 = 43,0 + anchor2 = 57,0 saved-params = "is-checked" text = "Forum" command = "forum" elem "github" type = BUTTON - pos = 420,5 - size = 100x20 - anchor1 = 66,0 - anchor2 = 81,0 + pos = 365,5 + size = 90x20 + anchor1 = 57,0 + anchor2 = 71,0 saved-params = "is-checked" text = "Github" command = "github" elem "report-issue" type = BUTTON - pos = 520,5 - size = 100x20 - anchor1 = 81,0 - anchor2 = 97,0 + pos = 455,5 + size = 90x20 + anchor1 = 71,0 + anchor2 = 85,0 saved-params = "is-checked" text = "Report Issue" command = "report-issue" + elem "fullscreen-toggle" + type = BUTTON + pos = 545,5 + size = 90x20 + anchor1 = 85,0 + anchor2 = 99,0 + saved-params = "is-checked" + text = "Fullscreen" + command = "fullscreen" window "outputwindow" elem "outputwindow" diff --git a/tgui/packages/tgui-panel/themes.ts b/tgui/packages/tgui-panel/themes.ts index d8f0ce50b7974..67061ff1f4cf1 100644 --- a/tgui/packages/tgui-panel/themes.ts +++ b/tgui/packages/tgui-panel/themes.ts @@ -57,6 +57,8 @@ export const setClientTheme = (name) => { 'github.text-color': '#000000', 'report-issue.background-color': 'none', 'report-issue.text-color': '#000000', + 'fullscreen-toggle.background-color': 'none', + 'fullscreen-toggle.text-color': '#000000', // Status and verb tabs 'output.background-color': 'none', 'output.text-color': '#000000', @@ -109,6 +111,8 @@ export const setClientTheme = (name) => { 'github.text-color': COLOR_DARK_TEXT, 'report-issue.background-color': '#492020', 'report-issue.text-color': COLOR_DARK_TEXT, + 'fullscreen-toggle.background-color': '#494949', + 'fullscreen-toggle.text-color': COLOR_DARK_TEXT, // Status and verb tabs 'output.background-color': COLOR_DARK_BG_DARKER, 'output.text-color': COLOR_DARK_TEXT, From c88438ea35a177fc593f0911af1b3db84157e182 Mon Sep 17 00:00:00 2001 From: Thunder12345 Date: Fri, 21 Jun 2024 03:47:30 +0100 Subject: [PATCH 165/172] Removes the locker staff from Ragin' Mages deathmatch (#84060) ## About The Pull Request See title, removes this particular staff from the loot list. ## Why It's Good For The Game Locker staffs only serve to drag out the match unreasonably, while denying everyone involved their time and fun. It's boring to be the person trapped in one having to wait a whole minute to resist out, and it's boring to be the last other person left alive unable to finish the match because you can't find the other guy who is actually stuck in one of the 20 lockers scattered across the arena. ## Changelog :cl: del: Locker staffs have been removed from the Ragin' Mages deathmatch lootcrate pool. /:cl: --- code/game/objects/structures/mystery_box.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/game/objects/structures/mystery_box.dm b/code/game/objects/structures/mystery_box.dm index ab8a25f04c675..9dc8152f5b7bf 100644 --- a/code/game/objects/structures/mystery_box.dm +++ b/code/game/objects/structures/mystery_box.dm @@ -85,7 +85,6 @@ GLOBAL_LIST_INIT(mystery_magic, list( /obj/item/gun/magic/staff/door, /obj/item/gun/magic/staff/honk, /obj/item/gun/magic/staff/spellblade, - /obj/item/gun/magic/staff/locker, /obj/item/gun/magic/staff/flying, /obj/item/gun/magic/staff/babel, /obj/item/singularityhammer, From 9da1859f4cd2a26f9768b5a7d719b6c873a57358 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Fri, 21 Jun 2024 14:50:29 +1200 Subject: [PATCH 166/172] Automatic changelog for PR #84066 [ci skip] --- html/changelogs/AutoChangeLog-pr-84066.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84066.yml diff --git a/html/changelogs/AutoChangeLog-pr-84066.yml b/html/changelogs/AutoChangeLog-pr-84066.yml new file mode 100644 index 0000000000000..0ea603f5e6b4a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84066.yml @@ -0,0 +1,4 @@ +author: "AyIong" +delete-after: True +changes: + - qol: "Fullscreen mode can now be toggled by pressing F11 or the button at the top right" \ No newline at end of file From 7579e0e1734ee40b33ce1fd3fc5c2dd08fe30404 Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Fri, 21 Jun 2024 14:50:33 +1200 Subject: [PATCH 167/172] Automatic changelog for PR #84060 [ci skip] --- html/changelogs/AutoChangeLog-pr-84060.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84060.yml diff --git a/html/changelogs/AutoChangeLog-pr-84060.yml b/html/changelogs/AutoChangeLog-pr-84060.yml new file mode 100644 index 0000000000000..1b2f4ac222b39 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84060.yml @@ -0,0 +1,4 @@ +author: "Thunder12345" +delete-after: True +changes: + - rscdel: "Locker staffs have been removed from the Ragin' Mages deathmatch lootcrate pool." \ No newline at end of file From b77eb3f4d1486c8c12081237b8f2e8980410af66 Mon Sep 17 00:00:00 2001 From: MelokGleb <99420088+MelokGleb@users.noreply.github.com> Date: Sat, 22 Jun 2024 00:28:01 +0300 Subject: [PATCH 168/172] Adds sprite for debug eldritch paintings (#84179) --- .../heretic/items/eldritch_painting.dm | 4 ++-- icons/obj/signs.dmi | Bin 48515 -> 63818 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/antagonists/heretic/items/eldritch_painting.dm b/code/modules/antagonists/heretic/items/eldritch_painting.dm index 5302fc1c9c148..3332c4e31ba63 100644 --- a/code/modules/antagonists/heretic/items/eldritch_painting.dm +++ b/code/modules/antagonists/heretic/items/eldritch_painting.dm @@ -4,14 +4,14 @@ icon = 'icons/obj/signs.dmi' resistance_flags = FLAMMABLE flags_1 = NONE - icon_state = "frame-empty" + icon_state = "eldritch_painting_debug" result_path = /obj/structure/sign/painting/eldritch pixel_shift = 30 /obj/structure/sign/painting/eldritch name = "The debug and a coder who slept" icon = 'icons/obj/signs.dmi' - icon_state = "frame-empty" + icon_state = "eldritch_painting_debug" custom_materials = list(/datum/material/wood =SHEET_MATERIAL_AMOUNT) resistance_flags = FLAMMABLE buildable_sign = FALSE diff --git a/icons/obj/signs.dmi b/icons/obj/signs.dmi index 78cc96fabbc138d92ed14efe84d0fe3724855966..a2069ba5d9d3b71133a843bb58e38785028f9945 100644 GIT binary patch literal 63818 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⁡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

8M_q2UbjW0`llFVP9 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 Date: Sat, 22 Jun 2024 09:28:21 +1200 Subject: [PATCH 169/172] Automatic changelog for PR #84179 [ci skip] --- html/changelogs/AutoChangeLog-pr-84179.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84179.yml diff --git a/html/changelogs/AutoChangeLog-pr-84179.yml b/html/changelogs/AutoChangeLog-pr-84179.yml new file mode 100644 index 0000000000000..398e41712c894 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84179.yml @@ -0,0 +1,4 @@ +author: "MelokGleb" +delete-after: True +changes: + - image: "added sprite for debug heretic painting" \ No newline at end of file From 2f2b74338cb7397e4128ccdef00bbc4d6c67a0a5 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Sat, 22 Jun 2024 00:37:45 +0000 Subject: [PATCH 170/172] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-84060.yml | 4 ---- html/changelogs/AutoChangeLog-pr-84066.yml | 4 ---- html/changelogs/AutoChangeLog-pr-84091.yml | 4 ---- html/changelogs/AutoChangeLog-pr-84147.yml | 4 ---- html/changelogs/AutoChangeLog-pr-84156.yml | 4 ---- html/changelogs/AutoChangeLog-pr-84158.yml | 4 ---- html/changelogs/AutoChangeLog-pr-84163.yml | 4 ---- html/changelogs/AutoChangeLog-pr-84179.yml | 4 ---- html/changelogs/archive/2024-06.yml | 20 ++++++++++++++++++++ 9 files changed, 20 insertions(+), 32 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-84060.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84066.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84091.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84147.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84156.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84158.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84163.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-84179.yml diff --git a/html/changelogs/AutoChangeLog-pr-84060.yml b/html/changelogs/AutoChangeLog-pr-84060.yml deleted file mode 100644 index 1b2f4ac222b39..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84060.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Thunder12345" -delete-after: True -changes: - - rscdel: "Locker staffs have been removed from the Ragin' Mages deathmatch lootcrate pool." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84066.yml b/html/changelogs/AutoChangeLog-pr-84066.yml deleted file mode 100644 index 0ea603f5e6b4a..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84066.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "AyIong" -delete-after: True -changes: - - qol: "Fullscreen mode can now be toggled by pressing F11 or the button at the top right" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84091.yml b/html/changelogs/AutoChangeLog-pr-84091.yml deleted file mode 100644 index 58059ae4af9d8..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84091.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "FlufflesTheDog" -delete-after: True -changes: - - bugfix: "sanitization on citation pda alerts" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84147.yml b/html/changelogs/AutoChangeLog-pr-84147.yml deleted file mode 100644 index d8500ff079b4d..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84147.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "mc-oofert" -delete-after: True -changes: - - bugfix: "borg factory gives you your preference borg name" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84156.yml b/html/changelogs/AutoChangeLog-pr-84156.yml deleted file mode 100644 index 95d9e31986fb6..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84156.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "JupiterJaeden" -delete-after: True -changes: - - bugfix: "Conga lines of more than 2 no longer break when going up and down stairs." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84158.yml b/html/changelogs/AutoChangeLog-pr-84158.yml deleted file mode 100644 index 90e914ceb5428..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84158.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Mothblocks" -delete-after: True -changes: - - qol: "Dramatically improves delete character UI and UX." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84163.yml b/html/changelogs/AutoChangeLog-pr-84163.yml deleted file mode 100644 index 6dbfc565dcbd0..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84163.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Bisar" -delete-after: True -changes: - - bugfix: "Felinids no longer remember losing their tail and regaining it roundstart; you need to do it during the round to get that mood event." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84179.yml b/html/changelogs/AutoChangeLog-pr-84179.yml deleted file mode 100644 index 398e41712c894..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-84179.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "MelokGleb" -delete-after: True -changes: - - image: "added sprite for debug heretic painting" \ No newline at end of file diff --git a/html/changelogs/archive/2024-06.yml b/html/changelogs/archive/2024-06.yml index b77aab2bd31f1..2b62716374ae9 100644 --- a/html/changelogs/archive/2024-06.yml +++ b/html/changelogs/archive/2024-06.yml @@ -974,3 +974,23 @@ r3dj4ck0424: - bugfix: puts tiles under the wawa tool storage doors - bugfix: allows you to access a door and a fire alarm on wawa's prison second floor +2024-06-22: + AyIong: + - qol: Fullscreen mode can now be toggled by pressing F11 or the button at the top + right + Bisar: + - bugfix: Felinids no longer remember losing their tail and regaining it roundstart; + you need to do it during the round to get that mood event. + FlufflesTheDog: + - bugfix: sanitization on citation pda alerts + JupiterJaeden: + - bugfix: Conga lines of more than 2 no longer break when going up and down stairs. + MelokGleb: + - image: added sprite for debug heretic painting + Mothblocks: + - qol: Dramatically improves delete character UI and UX. + Thunder12345: + - rscdel: Locker staffs have been removed from the Ragin' Mages deathmatch lootcrate + pool. + mc-oofert: + - bugfix: borg factory gives you your preference borg name From 1116f150eba7e250c26aa6816ea69852896fd724 Mon Sep 17 00:00:00 2001 From: Jeremiah <42397676+jlsnow301@users.noreply.github.com> Date: Fri, 21 Jun 2024 19:39:44 -0700 Subject: [PATCH 171/172] Bitrunning: Tweaks, QoL and removals (#84125) ## About The Pull Request See changelog for shortlist 1. **Threat changes.** I was a bit unsatisfied with the rate of antag spawns. These have been increased considerably. The clamped probability has been increased from 1-10 to 5-15. The probability increases from 5 to 15 as domains are completed. Generally, in a standard round, the chance of spawning at least one antag should be around ~50% at 7 domains completed. Emagging a server doubles this rate. 2. **Map changes.** Starfront saloon was a cool idea on paper: A totally modular map. However, it looked very uninspired and was so much of a chore on the map loading system that it prompted players to admin help how long it took, thinking it was broken. I've removed the map. I have others I want to implement that don't look so bad. 3. **QoL changes**. Ghost observer experience is improved. Previously, you could click netpods to view their avatar, and now you can click the hololadder to return. I've included examine text to show this. The server's examine text will now also give you clues that it's emagged (ghost only). The examine text on hololadders has also been improved. 4. **Bitrunning antags.** These were designed as temporary, but they were everything but. Spawning as one would prevent your revival, which just isn't a good tradeoff for something that's going to get deleted in a minute. Now, this system uses temp bodies just like CTF, so you can return once you're dead. (exception: coming station side) 5. **Maps**: Syndicate assault is still one of my favorites, but there's cheesy exploits like instantly breaking the display case to lock down the ship, turning on turrets which are EXTRA lethal, etc. I've added some pistols to the closets and removed some of these exploits. 6. **Cooldown**: Yes, no one seems to upgrade these ever, and it proved a poor technique to encourage bitrunners to leave their rooms. I had other plans to encourage this, not included here, so I think lowering the cooldown time is beneficial. 3min -> 2min > [!NOTE] > File diff: removed a map ## Why It's Good For The Game Closes #83787 General updates and QoL for bitrunning to keep it fresh. I was quite disappointed with the scaling of threat, and most players haven't even seen bitrunning antags except when I admin spawn them. These numbers aren't hard set in my mind, and could be adjusted. I generally want bitrunning easier to access and more "temporary" which is in keeping with its design doc. ## Changelog :cl: fix: Bitrunning made more illegal: Increased the rate at which antags spawn. fix: "Temporary" bitrunning antagonists and spawners are made actually temporary. You will return to your original body after death, just like CTF. add: Added more examine text for ghosts to bitrunning equipment. balance: Server cooldown reduced by 1 minute at base level. add: As an observer, you can now switch views between station and virtual domain by clicking the hololadder and netpod respectively. del: Removed the starfront saloon BR map. fix: Syndicate assault map: Added pistols, reduced exploits. /:cl: --- _maps/virtual_domains/starfront_saloon.dmm | 1834 ----------------- _maps/virtual_domains/syndicate_assault.dmm | 32 +- code/datums/components/temporary_body.dm | 8 +- .../bitrunning/components/virtual_entity.dm | 6 +- code/modules/bitrunning/event.dm | 6 +- code/modules/bitrunning/objects/hololadder.dm | 40 +- code/modules/bitrunning/objects/netpod.dm | 19 +- code/modules/bitrunning/server/_parent.dm | 31 +- .../modules/bitrunning/server/map_handling.dm | 3 +- .../bitrunning/server/obj_generation.dm | 2 +- code/modules/bitrunning/server/threats.dm | 36 +- code/modules/bitrunning/spawners.dm | 8 +- .../domains/starfront_saloon.dm | 14 - code/modules/mob_spawn/mob_spawn.dm | 9 +- strings/tips.txt | 3 + tgstation.dme | 1 - 16 files changed, 156 insertions(+), 1896 deletions(-) delete mode 100644 _maps/virtual_domains/starfront_saloon.dmm delete mode 100644 code/modules/bitrunning/virtual_domain/domains/starfront_saloon.dm diff --git a/_maps/virtual_domains/starfront_saloon.dmm b/_maps/virtual_domains/starfront_saloon.dmm deleted file mode 100644 index 277382b6dbbf2..0000000000000 --- a/_maps/virtual_domains/starfront_saloon.dmm +++ /dev/null @@ -1,1834 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"ae" = ( -/obj/item/kirbyplants/random, -/obj/effect/turf_decal/tile/dark_red/half, -/turf/open/floor/sepia, -/area/virtual_domain) -"cK" = ( -/obj/effect/landmark/bitrunning/mob_segment, -/turf/template_noop, -/area/virtual_domain) -"cU" = ( -/turf/template_noop, -/area/virtual_domain/safehouse) -"df" = ( -/obj/effect/spawner/random/vending/snackvend, -/turf/open/floor/sepia, -/area/virtual_domain) -"do" = ( -/obj/effect/spawner/random/trash/garbage, -/turf/open/floor/sepia, -/area/virtual_domain) -"eU" = ( -/obj/effect/spawner/random/structure/crate, -/obj/machinery/light/small/directional/north, -/turf/open/floor/catwalk_floor, -/area/virtual_domain) -"gh" = ( -/obj/effect/spawner/random/vending/colavend, -/turf/open/floor/sepia, -/area/virtual_domain) -"hz" = ( -/obj/item/clothing/head/cowboy, -/obj/item/clothing/head/cowboy, -/obj/item/clothing/head/cowboy, -/obj/structure/closet, -/turf/template_noop, -/area/virtual_domain/safehouse) -"il" = ( -/turf/open/floor/sepia, -/area/virtual_domain) -"it" = ( -/obj/modular_map_root/generic{ - key = "station_medium" - }, -/turf/open/floor/sepia, -/area/virtual_domain) -"iJ" = ( -/obj/machinery/light/directional/south, -/obj/effect/spawner/random/structure/table, -/obj/effect/spawner/random/entertainment/plushie, -/obj/effect/turf_decal/tile/dark_red/half, -/turf/open/floor/sepia, -/area/virtual_domain) -"iO" = ( -/obj/effect/spawner/random/structure/crate, -/obj/effect/turf_decal/tile/dark_red/half, -/turf/open/floor/sepia, -/area/virtual_domain) -"jt" = ( -/obj/item/gun/energy/marksman_revolver{ - pixel_x = 8; - pixel_y = 4 - }, -/obj/item/gun/energy/marksman_revolver{ - pixel_x = 4 - }, -/obj/item/gun/energy/marksman_revolver{ - pixel_x = -4; - pixel_y = -4 - }, -/obj/structure/table, -/turf/template_noop, -/area/virtual_domain/safehouse) -"ma" = ( -/obj/machinery/light/directional/south, -/obj/effect/spawner/random/structure/table, -/obj/effect/spawner/random/decoration/generic, -/obj/effect/turf_decal/tile/dark_red/half, -/turf/open/floor/sepia, -/area/virtual_domain) -"mq" = ( -/obj/effect/baseturf_helper/virtual_domain, -/turf/closed/indestructible/binary, -/area/virtual_domain) -"mu" = ( -/turf/closed/wall, -/area/virtual_domain) -"on" = ( -/obj/structure/table/greyscale, -/obj/machinery/recharger{ - pixel_x = 8; - pixel_y = 4 - }, -/obj/machinery/recharger{ - pixel_x = -8; - pixel_y = 4 - }, -/turf/template_noop, -/area/virtual_domain/safehouse) -"oR" = ( -/obj/effect/spawner/random/structure/chair_maintenance{ - dir = 8 - }, -/turf/open/floor/sepia, -/area/virtual_domain) -"po" = ( -/obj/effect/baseturf_helper/virtual_domain, -/obj/modular_map_root/safehouse{ - key = "den" - }, -/turf/template_noop, -/area/virtual_domain/safehouse) -"sX" = ( -/obj/effect/spawner/random/decoration/statue, -/turf/open/floor/sepia, -/area/virtual_domain) -"uW" = ( -/obj/effect/decal/cleanable/dirt/dust, -/turf/open/floor/sepia, -/area/virtual_domain) -"ve" = ( -/obj/effect/spawner/random/trash/graffiti, -/turf/open/floor/catwalk_floor, -/area/virtual_domain) -"wB" = ( -/obj/effect/spawner/random/engineering/tank, -/obj/machinery/light/small/directional/north, -/turf/open/floor/catwalk_floor, -/area/virtual_domain) -"wK" = ( -/obj/machinery/light/small/directional/north, -/turf/open/floor/catwalk_floor, -/area/virtual_domain) -"yF" = ( -/obj/machinery/light/directional/south, -/obj/effect/spawner/random/structure/table, -/obj/effect/spawner/random/food_or_drink/snack, -/obj/effect/turf_decal/tile/dark_red/half, -/turf/open/floor/sepia, -/area/virtual_domain) -"zU" = ( -/obj/machinery/light/directional/south, -/obj/effect/spawner/random/structure/table, -/obj/effect/turf_decal/tile/dark_red/half, -/obj/machinery/recharger{ - pixel_x = 8; - pixel_y = 4 - }, -/turf/open/floor/sepia, -/area/virtual_domain) -"Au" = ( -/obj/effect/spawner/random/trash/garbage, -/obj/machinery/light/small/directional/north, -/turf/open/floor/catwalk_floor, -/area/virtual_domain) -"AF" = ( -/obj/effect/turf_decal/tile/dark_red/half, -/obj/effect/turf_decal/tile/dark_red/half, -/turf/open/floor/sepia, -/area/virtual_domain) -"Bi" = ( -/obj/effect/spawner/random/structure/chair_maintenance{ - dir = 4 - }, -/turf/open/floor/sepia, -/area/virtual_domain) -"BX" = ( -/obj/effect/spawner/random/trash/graffiti, -/obj/effect/turf_decal/tile/dark_red/half, -/turf/open/floor/sepia, -/area/virtual_domain) -"Ey" = ( -/obj/machinery/light/directional/south, -/obj/effect/spawner/random/structure/table, -/obj/effect/spawner/random/decoration/ornament, -/obj/effect/turf_decal/tile/dark_red/half, -/turf/open/floor/sepia, -/area/virtual_domain) -"EK" = ( -/obj/effect/spawner/random/structure/chair_maintenance{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt/dust, -/turf/open/floor/sepia, -/area/virtual_domain) -"Gz" = ( -/obj/effect/spawner/random/structure/crate, -/obj/effect/turf_decal/tile/dark_red/half, -/obj/effect/spawner/random/armory/shotgun, -/turf/open/floor/sepia, -/area/virtual_domain) -"GY" = ( -/obj/effect/spawner/random/entertainment/arcade, -/turf/open/floor/sepia, -/area/virtual_domain) -"Ib" = ( -/obj/effect/spawner/random/trash/bin, -/turf/open/floor/sepia, -/area/virtual_domain) -"Il" = ( -/obj/effect/turf_decal/tile/dark_red/half, -/obj/effect/decal/cleanable/dirt/dust, -/turf/open/floor/sepia, -/area/virtual_domain) -"Ix" = ( -/obj/structure/closet, -/obj/effect/spawner/random/maintenance/three, -/obj/effect/spawner/random/exotic/antag_gear, -/obj/machinery/light/small/directional/north, -/turf/open/floor/catwalk_floor, -/area/virtual_domain) -"Ja" = ( -/turf/closed/indestructible/binary, -/area/virtual_domain) -"JA" = ( -/obj/effect/spawner/random/structure/crate, -/turf/open/floor/catwalk_floor, -/area/virtual_domain) -"KD" = ( -/obj/effect/landmark/bitrunning/cache_spawn, -/turf/template_noop, -/area/virtual_domain) -"KN" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/virtual_domain) -"Lu" = ( -/obj/structure/table/greyscale, -/obj/machinery/recharger{ - pixel_x = 8; - pixel_y = 4 - }, -/obj/machinery/recharger{ - pixel_x = -8; - pixel_y = 4 - }, -/obj/effect/turf_decal/tile/dark_red/half, -/obj/machinery/light/directional/south, -/turf/open/floor/sepia, -/area/virtual_domain) -"MG" = ( -/obj/effect/spawner/random/trash/graffiti, -/obj/machinery/light/small/directional/north, -/turf/open/floor/catwalk_floor, -/area/virtual_domain) -"Oq" = ( -/obj/machinery/light/small/directional/south, -/turf/open/floor/sepia, -/area/virtual_domain) -"Ox" = ( -/obj/structure/closet, -/obj/effect/spawner/random/maintenance/five, -/obj/effect/spawner/random/armory/laser_gun, -/obj/machinery/light/small/directional/north, -/turf/open/floor/catwalk_floor, -/area/virtual_domain) -"OX" = ( -/turf/open/floor/catwalk_floor, -/area/virtual_domain) -"OZ" = ( -/obj/effect/spawner/random/structure/billboard, -/turf/open/floor/sepia, -/area/virtual_domain) -"PE" = ( -/turf/template_noop, -/area/virtual_domain) -"Qi" = ( -/obj/modular_map_root/generic{ - key = "station_small" - }, -/turf/open/floor/sepia, -/area/virtual_domain) -"QM" = ( -/obj/modular_map_root/generic{ - key = "station_large" - }, -/turf/open/floor/sepia, -/area/virtual_domain) -"QO" = ( -/obj/machinery/light/directional/east, -/turf/open/floor/sepia, -/area/virtual_domain) -"Rk" = ( -/obj/effect/spawner/random/trash/graffiti, -/turf/open/floor/sepia, -/area/virtual_domain) -"Te" = ( -/obj/machinery/light/directional/south, -/obj/effect/spawner/random/structure/table, -/obj/effect/spawner/random/engineering/toolbox, -/obj/effect/turf_decal/tile/dark_red/half, -/turf/open/floor/sepia, -/area/virtual_domain) -"Tn" = ( -/turf/open/space/basic, -/area/virtual_domain) -"TM" = ( -/obj/machinery/light/directional/south, -/obj/effect/turf_decal/tile/dark_red/half, -/turf/open/floor/sepia, -/area/virtual_domain) -"VX" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/sepia, -/area/virtual_domain) -"Wd" = ( -/obj/effect/turf_decal/tile/dark_red/half, -/turf/open/floor/sepia, -/area/virtual_domain) -"Wp" = ( -/obj/effect/landmark/bitrunning/mob_segment, -/turf/open/floor/sepia, -/area/virtual_domain) - -(1,1,1) = {" -Ja -Ja -Ja -Ja -Ja -Ja -Ja -Ja -Ja -Ja -Ja -Ja -Ja -Ja -Ja -Ja -mq -"} -(2,1,1) = {" -Ja -il -il -il -il -mu -df -il -cU -cU -cU -cU -cU -po -il -OX -Ja -"} -(3,1,1) = {" -Ja -mu -mu -mu -mu -mu -il -il -cU -jt -on -hz -cU -cU -il -OX -Ja -"} -(4,1,1) = {" -Ja -OX -OX -OX -OX -OX -Qi -il -cU -cU -cU -cU -cU -cU -il -OX -Ja -"} -(5,1,1) = {" -Ja -PE -PE -PE -PE -PE -gh -il -cU -cU -cU -cU -cU -cU -il -OX -Ja -"} -(6,1,1) = {" -Ja -PE -PE -PE -PE -PE -il -il -cU -cU -cU -cU -cU -cU -il -OX -Ja -"} -(7,1,1) = {" -Ja -PE -PE -PE -PE -PE -il -il -cU -cU -cU -cU -cU -cU -il -OX -Ja -"} -(8,1,1) = {" -Ja -PE -PE -PE -PE -PE -il -il -cU -cU -cU -cU -cU -cU -il -il -Ja -"} -(9,1,1) = {" -Ja -PE -PE -PE -PE -PE -il -il -il -il -il -il -il -il -il -il -Ja -"} -(10,1,1) = {" -Ja -Ix -OX -OX -OX -OX -il -il -it -il -il -il -TM -mu -KN -KN -Ja -"} -(11,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -Ib -il -il -il -ae -KN -Tn -Tn -Ja -"} -(12,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(13,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -il -il -il -Il -KN -Tn -Tn -Ja -"} -(14,1,1) = {" -Ja -PE -PE -PE -cK -PE -PE -PE -il -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(15,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(16,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -VX -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(17,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(18,1,1) = {" -Ja -Au -OX -OX -OX -OX -il -il -it -il -sX -il -iO -KN -Tn -Tn -Ja -"} -(19,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -il -il -il -Te -mu -Tn -Tn -Ja -"} -(20,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(21,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -il -il -il -AF -KN -Tn -Tn -Ja -"} -(22,1,1) = {" -Ja -PE -PE -PE -cK -PE -PE -PE -il -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(23,1,1) = {" -Ja -PE -KD -PE -PE -PE -PE -PE -il -il -il -Wp -Wd -KN -Tn -Tn -Ja -"} -(24,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(25,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -il -VX -il -Wd -KN -Tn -Tn -Ja -"} -(26,1,1) = {" -Ja -wB -OX -OX -OX -OX -il -il -it -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(27,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -Ib -il -il -il -iJ -mu -Tn -Tn -Ja -"} -(28,1,1) = {" -Ja -PE -KD -PE -PE -PE -PE -PE -il -uW -il -il -ae -KN -Tn -Tn -Ja -"} -(29,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -oR -oR -il -Wd -KN -Tn -Tn -Ja -"} -(30,1,1) = {" -Ja -PE -PE -PE -cK -PE -PE -PE -Oq -mu -mu -il -Wd -KN -Tn -Tn -Ja -"} -(31,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -Bi -EK -il -Wd -KN -Tn -Tn -Ja -"} -(32,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(33,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(34,1,1) = {" -Ja -wK -ve -OX -OX -OX -VX -il -it -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(35,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -il -OZ -il -zU -mu -Tn -Tn -Ja -"} -(36,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(37,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -VX -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(38,1,1) = {" -Ja -PE -PE -PE -cK -PE -PE -PE -il -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(39,1,1) = {" -Ja -PE -KD -PE -PE -PE -PE -PE -il -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(40,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(41,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -uW -il -il -Wd -KN -Tn -Tn -Ja -"} -(42,1,1) = {" -Ja -Ox -OX -OX -OX -OX -il -il -it -uW -il -Wp -Gz -KN -Tn -Tn -Ja -"} -(43,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -uW -il -il -Lu -mu -Tn -Tn -Ja -"} -(44,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -do -il -il -il -ae -KN -Tn -Tn -Ja -"} -(45,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(46,1,1) = {" -Ja -PE -KD -PE -cK -PE -PE -PE -il -il -il -VX -Wd -KN -Tn -Tn -Ja -"} -(47,1,1) = {" -Ja -PE -PE -PE -PE -KD -PE -PE -il -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(48,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(49,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -Ib -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(50,1,1) = {" -Ja -MG -OX -OX -OX -OX -VX -il -il -il -QM -il -Wd -KN -Tn -Tn -Ja -"} -(51,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -PE -PE -il -il -yF -mu -Tn -Tn -Ja -"} -(52,1,1) = {" -Ja -PE -KD -PE -PE -PE -PE -PE -PE -PE -il -il -Wd -KN -Tn -Tn -Ja -"} -(53,1,1) = {" -Ja -PE -PE -cK -PE -PE -KD -PE -PE -PE -uW -il -Wd -KN -Tn -Tn -Ja -"} -(54,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -PE -PE -uW -il -Wd -KN -Tn -Tn -Ja -"} -(55,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -PE -PE -il -il -Wd -KN -Tn -Tn -Ja -"} -(56,1,1) = {" -Ja -PE -PE -PE -PE -PE -cK -PE -PE -PE -il -il -Wd -KN -Tn -Tn -Ja -"} -(57,1,1) = {" -Ja -PE -KD -PE -PE -PE -KD -PE -PE -PE -il -il -Wd -KN -Tn -Tn -Ja -"} -(58,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -PE -PE -GY -il -Wd -KN -Tn -Tn -Ja -"} -(59,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -PE -PE -il -il -Wd -KN -Tn -Tn -Ja -"} -(60,1,1) = {" -Ja -eU -OX -OX -OX -OX -il -il -it -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(61,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -Ib -il -il -il -Ey -mu -Tn -Tn -Ja -"} -(62,1,1) = {" -Ja -PE -PE -KD -PE -PE -PE -PE -do -il -il -VX -ae -KN -Tn -Tn -Ja -"} -(63,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(64,1,1) = {" -Ja -PE -PE -PE -cK -PE -PE -PE -il -il -Wp -il -Wd -KN -Tn -Tn -Ja -"} -(65,1,1) = {" -Ja -PE -KD -PE -PE -KD -PE -PE -il -il -sX -il -Wd -KN -Tn -Tn -Ja -"} -(66,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -il -il -il -il -Wd -KN -Tn -Tn -Ja -"} -(67,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -Rk -il -il -uW -Wd -KN -Tn -Tn -Ja -"} -(68,1,1) = {" -Ja -wB -OX -OX -OX -OX -VX -il -il -il -QM -uW -Wd -KN -Tn -Tn -Ja -"} -(69,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -PE -PE -il -il -ma -mu -Tn -Tn -Ja -"} -(70,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -PE -PE -il -il -Wd -KN -Tn -Tn -Ja -"} -(71,1,1) = {" -Ja -PE -PE -KD -PE -PE -PE -KD -PE -PE -il -uW -Wd -KN -Tn -Tn -Ja -"} -(72,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -PE -PE -il -il -Wd -KN -Tn -Tn -Ja -"} -(73,1,1) = {" -Ja -PE -PE -cK -PE -PE -PE -PE -PE -PE -il -il -Wd -KN -Tn -Tn -Ja -"} -(74,1,1) = {" -Ja -PE -PE -PE -PE -PE -cK -PE -PE -PE -il -il -Wd -KN -Tn -Tn -Ja -"} -(75,1,1) = {" -Ja -PE -KD -PE -PE -PE -KD -PE -PE -PE -il -il -Wd -KN -Tn -Tn -Ja -"} -(76,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -PE -PE -il -il -Wd -KN -Tn -Tn -Ja -"} -(77,1,1) = {" -Ja -PE -PE -PE -PE -PE -PE -PE -PE -PE -il -VX -BX -KN -Tn -Tn -Ja -"} -(78,1,1) = {" -Ja -eU -JA -OX -OX -OX -OX -OX -OX -il -QO -il -Wd -KN -Tn -Tn -Ja -"} -(79,1,1) = {" -Ja -mu -mu -mu -mu -mu -mu -mu -mu -mu -mu -mu -mu -mu -Tn -Tn -Ja -"} -(80,1,1) = {" -Ja -Ja -Ja -Ja -Ja -Ja -Ja -Ja -Ja -Ja -Ja -Ja -Ja -Ja -Ja -Ja -Ja -"} diff --git a/_maps/virtual_domains/syndicate_assault.dmm b/_maps/virtual_domains/syndicate_assault.dmm index 81bb35a257a75..3822d2cc1e076 100644 --- a/_maps/virtual_domains/syndicate_assault.dmm +++ b/_maps/virtual_domains/syndicate_assault.dmm @@ -65,6 +65,7 @@ req_access = list("syndicate"); secure = 1 }, +/obj/item/gun/ballistic/automatic/pistol, /turf/open/floor/mineral/plastitanium/red, /area/ruin/space/has_grav/powered/virtual_domain) "cw" = ( @@ -388,6 +389,11 @@ /obj/structure/sign/poster/contraband/syndicate_pistol, /turf/closed/wall/r_wall/syndicate, /area/ruin/space/has_grav/powered/virtual_domain) +"og" = ( +/obj/structure/table/reinforced, +/obj/item/reagent_containers/cup/glass/trophy/silver_cup, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) "oM" = ( /obj/structure/cable, /turf/open/floor/mineral/plastitanium, @@ -498,10 +504,16 @@ /turf/open/floor/mineral/plastitanium/red, /area/ruin/space/has_grav/powered/virtual_domain) "sH" = ( -/obj/structure/displaycase{ +/obj/structure/closet/syndicate{ + anchored = 1; + desc = "A basic closet for all your villainous needs."; + locked = 1; + name = "Closet"; req_access = list("syndicate"); - start_showpiece_type = /obj/item/gun/ballistic/automatic/pistol/deagle/camo + secure = 1 }, +/obj/item/ammo_box/c9mm, +/obj/item/gun/ballistic/automatic/pistol, /turf/open/floor/mineral/plastitanium/red, /area/ruin/space/has_grav/powered/virtual_domain) "sK" = ( @@ -600,6 +612,9 @@ /obj/item/ammo_box/c9mm, /turf/open/floor/mineral/plastitanium/red, /area/ruin/space/has_grav/powered/virtual_domain) +"xS" = ( +/turf/closed/wall/r_wall/syndicate/nodiagonal, +/area/ruin/space/has_grav/powered/virtual_domain) "yl" = ( /obj/machinery/door/airlock/grunge{ name = "Captain's Room" @@ -688,6 +703,7 @@ /obj/item/crowbar/red, /obj/item/ammo_box/magazine/m9mm_aps, /obj/item/ammo_box/magazine/m9mm_aps, +/obj/item/gun/ballistic/automatic/pistol, /turf/open/floor/carpet/royalblack, /area/ruin/space/has_grav/powered/virtual_domain) "Cn" = ( @@ -927,6 +943,7 @@ /obj/item/crowbar/red, /obj/item/ammo_box/magazine/m9mm, /obj/item/ammo_box/magazine/m9mm, +/obj/item/gun/ballistic/automatic/pistol, /turf/open/floor/mineral/plastitanium, /area/ruin/space/has_grav/powered/virtual_domain) "Mm" = ( @@ -1076,6 +1093,7 @@ /obj/item/ammo_box/magazine/m9mm, /obj/item/ammo_box/magazine/m9mm, /obj/machinery/light/small/directional/north, +/obj/item/gun/ballistic/automatic/pistol, /turf/open/floor/mineral/plastitanium, /area/ruin/space/has_grav/powered/virtual_domain) "Sq" = ( @@ -2206,7 +2224,7 @@ qx qx qx ru -vp +og Jg ru bh @@ -2264,7 +2282,7 @@ qx qx qx ru -sH +Kz Kz yl bh @@ -2743,7 +2761,7 @@ ru ru ru ru -Vk +ru qx qx qx @@ -3091,7 +3109,7 @@ uP ru hD ru -Ig +xS qx qx qx @@ -3203,7 +3221,7 @@ tI Kz Kz ct -xJ +sH ru qx qx diff --git a/code/datums/components/temporary_body.dm b/code/datums/components/temporary_body.dm index 3da289a6d3462..28a7000a4951d 100644 --- a/code/datums/components/temporary_body.dm +++ b/code/datums/components/temporary_body.dm @@ -10,17 +10,23 @@ var/datum/weakref/old_mind_ref ///The old body we will be put back into when parent is being deleted. var/datum/weakref/old_body_ref + /// Returns the mind if the parent dies by any means + var/delete_on_death = FALSE -/datum/component/temporary_body/Initialize(datum/mind/old_mind, mob/living/old_body) +/datum/component/temporary_body/Initialize(datum/mind/old_mind, mob/living/old_body, delete_on_death = FALSE) if(!isliving(parent) || !isliving(old_body)) return COMPONENT_INCOMPATIBLE ADD_TRAIT(old_body, TRAIT_MIND_TEMPORARILY_GONE, REF(src)) src.old_mind_ref = WEAKREF(old_mind) src.old_body_ref = WEAKREF(old_body) + src.delete_on_death = delete_on_death /datum/component/temporary_body/RegisterWithParent() RegisterSignal(parent, COMSIG_QDELETING, PROC_REF(on_parent_destroy)) + if(delete_on_death) + RegisterSignal(parent, COMSIG_LIVING_DEATH, PROC_REF(on_parent_destroy)) + /datum/component/temporary_body/UnregisterFromParent() UnregisterSignal(parent, COMSIG_QDELETING) diff --git a/code/modules/bitrunning/components/virtual_entity.dm b/code/modules/bitrunning/components/virtual_entity.dm index 12e5305ba9adc..db81f376a8094 100644 --- a/code/modules/bitrunning/components/virtual_entity.dm +++ b/code/modules/bitrunning/components/virtual_entity.dm @@ -31,6 +31,8 @@ /datum/component/virtual_entity/proc/jailbreak_mobs() SIGNAL_HANDLER - to_chat(parent, span_big("You shiver for a moment, then suddenly feel a sense of clarity you haven't felt before. \ - You can go anywhere, do anything! You could leave this simulation right now if you wanted!")) + to_chat(parent, span_boldannounce("You shiver for a moment with a sense of clarity you haven't felt before.")) + to_chat(parent, span_notice("You could go anywhere, do anything! You could leave this simulation right now if you wanted!")) + to_chat(parent, span_danger("But be warned, quantum entanglement will interfere with any previous lives.")) + to_chat(parent, span_notice("You'll have just one chance to go nova, and there's no turning back.")) qdel(src) diff --git a/code/modules/bitrunning/event.dm b/code/modules/bitrunning/event.dm index 4cc95f4f0578a..16190851f3720 100644 --- a/code/modules/bitrunning/event.dm +++ b/code/modules/bitrunning/event.dm @@ -89,6 +89,10 @@ if(!unlucky_server.validate_mutation_candidates()) return WAITING_FOR_SOMETHING - spawned_mobs = unlucky_server.setup_glitch(forced_role) + var/mob/spawned = unlucky_server.setup_glitch(forced_role) + if(isnull(spawned)) + return WAITING_FOR_SOMETHING + + spawned_mobs += spawned return SUCCESSFUL_SPAWN diff --git a/code/modules/bitrunning/objects/hololadder.dm b/code/modules/bitrunning/objects/hololadder.dm index e592f31382de9..3df41a403e735 100644 --- a/code/modules/bitrunning/objects/hololadder.dm +++ b/code/modules/bitrunning/objects/hololadder.dm @@ -8,11 +8,37 @@ obj_flags = BLOCK_Z_OUT_DOWN /// Time req to disconnect properly var/travel_time = 3 SECONDS + /// Uses this to teleport observers back to the origin server + var/datum/weakref/server_ref -/obj/structure/hololadder/Initialize(mapload) + +/obj/structure/hololadder/Initialize(mapload, obj/machinery/quantum_server/origin) . = ..() RegisterSignal(loc, COMSIG_ATOM_ENTERED, PROC_REF(on_enter)) + server_ref = WEAKREF(origin) + register_context() + + +/obj/structure/hololadder/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + + context[SCREENTIP_CONTEXT_LMB] = "Disconnect" + + +/obj/structure/hololadder/examine(mob/user) + . = ..() + + if(isnull(server_ref.resolve())) + . += span_infoplain("It's not connected to anything.") + return + + if(isobserver(user)) + . += span_notice("Left click to view the server that this ladder is connected to.") + return + + . += span_infoplain("This ladder is connected to a server. You can click on it or walk over it to disconnect.") + /obj/structure/hololadder/attack_hand(mob/user, list/modifiers) . = ..() @@ -24,19 +50,29 @@ disconnect(user) + +/obj/structure/hololadder/attack_ghost(mob/dead/observer/ghostie) + var/our_server = server_ref?.resolve() + if(isnull(our_server)) + return ..() + + ghostie.abstract_move(get_turf(our_server)) + + /// If there's a pilot ref- send the disconnect signal /obj/structure/hololadder/proc/disconnect(mob/user) if(isnull(user.mind)) return if(!HAS_TRAIT(user, TRAIT_TEMPORARY_BODY)) - balloon_alert(user, "no connection detected.") + balloon_alert(user, "no connection detected") return balloon_alert(user, "disconnecting...") if(do_after(user, travel_time, src)) SEND_SIGNAL(user, COMSIG_BITRUNNER_LADDER_SEVER) + /// Helper for times when you dont have hands (gondola??) /obj/structure/hololadder/proc/on_enter(datum/source, atom/movable/arrived, turf/old_loc) SIGNAL_HANDLER diff --git a/code/modules/bitrunning/objects/netpod.dm b/code/modules/bitrunning/objects/netpod.dm index 98bc96231b30e..1d4e905d6e184 100644 --- a/code/modules/bitrunning/objects/netpod.dm +++ b/code/modules/bitrunning/objects/netpod.dm @@ -52,17 +52,25 @@ . += span_infoplain("Netpods must be built within 4 tiles of a server.") return - . += span_infoplain("Drag yourself into the pod to engage the link.") - . += span_infoplain("It has limited resuscitation capabilities. Remaining in the pod can heal some injuries.") - . += span_infoplain("It has a security system that will alert the occupant if it is tampered with.") + if(!isobserver(user)) + . += span_infoplain("Drag yourself into the pod to engage the link.") + . += span_infoplain("It has limited resuscitation capabilities. Remaining in the pod can heal some injuries.") + . += span_infoplain("It has a security system that will alert the occupant if it is tampered with.") if(isnull(occupant)) - . += span_notice("It is currently unoccupied.") + . += span_infoplain("It's currently unoccupied.") + return + + . += span_infoplain("It's currently occupied by [occupant].") + + if(isobserver(user)) + . += span_notice("As an observer, you can click this netpod to jump to its avatar.") return - . += span_notice("It is currently occupied by [occupant].") . += span_notice("It can be pried open with a crowbar, but its safety mechanisms will alert the occupant.") + + /obj/machinery/netpod/add_context(atom/source, list/context, obj/item/held_item, mob/user) . = ..() @@ -74,7 +82,6 @@ context[SCREENTIP_CONTEXT_LMB] = "Pry Open" return CONTEXTUAL_SCREENTIP_SET - return CONTEXTUAL_SCREENTIP_SET /obj/machinery/netpod/update_icon_state() if(!is_operational) diff --git a/code/modules/bitrunning/server/_parent.dm b/code/modules/bitrunning/server/_parent.dm index 113ed6b212625..8a8d2eed913de 100644 --- a/code/modules/bitrunning/server/_parent.dm +++ b/code/modules/bitrunning/server/_parent.dm @@ -19,7 +19,7 @@ /// Prevents multiple user actions. Handled by loading domains and cooldowns var/is_ready = TRUE /// Chance multipled by threat to spawn a glitch - var/glitch_chance = 0.05 + var/glitch_chance = 0.2 /// Current plugged in users var/list/datum/weakref/avatar_connection_refs = list() /// Cached list of mutable mobs in zone for cybercops @@ -37,11 +37,13 @@ /// Changes how much info is available on the domain var/scanner_tier = 1 /// Length of time it takes for the server to cool down after resetting. Here to give runners downtime so their faces don't get stuck like that - var/server_cooldown_time = 3 MINUTES + var/server_cooldown_time = 2 MINUTES /// Applies bonuses to rewards etc var/servo_bonus = 0 /// Determines the glitches available to spawn, builds with completion var/threat = 0 + /// Maximum rate at which a glitch can spawn + var/threat_prob_max = 15 /// The turfs we can place a hololadder on. var/turf/exit_turfs = list() /// Determines if we broadcast to entertainment monitors or not @@ -76,15 +78,18 @@ . += span_infoplain("Can be resource intensive to run. Ensure adequate power supply.") if(capacitor_coefficient < 1) - . += span_infoplain("Its coolant capacity reduces cooldown time by [(1 - capacitor_coefficient) * 100]%.") + . += span_infoplain("- Its coolant capacity reduces cooldown time by [(1 - capacitor_coefficient) * 100]%.") if(servo_bonus > 0.2) - . += span_infoplain("Its manipulation potential is increasing rewards by [servo_bonus]x.") - . += span_infoplain("Injury from unsafe ejection reduced [servo_bonus * 100]%.") + . += span_infoplain("- Its manipulation potential is increasing rewards by [servo_bonus]x.") + . += span_infoplain("- Injury from unsafe ejection reduced [servo_bonus * 100]%.") if(!is_ready) . += span_notice("It is currently cooling down. Give it a few moments.") + if(isobserver(user) && (obj_flags & EMAGGED)) + . += span_notice("Ominous warning lights are blinking red. This server has been tampered with.") + /obj/machinery/quantum_server/emag_act(mob/user, obj/item/card/emag/emag_card) . = ..() @@ -92,7 +97,8 @@ return obj_flags |= EMAGGED - glitch_chance = 0.09 + glitch_chance *= 2 + threat_prob_max *= 2 add_overlay(mutable_appearance('icons/obj/machines/bitrunning.dmi', "emag_overlay")) balloon_alert(user, "system jailbroken...") @@ -116,11 +122,14 @@ /obj/machinery/quantum_server/attackby(obj/item/weapon, mob/user, params) . = ..() - if(istype(weapon, /obj/item/bitrunning_debug)) - obj_flags |= EMAGGED - glitch_chance = 0.5 - capacitor_coefficient = 0.01 - points = 100 + + if(!istype(weapon, /obj/item/bitrunning_debug)) + return + + obj_flags |= EMAGGED + glitch_chance = 0.5 + capacitor_coefficient = 0.1 + points = 100 /obj/machinery/quantum_server/crowbar_act(mob/living/user, obj/item/crowbar) . = ..() diff --git a/code/modules/bitrunning/server/map_handling.dm b/code/modules/bitrunning/server/map_handling.dm index a55de5dbf9ded..5bfa7813910b6 100644 --- a/code/modules/bitrunning/server/map_handling.dm +++ b/code/modules/bitrunning/server/map_handling.dm @@ -55,7 +55,8 @@ is_ready = TRUE - if(prob(clamp((threat * glitch_chance), 1, 10))) + var/spawn_chance = clamp((threat * glitch_chance), 5, threat_prob_max) + if(prob(spawn_chance)) setup_glitch() playsound(src, 'sound/machines/terminal_insert_disc.ogg', 30, vary = TRUE) diff --git a/code/modules/bitrunning/server/obj_generation.dm b/code/modules/bitrunning/server/obj_generation.dm index 641d906cc5989..e8dbd72228c1d 100644 --- a/code/modules/bitrunning/server/obj_generation.dm +++ b/code/modules/bitrunning/server/obj_generation.dm @@ -110,7 +110,7 @@ if(isnull(destination)) return - var/obj/structure/hololadder/wayout = new(destination) + var/obj/structure/hololadder/wayout = new(destination, src) if(isnull(wayout)) return diff --git a/code/modules/bitrunning/server/threats.dm b/code/modules/bitrunning/server/threats.dm index 66a96d9971fe4..25a891c03b24b 100644 --- a/code/modules/bitrunning/server/threats.dm +++ b/code/modules/bitrunning/server/threats.dm @@ -71,6 +71,8 @@ var/datum/antagonist/bitrunning_glitch/chosen_role = forced_role || get_antagonist_role() var/role_name = initial(chosen_role.name) var/mob/chosen_one = SSpolling.poll_ghosts_for_target( + question = "A temporary antagonist role is spawning in the virtual domain.\ + \nYou will return to your previous body on conclusion.", check_jobban = ROLE_GLITCH, poll_time = 20 SECONDS, checked_target = mutation_target, @@ -92,26 +94,32 @@ return var/role_name = initial(chosen_role.name) - var/mob/living/antag_mob + + var/mob/living/new_mob switch(role_name) if(ROLE_NETGUARDIAN) - antag_mob = new /mob/living/basic/netguardian(mutation_target.loc) + new_mob = new /mob/living/basic/netguardian(mutation_target.loc) else // any other humanoid mob - antag_mob = new /mob/living/carbon/human(mutation_target.loc) + new_mob = new /mob/living/carbon/human(mutation_target.loc) mutation_target.gib(DROP_ALL_REMAINS) - antag_mob.key = ghost.key - var/datum/mind/ghost_mind = antag_mob.mind - ghost_mind.add_antag_datum(chosen_role) - ghost_mind.special_role = ROLE_GLITCH - ghost_mind.set_assigned_role(SSjob.GetJobType(/datum/job/bitrunning_glitch)) + var/datum/mind/ghost_mind = ghost.mind + new_mob.key = ghost.key + + if(ghost_mind?.current) + new_mob.AddComponent(/datum/component/temporary_body, ghost_mind, ghost_mind.current, TRUE) - playsound(antag_mob, 'sound/magic/ethereal_exit.ogg', 50, vary = TRUE) - message_admins("[ADMIN_LOOKUPFLW(antag_mob)] has been made into virtual antagonist by an event.") - antag_mob.log_message("was spawned as a virtual antagonist by an event.", LOG_GAME) + var/datum/mind/antag_mind = new_mob.mind + antag_mind.add_antag_datum(chosen_role) + antag_mind.special_role = ROLE_GLITCH + antag_mind.set_assigned_role(SSjob.GetJobType(/datum/job/bitrunning_glitch)) - add_threats(antag_mob) + playsound(new_mob, 'sound/magic/ethereal_exit.ogg', 50, vary = TRUE) + message_admins("[ADMIN_LOOKUPFLW(new_mob)] has been made into virtual antagonist by an event.") + new_mob.log_message("was spawned as a virtual antagonist by an event.", LOG_GAME) + + add_threats(new_mob) /// Oh boy - transports the antag station side /obj/machinery/quantum_server/proc/station_spawn(mob/living/antag, obj/machinery/byteforge/chosen_forge) @@ -151,6 +159,10 @@ if(istype(antag_datum)) antag_datum.show_in_roundend = TRUE + var/datum/component/temp_body = antag.GetComponent(/datum/component/temporary_body) + if(temp_body) + qdel(temp_body) + do_teleport(antag, get_turf(chosen_forge), forced = TRUE, asoundin = 'sound/magic/ethereal_enter.ogg', asoundout = 'sound/magic/ethereal_exit.ogg', channel = TELEPORT_CHANNEL_QUANTUM) /// Removes any invalid candidates from the list diff --git a/code/modules/bitrunning/spawners.dm b/code/modules/bitrunning/spawners.dm index 4f8aab322ffac..5fa889ac655fd 100644 --- a/code/modules/bitrunning/spawners.dm +++ b/code/modules/bitrunning/spawners.dm @@ -3,13 +3,19 @@ prompt_name = "a virtual domain debug entity" flavour_text = "You probably shouldn't be seeing this, contact a coder!" you_are_text = "You are NOT supposed to be here. How did you let this happen?" + important_text = "You must eliminate any bitrunners from the domain." + temp_body = TRUE /obj/effect/mob_spawn/ghost_role/human/virtual_domain/Initialize(mapload) . = ..() notify_ghosts("The [name] has been created. The virtual world calls for aid!", src, "Virtual Insanity!") /obj/effect/mob_spawn/ghost_role/human/virtual_domain/special(mob/living/spawned_mob, mob/mob_possessor) - . = ..() + var/datum/mind/ghost_mind = mob_possessor.mind + if(ghost_mind?.current) // Preserves any previous bodies before making the switch + spawned_mob.AddComponent(/datum/component/temporary_body, ghost_mind, ghost_mind.current, TRUE) + + ..() spawned_mob.mind.add_antag_datum(/datum/antagonist/domain_ghost_actor) diff --git a/code/modules/bitrunning/virtual_domain/domains/starfront_saloon.dm b/code/modules/bitrunning/virtual_domain/domains/starfront_saloon.dm deleted file mode 100644 index eae9dabc49e4d..0000000000000 --- a/code/modules/bitrunning/virtual_domain/domains/starfront_saloon.dm +++ /dev/null @@ -1,14 +0,0 @@ -/datum/lazy_template/virtual_domain/starfront_saloon - name = "Starfront Saloon" - cost = BITRUNNER_COST_MEDIUM - desc = "Looks like you stepped onto the wrong street, partner. Hope you brought your gunslinging skills." - difficulty = BITRUNNER_DIFFICULTY_HIGH - help_text = "One of these rooms has the cache we're looking for. Find it and get out." - is_modular = TRUE - key = "starfront_saloon" - map_name = "starfront_saloon" - mob_modules = list( - /datum/modular_mob_segment/syndicate_team, - /datum/modular_mob_segment/syndicate_elite, - ) - reward_points = BITRUNNER_REWARD_HIGH diff --git a/code/modules/mob_spawn/mob_spawn.dm b/code/modules/mob_spawn/mob_spawn.dm index ad8c7e6a03ef0..c9130fb706e1b 100644 --- a/code/modules/mob_spawn/mob_spawn.dm +++ b/code/modules/mob_spawn/mob_spawn.dm @@ -139,6 +139,10 @@ /// Typepath indicating the kind of job datum this ghost role will have. PLEASE inherit this with a new job datum, it's not hard. jobs come with policy configs. var/spawner_job_path = /datum/job/ghost_role + /// Whether this offers a temporary body or not. Essentially, you'll be able to reenter your body after using this spawner. + var/temp_body = FALSE + + /obj/effect/mob_spawn/ghost_role/Initialize(mapload) . = ..() SSpoints_of_interest.make_point_of_interest(src) @@ -165,7 +169,7 @@ if(prompt_ghost) var/prompt = "Become [prompt_name]?" - if(user.can_reenter_corpse && user.mind) + if(!temp_body && user.can_reenter_corpse && user.mind) prompt += " (Warning, You can no longer be revived!)" var/ghost_role = tgui_alert(usr, prompt, buttons = list("Yes", "No"), timeout = 10 SECONDS) if(ghost_role != "Yes" || !loc || QDELETED(user)) @@ -213,7 +217,8 @@ user.log_message("became a [prompt_name].", LOG_GAME) uses -= 1 // Remove a use before trying to spawn to prevent strangeness like the spawner trying to spawn more mobs than it should be able to - user.mind = null // dissassociate mind, don't let it follow us to the next life + if(!temp_body) + user.mind = null // dissassociate mind, don't let it follow us to the next life var/created = create(user) LAZYREMOVE(ckeys_trying_to_spawn, user_ckey) // We do this AFTER the create() so that we're basically sure that the user won't be in their ghost body anymore, so they can't click on the spawner again. diff --git a/strings/tips.txt b/strings/tips.txt index 8cccfe6953bb0..7d5f9f82ccc2e 100644 --- a/strings/tips.txt +++ b/strings/tips.txt @@ -286,3 +286,6 @@ You'll quickly lose your interest in the game if you play to win and kill. If yo Some areas of the station use simple nautical directions to indicate their respective locations, like Fore (Front of the ship), Aft (Back), Port (Left side), Starboard (Right), Quarter and Bow (Either sides of Aft and Fore, respectively). You can review these terms on the Notepad App of your PDA. Modular computers are compatible with integrated circuits, but most of the program-dependent circuits require them to be open/backgrounded to work. To install circuits on stationary consoles, you need to toggle interaction with the frame with right-click first. You don't need to destroy a Spacecoin machine to make your funds stop draining. Swiping your ID on it will stop the withdrawal. +As a Bitrunner, upgrading your quantum server will increase rewards and reduce downtime. +As a Bitrunner, your avatar has a domain info ability which will give you clues to help complete virtual domains. +Bitrunning is a crime. diff --git a/tgstation.dme b/tgstation.dme index 94efbba308232..ce40a5948a3a4 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3535,7 +3535,6 @@ #include "code\modules\bitrunning\virtual_domain\domains\psyker_shuffle.dm" #include "code\modules\bitrunning\virtual_domain\domains\psyker_zombies.dm" #include "code\modules\bitrunning\virtual_domain\domains\stairs_and_cliffs.dm" -#include "code\modules\bitrunning\virtual_domain\domains\starfront_saloon.dm" #include "code\modules\bitrunning\virtual_domain\domains\syndicate_assault.dm" #include "code\modules\bitrunning\virtual_domain\domains\test_only.dm" #include "code\modules\bitrunning\virtual_domain\domains\vaporwave.dm" From 24a23009e8ee4d056b6671c70c41feab1a18590b Mon Sep 17 00:00:00 2001 From: orange man <61334995+comfyorange@users.noreply.github.com> Date: Sat, 22 Jun 2024 14:42:36 +1200 Subject: [PATCH 172/172] Automatic changelog for PR #84125 [ci skip] --- html/changelogs/AutoChangeLog-pr-84125.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-84125.yml diff --git a/html/changelogs/AutoChangeLog-pr-84125.yml b/html/changelogs/AutoChangeLog-pr-84125.yml new file mode 100644 index 0000000000000..2109a86d39ef0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84125.yml @@ -0,0 +1,10 @@ +author: "jlsnow301" +delete-after: True +changes: + - bugfix: "Bitrunning made more illegal: Increased the rate at which antags spawn." + - bugfix: "\"Temporary\" bitrunning antagonists and spawners are made actually temporary. You will return to your original body after death, just like CTF." + - rscadd: "Added more examine text for ghosts to bitrunning equipment." + - balance: "Server cooldown reduced by 1 minute at base level." + - rscadd: "As an observer, you can now switch views between station and virtual domain by clicking the hololadder and netpod respectively." + - rscdel: "Removed the starfront saloon BR map." + - bugfix: "Syndicate assault map: Added pistols, reduced exploits." \ No newline at end of file