From 1d629b2050f0b060b543a7c96e097b9c466b2326 Mon Sep 17 00:00:00 2001 From: Bubberbot <151680451+Bubberbot@users.noreply.github.com> Date: Wed, 1 Jul 2026 03:56:32 +0000 Subject: [PATCH 01/41] Bubberstation automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-bubber-pr-5842.yml | 4 ---- html/changelogs/bubber_archive/2026-07.yml | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5842.yml create mode 100644 html/changelogs/bubber_archive/2026-07.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5842.yml b/html/changelogs/AutoChangeLog-bubber-pr-5842.yml deleted file mode 100644 index 52757285209..00000000000 --- a/html/changelogs/AutoChangeLog-bubber-pr-5842.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "sippykot" -delete-after: True -changes: - - balance: "jaws of rescue have the same speed as jaws of life" \ No newline at end of file diff --git a/html/changelogs/bubber_archive/2026-07.yml b/html/changelogs/bubber_archive/2026-07.yml new file mode 100644 index 00000000000..2786cb0f992 --- /dev/null +++ b/html/changelogs/bubber_archive/2026-07.yml @@ -0,0 +1,3 @@ +2026-07-01: + sippykot: + - balance: jaws of rescue have the same speed as jaws of life From db8179a7311666f5b0a90f43da0ca0dde7c6070c Mon Sep 17 00:00:00 2001 From: Phantastic-Swan Date: Wed, 1 Jul 2026 17:39:54 +0200 Subject: [PATCH 02/41] Fixes the schedule button in the storyteller panel not working. Also a bit better logging. (#5876) ## About The Pull Request The "schedule" button in the storyteller panel was completely non-functional as it was not connected to any logic. It was also displaying the storyteller name as the event played, rather than the actual event. This PR fixes these. ## Why It's Good For The Game Makes the storyteller better to handle for admemes. ## Proof Of Testing https://github.com/user-attachments/assets/21cd66b6-79c7-47e4-beb3-cfd1c7f249d3 The video is before my changes to the strings outputted but I haven't changed the logic after that and it still worked so. image ----- image ## Changelog :cl: Swan fix: fixes the storyteller panel schedule button not working. Also improves the logging messages so that the name of the event selected is logged. /:cl: --- .../code/modules/storyteller/gamemode_ui.dm | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/modular_zubbers/code/modules/storyteller/gamemode_ui.dm b/modular_zubbers/code/modules/storyteller/gamemode_ui.dm index 3606a91d413..c8091d15fd6 100644 --- a/modular_zubbers/code/modules/storyteller/gamemode_ui.dm +++ b/modular_zubbers/code/modules/storyteller/gamemode_ui.dm @@ -142,17 +142,22 @@ sch_event.try_fire() if("panel_action") var/datum/round_event_control/event = get_event_by_track_and_type(params["track"], params["type"]) + var/track = params["track"] if(isnull(event)) return switch(params["action"]) if("fire") - message_admins("[key_name_admin(usr)] has fired event [src.name].") - log_admin_private("[key_name(usr)] has fired event [src.name].") + message_admins("[key_name_admin(usr)] has fired event [event.name].") + log_admin_private("[key_name(usr)] has fired event [event.name].") SSgamemode.TriggerEvent(event) if("force_next") - message_admins("[key_name_admin(usr)] has forced scheduled event [src.name].") - log_admin_private("[key_name(usr)] has forced scheduled event [src.name].") + message_admins("[key_name_admin(usr)] has forced next event on track [track] to be [event.name].") + log_admin_private("[key_name(usr)] has forced next event on track [track] to be [event.name].") SSgamemode.force_event(event) + if ("schedule") + message_admins("[key_name_admin(usr)] has scheduled event [event.name].") + log_admin_private("[key_name(usr)] has scheduled event [event.name].") + SSgamemode.schedule_event(event, (rand(3, 4) MINUTES), 0) if("panel_update") if(storyteller) storyteller.calculate_weights_all() From 07330f4b43820092dccfb22d2bfc880bb404b266 Mon Sep 17 00:00:00 2001 From: Bubberbot <151680451+Bubberbot@users.noreply.github.com> Date: Wed, 1 Jul 2026 17:40:24 +0200 Subject: [PATCH 03/41] Automatic changelog for PR #5876 [ci skip] --- html/changelogs/AutoChangeLog-bubber-pr-5876.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5876.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5876.yml b/html/changelogs/AutoChangeLog-bubber-pr-5876.yml new file mode 100644 index 00000000000..b2bd74bc895 --- /dev/null +++ b/html/changelogs/AutoChangeLog-bubber-pr-5876.yml @@ -0,0 +1,4 @@ +author: "Swan" +delete-after: True +changes: + - bugfix: "fixes the storyteller panel schedule button not working. Also improves the logging messages so that the name of the event selected is logged." \ No newline at end of file From 85bcd2cbbc27c32ea5f0d938f6dc20746c0f772d Mon Sep 17 00:00:00 2001 From: Mathilde <146444134+ibexgoetia@users.noreply.github.com> Date: Wed, 1 Jul 2026 22:33:37 +0200 Subject: [PATCH 04/41] The Return of the (printable) defib (#5875) image ## About The Pull Request With this I am reverting the removal of the printable defibrillator, a change made by /tg/ some time ago. Only the **base** defibrillator is printable, not the compact/belt slot defibrillator. It will need to have a cell inserted to work. ## Why It's Good For The Game The change was initially made to increase the amount of interactions with cargo, but I believe that this only makes the process of obtaining defibrillators bothersome, as the interdepartmental action solely involves pressing a single button on the order console... Obtaining defibrillators through cargo is still possible; you'll get three with charged batteries in them, without having to spend resources. I'm simply re-adding the old way to get them. This change was disliked both on /tg/ and here. ## Proof Of Testing image ## Changelog :cl: balance: Defibrillators are now printable once again from the medical techfab. /:cl: --- .../code/modules/research/designs/medical_designs.dm | 12 ++++++++++++ .../code/modules/research/techweb/all_nodes.dm | 7 +++++++ 2 files changed, 19 insertions(+) diff --git a/modular_zubbers/code/modules/research/designs/medical_designs.dm b/modular_zubbers/code/modules/research/designs/medical_designs.dm index 16d40eb49db..68660032c33 100644 --- a/modular_zubbers/code/modules/research/designs/medical_designs.dm +++ b/modular_zubbers/code/modules/research/designs/medical_designs.dm @@ -48,3 +48,15 @@ RND_CATEGORY_TOOLS + RND_SUBCATEGORY_TOOLS_MEDICAL_ALIEN ) departmental_flags = DEPARTMENT_BITFLAG_MEDICAL + +/datum/design/defibrillator + name = "Defibrillator" + desc = "A portable defibrillator, used for resuscitating recently deceased crew." + id = "defibrillator" + build_type = PROTOLATHE | AWAY_LATHE + build_path = /obj/item/defibrillator + materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT*4, /datum/material/glass = SHEET_MATERIAL_AMOUNT*2, /datum/material/silver =SHEET_MATERIAL_AMOUNT * 1.5, /datum/material/gold =HALF_SHEET_MATERIAL_AMOUNT * 1.5) + category = list( + RND_CATEGORY_EQUIPMENT + RND_SUBCATEGORY_EQUIPMENT_MEDICAL + ) + departmental_flags = DEPARTMENT_BITFLAG_MEDICAL diff --git a/modular_zubbers/code/modules/research/techweb/all_nodes.dm b/modular_zubbers/code/modules/research/techweb/all_nodes.dm index dcab939e082..e67450cb4d1 100644 --- a/modular_zubbers/code/modules/research/techweb/all_nodes.dm +++ b/modular_zubbers/code/modules/research/techweb/all_nodes.dm @@ -77,6 +77,13 @@ design_ids += list( "wound_scanner_internal" ) + +/datum/techweb_node/medbay_equip/New() + . = ..() + design_ids += list( + "defibrillator", + ) + //ENGINEERING /datum/techweb_node/atmos/New() . = ..() From 4733ede45b52ba465244357f0da8c016fb518fa8 Mon Sep 17 00:00:00 2001 From: Bubberbot <151680451+Bubberbot@users.noreply.github.com> Date: Wed, 1 Jul 2026 22:34:08 +0200 Subject: [PATCH 05/41] Automatic changelog for PR #5875 [ci skip] --- html/changelogs/AutoChangeLog-bubber-pr-5875.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5875.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5875.yml b/html/changelogs/AutoChangeLog-bubber-pr-5875.yml new file mode 100644 index 00000000000..5be03a28e82 --- /dev/null +++ b/html/changelogs/AutoChangeLog-bubber-pr-5875.yml @@ -0,0 +1,4 @@ +author: "ibexgoetia" +delete-after: True +changes: + - balance: "Defibrillators are now printable once again from the medical techfab." \ No newline at end of file From ffb3aa84f27b92235c4accdb4d75e2c597e251f7 Mon Sep 17 00:00:00 2001 From: Bubberbot <151680451+Bubberbot@users.noreply.github.com> Date: Wed, 1 Jul 2026 21:55:33 +0000 Subject: [PATCH 06/41] Bubberstation automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-bubber-pr-5875.yml | 4 ---- html/changelogs/AutoChangeLog-bubber-pr-5876.yml | 4 ---- html/changelogs/bubber_archive/2026-07.yml | 5 +++++ 3 files changed, 5 insertions(+), 8 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5875.yml delete mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5876.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5875.yml b/html/changelogs/AutoChangeLog-bubber-pr-5875.yml deleted file mode 100644 index 5be03a28e82..00000000000 --- a/html/changelogs/AutoChangeLog-bubber-pr-5875.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "ibexgoetia" -delete-after: True -changes: - - balance: "Defibrillators are now printable once again from the medical techfab." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5876.yml b/html/changelogs/AutoChangeLog-bubber-pr-5876.yml deleted file mode 100644 index b2bd74bc895..00000000000 --- a/html/changelogs/AutoChangeLog-bubber-pr-5876.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Swan" -delete-after: True -changes: - - bugfix: "fixes the storyteller panel schedule button not working. Also improves the logging messages so that the name of the event selected is logged." \ No newline at end of file diff --git a/html/changelogs/bubber_archive/2026-07.yml b/html/changelogs/bubber_archive/2026-07.yml index 2786cb0f992..9d30a98ef95 100644 --- a/html/changelogs/bubber_archive/2026-07.yml +++ b/html/changelogs/bubber_archive/2026-07.yml @@ -1,3 +1,8 @@ 2026-07-01: + Swan: + - bugfix: fixes the storyteller panel schedule button not working. Also improves + the logging messages so that the name of the event selected is logged. + ibexgoetia: + - balance: Defibrillators are now printable once again from the medical techfab. sippykot: - balance: jaws of rescue have the same speed as jaws of life From 68dea08d44597f14ae13c7b917e7692ce572b4e4 Mon Sep 17 00:00:00 2001 From: nikothedude <59709059+nikothedude@users.noreply.github.com> Date: Thu, 2 Jul 2026 02:04:35 -0400 Subject: [PATCH 07/41] Makes lycan TF sound a variable (#5872) ## About The Pull Request Title. 2 vars added to the lycan brain - from lycan to human, human to lycan. ## Why It's Good For The Game Lets admins var edit it at runtime and do silliness, ## Proof Of Testing
Screenshots/Videos The maroon 5 is just proof you can varedit it and it works https://github.com/user-attachments/assets/f962be9e-9559-4dd4-a630-43e208490c48
## Changelog :cl: code: Lycan transformation sfx is now a variable on the brain /:cl: --- .../code/modules/customization/species/lycans/lycan_status.dm | 4 ++-- .../customization/species/lycans/organs/lycan_brain.dm | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/modular_zubbers/code/modules/customization/species/lycans/lycan_status.dm b/modular_zubbers/code/modules/customization/species/lycans/lycan_status.dm index 1a8223a912c..9a2678bb351 100644 --- a/modular_zubbers/code/modules/customization/species/lycans/lycan_status.dm +++ b/modular_zubbers/code/modules/customization/species/lycans/lycan_status.dm @@ -51,7 +51,7 @@ target_client.prefs.load_character(lycan_brain.last_slot) ADD_TRAIT(human_owner, TRAIT_BEAST_FORM, SPECIES_TRAIT) - playsound(human_owner, 'modular_zubbers/code/modules/customization/species/lycans/transform.ogg', 50) + playsound(human_owner, lycan_brain.to_lycan_sfx, 50) /datum/status_effect/beast_form/on_remove() . = ..() @@ -79,7 +79,7 @@ human_owner.set_species(initial_species, TRUE, TRUE, FALSE) REMOVE_TRAIT(human_owner, TRAIT_BEAST_FORM, SPECIES_TRAIT) - playsound(human_owner, 'modular_zubbers/code/modules/customization/species/lycans/transform.ogg', 50) + playsound(human_owner, lycan_brain.to_human_sfx, 50) /datum/status_effect/beast_form/tick(seconds_between_ticks) . = ..() diff --git a/modular_zubbers/code/modules/customization/species/lycans/organs/lycan_brain.dm b/modular_zubbers/code/modules/customization/species/lycans/organs/lycan_brain.dm index 304b30705b3..24053a642e7 100644 --- a/modular_zubbers/code/modules/customization/species/lycans/organs/lycan_brain.dm +++ b/modular_zubbers/code/modules/customization/species/lycans/organs/lycan_brain.dm @@ -3,6 +3,8 @@ desc = "A larger than average, albeit slightly smoother brain. The hypothalamus seems larger than normal." // I read in a random medical artical that the hypothalamus controls aggression. actions_types = list(/datum/action/cooldown/spell/beast_form) var/last_slot + var/to_human_sfx = 'modular_zubbers/code/modules/customization/species/lycans/transform.ogg' + var/to_lycan_sfx = 'modular_zubbers/code/modules/customization/species/lycans/transform.ogg' /obj/item/organ/brain/lycan/on_mob_insert(mob/living/carbon/brain_owner, special, movement_flags) . = ..() From 1dff76e958147d2116ec2fddaf9ea6ac0af3e318 Mon Sep 17 00:00:00 2001 From: Bubberbot <151680451+Bubberbot@users.noreply.github.com> Date: Thu, 2 Jul 2026 08:05:00 +0200 Subject: [PATCH 08/41] Automatic changelog for PR #5872 [ci skip] --- html/changelogs/AutoChangeLog-bubber-pr-5872.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5872.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5872.yml b/html/changelogs/AutoChangeLog-bubber-pr-5872.yml new file mode 100644 index 00000000000..84e634989de --- /dev/null +++ b/html/changelogs/AutoChangeLog-bubber-pr-5872.yml @@ -0,0 +1,4 @@ +author: "nikothedude" +delete-after: True +changes: + - code_imp: "Lycan transformation sfx is now a variable on the brain" \ No newline at end of file From 92da873ec5642a15b6166d831ce1a49bd556053c Mon Sep 17 00:00:00 2001 From: Vanilla1040 <94153240+Vanilla1040@users.noreply.github.com> Date: Thu, 2 Jul 2026 09:53:43 +0200 Subject: [PATCH 09/41] Positronic Brain Changes (#5764) ## About The Pull Request This PR aims to change how positronic are handled and work, instead of them being their standalone thing and you "dying" when its removed it acts like a real positronic that you are confined to said positronic even on gibbing, which can be moved from a cyborg to a synthetic shell and back into said shell without much workarounds, RSD or anything else annyoing, just as an example. ## Why It's Good For The Game I think changing it to a behavior that is like a cyborgs positronic makes overall more sense then the synthetics magically dying when their positronic is removed, cyborgs can somehow exist and stay alive as a positronic but synthetics cant? ## Proof Of Testing Works on my machine ## Changelog :cl: refactor: refactored how the synthetics brains work and behave /:cl: --------- Co-authored-by: Artur Lang <24881678+Arturlang@users.noreply.github.com> Co-authored-by: Mathilde <146444134+ibexgoetia@users.noreply.github.com> --- code/modules/mob/living/brain/MMI.dm | 1 + code/modules/mob/living/brain/brain.dm | 19 +++- .../operations/operation_organ_manip.dm | 12 +++ .../modules/synths/code/bodyparts/brain.dm | 98 +++++++++++++++++-- .../code/bodyparts/internal_computer/brain.dm | 35 ------- tgstation.dme | 1 - 6 files changed, 121 insertions(+), 45 deletions(-) delete mode 100644 modular_skyrat/modules/synths/code/bodyparts/internal_computer/brain.dm diff --git a/code/modules/mob/living/brain/MMI.dm b/code/modules/mob/living/brain/MMI.dm index 00adadd33fd..5cbf9727f71 100644 --- a/code/modules/mob/living/brain/MMI.dm +++ b/code/modules/mob/living/brain/MMI.dm @@ -16,6 +16,7 @@ var/overrides_aicore_laws = FALSE // Whether the laws on the MMI, if any, override possible pre-existing laws loaded on the AI core. /// Whether the brainmob can move. Doesnt usually matter but SPHERICAL POSIBRAINSSS var/immobilize = TRUE + var/slot = ORGAN_SLOT_BRAIN //Bubber Addition /obj/item/mmi/Initialize(mapload) . = ..() diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm index fc8e60b63e0..f7dbf120791 100644 --- a/code/modules/mob/living/brain/brain.dm +++ b/code/modules/mob/living/brain/brain.dm @@ -19,9 +19,22 @@ ADD_TRAIT(src, TRAIT_SILICON_EMOTES_ALLOWED, INNATE_TRAIT) /mob/living/brain/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents) - var/obj/item/organ/brain/brain_loc = loc - if(brain_loc && isnull(new_turf) && brain_loc.owner) //we're actively being put inside a new body. - return ..(old_turf, get_turf(brain_loc.owner), same_z_layer, notify_contents) + //Bubber Edit Start + if(isnull(new_turf)) + var/mob/living/carbon/brain_owner = null + + if(istype(loc, /obj/item/organ/brain)) + var/obj/item/organ/brain/brain_loc = loc + brain_owner = brain_loc.owner + else if(istype(loc, /obj/item/mmi)) + var/obj/item/mmi/mmi_loc = loc + if(istype(mmi_loc.loc, /obj/item/organ/brain)) + var/obj/item/organ/brain/brain_loc = mmi_loc.loc + brain_owner = brain_loc.owner + + if(brain_owner) + return ..(old_turf, get_turf(brain_owner), same_z_layer, notify_contents) + //Bubber Edit End return ..() /mob/living/brain/proc/create_dna() diff --git a/code/modules/surgery/operations/operation_organ_manip.dm b/code/modules/surgery/operations/operation_organ_manip.dm index 788de1c927c..063143f26b7 100644 --- a/code/modules/surgery/operations/operation_organ_manip.dm +++ b/code/modules/surgery/operations/operation_organ_manip.dm @@ -95,9 +95,13 @@ return TRUE /datum/surgery_operation/limb/organ_manipulation/snowflake_check_availability(obj/item/bodypart/limb, mob/living/surgeon, obj/item/tool, operated_zone) + if(istype(tool, /obj/item/mmi)) //Bubber Edit + return TRUE return isorgan(tool) ? is_insert_available(limb, tool, operated_zone) : is_remove_available(limb, operated_zone) /datum/surgery_operation/limb/organ_manipulation/get_radial_options(obj/item/bodypart/limb, obj/item/tool, operating_zone) + if(istype(tool, /obj/item/mmi)) //Bubber Edit + return get_insert_options(limb, tool, operating_zone) return isorgan(tool) ? get_insert_options(limb, tool, operating_zone) : get_remove_options(limb, operating_zone) /datum/surgery_operation/limb/organ_manipulation/proc/get_remove_options(obj/item/bodypart/limb, operating_zone) @@ -200,6 +204,10 @@ organ.on_surgical_removal(surgeon, limb, tool) /datum/surgery_operation/limb/organ_manipulation/proc/on_success_insert_organ(obj/item/bodypart/limb, mob/living/surgeon, obj/item/organ/organ) + //Bubber Edit Start, Checks if the type attempted to be inserted is a positronic or not + if(istype(organ, /obj/item/mmi/posibrain)) + organ = new /obj/item/organ/brain/synth(null, organ) + //Bubber Edit End surgeon.temporarilyRemoveItemFromInventory(organ, TRUE) organ.pre_surgical_insertion(surgeon, limb, limb.body_zone) if (limb.owner) @@ -280,6 +288,10 @@ ) operation_flags = parent_type::operation_flags | OPERATION_SELF_OPERABLE replaced_by = null + insert_implements = list( + /obj/item/organ = 1, + /obj/item/mmi = 1, + ) /// Abductor subtype that works through clothes /datum/surgery_operation/limb/organ_manipulation/external/abductor diff --git a/modular_skyrat/modules/synths/code/bodyparts/brain.dm b/modular_skyrat/modules/synths/code/bodyparts/brain.dm index 2a93b691cda..b77c5cb6e83 100644 --- a/modular_skyrat/modules/synths/code/bodyparts/brain.dm +++ b/modular_skyrat/modules/synths/code/bodyparts/brain.dm @@ -9,17 +9,101 @@ icon_state = "posibrain-ipc" /// The last time (in ticks) a message about brain damage was sent. Don't touch. var/last_message_time = 0 + var/obj/item/modular_computer/pda/synth/internal_computer + actions_types = list(/datum/action/item_action/synth/open_internal_computer) organ_traits = list(TRAIT_SILICON_EMOTES_ALLOWED) + var/mmi_type = /obj/item/mmi/posibrain + var/obj/item/mmi/posibrain/stored_mmi + +/obj/item/organ/brain/synth/Initialize(mapload, obj/item/mmi/brain_mmi) + . = ..() + internal_computer = new(src) + ADD_TRAIT(src, TRAIT_SILICON_EMOTES_ALLOWED, INNATE_TRAIT) + if(istype(brain_mmi)) + stored_mmi = brain_mmi + stored_mmi.forceMove(src) + else + stored_mmi = new mmi_type(src, FALSE) + +/obj/item/organ/brain/synth/Destroy() + QDEL_NULL(internal_computer) + QDEL_NULL(stored_mmi) + . = ..() + +/obj/item/organ/brain/synth/Remove(mob/living/carbon/organ_owner, special = FALSE, movement_flags) + var/atom/drop_target = organ_owner ? organ_owner.drop_location() : drop_location() + . = ..() + if(istype(stored_mmi)) + stored_mmi.forceMove(drop_target) + stored_mmi = null + if(!QDELING(src)) + qdel(src) /obj/item/organ/brain/synth/on_mob_insert(mob/living/carbon/brain_owner, special, movement_flags = NO_ID_TRANSFER) . = ..() + if(stored_mmi?.brainmob?.mind && stored_mmi.brainmob.mind.current == stored_mmi.brainmob) + stored_mmi.brainmob.mind.transfer_to(brain_owner) - if(brain_owner.stat != DEAD || !ishuman(brain_owner)) + if(brain_owner.stat == DEAD && ishuman(brain_owner)) + var/mob/living/carbon/human/user_human = brain_owner + if(HAS_TRAIT(user_human, TRAIT_REVIVES_BY_HEALING) && user_human.health > SYNTH_BRAIN_WAKE_THRESHOLD) + user_human.revive(FALSE) + + RegisterSignal(brain_owner, COMSIG_MOB_EQUIPPED_ITEM, PROC_REF(on_equip_signal)) + RegisterSignal(brain_owner, COMSIG_HUMAN_UNEQUIPPED_ITEM, PROC_REF(on_unequip_signal)) + +/obj/item/organ/brain/synth/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) + . = ..() + cache_brainmob_into_stored_mmi(organ_owner) + + UnregisterSignal(organ_owner, COMSIG_MOB_EQUIPPED_ITEM) + UnregisterSignal(organ_owner, COMSIG_HUMAN_UNEQUIPPED_ITEM) + +/obj/item/organ/brain/synth/proc/on_equip_signal(datum/source, obj/item/item, slot) + SIGNAL_HANDLER + if(isnull(internal_computer)) return + if(slot == ITEM_SLOT_ID) + internal_computer.handle_id_slot(owner) + +/obj/item/organ/brain/synth/proc/on_unequip_signal(datum/source, obj/item/dropped_item, force, new_location) + SIGNAL_HANDLER + if(isnull(internal_computer)) + return + internal_computer.handle_id_slot(owner) + +/obj/item/organ/brain/synth/proc/cache_brainmob_into_stored_mmi(mob/living/carbon/organ_owner) + if(!istype(stored_mmi)) + return FALSE + + var/mob/living/brain/brainmob_to_store = brainmob + if(QDELETED(brainmob_to_store)) + brainmob_to_store = null + + if(!brainmob_to_store) + brainmob_to_store = stored_mmi.brainmob + + if(!brainmob_to_store) + brainmob_to_store = new /mob/living/brain(stored_mmi) + + if(organ_owner?.mind?.current == organ_owner) + organ_owner.mind.transfer_to(brainmob_to_store) + + stored_mmi.set_brainmob(brainmob_to_store) + brainmob_to_store.doMove(stored_mmi) + brainmob_to_store.container = stored_mmi + brainmob_to_store.set_stat(CONSCIOUS) + brainmob_to_store.reset_perspective() + if(brainmob == brainmob_to_store) + brainmob = null + stored_mmi.update_appearance() + return TRUE + +/obj/item/organ/brain/synth/transfer_identity(mob/living/L) + if(L.mind && L.mind.current && !decoy_override) + to_chat(L, span_userdanger("Memories Corrupted, Positronic rerolling to most stable version, last version backup ERROR minutes ago, last attacker's: Unknown, unable to pinpoint features, please standby.")) + . = ..() - var/mob/living/carbon/human/user_human = brain_owner - if(HAS_TRAIT(user_human, TRAIT_REVIVES_BY_HEALING) && user_human.health > SYNTH_BRAIN_WAKE_THRESHOLD) - user_human.revive(FALSE) /obj/item/organ/brain/synth/emp_act(severity) // EMP act against the posi, keep the cap far below the organ health . = ..() @@ -52,15 +136,17 @@ /obj/item/organ/brain/synth/circuit name = "compact AI circuit" - desc = "A compact and extremely complex circuit, perfectly dimensioned to fit in the same slot as a synthetic-compatible positronic brain. It is usually slotted into the chest of synthetic crewmembers." + desc = "A compact and extremely complex circuit, It is usually slotted into the chest of synthetic crewmembers." icon = 'modular_skyrat/master_files/icons/obj/alt_silicon_brains.dmi' icon_state = "circuit-occupied" inhand_icon_state = "electronic" lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi' + mmi_type = /obj/item/mmi/posibrain/circuit /obj/item/organ/brain/synth/mmi name = "compact man-machine interface" - desc = "A compact man-machine interface, perfectly dimensioned to fit in the same slot as a synthetic-compatible positronic brain. Unfortunately, the brain seems to be permanently attached to the circuitry, and it seems relatively sensitive to it's environment. It is usually slotted into the chest of synthetic crewmembers." + desc = "A compact man-machine interface, It is usually slotted into the chest of synthetic crewmembers." icon = 'modular_skyrat/master_files/icons/obj/surgery.dmi' icon_state = "mmi-ipc" + mmi_type = /obj/item/mmi diff --git a/modular_skyrat/modules/synths/code/bodyparts/internal_computer/brain.dm b/modular_skyrat/modules/synths/code/bodyparts/internal_computer/brain.dm deleted file mode 100644 index 3aa90da9ce5..00000000000 --- a/modular_skyrat/modules/synths/code/bodyparts/internal_computer/brain.dm +++ /dev/null @@ -1,35 +0,0 @@ -/obj/item/organ/brain/synth - var/obj/item/modular_computer/pda/synth/internal_computer - actions_types = list(/datum/action/item_action/synth/open_internal_computer) - -/obj/item/organ/brain/synth/Initialize(mapload) - . = ..() - internal_computer = new(src) - ADD_TRAIT(src, TRAIT_SILICON_EMOTES_ALLOWED, INNATE_TRAIT) - -/obj/item/organ/brain/synth/Destroy() - QDEL_NULL(internal_computer) - return ..() - -/obj/item/organ/brain/synth/on_mob_insert(mob/living/carbon/brain_owner, special, movement_flags) - . = ..() - RegisterSignal(brain_owner, COMSIG_MOB_EQUIPPED_ITEM, PROC_REF(on_equip_signal)) - RegisterSignal(brain_owner, COMSIG_HUMAN_UNEQUIPPED_ITEM, PROC_REF(on_unequip_signal)) - -/obj/item/organ/brain/synth/on_mob_remove(mob/living/carbon/brain_owner, special) - . = ..() - UnregisterSignal(brain_owner, COMSIG_MOB_EQUIPPED_ITEM) - UnregisterSignal(brain_owner, COMSIG_HUMAN_UNEQUIPPED_ITEM) - -/obj/item/organ/brain/synth/proc/on_equip_signal(datum/source, obj/item/item, slot) - SIGNAL_HANDLER - if(isnull(internal_computer)) - return - if(slot == ITEM_SLOT_ID) - internal_computer.handle_id_slot(owner) - -/obj/item/organ/brain/synth/proc/on_unequip_signal(datum/source, obj/item/dropped_item, force, new_location) - SIGNAL_HANDLER - if(isnull(internal_computer)) - return - internal_computer.handle_id_slot(owner) diff --git a/tgstation.dme b/tgstation.dme index cacc556a52f..46aa1901475 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -8962,7 +8962,6 @@ #include "modular_skyrat\modules\synths\code\bodyparts\silicon_alt_brains.dm" #include "modular_skyrat\modules\synths\code\bodyparts\stomach.dm" #include "modular_skyrat\modules\synths\code\bodyparts\tongue.dm" -#include "modular_skyrat\modules\synths\code\bodyparts\internal_computer\brain.dm" #include "modular_skyrat\modules\synths\code\bodyparts\internal_computer\internal_computer.dm" #include "modular_skyrat\modules\synths\code\reagents\blood_pack.dm" #include "modular_skyrat\modules\synths\code\reagents\pill.dm" From b50c107c815875cd4bb2fef33d34dc679b395ea8 Mon Sep 17 00:00:00 2001 From: Bubberbot <151680451+Bubberbot@users.noreply.github.com> Date: Thu, 2 Jul 2026 09:54:14 +0200 Subject: [PATCH 10/41] Automatic changelog for PR #5764 [ci skip] --- html/changelogs/AutoChangeLog-bubber-pr-5764.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5764.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5764.yml b/html/changelogs/AutoChangeLog-bubber-pr-5764.yml new file mode 100644 index 00000000000..d6721d6fcdd --- /dev/null +++ b/html/changelogs/AutoChangeLog-bubber-pr-5764.yml @@ -0,0 +1,4 @@ +author: "Vanilla1040" +delete-after: True +changes: + - refactor: "refactored how the synthetics brains work and behave" \ No newline at end of file From 0d22990b732b71cbd17c2fe75a84dd7f6f335fb4 Mon Sep 17 00:00:00 2001 From: Phantastic-Swan Date: Thu, 2 Jul 2026 17:30:08 +0200 Subject: [PATCH 11/41] Fixes breast sprite not changing when switching between breast types (#5884) ## About The Pull Request This PR fixes the bug described in #5870. I had to change so, SO MANY icon state names... ## Why It's Good For The Game Fixes #5870 ## Proof Of Testing https://github.com/user-attachments/assets/af43803a-54a4-4b22-8674-b3fa38ced2e2 ## Changelog :cl: Swan fix: fixes the breast sprite not changing when switching between different types /:cl: --- .../new_player/sprite_accessories/genitals.dm | 4 ++++ .../modules/surgery/organs/genitals.dm | 9 ++++----- .../sprite_accessories/genitals.dm | 7 ++++--- .../genitals/breasts_onmob.dmi | Bin 103261 -> 103274 bytes 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/genitals.dm b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/genitals.dm index dcba8822e51..e49e9c6fe22 100644 --- a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/genitals.dm +++ b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/genitals.dm @@ -267,6 +267,7 @@ relevent_layers = list(BODY_BEHIND_LAYER, BODY_FRONT_LAYER) has_skintone_shading = TRUE genital_location = CHEST + var/max_size = 0 /datum/sprite_accessory/genital/breasts/none icon_state = "none" @@ -277,13 +278,16 @@ /datum/sprite_accessory/genital/breasts/pair icon_state = "pair" name = "Pair" + max_size = 16 /datum/sprite_accessory/genital/breasts/quad icon_state = "quad" name = "Quad" + max_size = 5 /datum/sprite_accessory/genital/breasts/sextuple icon_state = "sextuple" name = "Sextuple" + max_size = 5 #undef TAUR_DIMENSION_X diff --git a/modular_skyrat/modules/customization/modules/surgery/organs/genitals.dm b/modular_skyrat/modules/customization/modules/surgery/organs/genitals.dm index ca0a32c8cd7..b0d1e803988 100644 --- a/modular_skyrat/modules/customization/modules/surgery/organs/genitals.dm +++ b/modular_skyrat/modules/customization/modules/surgery/organs/genitals.dm @@ -523,11 +523,10 @@ icon_state = passed_string /obj/item/organ/genital/breasts/get_sprite_size_string() - var/max_size = 5 - if(genital_type == "pair") - max_size = findtext(genital_name, "(Alt)") ? 19 : 16 - if(genital_type == "quad") - max_size = findtext(genital_name, "(Alt)") ? 19 : 5 + var/max_size = 0 + var/datum/sprite_accessory/genital/breasts/sprite_accessory = bodypart_overlay.sprite_datum + if (istype(sprite_accessory)) + max_size = sprite_accessory.max_size var/current_size = FLOOR(genital_size, 1) if(current_size < 0) current_size = 0 diff --git a/modular_zubbers/code/modules/customization/sprite_accessories/genitals.dm b/modular_zubbers/code/modules/customization/sprite_accessories/genitals.dm index a91f52804e7..af8569ab398 100644 --- a/modular_zubbers/code/modules/customization/sprite_accessories/genitals.dm +++ b/modular_zubbers/code/modules/customization/sprite_accessories/genitals.dm @@ -47,18 +47,19 @@ /datum/sprite_accessory/genital/breasts/alt icon = 'modular_zubbers/icons/mob/sprite_accesory/genitals/breasts_onmob.dmi' color_src = USE_MATRIXED_COLORS + max_size = 19 /datum/sprite_accessory/genital/breasts/alt/pair name = "Pair (Alt)" - icon_state = "pair" + icon_state = "pair_alt" /datum/sprite_accessory/genital/breasts/alt/quad name = "Quad (Alt)" - icon_state = "quad" + icon_state = "quad_alt" /datum/sprite_accessory/genital/breasts/alt/sextuple name = "Sextuple (Alt)" - icon_state = "sextuple" + icon_state = "sextuple_alt" /datum/sprite_accessory/genital/testicles/alt name = "Pair (Alt)" diff --git a/modular_zubbers/icons/mob/sprite_accesory/genitals/breasts_onmob.dmi b/modular_zubbers/icons/mob/sprite_accesory/genitals/breasts_onmob.dmi index 50a443174b4a9589713ba3ba1d2952e2775a6010..6e2e81e3ec055561576a3819f26db58d4468a5be 100644 GIT binary patch delta 1638 zcma*le>~F(9LI5Ttz1kwKgNDAR#wPLWs|NhoaRS#y3Qdsh5Xn?G{1WE%`_a9+2zaO zkxDi-sm+=5V>#Sf?DWHA6DbqRkC}xyDo20cANSAu@p(M|`#c`6R~*O$2g1St2h)!S zC3{3BojMznkQ_s!>gc4F-z)cv8#w{{Uaq~r*?E~Q2V2dC42S~`+n7C~M0ou!-`#hr z=0;wp9NRJJ{gcTw!6%Er>&U{-3>CcKE^AOIUh`9<{DY-F8K0Mek$0EM2E^SJD(-Zn z>v7(wa;%ZC@?r4Pa;5s{$v`A<*XX2-E>SHM%O-Qg-LijrPUPGT8~m6~5bdFyt5z<_ zi$|UokM+{kT6OY6gnxL`h*~>f1*Co)U!)US%Xb3B)(l$^!B^&%+V&y%!?})LQ}_s{ z>d1H77cCe!&@fBJEi~SeaT^_E$>5+A-rRArGfxbDI@?8*t9(#Qa-Cy8B4c+^2@rLel+<8NH1@5w%$+QwcBJTv8_`2!@HjXJch7Dl~ z0p4Ct#qbwHgiAPH`&3BTX~0Wwep!bxmH2I)-Xa z_eh&ug*&TIyar9HplZ6i_N#vSR1q5X_1faUY|xiY^;Y(s_S$mk_PtKfW}|+{uLnFg zv+K8&?~wsXx49|2CN2%tv#NT8(ZR?K9xXPpNqC1=Xablwa&hOTLR@4xd-%=Qtdyo z_hPG~{mjiS{B3DsQpef9sWsX#FHjIv&^_h&iSr}wYHJN3iJ})@kney=$bF}rmqQpa zWvxvM4Nivf0)0+P#@3Seb48@C$)6b8jYzAIxe5j#smmvbvAux23OQ9vKU?~sva-w0 zVt)Nj>PKKpZ;W#gol(!|fmh!;>qqsUd}Ph;77See4s$(n!6NI(VJUSFq>u%^irIOa zD+I>&#kT(=8pHU}dUIxZ-Ne%2YExB1$RcNFt!<^2j<M!|mTtS3Fm@2XuoH-?Dt6#8Fl#lsLwUhZ0q+^A8UQyEYkr zNfP*vCjTo*i8AxA#STSUT>Eeh=BQ(0pK-KpqR=?nF7X4HQ~C^iPTr0LWn>}}d_j&u zf^zaN$Y)b+>%G$;7Kj@gH?xNzD!X-;E;Y1if6+nrQxei`4joB`Bd!B50ikQhlUreK zZmzqqdBSRQBd4PVYYB=wlD^4oKO7Q88x~hE$VHBIO*8NO+aCM{_J^e|a7jVoQb*i@ zPf2+8;|Jy{u;ls*0YQvXQ{ zJ`F)>^M~8;O9CLQeEPxrB_<=$Bua#TMH)3V(9@d@reyxA+|Kr*u<#OC(-4W<(i$9vIUyb3JIi81aChXSqWgyJ-O*_Vgare)j!TKllwQ-wkMNe+tbbIl$ zc?I=&(+BSyCWDwrl@&RqXzHN_>t~gNLi=#d5D$sk#CgC#GjRlveIM>m6w?q#+!l`}y*}!DKC{ delta 1625 zcmV-f2B!JyrUu=n29P9wGI~^4bVOxyV{&P5bZKvH004NLt=zkA<5m<#;o5!*Vx|wg zbywkLU?*`g4iKalIH3{?h&`iQE^nX05=Dvxg7Dj=0iRVZ{5W3V@yFuR;}1{I#lz>P z+dtR4{pRaiabHZnySu&lYf~Lwiu+Z+?F{y#KI2l!tYHabJ8mtoMi2%ki~* z`*3?xZFc+OzL?zJ{I)A!*ZbnWh|90OuDP!OcXFxz)S&i1uPV>WRYA&b}?ASU>k#V4E8Zt$Y3Lbl?-=?Kf?24JU_wnQ#?Pz^K(4E!1GJ>hXqsvLlq2lFjT@&3qv&w^)OV#P!nqr z;i9O75fjEtm@r|=gc%d&Ojs~s=|&|;=~jko8SZ7cnBiuBhN~IwX1JU|c5aVl1wC)9`wZb^JpLR#P{>)pG2J2?hOV=!f9>aV1NXi*8U9!NWN)p;9!8n zo7N5v7s*wBWEZI?w)b#2fpw&w*j~lq1U8a-VtX6mPB{3l@Y6Wjd5AfuX|(f@a!$i& z=ON^rX3@?=#yO25`ojXMfzlJtgNOi?P4mbp#dn}w6_p$ib|kv(_Tcl zEGmJbO?wyNzNiE*Hr5lb_EGMPjBqclCtmHO+#4Bx;ci+_yxPkli2eHS!|~f6YiNo! zVtC)F5yKNtjTl~eYQ*r+QzM4Ao*FSc_tc2t#ivFLk3KbGc=x%em7!;XpU@yLj08iW zMP3*QjzW{XFcK_?uJc6?Hb1AQFr^yK1uKD4XIe zHO=mSz8WP(Tk4zLl{HF=xzswlTZ?zr!KI)vw$6a?)R7~teO@L(hD($p6tq!4F)!kOS$!1WfTXh!}FS8jG3RvBp z#rtdqC8uOrYwg)vz0;;(a{RUS+OxZQuT8;!i zSSF~Ip=W}hksxR!7#azRMuMY}AZa968VQ<4f~R+@J-?1%D)9G`41V~^yeXNfF z$xEkC^${R(>GYw#isUM?i_|;MAL%Q9fpw(bdHzCQ32Y?w&hzK_NU)%EwU6+ki4j(l zu2vErH8H|c($!YNyCz0hN4j22dD`TR1VOQPUN5ISZ*oS0q}V&J7gU}&F@w@lJ)-(X zUJ2Bd>IK!8@=BnnRL`frmsbK6rOS5mt9eGamexBjyUDNT8R2SL@4Rd#zoJ)v1ZJe` z&7_;BzovHvCZy}_q}!*zs&@wFqw5W|8)(Ao`UFUZs@gj{Yiiffgm?A{kPKh7cXoCa z-!2W$0*w#s6CjeC8lTrEKqNXfKCVxINP22~TAu)s0M+=gK0~$~WmBA`M%w(SK7*2? zE%nmo7xfvG6mzMaHb19Npjf1T>e*X-(UgL*TGg|<_^2rbW7(=_d+}XU3dZ_X-vaB? zrW{U^$k<)`mRO%R<#3W@#tz%J$oj-7g+uwPHOd)p_%kTf!CH%)@sdA-LP4xG#~JVW zGbmKX+FP9Rsy_vjqpx+`_711K?oYwwC~RG~y}>E3{4+3^&iXc(Z^k)Cul;j4n9=&S zm~Y29ul{p5nAG|<*>A{6um6)kSxRdc?pAEcltj;AB)H5hvMP$ X)9t_aK@ Date: Thu, 2 Jul 2026 17:30:42 +0200 Subject: [PATCH 12/41] Automatic changelog for PR #5884 [ci skip] --- html/changelogs/AutoChangeLog-bubber-pr-5884.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5884.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5884.yml b/html/changelogs/AutoChangeLog-bubber-pr-5884.yml new file mode 100644 index 00000000000..aa31adb08fc --- /dev/null +++ b/html/changelogs/AutoChangeLog-bubber-pr-5884.yml @@ -0,0 +1,4 @@ +author: "Swan" +delete-after: True +changes: + - bugfix: "fixes the breast sprite not changing when switching between different types" \ No newline at end of file From bb81b9b613c5be7ccb06fa6d84476f427ad99f76 Mon Sep 17 00:00:00 2001 From: Odairu <39929315+Odairu@users.noreply.github.com> Date: Thu, 2 Jul 2026 13:21:15 -0400 Subject: [PATCH 13/41] makes the long range gas analyzer pocketable like the normal range one (#5883) ## About The Pull Request title ## Why It's Good For The Game atmos gaming - there's like no reason for this thing not to be pocketable ## Proof Of Testing it works
Screenshots/Videos
## Changelog :cl: qol: long range gas analyzer is pocketable like short range /:cl: --- modular_zubbers/code/game/Items/tools.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modular_zubbers/code/game/Items/tools.dm b/modular_zubbers/code/game/Items/tools.dm index 20181449adf..b503c52956a 100644 --- a/modular_zubbers/code/game/Items/tools.dm +++ b/modular_zubbers/code/game/Items/tools.dm @@ -92,3 +92,5 @@ icon_state = "pn_welder" toolspeed = 0.25 +/obj/item/analyzer/ranged + w_class = WEIGHT_CLASS_SMALL From 490fe75ad850bde39b85f64468947e220f089ba0 Mon Sep 17 00:00:00 2001 From: Bubberbot <151680451+Bubberbot@users.noreply.github.com> Date: Thu, 2 Jul 2026 19:21:43 +0200 Subject: [PATCH 14/41] Automatic changelog for PR #5883 [ci skip] --- html/changelogs/AutoChangeLog-bubber-pr-5883.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5883.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5883.yml b/html/changelogs/AutoChangeLog-bubber-pr-5883.yml new file mode 100644 index 00000000000..41ccd17ec3c --- /dev/null +++ b/html/changelogs/AutoChangeLog-bubber-pr-5883.yml @@ -0,0 +1,4 @@ +author: "Odairu" +delete-after: True +changes: + - qol: "long range gas analyzer is pocketable like short range" \ No newline at end of file From 70eef1f46f28bb3f0d7eda332d6471bc6dece72d Mon Sep 17 00:00:00 2001 From: Robwo <31576505+R0bro@users.noreply.github.com> Date: Thu, 2 Jul 2026 13:22:08 -0400 Subject: [PATCH 15/41] Returns Space Z Level Count To 7 (#5864) ## About The Pull Request [The count was reduced all the way back in 2024 as a way to help server performance ](https://github.com/Bubberstation/Bubberstation/pull/2510) however I've been told it might be worth upping again. ## Why It's Good For The Game People yearn for the space age. Tiding gets boring and there's often not a lot in a given round, especially when you have stuff like Tarkon that take up half a large portion of a given z-level. ## Proof Of Testing The tests don't fail! Might need a test merge to judge the performance impact at scale if there's still concern. :cl: Robwo code: Returned space Z-level count back to 7. /:cl: --------- Co-authored-by: LT3 <83487515+lessthnthree@users.noreply.github.com> --- .../SpaceRuins/skyrat/waypointstation.dmm | 1370 +---------------- code/__DEFINES/maps.dm | 2 +- 2 files changed, 52 insertions(+), 1320 deletions(-) diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/waypointstation.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/waypointstation.dmm index 1d255a03c7b..8b12c9c9233 100644 --- a/_maps/RandomRuins/SpaceRuins/skyrat/waypointstation.dmm +++ b/_maps/RandomRuins/SpaceRuins/skyrat/waypointstation.dmm @@ -4,10 +4,6 @@ /obj/structure/alien/weeds, /turf/open/floor/iron/airless, /area/ruin/space/has_grav/waypoint) -"ay" = ( -/obj/item/stack/sheet/iron, -/turf/template_noop, -/area/ruin) "aR" = ( /obj/machinery/light/broken/directional/north, /turf/open/floor/iron/airless, @@ -54,7 +50,7 @@ /obj/structure/lattice, /mob/living/basic/alien, /turf/template_noop, -/area/ruin) +/area/space/nearstation) "cV" = ( /obj/effect/decal/cleanable/blood/drip, /turf/open/floor/iron/airless, @@ -74,7 +70,7 @@ /obj/item/shard, /obj/structure/lattice, /turf/template_noop, -/area/ruin) +/area/space/nearstation) "eD" = ( /obj/item/stack/cable_coil/cut{ pixel_x = 2; @@ -137,7 +133,7 @@ /obj/item/stack/tile/iron/base, /obj/structure/lattice, /turf/template_noop, -/area/ruin) +/area/space/nearstation) "hE" = ( /obj/effect/decal/cleanable/blood/tracks, /mob/living/basic/alien, @@ -159,10 +155,6 @@ /obj/item/flashlight, /turf/open/floor/iron/airless, /area/ruin/space/has_grav/waypoint) -"ju" = ( -/obj/structure/lattice, -/turf/template_noop, -/area/ruin) "ka" = ( /turf/open/floor/plating/airless, /area/ruin/space/has_grav/waypoint) @@ -222,7 +214,7 @@ /obj/item/stack/sheet/iron, /obj/structure/lattice, /turf/template_noop, -/area/ruin) +/area/space/nearstation) "mJ" = ( /obj/effect/mob_spawn/corpse/human/cargo_tech, /obj/effect/decal/cleanable/blood/splatter, @@ -285,9 +277,6 @@ /obj/effect/decal/cleanable/blood/gibs/xeno, /turf/open/floor/iron/airless, /area/ruin/space/has_grav/waypoint) -"pO" = ( -/turf/open/misc/asteroid/airless, -/area/ruin/space) "pP" = ( /obj/structure/closet/crate/large, /obj/effect/decal/cleanable/blood/gibs/xeno/down, @@ -301,10 +290,6 @@ "qT" = ( /turf/open/floor/iron/dark, /area/ruin/space/has_grav/waypoint) -"ra" = ( -/obj/item/stack/tile/iron/base, -/turf/template_noop, -/area/ruin) "rc" = ( /obj/effect/decal/cleanable/blood/tracks{ dir = 9 @@ -580,9 +565,6 @@ }, /turf/open/floor/iron/airless, /area/ruin/space/has_grav/waypoint) -"Dg" = ( -/turf/closed/mineral, -/area/ruin/space) "Dj" = ( /obj/item/shard{ pixel_x = 5; @@ -619,9 +601,6 @@ /obj/effect/decal/cleanable/blood/gibs/torso, /turf/open/floor/carpet/royalblue/airless, /area/ruin/space/has_grav/waypoint) -"FS" = ( -/turf/closed/mineral/bananium, -/area/ruin/space) "Gh" = ( /obj/effect/spawner/random/vending/colavend, /turf/open/floor/iron/airless, @@ -725,9 +704,6 @@ /obj/structure/alien/weeds, /turf/open/floor/iron/airless, /area/ruin/space/has_grav/waypoint) -"Ke" = ( -/turf/template_noop, -/area/ruin) "Kh" = ( /obj/effect/decal/cleanable/blood, /turf/open/floor/iron/airless, @@ -1027,10 +1003,6 @@ /obj/effect/decal/cleanable/blood/innards, /turf/open/floor/iron/airless, /area/ruin/space/has_grav/waypoint) -"YL" = ( -/obj/item/shard, -/turf/template_noop, -/area/ruin) "YT" = ( /turf/closed/wall/r_wall/plastitanium/syndicate, /area/ruin/space/has_grav/waypoint) @@ -1372,9 +1344,9 @@ hl hl ka co -ju -ju -Ke +tH +tH +eP rH eP eP @@ -1435,8 +1407,8 @@ pB ka bG dQ -Ke -Ke +eP +eP eP eP eP @@ -1495,10 +1467,10 @@ ka ka Pj bG -ju -Ke -Ke -Ke +tH +eP +eP +eP eP eP eP @@ -1559,8 +1531,8 @@ bG ka ZA bG -ju -ay +tH +Rk eP OB eP @@ -1620,9 +1592,9 @@ qh yn zu bG -ju -Ke -Ke +tH +eP +eP eP eP eP @@ -1683,10 +1655,10 @@ hl qh Pj ZA -ju -Ke -ju -Ke +tH +eP +tH +eP eP eP eP @@ -1746,12 +1718,12 @@ qh bG bG Um -ju +tH bG -Ke +eP bG Wg -Ke +eP ZA ka ka @@ -1810,8 +1782,8 @@ CC Pj OQ ka -ju -ay +tH +Rk bG ka Pj @@ -1966,7 +1938,7 @@ Pj Pj QC bG -ju +tH ka bG Oc @@ -2027,9 +1999,9 @@ wB OC OC ka -ju -Ke -Ke +tH +eP +eP mD wB gW @@ -2093,7 +2065,7 @@ eP Jj eP eP -ju +tH bG OC eP @@ -2155,8 +2127,8 @@ eP eP eP eP -ju -ju +tH +tH bG eP eP @@ -2217,8 +2189,8 @@ eP eP eP eP -ju -Ke +tH +eP mD eP eP @@ -2822,7 +2794,7 @@ eP OC Pj ka -ju +tH OC Jf eP @@ -2870,7 +2842,7 @@ eP bG IC bG -ju +tH OC eP rH @@ -2883,7 +2855,7 @@ eP eP OC bG -ju +tH bG OC eP @@ -2930,10 +2902,10 @@ eP eP eP ZA -ju -Ke -YL -ju +tH +eP +Qw +tH eP eP eP @@ -2946,7 +2918,7 @@ eP OC bG mD -Ke +eP ht eP eP @@ -2991,11 +2963,11 @@ eP eP eP eP -ju +tH bG -Ke -ra -ju +eP +Jj +tH eP eP eP @@ -3006,10 +2978,10 @@ eP eP eP bG -ju -Ke +tH +eP dQ -Ke +eP eP eP eP @@ -3527,1243 +3499,3 @@ eP eP eP "} -(41,1,1) = {" -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -"} -(42,1,1) = {" -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -"} -(43,1,1) = {" -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -"} -(44,1,1) = {" -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -"} -(45,1,1) = {" -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -"} -(46,1,1) = {" -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -"} -(47,1,1) = {" -eP -eP -eP -pO -Dg -Dg -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -"} -(48,1,1) = {" -eP -eP -eP -Dg -Dg -Dg -Dg -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -"} -(49,1,1) = {" -eP -eP -pO -Dg -Dg -FS -Dg -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -pO -Dg -Dg -eP -eP -eP -eP -"} -(50,1,1) = {" -eP -eP -pO -Dg -Dg -FS -Dg -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -Dg -Dg -Dg -eP -eP -eP -eP -"} -(51,1,1) = {" -eP -eP -Dg -Dg -Dg -Dg -Dg -Dg -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -pO -Dg -FS -Dg -pO -eP -eP -eP -"} -(52,1,1) = {" -eP -eP -Dg -Dg -Dg -Dg -Dg -Dg -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -Dg -Dg -Dg -Dg -pO -eP -eP -eP -"} -(53,1,1) = {" -eP -eP -Dg -Dg -Dg -Dg -Dg -Dg -pO -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -pO -Dg -Dg -Dg -Dg -FS -eP -eP -eP -"} -(54,1,1) = {" -eP -eP -pO -Dg -Dg -Dg -Dg -Dg -Dg -Dg -pO -pO -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -pO -Dg -FS -Dg -Dg -Dg -eP -eP -eP -"} -(55,1,1) = {" -eP -eP -eP -Dg -Dg -Dg -FS -Dg -Dg -Dg -Dg -Dg -pO -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -pO -Dg -FS -Dg -Dg -Dg -eP -eP -eP -"} -(56,1,1) = {" -eP -eP -eP -pO -Dg -Dg -Dg -Dg -Dg -Dg -Dg -FS -Dg -Dg -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -pO -Dg -Dg -Dg -eP -eP -eP -eP -"} -(57,1,1) = {" -eP -eP -eP -eP -Dg -Dg -Dg -Dg -Dg -Dg -FS -Dg -Dg -Dg -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -"} -(58,1,1) = {" -eP -eP -eP -eP -eP -eP -Dg -Dg -Dg -Dg -Dg -Dg -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -"} -(59,1,1) = {" -eP -eP -eP -eP -eP -eP -pO -pO -pO -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -"} -(60,1,1) = {" -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -eP -"} diff --git a/code/__DEFINES/maps.dm b/code/__DEFINES/maps.dm index 6531f0db9a2..63f1b4b0f63 100644 --- a/code/__DEFINES/maps.dm +++ b/code/__DEFINES/maps.dm @@ -182,7 +182,7 @@ Always compile, always use that verb, and always make sure that it works for wha #define PLACE_ISOLATED "isolated" //On isolated ruin z level ///Map generation defines -#define DEFAULT_SPACE_RUIN_LEVELS 4 // Bubber Edit - ORG: 7 +#define DEFAULT_SPACE_RUIN_LEVELS 7 #define DEFAULT_SPACE_EMPTY_LEVELS 1 #define BIOME_LOW_HEAT "low_heat" From bd8747eca3782337cf2bbb3e7c6cd37663d0ce71 Mon Sep 17 00:00:00 2001 From: Bubberbot <151680451+Bubberbot@users.noreply.github.com> Date: Thu, 2 Jul 2026 19:22:35 +0200 Subject: [PATCH 16/41] Automatic changelog for PR #5864 [ci skip] --- html/changelogs/AutoChangeLog-bubber-pr-5864.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5864.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5864.yml b/html/changelogs/AutoChangeLog-bubber-pr-5864.yml new file mode 100644 index 00000000000..25bb3ecc317 --- /dev/null +++ b/html/changelogs/AutoChangeLog-bubber-pr-5864.yml @@ -0,0 +1,4 @@ +author: "Robwo" +delete-after: True +changes: + - code_imp: "Returned space Z-level count back to 7." \ No newline at end of file From 3f7747c6a55e572a2e3d723e898395df4a2d0eb6 Mon Sep 17 00:00:00 2001 From: gavla <96078776+shayoki@users.noreply.github.com> Date: Thu, 2 Jul 2026 12:22:46 -0500 Subject: [PATCH 17/41] Fix flaky cable powernets unit tests (#5874) ## About The Pull Request some SMES' on our stations were a culprit in some wires having no power. This should fix https://github.com/Bubberstation/Bubberstation/issues/5797 . ## Why It's Good For The Game This is mostly better for contributors who open pull requests, this will likely prevent their PR from failing checks from maps they didn't touch. ## Proof Of Testing green means go, I think. image --- _maps/map_files/PubbyStation/PubbyStation.dmm | 26 ++----------------- _maps/map_files/biodome/biodome.dmm | 4 +-- 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index e337647cef0..98f38c34609 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -27698,7 +27698,6 @@ /turf/open/floor/plating, /area/station/security/execution/education) "dVJ" = ( -/obj/structure/cable, /obj/machinery/camera/directional/north{ c_tag = "Engineering Power Storage" }, @@ -30190,17 +30189,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/medbay) -"ftY" = ( -/obj/machinery/conveyor{ - dir = 8; - id = "garbage" - }, -/obj/effect/decal/cleanable/blood/splatter, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plating, -/area/station/maintenance/disposal) "fuf" = ( /obj/effect/turf_decal/tile/yellow, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -49441,11 +49429,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/station/medical/virology) -"rse" = ( -/obj/machinery/power/smes/engineering, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/maintenance/department/engine) "rsy" = ( /obj/effect/turf_decal/box/white{ color = "#9FED58" @@ -51138,9 +51121,6 @@ /area/station/service/abandoned_gambling_den) "stQ" = ( /obj/structure/sign/departments/science/directional/north, -/obj/machinery/power/terminal{ - dir = 8 - }, /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/department/engine) @@ -57754,7 +57734,6 @@ id = "garbage" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/blood/splatter, /obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/station/maintenance/disposal) @@ -59418,7 +59397,6 @@ name = "Danger: Conveyor Access"; req_access = list("maint_tunnels") }, -/obj/effect/decal/cleanable/blood/splatter, /obj/machinery/conveyor/inverted{ dir = 10; id = "garbage" @@ -84577,7 +84555,7 @@ cab jPf oFI bva -rse +fSx uIn mIa qdj @@ -112023,7 +112001,7 @@ bbP wFq ycT dSx -ftY +hEc cMl wPw ezn diff --git a/_maps/map_files/biodome/biodome.dmm b/_maps/map_files/biodome/biodome.dmm index 83f499f51b3..84916a144d7 100644 --- a/_maps/map_files/biodome/biodome.dmm +++ b/_maps/map_files/biodome/biodome.dmm @@ -37264,9 +37264,7 @@ /area/station/maintenance/port/lower) "naC" = ( /obj/structure/cable, -/obj/machinery/power/smes{ - charge = 5e+006 - }, +/obj/machinery/power/smes/super/full, /turf/open/floor/circuit, /area/station/ai/satellite/chamber) "naO" = ( From b36effae4782fee161f57055fd5c53305fe5d334 Mon Sep 17 00:00:00 2001 From: Bubberbot <151680451+Bubberbot@users.noreply.github.com> Date: Thu, 2 Jul 2026 18:22:35 +0000 Subject: [PATCH 18/41] Bubberstation automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-bubber-pr-5764.yml | 4 ---- html/changelogs/AutoChangeLog-bubber-pr-5864.yml | 4 ---- html/changelogs/AutoChangeLog-bubber-pr-5872.yml | 4 ---- html/changelogs/AutoChangeLog-bubber-pr-5883.yml | 4 ---- html/changelogs/AutoChangeLog-bubber-pr-5884.yml | 4 ---- html/changelogs/bubber_archive/2026-07.yml | 12 ++++++++++++ 6 files changed, 12 insertions(+), 20 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5764.yml delete mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5864.yml delete mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5872.yml delete mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5883.yml delete mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5884.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5764.yml b/html/changelogs/AutoChangeLog-bubber-pr-5764.yml deleted file mode 100644 index d6721d6fcdd..00000000000 --- a/html/changelogs/AutoChangeLog-bubber-pr-5764.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Vanilla1040" -delete-after: True -changes: - - refactor: "refactored how the synthetics brains work and behave" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5864.yml b/html/changelogs/AutoChangeLog-bubber-pr-5864.yml deleted file mode 100644 index 25bb3ecc317..00000000000 --- a/html/changelogs/AutoChangeLog-bubber-pr-5864.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Robwo" -delete-after: True -changes: - - code_imp: "Returned space Z-level count back to 7." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5872.yml b/html/changelogs/AutoChangeLog-bubber-pr-5872.yml deleted file mode 100644 index 84e634989de..00000000000 --- a/html/changelogs/AutoChangeLog-bubber-pr-5872.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "nikothedude" -delete-after: True -changes: - - code_imp: "Lycan transformation sfx is now a variable on the brain" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5883.yml b/html/changelogs/AutoChangeLog-bubber-pr-5883.yml deleted file mode 100644 index 41ccd17ec3c..00000000000 --- a/html/changelogs/AutoChangeLog-bubber-pr-5883.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Odairu" -delete-after: True -changes: - - qol: "long range gas analyzer is pocketable like short range" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5884.yml b/html/changelogs/AutoChangeLog-bubber-pr-5884.yml deleted file mode 100644 index aa31adb08fc..00000000000 --- a/html/changelogs/AutoChangeLog-bubber-pr-5884.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Swan" -delete-after: True -changes: - - bugfix: "fixes the breast sprite not changing when switching between different types" \ No newline at end of file diff --git a/html/changelogs/bubber_archive/2026-07.yml b/html/changelogs/bubber_archive/2026-07.yml index 9d30a98ef95..ab5642cd888 100644 --- a/html/changelogs/bubber_archive/2026-07.yml +++ b/html/changelogs/bubber_archive/2026-07.yml @@ -6,3 +6,15 @@ - balance: Defibrillators are now printable once again from the medical techfab. sippykot: - balance: jaws of rescue have the same speed as jaws of life +2026-07-02: + Odairu: + - qol: long range gas analyzer is pocketable like short range + Robwo: + - code_imp: Returned space Z-level count back to 7. + Swan: + - bugfix: fixes the breast sprite not changing when switching between different + types + Vanilla1040: + - refactor: refactored how the synthetics brains work and behave + nikothedude: + - code_imp: Lycan transformation sfx is now a variable on the brain From 61f75fb9bb6e9c6ad667b30af93dfbb3410b169d Mon Sep 17 00:00:00 2001 From: LT3 <83487515+lessthnthree@users.noreply.github.com> Date: Thu, 2 Jul 2026 19:07:51 -0700 Subject: [PATCH 19/41] Pubbystation cargo updates (#5886) ## About The Pull Request - Updates some airlock access helpers for consistency - Adds an airlock to the forge area - Adds plastic flaps - Adds a shuttle timer display on the south wall - Swaps the stamps table and fax machine in lobby ## Why It's Good For The Game Cargo QoL ## Proof Of Testing image ## Changelog :cl: LT3 map: QoL improvements to PubbyStation cargo area /:cl: --- _maps/map_files/PubbyStation/PubbyStation.dmm | 192 +++++++++--------- 1 file changed, 96 insertions(+), 96 deletions(-) diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 98f38c34609..902b45d5d9a 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -211,24 +211,13 @@ /area/station/engineering/main) "abc" = ( /obj/structure/table, -/obj/item/stamp/granted{ - pixel_x = -8; - pixel_y = 3 - }, -/obj/item/stamp/denied{ - pixel_x = -2; - pixel_y = -2 - }, -/obj/item/pen/red{ - pixel_y = 7 - }, -/obj/item/dest_tagger{ - pixel_x = 9; - pixel_y = -1 - }, /obj/effect/turf_decal/tile/brown/half/contrasted{ dir = 1 }, +/obj/machinery/fax{ + fax_name = "Cargo Office"; + name = "Cargo Office Fax Machine" + }, /turf/open/floor/iron, /area/station/cargo/sorting) "abe" = ( @@ -1961,7 +1950,7 @@ /turf/open/floor/plating, /area/station/maintenance/department/security/brig) "aiJ" = ( -/obj/structure/window/reinforced/spawner/directional/east, +/obj/structure/window/spawner/directional/east, /obj/machinery/door/firedoor, /obj/machinery/gbp_redemption, /turf/open/floor/iron, @@ -3223,6 +3212,7 @@ /area/station/maintenance/department/security/brig) "anu" = ( /obj/effect/decal/cleanable/dirt, +/obj/effect/spawner/random/structure/crate_abandoned, /turf/open/floor/iron, /area/station/cargo/miningfoundry) "anw" = ( @@ -9557,12 +9547,13 @@ /turf/open/floor/plating, /area/station/maintenance/department/cargo) "aNQ" = ( -/obj/structure/sign/warning/directional/south, -/obj/machinery/mech_bay_recharge_port{ - dir = 1 +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/mining{ + name = "Cargo Bay Foundry" }, -/turf/open/floor/plating, -/area/station/cargo/miningfoundry) +/obj/effect/mapping_helpers/airlock/access/all/supply/general, +/turf/open/floor/iron, +/area/station/cargo/storage) "aNT" = ( /obj/machinery/airalarm/directional/south, /obj/effect/turf_decal/tile/red/half/contrasted, @@ -9574,7 +9565,7 @@ }, /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/mapping_helpers/airlock/access/any/supply/general, +/obj/effect/mapping_helpers/airlock/access/all/supply/general, /obj/structure/disposalpipe/segment{ dir = 8 }, @@ -10648,8 +10639,7 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ dir = 4 }, -/obj/effect/mapping_helpers/airlock/access/any/supply/general, -/obj/effect/mapping_helpers/airlock/access/any/supply/mining, +/obj/effect/mapping_helpers/airlock/access/all/supply/general, /obj/structure/disposalpipe/segment{ dir = 4 }, @@ -11601,13 +11591,24 @@ /area/station/hallway/primary/central/fore) "aXs" = ( /obj/structure/table, -/obj/machinery/fax{ - fax_name = "Cargo Office"; - name = "Cargo Office Fax Machine" - }, /obj/effect/turf_decal/tile/brown/half/contrasted{ dir = 1 }, +/obj/item/stamp/granted{ + pixel_x = -8; + pixel_y = 3 + }, +/obj/item/stamp/denied{ + pixel_x = -2; + pixel_y = -2 + }, +/obj/item/dest_tagger{ + pixel_x = 9; + pixel_y = -1 + }, +/obj/item/pen/red{ + pixel_y = 7 + }, /turf/open/floor/iron, /area/station/cargo/sorting) "aXx" = ( @@ -12011,9 +12012,6 @@ /obj/structure/window/reinforced/spawner/directional/north{ pixel_y = 4 }, -/obj/structure/disposaloutlet{ - dir = 8 - }, /obj/effect/turf_decal/stripes/line{ dir = 4 }, @@ -12021,6 +12019,9 @@ dir = 1 }, /obj/machinery/light/small/directional/east, +/obj/structure/disposaloutlet{ + dir = 8 + }, /turf/open/floor/iron, /area/station/cargo/sorting) "aZn" = ( @@ -12924,8 +12925,7 @@ name = "Cargo Bay" }, /obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/any/supply/general, -/obj/effect/mapping_helpers/airlock/access/any/supply/mining, +/obj/effect/mapping_helpers/airlock/access/all/supply/general, /obj/effect/turf_decal/tile/brown/half/contrasted{ dir = 4 }, @@ -15379,9 +15379,7 @@ /turf/open/floor/iron/dark, /area/station/science/research) "bqi" = ( -/obj/structure/rack, -/obj/effect/spawner/random/maintenance, -/obj/structure/sign/poster/random/directional/north, +/obj/machinery/computer/mech_bay_power_console, /turf/open/floor/iron, /area/station/cargo/miningfoundry) "bql" = ( @@ -15823,9 +15821,13 @@ /turf/open/floor/iron, /area/station/security/checkpoint/medical) "bsR" = ( -/obj/vehicle/sealed/mecha/ripley/cargo, -/turf/open/floor/iron/recharge_floor, -/area/station/cargo/miningfoundry) +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters{ + id = "warehouse"; + name = "Warehouse Shutter" + }, +/turf/open/floor/plating, +/area/station/cargo/storage) "bsV" = ( /obj/effect/turf_decal/tile/purple/half/contrasted{ dir = 4 @@ -24191,15 +24193,11 @@ /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) "cqh" = ( -/obj/structure/window/spawner/directional/west, -/obj/structure/disposalpipe/trunk{ - dir = 8 +/obj/machinery/conveyor{ + dir = 8; + id = "QMLoad2" }, -/obj/structure/window/spawner/directional/north, -/obj/machinery/disposal/delivery_chute{ - dir = 4 - }, -/turf/open/floor/plating, +/turf/open/floor/iron, /area/station/cargo/storage) "cqk" = ( /obj/machinery/door/poddoor/shutters/preopen{ @@ -26462,6 +26460,7 @@ dir = 4; id = "QMLoad" }, +/obj/structure/plasticflaps, /turf/open/floor/plating, /area/station/cargo/storage) "dbj" = ( @@ -27822,13 +27821,18 @@ /turf/closed/wall, /area/station/medical/treatment_center) "dYl" = ( -/obj/effect/turf_decal/tile/brown/half/contrasted, -/obj/structure/reagent_dispensers/fueltank, -/obj/structure/disposalpipe/segment{ +/obj/structure/window/spawner/directional/west, +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/obj/structure/window/spawner/directional/north, +/obj/machinery/disposal/delivery_chute{ dir = 4 }, /obj/machinery/light, -/obj/machinery/firealarm/directional/south, +/obj/machinery/status_display/supply{ + pixel_y = -32 + }, /turf/open/floor/iron, /area/station/cargo/storage) "dYm" = ( @@ -28218,7 +28222,7 @@ dir = 8; pixel_y = -2 }, -/obj/structure/window/reinforced/spawner/directional/east, +/obj/structure/window/spawner/directional/east, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) "elj" = ( @@ -29952,7 +29956,9 @@ /obj/structure/disposalpipe/segment{ dir = 8 }, -/obj/effect/spawner/random/structure/crate_abandoned, +/obj/machinery/firealarm/directional/north, +/obj/structure/rack, +/obj/effect/spawner/random/maintenance, /turf/open/floor/iron, /area/station/cargo/miningfoundry) "flQ" = ( @@ -30074,6 +30080,8 @@ dir = 4 }, /obj/effect/decal/cleanable/dirt, +/obj/structure/rack, +/obj/effect/spawner/random/maintenance, /turf/open/floor/plating, /area/station/cargo/miningfoundry) "fqv" = ( @@ -30484,6 +30492,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/reagent_dispensers/watertank, /turf/open/floor/iron, /area/station/cargo/storage) "fEU" = ( @@ -32675,7 +32684,7 @@ dir = 4 }, /obj/structure/cable, -/turf/open/floor/plating, +/turf/open/floor/iron, /area/station/cargo/miningfoundry) "gYY" = ( /obj/machinery/atmospherics/pipe/smart/simple/cyan/visible, @@ -33870,9 +33879,8 @@ /area/station/maintenance/department/cargo) "hOI" = ( /obj/machinery/light/small/directional/west, -/obj/structure/closet/crate/freezer, -/obj/effect/spawner/random/maintenance/two, -/turf/open/floor/iron, +/obj/vehicle/sealed/mecha/ripley/cargo, +/turf/open/floor/iron/recharge_floor, /area/station/cargo/miningfoundry) "hOL" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, @@ -38583,16 +38591,10 @@ /turf/open/floor/plating, /area/station/maintenance/department/security/brig) "kRa" = ( -/obj/machinery/door/window/left/directional/west{ - pixel_x = -4; - name = "Deliveries Transfer Chute" - }, -/obj/machinery/conveyor{ - dir = 8; - id = "QMLoad2" - }, -/turf/open/floor/plating, -/area/station/cargo/storage) +/obj/structure/closet/crate/freezer, +/obj/effect/spawner/random/maintenance/two, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "kRk" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ dir = 4 @@ -39804,13 +39806,14 @@ /area/station/science/genetics) "lEm" = ( /obj/effect/turf_decal/tile/brown/half/contrasted, -/obj/structure/reagent_dispensers/watertank, /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/item/radio/intercom{ - pixel_y = -26 +/obj/structure/reagent_dispensers/fueltank, +/obj/effect/turf_decal/stripes/line{ + dir = 4 }, +/obj/machinery/firealarm/directional/south, /turf/open/floor/iron, /area/station/cargo/storage) "lEn" = ( @@ -42131,7 +42134,7 @@ "ndU" = ( /obj/machinery/door/firedoor, /obj/machinery/piratepad/civilian, -/obj/structure/window/reinforced/spawner/directional/east, +/obj/structure/window/spawner/directional/east, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) "nei" = ( @@ -42557,9 +42560,9 @@ /turf/open/floor/iron, /area/station/construction/mining/aux_base) "nsH" = ( -/obj/structure/rack, -/obj/effect/spawner/random/maintenance, -/obj/machinery/firealarm/directional/west, +/obj/machinery/mech_bay_recharge_port{ + dir = 2 + }, /turf/open/floor/iron, /area/station/cargo/miningfoundry) "nsJ" = ( @@ -43313,9 +43316,6 @@ "nSz" = ( /obj/machinery/light_switch/directional/south, /obj/machinery/light/small/directional/south, -/obj/machinery/computer/mech_bay_power_console{ - dir = 1 - }, /turf/open/floor/iron, /area/station/cargo/miningfoundry) "nTk" = ( @@ -46717,7 +46717,7 @@ dir = 8 }, /obj/machinery/airalarm/directional/north, -/turf/open/floor/plating, +/turf/open/floor/iron, /area/station/cargo/miningfoundry) "pOE" = ( /obj/structure/rack, @@ -47217,8 +47217,7 @@ dir = 4 }, /obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/any/supply/general, -/obj/effect/mapping_helpers/airlock/access/any/supply/mining, +/obj/effect/mapping_helpers/airlock/access/all/supply/general, /obj/effect/turf_decal/tile/brown/half/contrasted{ dir = 4 }, @@ -54361,7 +54360,7 @@ name = "Deliveries" }, /obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/any/supply/general, +/obj/effect/mapping_helpers/airlock/access/all/supply/general, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ dir = 8 }, @@ -58293,6 +58292,7 @@ dir = 8; id = "QMLoad2" }, +/obj/structure/plasticflaps, /turf/open/floor/plating, /area/station/cargo/storage) "wCi" = ( @@ -102727,18 +102727,18 @@ aEj uXX aEj fln -vBZ +kRa ney -bsR +vBZ +vBZ aNQ -bbG jQv asK cCB cCB cCB cCB -cCB +acx lEm bbG aaa @@ -102995,7 +102995,7 @@ aTr vrX aTr aTr -cCB +cpo dYl bbG aht @@ -103245,7 +103245,7 @@ anu aQo jBh bMV -aTy +bsR pcy gnh baD @@ -103254,7 +103254,7 @@ aXA aXA hvF cqh -bbG +aTy aaa aaa aaa @@ -103502,7 +103502,7 @@ rmO xog lmw wPU -aTy +bsR pcy aKh cCB @@ -103510,7 +103510,7 @@ vFu cCB cCB cpo -kRa +poF aTy aaa aaa @@ -103759,7 +103759,7 @@ aEj btg coL aQp -aTy +bsR pcy bTu cCB @@ -104016,7 +104016,7 @@ aEj hkA ylY wZg -bbG +bsR pcy bUX qof @@ -104279,10 +104279,10 @@ fHp bbG fHp kIV +bbG aTy aTy -aTy -aTy +bbG aaa aaa aaa @@ -104536,7 +104536,7 @@ vsO aTy iYH wBY -aTy +bbG aht aht aht @@ -104793,7 +104793,7 @@ jTV bbG jTV kIV -aTy +bbG aaa aaa aaa From 82b22c27b4dcd1577be01d34edc79154e5b983c2 Mon Sep 17 00:00:00 2001 From: Bubberbot <151680451+Bubberbot@users.noreply.github.com> Date: Fri, 3 Jul 2026 04:08:17 +0200 Subject: [PATCH 20/41] Automatic changelog for PR #5886 [ci skip] --- html/changelogs/AutoChangeLog-bubber-pr-5886.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5886.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5886.yml b/html/changelogs/AutoChangeLog-bubber-pr-5886.yml new file mode 100644 index 00000000000..f7744cd0c30 --- /dev/null +++ b/html/changelogs/AutoChangeLog-bubber-pr-5886.yml @@ -0,0 +1,4 @@ +author: "LT3" +delete-after: True +changes: + - map: "QoL improvements to PubbyStation cargo area" \ No newline at end of file From 041749ff698b1b5d7de008fbb3b63db071c1577c Mon Sep 17 00:00:00 2001 From: LT3 <83487515+lessthnthree@users.noreply.github.com> Date: Thu, 2 Jul 2026 19:14:05 -0700 Subject: [PATCH 21/41] Adds a crate return to Void Raptor (#5888) ## About The Pull Request Rearranges VR deliveries room to give it a full crate return and more movement space. image ## Why It's Good For The Game Crate returns, less cramped near doorway ## Changelog :cl: LT3 map: Added a crate return to Void Raptor cargo /:cl: --- _maps/map_files/VoidRaptor/VoidRaptor.dmm | 190 ++++++++++++---------- 1 file changed, 100 insertions(+), 90 deletions(-) diff --git a/_maps/map_files/VoidRaptor/VoidRaptor.dmm b/_maps/map_files/VoidRaptor/VoidRaptor.dmm index 927b4012657..0882677b6b2 100644 --- a/_maps/map_files/VoidRaptor/VoidRaptor.dmm +++ b/_maps/map_files/VoidRaptor/VoidRaptor.dmm @@ -2355,10 +2355,17 @@ /turf/open/floor/iron/white/smooth_large, /area/station/medical/pharmacy) "aJH" = ( -/obj/effect/turf_decal/trimline/brown/filled/corner, /obj/structure/disposalpipe/segment{ dir = 10 }, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 10 + }, +/obj/machinery/conveyor_switch/oneway{ + id = "cargodisposals"; + name = "disposals conveyor switch"; + pixel_x = -11 + }, /turf/open/floor/iron/smooth_corner, /area/station/cargo/sorting) "aKj" = ( @@ -2984,9 +2991,7 @@ c_tag = "Cargo Bay - Delivery Office Port"; name = "cargo camera" }, -/obj/structure/window/reinforced/spawner/directional/east{ - pixel_x = 4 - }, +/obj/structure/window/spawner/directional/east, /turf/open/floor/iron/smooth_large, /area/station/cargo/sorting) "aRQ" = ( @@ -4660,6 +4665,7 @@ dir = 5 }, /obj/structure/plasticflaps, +/obj/structure/window/spawner/directional/east, /turf/open/floor/iron/smooth_large, /area/station/cargo/sorting) "bru" = ( @@ -5165,7 +5171,7 @@ dir = 1 }, /obj/item/radio/intercom/directional/north, -/obj/machinery/computer/piratepad_control/civilian, +/obj/machinery/piratepad/civilian, /obj/effect/turf_decal/bot, /turf/open/floor/iron/smooth_edge, /area/station/cargo/lobby) @@ -7924,6 +7930,11 @@ /obj/effect/turf_decal/tile/blue/diagonal_centre, /turf/open/floor/iron/dark/diagonal, /area/station/engineering/transit_tube) +"ctc" = ( +/obj/structure/window/reinforced/spawner/directional/south, +/obj/structure/table, +/turf/open/floor/iron/smooth_large, +/area/station/cargo/sorting) "ctd" = ( /turf/open/floor/iron/smooth, /area/station/maintenance/starboard/lesser) @@ -10791,6 +10802,10 @@ "djy" = ( /obj/effect/turf_decal/trimline/brown/filled/line, /obj/item/radio/intercom/directional/south, +/obj/machinery/conveyor_switch/oneway{ + id = "cratereturn"; + name = "crate return switch" + }, /turf/open/floor/iron/smooth_edge{ dir = 1 }, @@ -12330,14 +12345,11 @@ /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 6 }, -/obj/structure/table, -/obj/item/storage/box{ - pixel_x = 4; - pixel_y = 4 - }, +/obj/structure/rack, +/obj/effect/spawner/random/bureaucracy/birthday_wrap, /obj/item/storage/box/lights/mixed{ - pixel_x = -13; - pixel_y = 4 + pixel_x = 5; + pixel_y = 1 }, /turf/open/floor/iron/smooth, /area/station/cargo/sorting) @@ -14571,7 +14583,6 @@ /area/station/engineering/supermatter/room) "ekf" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/delivery, /obj/structure/disposalpipe/segment, /obj/structure/disposalpipe/segment{ dir = 4 @@ -18150,6 +18161,9 @@ /obj/effect/turf_decal/trimline/brown/filled/warning{ dir = 9 }, +/obj/effect/turf_decal/loading_area{ + dir = 1 + }, /turf/open/floor/iron/smooth, /area/station/cargo/lobby) "fnt" = ( @@ -18770,10 +18784,7 @@ /turf/open/floor/iron/dark/smooth_large, /area/station/command/heads_quarters/blueshield) "fwW" = ( -/obj/effect/turf_decal/trimline/brown/filled/warning{ - dir = 1 - }, -/obj/effect/turf_decal/loading_area{ +/obj/effect/turf_decal/trimline/brown/filled/line{ dir = 1 }, /obj/structure/disposalpipe/segment, @@ -20115,18 +20126,16 @@ /turf/open/floor/iron/smooth_large, /area/station/maintenance/department/science/ordnance_maint) "fTO" = ( -/obj/effect/turf_decal/trimline/brown/filled/warning{ - dir = 8 - }, -/obj/machinery/conveyor_switch/oneway{ - id = "cargodisposals"; - name = "disposals conveyor switch" - }, /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/structure/railing{ - dir = 8 +/obj/machinery/conveyor{ + dir = 1; + id = "cratereturn" + }, +/obj/structure/window/spawner/directional/east, +/obj/structure/plasticflaps{ + name = "Returns" }, /turf/open/floor/iron/smooth_edge{ dir = 4 @@ -21221,14 +21230,18 @@ /obj/structure/disposalpipe/segment{ dir = 10 }, -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 10 +/obj/machinery/conveyor{ + dir = 1; + id = "cratereturn" }, -/obj/structure/railing{ - dir = 8 +/obj/machinery/door/window/left/directional/north{ + req_access = list("cargo"); + name = "Crate Returns" + }, +/obj/machinery/door/window/right/directional/east{ + name = "Crate Returns"; + req_access = list("cargo") }, -/obj/structure/filingcabinet/white, -/obj/effect/turf_decal/bot, /turf/open/floor/iron/smooth, /area/station/cargo/sorting) "gjA" = ( @@ -24004,10 +24017,9 @@ c_tag = "Cargo - Waiting Room"; name = "cargo camera" }, -/obj/machinery/piratepad/civilian, -/obj/effect/turf_decal/trimline/yellow, /obj/effect/turf_decal/bot, /obj/machinery/light/directional/north, +/obj/machinery/computer/piratepad_control/civilian, /turf/open/floor/iron/smooth_edge, /area/station/cargo/lobby) "gXD" = ( @@ -31868,7 +31880,7 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 1 }, -/obj/effect/turf_decal/trimline/brown/filled/warning, +/obj/effect/turf_decal/trimline/brown/filled/line, /obj/structure/disposalpipe/segment, /turf/open/floor/iron/smooth_edge{ dir = 1 @@ -36149,6 +36161,7 @@ dir = 2 }, /obj/effect/turf_decal/delivery, +/obj/structure/window/spawner/directional/east, /turf/open/floor/iron/smooth_large, /area/station/cargo/sorting) "kpB" = ( @@ -39111,11 +39124,9 @@ /obj/structure/disposalpipe/trunk{ dir = 2 }, -/obj/structure/window/reinforced/spawner/directional/east{ - pixel_x = 4 - }, /obj/structure/plasticflaps, /obj/effect/turf_decal/delivery, +/obj/structure/window/spawner/directional/east, /turf/open/floor/iron/smooth_large, /area/station/cargo/sorting) "lct" = ( @@ -43658,16 +43669,27 @@ /turf/open/floor/iron/dark/smooth_large, /area/station/command/heads_quarters/qm) "mna" = ( -/obj/structure/plasticflaps{ - name = "Deliveries" - }, /obj/structure/window/reinforced/spawner/directional/west{ pixel_x = -4 }, /obj/structure/disposalpipe/segment, -/obj/machinery/door/window/right/directional/north{ - name = "Deliveries"; - req_access = list("shipping") +/obj/structure/window/reinforced/spawner/directional/south, +/obj/structure/table, +/obj/item/storage/box/shipping{ + pixel_x = 36; + pixel_y = 2 + }, +/obj/item/paper_bin{ + pixel_y = 4; + pixel_x = -5 + }, +/obj/item/pen{ + pixel_y = 4; + pixel_x = -6 + }, +/obj/item/folder/yellow{ + pixel_x = 17; + pixel_y = 3 }, /turf/open/floor/iron/smooth_large, /area/station/cargo/sorting) @@ -44004,13 +44026,6 @@ /obj/structure/cable, /obj/machinery/power/apc/auto_name/directional/south, /obj/effect/turf_decal/trimline/brown/filled/line, -/obj/structure/table, -/obj/item/paper_bin{ - pixel_y = 4 - }, -/obj/item/pen{ - pixel_y = 4 - }, /turf/open/floor/iron/smooth_edge{ dir = 1 }, @@ -51317,11 +51332,9 @@ /area/space/nearstation) "osm" = ( /obj/structure/chair/office, -/obj/effect/turf_decal/trimline/brown/filled/warning{ - dir = 6 - }, /obj/effect/landmark/start/cargo_technician, /obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/trimline/brown/filled, /turf/open/floor/iron/smooth, /area/station/cargo/sorting) "osw" = ( @@ -51616,8 +51629,12 @@ /area/station/maintenance/department/engine) "owG" = ( /obj/structure/disposalpipe/segment, -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, +/obj/machinery/conveyor{ + dir = 1; + id = "cratereturn" + }, +/obj/structure/window/spawner/directional/east, +/turf/open/floor/iron/smooth_large, /area/station/cargo/sorting) "oxa" = ( /obj/machinery/atmospherics/pipe/smart/simple/yellow/visible, @@ -54764,17 +54781,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/machinery/door/window/right/directional/south{ - name = "Shuttle Deliveries"; - req_access = list("cargo") - }, -/obj/structure/window/reinforced/spawner/directional/east{ - pixel_x = 4 - }, /obj/structure/disposalpipe/segment{ dir = 5 }, -/obj/effect/turf_decal/tile/brown/half, /obj/effect/turf_decal/trimline/neutral/line, /obj/effect/turf_decal/trimline/neutral/line, /obj/effect/turf_decal/trimline/neutral/line, @@ -54785,6 +54794,11 @@ /obj/effect/turf_decal/trimline/neutral/mid_joiner, /obj/effect/turf_decal/trimline/neutral/mid_joiner, /obj/effect/turf_decal/trimline/neutral/mid_joiner, +/obj/machinery/conveyor{ + dir = 1; + id = "cratereturn" + }, +/obj/structure/window/spawner/directional/east, /turf/open/floor/iron/smooth_large, /area/station/cargo/sorting) "pnN" = ( @@ -56884,8 +56898,8 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/effect/turf_decal/trimline/brown/filled/corner{ - dir = 1 +/obj/effect/turf_decal/trimline/brown/filled/warning{ + dir = 8 }, /turf/open/floor/iron/smooth_corner{ dir = 1 @@ -58514,11 +58528,6 @@ /area/station/medical/medbay/central) "qni" = ( /obj/effect/turf_decal/trimline/brown/filled/line, -/obj/structure/rack, -/obj/effect/turf_decal/box/white{ - color = "#A46106" - }, -/obj/effect/spawner/random/bureaucracy/birthday_wrap, /turf/open/floor/iron/smooth_edge{ dir = 1 }, @@ -60682,6 +60691,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/effect/turf_decal/bot, /turf/open/floor/iron/smooth_large, /area/station/cargo/lobby) "qTh" = ( @@ -65728,11 +65738,13 @@ /turf/open/floor/engine, /area/station/engineering/supermatter/room) "ssQ" = ( -/obj/effect/turf_decal/trimline/brown/filled/line{ +/obj/effect/turf_decal/trimline/brown/filled/warning{ dir = 1 }, /obj/structure/disposalpipe/segment, -/obj/machinery/gbp_redemption, +/obj/effect/turf_decal/loading_area{ + dir = 1 + }, /turf/open/floor/iron/smooth_edge, /area/station/cargo/lobby) "ssU" = ( @@ -67726,14 +67738,9 @@ /area/station/service/kitchen) "sSn" = ( /obj/effect/turf_decal/trimline/brown/filled/line, -/obj/structure/table, -/obj/item/storage/box/shipping{ - pixel_x = 2; - pixel_y = 4 - }, -/obj/item/folder/yellow{ - pixel_x = -15; - pixel_y = 3 +/obj/machinery/conveyor_switch/oneway{ + id = "shuttletodelivery"; + name = "disposals conveyor switch" }, /turf/open/floor/iron/smooth_edge{ dir = 1 @@ -69478,6 +69485,7 @@ /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/gbp_redemption, /turf/open/floor/iron/smooth, /area/station/hallway/primary/aft) "tqi" = ( @@ -70049,15 +70057,16 @@ /turf/closed/wall/r_wall, /area/station/security/office) "txh" = ( -/obj/effect/turf_decal/trimline/brown/filled/warning{ - dir = 9 - }, /obj/structure/disposalpipe/segment{ dir = 4 }, /obj/effect/turf_decal/arrows{ dir = 1 }, +/obj/machinery/conveyor{ + dir = 1; + id = "cratereturn" + }, /turf/open/floor/iron/smooth, /area/station/cargo/sorting) "txi" = ( @@ -71224,6 +71233,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/effect/turf_decal/bot, /turf/open/floor/iron/smooth_large, /area/station/cargo/lobby) "tNq" = ( @@ -77301,6 +77311,10 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/machinery/door/window/left/directional/east{ + req_access = list("cargo"); + name = "Cargo Disposals" + }, /turf/open/floor/iron/smooth_large, /area/station/cargo/sorting) "vwo" = ( @@ -78064,7 +78078,6 @@ /turf/closed/wall/mineral/iron, /area/station/service/chapel/office) "vIF" = ( -/obj/effect/turf_decal/delivery, /obj/structure/disposalpipe/segment, /obj/effect/landmark/start/hangover, /turf/open/floor/iron/smooth_large, @@ -80920,6 +80933,7 @@ dir = 4 }, /obj/effect/turf_decal/delivery, +/obj/structure/window/spawner/directional/east, /turf/open/floor/iron/smooth_large, /area/station/cargo/sorting) "wwA" = ( @@ -85094,10 +85108,6 @@ /obj/structure/disposalpipe/segment{ dir = 5 }, -/obj/machinery/conveyor_switch/oneway{ - id = "shuttletodelivery"; - name = "disposals conveyor switch" - }, /obj/effect/turf_decal/trimline/brown/filled/corner{ dir = 4 }, @@ -126942,7 +126952,7 @@ vXh jTg nLC qni -wVD +ctc cfZ tjR eiX From 2ad4a8f54fe6c0b3659bea250cadc7bb16e6f16b Mon Sep 17 00:00:00 2001 From: Bubberbot <151680451+Bubberbot@users.noreply.github.com> Date: Fri, 3 Jul 2026 04:14:30 +0200 Subject: [PATCH 22/41] Automatic changelog for PR #5888 [ci skip] --- html/changelogs/AutoChangeLog-bubber-pr-5888.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5888.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5888.yml b/html/changelogs/AutoChangeLog-bubber-pr-5888.yml new file mode 100644 index 00000000000..bad1fea1891 --- /dev/null +++ b/html/changelogs/AutoChangeLog-bubber-pr-5888.yml @@ -0,0 +1,4 @@ +author: "LT3" +delete-after: True +changes: + - map: "Added a crate return to Void Raptor cargo" \ No newline at end of file From a14cba8efc0376417f80c533bfad9a5d4d350da5 Mon Sep 17 00:00:00 2001 From: Bubberbot <151680451+Bubberbot@users.noreply.github.com> Date: Fri, 3 Jul 2026 02:20:13 +0000 Subject: [PATCH 23/41] Bubberstation automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-bubber-pr-5886.yml | 4 ---- html/changelogs/AutoChangeLog-bubber-pr-5888.yml | 4 ---- html/changelogs/bubber_archive/2026-07.yml | 4 ++++ 3 files changed, 4 insertions(+), 8 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5886.yml delete mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5888.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5886.yml b/html/changelogs/AutoChangeLog-bubber-pr-5886.yml deleted file mode 100644 index f7744cd0c30..00000000000 --- a/html/changelogs/AutoChangeLog-bubber-pr-5886.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "LT3" -delete-after: True -changes: - - map: "QoL improvements to PubbyStation cargo area" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5888.yml b/html/changelogs/AutoChangeLog-bubber-pr-5888.yml deleted file mode 100644 index bad1fea1891..00000000000 --- a/html/changelogs/AutoChangeLog-bubber-pr-5888.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "LT3" -delete-after: True -changes: - - map: "Added a crate return to Void Raptor cargo" \ No newline at end of file diff --git a/html/changelogs/bubber_archive/2026-07.yml b/html/changelogs/bubber_archive/2026-07.yml index ab5642cd888..d84bf089cd1 100644 --- a/html/changelogs/bubber_archive/2026-07.yml +++ b/html/changelogs/bubber_archive/2026-07.yml @@ -18,3 +18,7 @@ - refactor: refactored how the synthetics brains work and behave nikothedude: - code_imp: Lycan transformation sfx is now a variable on the brain +2026-07-03: + LT3: + - map: Added a crate return to Void Raptor cargo + - map: QoL improvements to PubbyStation cargo area From e2cf25470dcb9e2a58f2d275a38fc49229ee0097 Mon Sep 17 00:00:00 2001 From: Roxy <75404941+TealSeer@users.noreply.github.com> Date: Fri, 3 Jul 2026 14:12:07 -0400 Subject: [PATCH 24/41] Fix horns getting hidden in modsuits (#5891) ## About The Pull Request Couple things going on here but basically boils down to the `/datum/bodypart_overlay/mutant/horns/can_draw_on_bodypart` proc in `_visual_organs.dm` blocking horns if outfit has `HIDEHAIR` flagged which mods do, this is all fine and dandy but we have a specific carve-out for mods because of the hardlight overlays they add, problem is that the latter check was taking precedence over the carve-out (`is_deely_bopper_hidden`). I commented out this check because `is_deely_bopper_hidden` does everything it does and more, so we don't need it. Also deleted a redundant skyrat override on `/datum/bodypart_overlay/mutant/horns/can_draw_on_bodypart` because the parent `/datum/bodypart_overlay/mutant/can_draw_on_bodypart` override does the same thing. ## Why It's Good For The Game Fixes #5631 ## Proof Of Testing
Screenshots/Videos image
## Changelog :cl: fix: fixed modsuits hiding horns /:cl: --- code/modules/surgery/organs/external/_visual_organs.dm | 2 ++ .../modules/customization/modules/surgery/organs/horns.dm | 7 ------- .../datums/bodypart_overlays/mutant_bodypart_overlay.dm | 8 ++++---- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/code/modules/surgery/organs/external/_visual_organs.dm b/code/modules/surgery/organs/external/_visual_organs.dm index 953332b338b..6c51c0f95ed 100644 --- a/code/modules/surgery/organs/external/_visual_organs.dm +++ b/code/modules/surgery/organs/external/_visual_organs.dm @@ -126,8 +126,10 @@ Unlike normal organs, we're actually inside a persons limbs at all times dyable = TRUE draw_on_husks = HUSK_OVERLAY_NORMAL +/* BUBBER EDIT REMOVE BEGIN - Customization /datum/bodypart_overlay/mutant/horns/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner, mob/living/carbon/owner, is_husked = FALSE) return ..() && !(bodypart_owner.owner?.obscured_slots & HIDEHAIR) +*/// BUBBER EDIT REMOVE END ///The frills of a lizard (like weird fin ears) /obj/item/organ/frills diff --git a/modular_skyrat/modules/customization/modules/surgery/organs/horns.dm b/modular_skyrat/modules/customization/modules/surgery/organs/horns.dm index 94c2365c1dc..3f0d68db4e0 100644 --- a/modular_skyrat/modules/customization/modules/surgery/organs/horns.dm +++ b/modular_skyrat/modules/customization/modules/surgery/organs/horns.dm @@ -12,10 +12,3 @@ /datum/bodypart_overlay/mutant/horns/override_color(rgb_value) return draw_color -/datum/bodypart_overlay/mutant/horns/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner) - if(!..(bodypart_owner)) - return FALSE - var/mob/living/carbon/human/human = bodypart_owner.owner - if(!human) - return TRUE - return !sprite_datum.is_hidden(human) diff --git a/modular_zubbers/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm b/modular_zubbers/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm index 046d182393f..6a7499be7f1 100644 --- a/modular_zubbers/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm +++ b/modular_zubbers/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm @@ -86,13 +86,13 @@ return sprite_datum?.feature_key_override || feature_key -/datum/bodypart_overlay/mutant/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner) +/datum/bodypart_overlay/mutant/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner, mob/living/carbon/owner, is_husked) if(!..()) return FALSE - var/mob/living/carbon/human/human = bodypart_owner.owner - if(!istype(human)) + var/mob/living/carbon/human/human_owner = owner + if(!istype(human_owner)) return TRUE - return !isnull(sprite_datum) && !sprite_datum.is_hidden(human) + return !isnull(sprite_datum) && !sprite_datum.is_hidden(human_owner) /// Get the images we need to draw on the person. Called from get_overlay() which is called from _bodyparts.dm. From 359d9e1beaf25807186b662863da4293d987c628 Mon Sep 17 00:00:00 2001 From: Bubberbot <151680451+Bubberbot@users.noreply.github.com> Date: Fri, 3 Jul 2026 20:12:32 +0200 Subject: [PATCH 25/41] Automatic changelog for PR #5891 [ci skip] --- html/changelogs/AutoChangeLog-bubber-pr-5891.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5891.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5891.yml b/html/changelogs/AutoChangeLog-bubber-pr-5891.yml new file mode 100644 index 00000000000..b0b184eedd9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-bubber-pr-5891.yml @@ -0,0 +1,4 @@ +author: "TealSeer" +delete-after: True +changes: + - bugfix: "fixed modsuits hiding horns" \ No newline at end of file From c433cfa0271494e48f7a0c2d6fbadb845f23414c Mon Sep 17 00:00:00 2001 From: gavla <96078776+shayoki@users.noreply.github.com> Date: Fri, 3 Jul 2026 13:18:17 -0500 Subject: [PATCH 26/41] actually fixes biodome's flaky power cable unit test its AI sat (#5890) ## About The Pull Request The cable under the AI Sat's Smes wasn't actually going anywhere. This fixes that on possibly, HOPEFULLY, fixes the unit test. ## Proof Of Testing If this passes the unit test, yeh. --- _maps/map_files/biodome/biodome.dmm | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/_maps/map_files/biodome/biodome.dmm b/_maps/map_files/biodome/biodome.dmm index 84916a144d7..5da93c2522d 100644 --- a/_maps/map_files/biodome/biodome.dmm +++ b/_maps/map_files/biodome/biodome.dmm @@ -10772,7 +10772,6 @@ dir = 1 }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, /turf/open/floor/iron/dark, /area/station/ai/satellite/chamber) "dPD" = ( @@ -16675,6 +16674,7 @@ /obj/effect/mapping_helpers/requests_console/assistance, /obj/effect/mapping_helpers/requests_console/information, /obj/machinery/firealarm/directional/north, +/obj/structure/cable, /turf/open/floor/circuit, /area/station/ai/satellite/chamber) "fVJ" = ( @@ -30338,6 +30338,7 @@ dir = 8 }, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/structure/cable, /turf/open/floor/iron/dark, /area/station/ai/satellite/chamber) "kJT" = ( @@ -50530,6 +50531,10 @@ /obj/item/folder/yellow, /turf/open/floor/iron/dark, /area/station/tcommsat/computer) +"rCO" = ( +/obj/structure/cable, +/turf/closed/wall/r_wall, +/area/station/ai/satellite/chamber) "rCP" = ( /obj/effect/turf_decal/siding/dark/corner{ dir = 1 @@ -58726,7 +58731,6 @@ }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, /turf/open/floor/iron/dark, /area/station/ai/satellite/chamber) "ulx" = ( @@ -156655,7 +156659,7 @@ yiK ulw npE lRp -sjc +rCO naC uio nKg From fa7e5beeb5e7d1e8ce9f7d83716d7d22d3bf1754 Mon Sep 17 00:00:00 2001 From: Odairu <39929315+Odairu@users.noreply.github.com> Date: Fri, 3 Jul 2026 14:21:00 -0400 Subject: [PATCH 27/41] reverts the change that removed the healing factor on the bluelens emitter beams (#5882) ## About The Pull Request Title ## Why It's Good For The Game A) No one uses the diode disks anyway (booooo) B) This lens reduces SM power as well as healing the SM, so you can't only use them C) this was the worst PR that I ever made and Idk why I actually made it. ## Proof Of Testing it worky for sure
Screenshots/Videos
## Changelog :cl: balance: reverts bluelens to TG base /:cl: --- modular_zubbers/code/modules/projectiles/beams.dm | 2 -- tgstation.dme | 1 - 2 files changed, 3 deletions(-) delete mode 100644 modular_zubbers/code/modules/projectiles/beams.dm diff --git a/modular_zubbers/code/modules/projectiles/beams.dm b/modular_zubbers/code/modules/projectiles/beams.dm deleted file mode 100644 index fed083ce038..00000000000 --- a/modular_zubbers/code/modules/projectiles/beams.dm +++ /dev/null @@ -1,2 +0,0 @@ -/obj/projectile/beam/emitter/hitscan/bluelens - integrity_heal = 0 diff --git a/tgstation.dme b/tgstation.dme index 46aa1901475..b3f02dd1da4 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -10095,7 +10095,6 @@ #include "modular_zubbers\code\modules\primitive_catgirls\code\spawner.dm" #include "modular_zubbers\code\modules\primitive_structures\code\wall_torch.dm" #include "modular_zubbers\code\modules\privacy_policy\privacy_policy.dm" -#include "modular_zubbers\code\modules\projectiles\beams.dm" #include "modular_zubbers\code\modules\projectiles\ammunition\ballistic\arrows.dm" #include "modular_zubbers\code\modules\projectiles\ammunition\ballistic\pistol.dm" #include "modular_zubbers\code\modules\projectiles\ammunition\ballistic\rifle.dm" From 6381dace445e773e83142d5eb63a3ce158a7137b Mon Sep 17 00:00:00 2001 From: Bubberbot <151680451+Bubberbot@users.noreply.github.com> Date: Fri, 3 Jul 2026 20:21:27 +0200 Subject: [PATCH 28/41] Automatic changelog for PR #5882 [ci skip] --- html/changelogs/AutoChangeLog-bubber-pr-5882.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5882.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5882.yml b/html/changelogs/AutoChangeLog-bubber-pr-5882.yml new file mode 100644 index 00000000000..c2a5b7534d5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-bubber-pr-5882.yml @@ -0,0 +1,4 @@ +author: "Odairu" +delete-after: True +changes: + - balance: "reverts bluelens to TG base" \ No newline at end of file From b8fec990e10eb339f79d77f1e6e5ca69f8c7f904 Mon Sep 17 00:00:00 2001 From: Bubberbot <151680451+Bubberbot@users.noreply.github.com> Date: Fri, 3 Jul 2026 18:30:09 +0000 Subject: [PATCH 29/41] Bubberstation automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-bubber-pr-5882.yml | 4 ---- html/changelogs/AutoChangeLog-bubber-pr-5891.yml | 4 ---- html/changelogs/bubber_archive/2026-07.yml | 4 ++++ 3 files changed, 4 insertions(+), 8 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5882.yml delete mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5891.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5882.yml b/html/changelogs/AutoChangeLog-bubber-pr-5882.yml deleted file mode 100644 index c2a5b7534d5..00000000000 --- a/html/changelogs/AutoChangeLog-bubber-pr-5882.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Odairu" -delete-after: True -changes: - - balance: "reverts bluelens to TG base" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5891.yml b/html/changelogs/AutoChangeLog-bubber-pr-5891.yml deleted file mode 100644 index b0b184eedd9..00000000000 --- a/html/changelogs/AutoChangeLog-bubber-pr-5891.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "TealSeer" -delete-after: True -changes: - - bugfix: "fixed modsuits hiding horns" \ No newline at end of file diff --git a/html/changelogs/bubber_archive/2026-07.yml b/html/changelogs/bubber_archive/2026-07.yml index d84bf089cd1..1d5d1c3712e 100644 --- a/html/changelogs/bubber_archive/2026-07.yml +++ b/html/changelogs/bubber_archive/2026-07.yml @@ -22,3 +22,7 @@ LT3: - map: Added a crate return to Void Raptor cargo - map: QoL improvements to PubbyStation cargo area + Odairu: + - balance: reverts bluelens to TG base + TealSeer: + - bugfix: fixed modsuits hiding horns From 4b5fc14909cecbb3cd9a7b0513e4f3e4852af0bd Mon Sep 17 00:00:00 2001 From: CatoChristopherMrow Date: Fri, 3 Jul 2026 15:03:00 -0400 Subject: [PATCH 30/41] Hos updates + kaza ruz prevents shove knockdown (#5719) ## About The Pull Request This PR is focused around the HoS and their gear. Most of it hasn't changed in ages, and is quite frankly, VERY underwhelming for what is widely considered the hardest job on station. What this PR does: Adds a case to the hoses locker instead of the x-01. It acts as a voucher more or less. When it's opened you can select one of the 4 available service weapons. One, is the classic x-01 One, is the compact peacekeeper shotgun Two, are new guns: The smart pistol is a prototype murphy. It does 10% less damage then normal murphys, HOWEVER, it shoots past anyone with a mindsheild implant. Great for HoSes who want to act more as supporters then direct combatents. The second, is the law. It's just a .38 revolver that does 10% more damage, with a cool new sprite by Niim The compact shotgun has been taken away from the warden, and in return: Their martial arts gloves now give the wearer the inability to be staggered or knocked down via shoving! They can still be knocked down via plenty of other means, but it's like riot armor. This is good for the warden, as they work in VERY close quarters. This makes it so their gear is more directed at that then just a good gun. The objective to steal the wardens compact has been changed to stealing said gloves. The x-01 traitor objective is of course accounted for. It now starts as an objective to steal the case itself, but when the cases gun is selected, it updates the objective to that specific gun and informs the traitor. Additionally, I resprited the compact shotgun slightly, and gave it some additional basic animation. I also added a bayonet lug to it with a custom placement/sprite for it. ## Why It's Good For The Game Hos has felt incredibly lame gear wise for quite some time. When the x-01 was initially added way back, it was cool and unique, but these days the game has changed so much that it's just...meh. Additionally, the warden having a compact shotgun felt...off. They're intended to mostly be in the brig, so a portable compact shotgun didn't entirely make sense for them. ## Proof Of Testing Videos were too big for direct upload on github, so here they are. Gun demo: https://files.catbox.moe/dzhihr.mp4
Screenshots/Videos image
## Changelog :cl: UvvU add: Added a HoS service weapon case, allowing them to select their weapon. Revolver sprite by Niim del: Removed the wardens compact shotgun from their locker balance: made the wardens martial arts gloves make them unable to be shoved down or staggered /:cl: --------- Co-authored-by: Roxy <75404941+TealSeer@users.noreply.github.com> --- .../carwo_defense_systems/guns48x.dmi | Bin 3612 -> 3924 bytes .../nanotrasen_system_inc/pistol.dmi | Bin 1349 -> 3503 bytes .../game/gamemodes/objectives/overrides.dm | 26 +++ .../game/objects/items/storage/garment.dm | 4 +- .../crates_lockers/closets/secure/security.dm | 33 +++ .../projectiles/guns/ballistic/shotgun.dm | 46 ++++ .../modules/security/sec_vouchers_vendor.dm | 205 ++++++++++++++++++ .../security/security_glock/lockers.dm | 2 + .../icons/obj/weapons/hos_revolver.dmi | Bin 0 -> 698 bytes tgstation.dme | 1 + 10 files changed, 316 insertions(+), 1 deletion(-) create mode 100644 modular_zubbers/code/game/gamemodes/objectives/overrides.dm create mode 100644 modular_zubbers/icons/obj/weapons/hos_revolver.dmi diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns48x.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns48x.dmi index b6e68e56dc79b78c30bf903f1173372a8d9012f1..8a8cc13c3822bf1d9c9655124dbc63d9acc26d92 100644 GIT binary patch literal 3924 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 BYNP-F diff --git a/modular_zubbers/code/game/gamemodes/objectives/overrides.dm b/modular_zubbers/code/game/gamemodes/objectives/overrides.dm new file mode 100644 index 00000000000..e2e3432808d --- /dev/null +++ b/modular_zubbers/code/game/gamemodes/objectives/overrides.dm @@ -0,0 +1,26 @@ +/datum/antagonist/traitor/forge_single_generic_objective() + if(prob(KILL_PROB)) + + var/datum/objective/gimmick/gimmick_objective = new() + gimmick_objective.owner = owner + return gimmick_objective + + var/datum/objective/steal/steal_objective = new() + steal_objective.owner = owner + steal_objective.find_target() + return steal_objective + +/datum/objective_item/steal/hoslaser + name = "the head of security's service weapon" + targetitem = /obj/item/gun/energy/e_gun/hos + altitems = list(/obj/item/hos_primary_case) + steal_hint = "A gun case found in the Head of Security's locker." + +/datum/objective_item/steal/compactshotty + name = "the warden's kaza ruk gloves" + targetitem = /obj/item/gun/ballistic/shotgun/automatic/combat/compact + altitems = list(/obj/item/clothing/gloves/kaza_ruk/sec/warden) + steal_hint = "A reinforced set of kaza ruk gloves found in the Warden's locker." + +/datum/objective_item/steal/compactshotty/check_special_completion(obj/item/thing) + return istype(thing, /obj/item/clothing/gloves/kaza_ruk/sec/warden) diff --git a/modular_zubbers/code/game/objects/items/storage/garment.dm b/modular_zubbers/code/game/objects/items/storage/garment.dm index 32d89fffde4..9fc1b888b4c 100644 --- a/modular_zubbers/code/game/objects/items/storage/garment.dm +++ b/modular_zubbers/code/game/objects/items/storage/garment.dm @@ -38,6 +38,9 @@ /obj/item/storage/bag/garment/warden/PopulateContents() . = ..() + for(var/obj/item/clothing/gloves/kaza_ruk/sec/original_gloves in src) + if(original_gloves.type == /obj/item/clothing/gloves/kaza_ruk/sec) + qdel(original_gloves) new /obj/item/clothing/under/rank/security/viro/warden/skirt/(src) new /obj/item/clothing/under/rank/security/viro/warden/(src) new /obj/item/clothing/under/rank/security/viro/warden/formal/(src) @@ -55,4 +58,3 @@ - diff --git a/modular_zubbers/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/modular_zubbers/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 438acde0120..e8abfcd103c 100644 --- a/modular_zubbers/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/modular_zubbers/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -1,6 +1,39 @@ +/obj/item/clothing/gloves/kaza_ruk/sec/warden + name = "warden's kaza ruk gloves" + desc = "These gloves seem to guide you through a non-lizardperson friendly variant of the Tiziran martial art, Kaza Ruk. \ + Reinforced bracing helps keep the wearer planted during close-quarters scuffles." + clothing_traits = list(TRAIT_FAST_CUFFING, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED, TRAIT_NO_STAGGER, TRAIT_NO_THROW_HITPUSH) + +/obj/item/gun/energy/laser/scatter/shotty/warden + name = "warden's disabler shotgun" + desc = "A combat shotgun gutted and refitted with an internal disabler system. The power supply unit seems to have suffered during The Great Burgerstation Riots of '69" + ammo_type = list(/obj/item/ammo_casing/energy/laser/scatter/disabler) + pin = /obj/item/firing_pin + projectile_damage_multiplier = 0.75 + +/obj/item/clothing/gloves/kaza_ruk/sec/warden/add_stealing_item_objective() + return add_item_to_steal(src, /obj/item/gun/ballistic/shotgun/automatic/combat/compact) + +/obj/structure/closet/secure_closet/hos/populate_contents_immediate() + . = ..() + var/obj/item/gun/energy/e_gun/hos/original_primary = locate(/obj/item/gun/energy/e_gun/hos) in src + if(original_primary) + qdel(original_primary) + new /obj/item/hos_primary_case(src) + /obj/structure/closet/secure_closet/warden/PopulateContents() . = ..() new /obj/item/stamp/warden(src) + if(!locate(/obj/item/clothing/gloves/kaza_ruk/sec/warden) in src) + new /obj/item/clothing/gloves/kaza_ruk/sec/warden(src) + if(!locate(/obj/item/gun/energy/laser/scatter/shotty) in src) + new /obj/item/gun/energy/laser/scatter/shotty/warden(src) + +/obj/structure/closet/secure_closet/warden/populate_contents_immediate() + . = ..() + for(var/obj/item/gun/ballistic/shotgun/automatic/combat/compact/warden_primary in src) + if(warden_primary.type == /obj/item/gun/ballistic/shotgun/automatic/combat/compact) + qdel(warden_primary) /obj/structure/closet/secure_closet/hop/populate_contents_immediate() . = ..() diff --git a/modular_zubbers/code/modules/projectiles/guns/ballistic/shotgun.dm b/modular_zubbers/code/modules/projectiles/guns/ballistic/shotgun.dm index d80116c8524..bcedd3bc882 100644 --- a/modular_zubbers/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/modular_zubbers/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -1,3 +1,49 @@ +/datum/component/bayonet_attachable/no_overlay/on_update_overlays(obj/item/source, list/overlays) + return + +/datum/component/seclite_attachable/compact_shotgun/on_update_overlays(obj/item/source, list/overlays) + if(!light_overlay || !light_overlay_icon || !light) + return + + overlays += mutable_appearance(light_overlay_icon, "[light_overlay]_[light.light_on ? "on" : "off"]") + +/obj/item/gun/ballistic/shotgun/automatic/combat/compact/add_seclight_point() + AddComponent(/datum/component/seclite_attachable/compact_shotgun, \ + light_overlay_icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns48x.dmi', \ + light_overlay = "cshotgunc_light") + +/obj/item/gun/ballistic/shotgun/automatic/combat/compact/add_bayonet_point() + AddComponent(/datum/component/bayonet_attachable/no_overlay) + +/obj/item/gun/ballistic/shotgun/automatic/combat/compact + var/compact_bolt_animating = FALSE + +/obj/item/gun/ballistic/shotgun/automatic/combat/compact/update_overlays() + . = ..() + var/datum/component/bayonet_attachable/bayonet_component = GetComponent(/datum/component/bayonet_attachable) + var/has_bayonet = bayonet_component?.bayonet ? TRUE : FALSE + if(has_bayonet) + . += "cshotgunc_bayonet" + . += has_bayonet ? "cshotgunc_laser_bayonet" : "cshotgunc_laser" + +/obj/item/gun/ballistic/shotgun/automatic/combat/compact/shoot_live_shot(mob/living/user) + . = ..() + animate_compact_bolt() + +/obj/item/gun/ballistic/shotgun/automatic/combat/compact/proc/animate_compact_bolt() + compact_bolt_animating = TRUE + update_appearance(UPDATE_OVERLAYS) + var/icon/bolt_icon = icon(src.icon, "cshotgunc_bolt_animated", SOUTH, 1) + var/atom/movable/flick_visual/bolt = flick_overlay_view(mutable_appearance(bolt_icon, "", layer + 0.1), 1) + if(bolt) + animate(bolt, icon = icon(src.icon, "cshotgunc_bolt_animated", SOUTH, 2), time = 0.2) + for(var/frame in 3 to 6) + animate(icon = icon(src.icon, "cshotgunc_bolt_animated", SOUTH, frame), time = 0.2) + addtimer(CALLBACK(src, PROC_REF(reset_compact_bolt_animation)), 1) + +/obj/item/gun/ballistic/shotgun/automatic/combat/compact/proc/reset_compact_bolt_animation() + compact_bolt_animating = FALSE + update_appearance(UPDATE_OVERLAYS) /obj/item/gun/ballistic/shotgun/bulldog/beanbag name = "\improper Beandog Shotgun" desc = "A 2-round burst fire, mag-fed shotgun for target suppression in narrow corridors, \ diff --git a/modular_zubbers/code/modules/security/sec_vouchers_vendor.dm b/modular_zubbers/code/modules/security/sec_vouchers_vendor.dm index 15d13e30b9d..297e78dce28 100644 --- a/modular_zubbers/code/modules/security/sec_vouchers_vendor.dm +++ b/modular_zubbers/code/modules/security/sec_vouchers_vendor.dm @@ -19,6 +19,211 @@ name = "security utility voucher" icon_state = "security_voucher_utility" +#define HOS_PRIMARY_MARKINGS " This one's markings indicate that it was issued to the Head of Security." + +/proc/retarget_hos_primary_objectives(obj/item/weapon_path, objective_name) + for(var/datum/objective/objective as anything in GLOB.objectives) + if(!istype(objective, /datum/objective/steal)) + continue + var/datum/objective/steal/steal_objective = objective + if(!istype(steal_objective.targetinfo, /datum/objective_item/steal/hoslaser)) + continue + + steal_objective.steal_target = weapon_path + steal_objective.explanation_text = "Steal [objective_name], the head of security's service weapon." + + for(var/datum/mind/owner as anything in steal_objective.get_owners()) + if(!owner.current) + continue + to_chat(owner.current, span_notice("Your objective has been updated: [steal_objective.explanation_text]")) + for(var/datum/antagonist/antag as anything in owner.antag_datums) + antag.update_static_data(owner.current) + +/obj/item/gun/energy/e_gun/hos/hos_primary + desc = parent_type::desc + HOS_PRIMARY_MARKINGS + +/obj/item/gun/ballistic/shotgun/automatic/combat/compact/hos_primary + desc = parent_type::desc + HOS_PRIMARY_MARKINGS + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF + +/obj/projectile/bullet/security/smart + name = "smart 9x19mm Murphy bullet" + +/obj/projectile/bullet/security/smart/prehit_pierce(atom/target) + if(isliving(target) && HAS_TRAIT(target, TRAIT_MINDSHIELD)) + return PROJECTILE_PIERCE_PHASE + return ..() + +/obj/item/ammo_casing/security/ready_proj(atom/target, mob/living/user, quiet, zone_override = "", atom/fired_from) + if(istype(fired_from, /obj/item/gun/ballistic/automatic/pistol/sec_glock/smart)) + QDEL_NULL(loaded_projectile) + loaded_projectile = new /obj/projectile/bullet/security/smart(src) + return ..() + +/obj/item/gun/ballistic/automatic/pistol/sec_glock/smart + name = "\improper Smart Pistol" + desc = parent_type::desc + " This model is a new prototype that uses a compact IFF package to guide rounds past mindshield-implanted targets." + HOS_PRIMARY_MARKINGS + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/nanotrasen_system_inc/pistol.dmi' + icon_state = "firefly" + base_icon_state = "firefly" + projectile_damage_multiplier = 0.9 + show_bolt_icon = FALSE + mag_display = FALSE + var/firefly_slide_animating = FALSE + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF + +/obj/item/gun/ballistic/automatic/pistol/sec_glock/smart/add_seclight_point() + AddComponent(/datum/component/seclite_attachable, \ + starting_light = new /obj/item/flashlight/seclite(src), \ + is_light_removable = FALSE) + +/obj/item/gun/ballistic/automatic/pistol/sec_glock/smart/update_overlays() + . = ..() + if(magazine && !internal_magazine) + . += "firefly_mag" + var/datum/component/seclite_attachable/seclite = GetComponent(/datum/component/seclite_attachable) + if(seclite?.light) + var/light_state = seclite.light.light_on ? "on" : "off" + . += "firefly-light_[light_state]" + if(!firefly_slide_animating) + . += bolt_locked ? "firefly_bolt_locked" : "firefly_bolt" + +/obj/item/gun/ballistic/automatic/pistol/sec_glock/smart/shoot_live_shot(mob/living/user, pointblank = FALSE, atom/pbtarget = null, message = TRUE) + . = ..() + recoil_firefly_slide() + +/obj/item/gun/ballistic/automatic/pistol/sec_glock/smart/proc/recoil_firefly_slide() + firefly_slide_animating = TRUE + update_appearance(UPDATE_OVERLAYS) + var/atom/movable/flick_visual/slide = flick_overlay_view(mutable_appearance(icon, "firefly_bolt", layer + 0.1), 0.75) + if(slide) + animate(slide, pixel_w = -3, time = 0.375) + animate(pixel_w = 0, time = 0.375) + addtimer(CALLBACK(src, PROC_REF(reset_firefly_slide_recoil)), 0.75) + +/obj/item/gun/ballistic/automatic/pistol/sec_glock/smart/proc/reset_firefly_slide_recoil() + firefly_slide_animating = FALSE + update_appearance(UPDATE_OVERLAYS) + +/obj/item/gun/ballistic/revolver/c38/the_law + name = "\improper The Law" + desc = "A custom modified .38 Special revolver, it seems far heavier than standard models." + HOS_PRIMARY_MARKINGS + icon = 'modular_zubbers/icons/obj/weapons/hos_revolver.dmi' + icon_state = "the_law" + base_icon_state = "the_law" + projectile_damage_multiplier = 1.1 + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF + +/obj/item/storage/belt/holster/detective/full/ert/the_law + desc = parent_type::desc + HOS_PRIMARY_MARKINGS + +/obj/item/storage/belt/holster/detective/full/ert/the_law/PopulateContents() + generate_items_inside(list( + /obj/item/ammo_box/speedloader/c38 = 3, + /obj/item/gun/ballistic/revolver/c38/the_law = 1, + ), src) + +/obj/item/hos_primary_case + name = "head of security's service weapon case" + desc = "A secure gun case containing one of the Head of Security's service weapons." + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/gunsets.dmi' + icon_state = "guncase" + worn_icon = 'modular_skyrat/modules/modular_weapons/icons/mob/worn/cases.dmi' + worn_icon_state = "darkcase" + material_flags = NONE + w_class = WEIGHT_CLASS_NORMAL + /// Prevents double redemption if two interactions race each other. + var/redeemed = FALSE + +/obj/item/hos_primary_case/click_alt(mob/user) + try_redeem(user) + return CLICK_ACTION_SUCCESS + +/obj/item/hos_primary_case/attack_self(mob/user) + try_redeem(user) + +/obj/item/hos_primary_case/add_stealing_item_objective() + return add_item_to_steal(src, /obj/item/gun/energy/e_gun/hos) + +/obj/item/hos_primary_case/proc/try_redeem(mob/user) + if(redeemed || QDELETED(src)) + return + if(!isliving(user)) + return + var/mob/living/redeemer = user + if(redeemer.incapacitated) + return + + var/static/list/primary_options + if(!primary_options) + var/datum/radial_menu_choice/x01_option = new + x01_option.image = image(icon = 'icons/obj/weapons/guns/energy.dmi', icon_state = "hoslaser") + x01_option.info = span_boldnotice("The Head of Security's unique three-mode energy gun.") + + var/datum/radial_menu_choice/shotgun_option = new + shotgun_option.image = image(icon = 'icons/obj/weapons/guns/ballistic.dmi', icon_state = "cshotgunc") + shotgun_option.info = span_boldnotice("A miniaturized combat shotgun.") + + var/datum/radial_menu_choice/smart_pistol_option = new + smart_pistol_option.image = image(icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/nanotrasen_system_inc/pistol.dmi', icon_state = "firefly") + smart_pistol_option.info = span_boldnotice("A Murphy-pattern pistol that fires past mindshield-implanted targets.") + + var/datum/radial_menu_choice/the_law_option = new + the_law_option.image = image(icon = 'modular_zubbers/icons/obj/weapons/hos_revolver.dmi', icon_state = "the_law") + the_law_option.info = span_boldnotice("The Law, an modified Detective Special that hits harder than standard models.") + + primary_options = list( + "X-01 MultiPhase Energy Gun" = x01_option, + "Compact Shotgun" = shotgun_option, + "Smart Pistol" = smart_pistol_option, + "The Law" = the_law_option, + ) + + var/selection = show_radial_menu(redeemer, src, primary_options, custom_check = CALLBACK(src, PROC_REF(check_redeem_menu), redeemer), radius = 38, require_near = TRUE, tooltips = TRUE) + if(!selection || redeemed || QDELETED(src)) + return + + var/spawn_path + var/objective_path + var/objective_name + switch(selection) + if("X-01 MultiPhase Energy Gun") + spawn_path = /obj/item/gun/energy/e_gun/hos/hos_primary + objective_name = "the X-01 MultiPhase Energy Gun" + if("Compact Shotgun") + spawn_path = /obj/item/gun/ballistic/shotgun/automatic/combat/compact/hos_primary + objective_name = "the compact shotgun" + if("Smart Pistol") + spawn_path = /obj/item/gun/ballistic/automatic/pistol/sec_glock/smart + objective_name = "the Smart Pistol" + if("The Law") + spawn_path = /obj/item/storage/belt/holster/detective/full/ert/the_law + objective_path = /obj/item/gun/ballistic/revolver/c38/the_law + objective_name = "\"The Law\"" + else + return + + objective_path ||= spawn_path + redeemed = TRUE + var/obj/item/chosen_item = new spawn_path(drop_location()) + redeemer.put_in_hands(chosen_item) + retarget_hos_primary_objectives(objective_path, objective_name) + balloon_alert(redeemer, "selected [LOWER_TEXT(selection)]") + qdel(src) + +/obj/item/hos_primary_case/proc/check_redeem_menu(mob/living/redeemer) + if(!istype(redeemer)) + return FALSE + if(redeemer.incapacitated) + return FALSE + if(QDELETED(src) || redeemed) + return FALSE + if(!redeemer.Adjacent(src)) + return FALSE + return TRUE + +#undef HOS_PRIMARY_MARKINGS + /obj/machinery/vending/security/Initialize(mapload) . = ..() AddElement(/datum/element/voucher_redeemer, /obj/item/security_voucher/primary, /datum/voucher_set/security/primary) diff --git a/modular_zubbers/code/modules/security/security_glock/lockers.dm b/modular_zubbers/code/modules/security/security_glock/lockers.dm index 531d184e40b..c37fcdc5f7d 100644 --- a/modular_zubbers/code/modules/security/security_glock/lockers.dm +++ b/modular_zubbers/code/modules/security/security_glock/lockers.dm @@ -4,4 +4,6 @@ /obj/structure/closet/secure_closet/warden/PopulateContents() . = ..() + if(!locate(/obj/item/clothing/gloves/kaza_ruk/sec/warden) in src) + new /obj/item/clothing/gloves/kaza_ruk/sec/warden(src) new /obj/item/storage/toolbox/guncase/skyrat/pistol/hos_glock(src) diff --git a/modular_zubbers/icons/obj/weapons/hos_revolver.dmi b/modular_zubbers/icons/obj/weapons/hos_revolver.dmi new file mode 100644 index 0000000000000000000000000000000000000000..90b69d9119135bb6d37b66e4b9c1c2a3bdbc29b8 GIT binary patch literal 698 zcmV;r0!96aP)V=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex6#a*U0*I5Sc+ z(=$pSoZ^zil2jm5sU#ycJ}0qUiHkEOv#1y-V#vjrR+N~V3SlcNxca$(3PH z6e2(X00Ih0L_t(|+U=FiZrV@~g+G(X1c3=j3?WoD>Y^wpDMDgfRcaSVMd}MQFT%U^ z1?Ub`q_&GzU?&C_i+|eUjk}=S1V{p<$)b{vbR~~Gch1~1=i1=IhYuhB3yN>vdfBs_ zx9$GyS3q4+i&w7+N0o&&8ICZGCYqk6=Q#8n2Tf0l*mb9zo}d3Y^)>D8I&w`<DiP7IXg4VYWWU|kBnTgV_zZbKf3`fXvP^{!hg2SVIA#vNbq_%BI2dauJ2SqH) z!4;0RCd_GjUOt<_xEjzM+7Nqo-C(OlI1-t8V>~7lQWj1>CtOyfZClbtBgkoc9zaS{ zFs=pwyt}xdTrNuhaaHwVu^82ARf?;s_v6`6jp_IM z0CXHj+UENpt&={bDOl#rT*lRa-p(PGWzPH%iHQ5WEu_21OT~g9o|88w(mxX}7_8A3gwn1IBaOg1%u{6aWAK07*qoM6N<$f~HA9B>(^b literal 0 HcmV?d00001 diff --git a/tgstation.dme b/tgstation.dme index b3f02dd1da4..24105fbacda 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -9281,6 +9281,7 @@ #include "modular_zubbers\code\game\gamemodes\fleshmind\tyrant\tyrant.dm" #include "modular_zubbers\code\game\gamemodes\fleshmind\tyrant\tyrant_ai.dm" #include "modular_zubbers\code\game\gamemodes\objectives\gimmick.dm" +#include "modular_zubbers\code\game\gamemodes\objectives\overrides.dm" #include "modular_zubbers\code\game\Items\big_bertha_shield.dm" #include "modular_zubbers\code\game\Items\coins.dm" #include "modular_zubbers\code\game\Items\lipstick.dm" From 5292f8b495c2dd8180cb66629e9355b76c1211d9 Mon Sep 17 00:00:00 2001 From: Bubberbot <151680451+Bubberbot@users.noreply.github.com> Date: Fri, 3 Jul 2026 21:03:26 +0200 Subject: [PATCH 31/41] Automatic changelog for PR #5719 [ci skip] --- html/changelogs/AutoChangeLog-bubber-pr-5719.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5719.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5719.yml b/html/changelogs/AutoChangeLog-bubber-pr-5719.yml new file mode 100644 index 00000000000..613352920c5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-bubber-pr-5719.yml @@ -0,0 +1,6 @@ +author: "UvvU" +delete-after: True +changes: + - rscadd: "Added a HoS service weapon case, allowing them to select their weapon. Revolver sprite by Niim" + - rscdel: "Removed the wardens compact shotgun from their locker" + - balance: "made the wardens martial arts gloves make them unable to be shoved down or staggered" \ No newline at end of file From e9061e8b19b36c0fc0b9ffbf5eb7d5402e35e7be Mon Sep 17 00:00:00 2001 From: ArrisFairburne Date: Fri, 3 Jul 2026 15:05:07 -0400 Subject: [PATCH 32/41] Blacksmith Revamp (#5360) ## About The Pull Request Makes a number of changes to blacksmithing to make the role more appealing, convenient, and special:
New Additions - [ ] Added a new blacksmith recipe that requires legendary skill and the skillchip: parts for a classical single-action revolver. High damage, but finnicky to use; no safety mechanism, can't accept speed loaders, and the hammer has to be cocked before each shot. Cocking the hammer is faster if both hands are free, allowing for fanning the hammer. - [ ] Smiths can now make new storage options: a cowboy holster that stores a handgun and multiple ammo boxes, a charging belt that recharges one energy gun, a botany bag with expanded storage, and multiple types of scabbards. - [ ] Added a new skillchip specific to blacksmithing; without the skillchip, your options on what you can produce via smithing are reduced. This is to make it so that the smithing job role (or at least, whoever has been given the skillchip from the QM's locker) is more special. Currently smithing is just sort of something anyone can do, the only things unique about spawning in as the blacksmith is that you have cargo access and smithing-specific bounties. - [ ] Replaced the water barrel with a new structure: the reagent quenching trough. This spawns in filled with a new reagent, quenching oil. Quenching a smithing item in the trough with any reagent will imbue it for zero reagent use, and heat the trough's reagent.
General direction changes - [ ] Perfect hits are no longer probability-dependant; they're based on the player's timing. Except if the player is max level at blacksmithing, in which case all hits are perfects. - [ ] Right-clicking with a hammer on the anvil will allow the player to automatically forge the item they're working on, with a slower pace compared to manual forging. This is mostly meant to allow talking to someone while working on forges. - [ ] Removed multi-anvil smithing; blacksmithing lacks a dedicated space on most maps and so must occupy a hallway or something else instead. "Playing optimally" with multi-anvil smithing means taking up significantly more space, in addition to looking extremely silly and bypassing part of the loop with blacksmithing (levelling up the smithing skills to produce equipment faster); the smithing chip will reduce the swings needed to finish a job to compensate. - [ ] Reworked reagent imbued equipment; removed the bonus from leaving a weapon unimbued. This bonus can now be regained specifically by imbuing smithing oil (smithing oil is special; imbuing it doesn't inflict it as a reagent for effects, but makes the armor/weapon/etc. better by numbers). Also, reagent imbued equipment no longer has a big damage multiplier but will merely stop applying reagents after a certain integrity threshold is passed. - [ ] Significantly reduced the income from smithing cargo bounties. It honestly kind of sucks that blacksmiths' value to the station is that they print money and not for the actual quality of their items. - [ ] Blacksmiths now have weapon access by default. It's honestly kind of weird that the guy whose whole schtick is making weapons, didn't have weapon access to start. - [ ] Moved the crusader belt from the general crafting menu to the smithing crafting menu; it now requires lv7 smithing and the smithing chip. This change is because it's highly contingent on blacksmithing equipment for its main storage so it seems most sensible for a smith to work it. - [ ] The leather apron that blacksmiths roundstart with now has dedicated storage for various smithing and glassblowing tools.
Interactivity changes - [ ] Trying to pick up a heated blacksmith item will now burn your hand. - [ ] Various quenched smithing items now have associated force values for dealing damage, but will also (usually) cut the user's hand for doing so. - [ ] You can now use water tiles or certain reagent containers (needs at least 300 units) to quench smithing equipment. - [ ] The forge now heats up it's surroundings and burns carbon dioxide while doing so. The wall-mounted heater now auto charges it's cell to compensate for this. - [ ] You can now weapon-bash your blacksmithing shields, similar to how you can slap your baton against your riot shields to intimidate.
Convenience and misc. - [ ] Changed the Rapier sprites to match the other smithing weapon sprites. - [ ] Added more tutorial tooltips when inspecting blacksmith equipment. - [ ] The blacksmithing noises are quieter, thank god. - [ ] Using tongs on a stack now pulls only one item from the stack, instead of pulling all items in the stack. You never actually want to have more than one sheet in the tongs so there's no reason to include it really. - [ ] Completed blacksmith items can now be picked up with tongs and placed into the crafting bench with them. This is meant to reduce the tool-juggling for moving the item from the anvil to the basin, then moving the item from the basin to the bench. - [ ] The blacksmith ID trim now has an actual icon - [ ] Commented out the cortical borer cage recipe. We don't really need this since we don't run cortical borers. - [ ] Halved the number of necessary chains and plates for all recipes, but doubled the time needed to hammer them; this is to reduce how much item juggling is needed. - [ ] Cargo guards and cargo secoffs now have blacksmithing access. - [ ] Ensure that Ashwalkers, Primal Podpeople, and feral nekos have all the same mechanics as a skillchipped crewie, except cannot make the revolver
Code refactoring - [ ] The reagent clothing and reagent weapon components now come from a general reagent imbued parent component. - [ ] Refactored how anvil smithing works; it now relies on an item component that handles item heat, hammer strikes, and quenching, instead of all the code being handled within the anvil itself. - [ ] Removed the skyrat_obj_flags variable that only functioned for the anvil_repair flag and nothing else. We have different ways to check for the stuff it relied on so it's not really needed. - [ ] Removed the in_use code from various forging objects. It's a really cumbersome system and annoying to manage all the time. Doafters with interaction_key stand as a replacement.
Overall, in the hands of blacksmiths, smithing-chipped characters, and the tribal factions, this should feel like a general buff. For everyone else, this should feel like a nerf, and they should go to the blacksmith or get skillchipped so they can make smithing stuff. It should also feel less 'shallow' and a bit more interactive with the rest of the game. ## Proof Of Testing
Screenshots/Videos image image https://youtu.be/hcPZXzCOSIU https://youtu.be/V7GeLetcRtk https://youtu.be/YEyW9pKidTU
## Changelog :cl: add: Way, way too many blacksmith job features & smithing system changes to list. But here's the highlights: balance: Forged blacksmith weapons can now be used nonlethally via striking with pommels, spear shafts, etc. which knocks down victims and stamina damages them like a weaker baton. qol: Blacksmith tongs now only pull one item at a time, if used on a stackable item. qol: Blacksmiths can now auto-smith at an anvil by right clicking with a hammer. qol: Blacksmithing tools now have more tooltips to tutorialize their usage. qol: Blacksmithing crafting bench can now store item stacks, forging plates, and forging chains. Right-click to view what's in it. balance: Removed multi-anvil smithing. Individual smithing pieces can now be made faster with the smithing chip and other means to compensate. add: Blacksmiths can now build a single action revolver if they are fully levelled. add: Blacksmiths can build a variety of new equipment at the crafting bench -- gun-charging holsters, knife belts, multiple types of scabbards, and even a new expanded-storage botany bag. add: Replaced the water barrel for smithing with a barrel of smithing oil; smithing oil is now used to grant the bonuses that was previously given by leaving the item unimbued. The new barrel can have its contents changed for reagent imbuing. add: A new reagent "smithing oil" which gives innate bonuses to any blacksmith equipment imbued using it. balance: Material types now affect the quality of resulting items and how quickly they can be forged. balance: The reagent smithing hammer now has increased toolspeed if forged well. balance: Reagent imbuing's durability penalty has been altered; it reduces durability for each time an imbue effect procs, and then stops functioning for such when below a certain durability percentage. /:cl: --------- Co-authored-by: Mathilde <146444134+ibexgoetia@users.noreply.github.com> Co-authored-by: The Sharkening <95130227+StrangeWeirdKitten@users.noreply.github.com> Co-authored-by: LT3 <83487515+lessthnthree@users.noreply.github.com> Co-authored-by: Roxy <75404941+TealSeer@users.noreply.github.com> --- .../lavaland_surface_seed_vault_bubber.dmm | 2 +- .../lavaland_surface_ash_walker1_skyrat.dmm | 2 +- _maps/RandomZLevels/maintsroom.dmm | 54 +- .../iceboxstation_icecats_lower.dmm | 232 ++--- .../lavaland/lavaland_ashwalker_fortress.dmm | 9 +- .../lavaland/lavaland_ashwalker_nest.dmm | 2 +- .../templates/lavaland/lavaland_smithy.dmm | 2 +- _maps/map_files/biodome/biodome.dmm | 132 +-- _maps/map_files/generic/CentCom_skyrat_z2.dmm | 194 ++-- _maps/map_files/moonstation/moonstation.dmm | 974 +++++++++--------- .../~skyrat_defines/_globalvars/bitfields.dm | 4 - code/__DEFINES/~skyrat_defines/atom_hud.dm | 2 + code/__DEFINES/~skyrat_defines/obj_flags.dm | 3 - .../~~bubber_defines/traits/declarations.dm | 5 + code/_globalvars/traits/_traits.dm | 3 + code/datums/id_trim/jobs.dm | 1 + .../carbon/human/species_types/felinid.dm | 1 + .../human/species_types/lizardpeople.dm | 1 + .../carbon/human/species_types/podpeople.dm | 1 + .../items/stacks/sheets/sheet_types.dm | 13 +- .../master_files/code/game/objects/objs.dm | 3 - .../master_files/icons/mob/huds/hud.dmi | Bin 14474 -> 13584 bytes .../master_files/icons/obj/card.dmi | Bin 6094 -> 6731 bytes .../master_files/icons/obj/clothing/belts.dmi | Bin 9888 -> 8694 bytes .../ashwalkers/code/effects/ash_rituals.dm | 4 +- .../modules/borgs/code/robot_items.dm | 2 +- .../code/appliances/space_heater.dm | 27 +- .../modules/clothing/storage/belts.dm | 136 --- .../modules/goofsec/code/department_guards.dm | 1 + .../modules/modular_items/code/tailoring.dm | 9 - .../primitive_catgirls/code/clothing.dm | 4 +- .../modules/reagent_forging/code/_DEFINES.dm | 210 ++++ .../modules/reagent_forging/code/anvil.dm | 200 ++-- .../reagent_forging/code/cargo_orders.dm | 28 + .../reagent_forging/code/container_boxes.dm | 35 + .../reagent_forging/code/crafting_bench.dm | 475 ++++++--- .../code/crafting_bench_recipes.dm | 545 ++++++++-- .../modules/reagent_forging/code/forge.dm | 526 +++++----- .../reagent_forging/code/forge_belts.dm | 542 ++++++++++ .../reagent_forging/code/forge_clothing.dm | 193 ++-- .../reagent_forging/code/forge_equipment.dm | 60 ++ .../reagent_forging/code/forge_items.dm | 299 ++++-- .../reagent_forging/code/forge_revolver.dm | 225 ++++ .../code/forge_smithable_component.dm | 376 +++++++ .../reagent_forging/code/forge_weapons.dm | 391 +++++-- .../modules/reagent_forging/code/memories.dm | 125 +++ .../reagent_forging/code/mindless_killer.dm | 2 + .../reagent_forging/code/reagent_component.dm | 241 +++-- .../code/reagent_smithing_oil.dm | 16 + .../reagent_forging/code/smith_skill.dm | 2 +- .../code/smithing_trait_and_chip.dm | 21 + .../reagent_forging/code/water_basin.dm | 159 +-- .../icons/obj/forge_clothing.dmi | Bin 1863 -> 10407 bytes .../reagent_forging/icons/obj/forge_items.dmi | Bin 7282 -> 8770 bytes .../icons/obj/forge_structures.dmi | Bin 3464 -> 4395 bytes .../modules/reagent_forging/readme.md | 6 + .../lists/maintenance_loot_common.dm | 2 +- .../code/modules/cargo/bounties/blacksmith.dm | 37 +- .../goodies/company_imports/blacksteel.dm | 2 +- .../code/modules/clothing/outfits/outlast.dm | 4 +- .../code/modules/jobs/job_types/blacksmith.dm | 72 ++ .../code/modules/jobs/trims/jobs.dm | 9 +- modular_zubbers/icons/mob/huds/hud.dmi | Bin 15116 -> 14358 bytes tgstation.dme | 11 +- .../tgui/interfaces/Orbit/JobIcon.tsx | 1 + .../Scripts_Bubber/5360_smithing_repath.txt | 2 + 66 files changed, 4691 insertions(+), 1949 deletions(-) delete mode 100644 modular_skyrat/master_files/code/game/objects/objs.dm create mode 100644 modular_skyrat/modules/reagent_forging/code/_DEFINES.dm create mode 100644 modular_skyrat/modules/reagent_forging/code/cargo_orders.dm create mode 100644 modular_skyrat/modules/reagent_forging/code/container_boxes.dm create mode 100644 modular_skyrat/modules/reagent_forging/code/forge_belts.dm create mode 100644 modular_skyrat/modules/reagent_forging/code/forge_equipment.dm create mode 100644 modular_skyrat/modules/reagent_forging/code/forge_revolver.dm create mode 100644 modular_skyrat/modules/reagent_forging/code/forge_smithable_component.dm create mode 100644 modular_skyrat/modules/reagent_forging/code/memories.dm create mode 100644 modular_skyrat/modules/reagent_forging/code/reagent_smithing_oil.dm create mode 100644 modular_skyrat/modules/reagent_forging/code/smithing_trait_and_chip.dm create mode 100644 tools/UpdatePaths/Scripts_Bubber/5360_smithing_repath.txt diff --git a/_maps/RandomRuins/LavaRuins/bubberstation/lavaland_surface_seed_vault_bubber.dmm b/_maps/RandomRuins/LavaRuins/bubberstation/lavaland_surface_seed_vault_bubber.dmm index 1f0ba31e595..1495c9a30dd 100644 --- a/_maps/RandomRuins/LavaRuins/bubberstation/lavaland_surface_seed_vault_bubber.dmm +++ b/_maps/RandomRuins/LavaRuins/bubberstation/lavaland_surface_seed_vault_bubber.dmm @@ -2068,7 +2068,7 @@ name = "Server Vent" }, /obj/effect/decal/cleanable/dirt, -/obj/structure/reagent_water_basin, +/obj/structure/reagent_dispensers/reagent_smithing_basin, /obj/effect/turf_decal/siding/wideplating_new/dark{ dir = 8 }, diff --git a/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_ash_walker1_skyrat.dmm b/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_ash_walker1_skyrat.dmm index 6d8c3d0ed0a..c538c60fba2 100644 --- a/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_ash_walker1_skyrat.dmm +++ b/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_ash_walker1_skyrat.dmm @@ -372,7 +372,7 @@ /turf/open/lava/smooth/lava_land_surface, /area/ruin/unpowered/ash_walkers) "nY" = ( -/obj/structure/reagent_water_basin, +/obj/structure/reagent_dispensers/reagent_smithing_basin, /obj/structure/stone_tile/slab, /turf/open/misc/asteroid/basalt/lava_land_surface, /area/ruin/unpowered/ash_walkers) diff --git a/_maps/RandomZLevels/maintsroom.dmm b/_maps/RandomZLevels/maintsroom.dmm index 832600635d8..c1a3339127d 100644 --- a/_maps/RandomZLevels/maintsroom.dmm +++ b/_maps/RandomZLevels/maintsroom.dmm @@ -6234,22 +6234,6 @@ }, /turf/open/floor/plating/rust, /area/awaymission/caves/maintsroom) -"tX" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/structure/safe/floor, -/obj/item/forging/reagent_weapon/axe/fake_copper{ - desc = "Ea-nasir's own copper axe" - }, -/obj/item/claymore/weak/weaker, -/turf/open/floor/engine{ - slowdown = 2 - }, -/area/awaymission/caves/maintsroom) "tY" = ( /obj/effect/light_emitter/fake_outdoors, /obj/structure/spacevine, @@ -9845,6 +9829,22 @@ /obj/effect/spawner/random/structure/chair_flipped, /turf/open/floor/circuit/red/anim, /area/awaymission/caves/maintsroom) +"Gb" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/safe/floor, +/obj/item/melee/forged_reagent_weapon/axe/fake_copper{ + desc = "Ea-nasir's own copper axe" + }, +/obj/item/claymore/weak/weaker, +/turf/open/floor/engine{ + slowdown = 2 + }, +/area/awaymission/caves/maintsroom) "Gc" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -12447,6 +12447,15 @@ /obj/structure/mecha_wreckage/odysseus, /turf/open/floor/circuit/green, /area/awaymission/caves/maintsroom) +"OB" = ( +/obj/structure/lattice/catwalk/mining, +/obj/item/melee/forged_reagent_weapon/sword, +/obj/structure/closet/crate/goldcrate{ + name = "Bait" + }, +/obj/item/disk/design_disk/cleric_mace, +/turf/open/floor/plating, +/area/awaymission/caves/maintsroom) "OC" = ( /obj/structure/disposalpipe/segment{ dir = 8 @@ -12907,15 +12916,6 @@ /obj/structure/grille/broken, /turf/open/floor/iron/smooth, /area/awaymission/caves/maintsroom) -"Qi" = ( -/obj/structure/lattice/catwalk/mining, -/obj/item/forging/reagent_weapon/sword, -/obj/structure/closet/crate/goldcrate{ - name = "Bait" - }, -/obj/item/disk/design_disk/cleric_mace, -/turf/open/floor/plating, -/area/awaymission/caves/maintsroom) "Qj" = ( /obj/structure/table/optable/abductor, /turf/open/floor/plating/abductor, @@ -17188,7 +17188,7 @@ ov ov ov TM -Qi +OB TA ov ov @@ -40731,7 +40731,7 @@ PR PR PR PR -tX +Gb MD rW gW diff --git a/_maps/bubber/automapper/templates/IceBoxStation/iceboxstation_icecats_lower.dmm b/_maps/bubber/automapper/templates/IceBoxStation/iceboxstation_icecats_lower.dmm index 786351ecbe0..4d41238ce0b 100644 --- a/_maps/bubber/automapper/templates/IceBoxStation/iceboxstation_icecats_lower.dmm +++ b/_maps/bubber/automapper/templates/IceBoxStation/iceboxstation_icecats_lower.dmm @@ -211,14 +211,6 @@ }, /turf/open/misc/dirt/icemoon, /area/ruin/unpowered/primitive_catgirl_den) -"eY" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 1 - }, -/obj/structure/water_source/puddle, -/obj/effect/turf_decal/weather/snow/corner, -/turf/open/misc/dirt/icemoon, -/area/ruin/unpowered/primitive_catgirl_den) "fd" = ( /obj/structure/wall_torch/spawns_lit/directional/south, /obj/effect/turf_decal/weather/snow/corner{ @@ -400,6 +392,23 @@ /obj/structure/fluff/minepost, /turf/open/misc/dirt/icemoon, /area/ruin/unpowered/primitive_catgirl_den) +"jY" = ( +/obj/structure/closet/crate/wooden/storage_barrel, +/obj/structure/wall_torch/spawns_lit/directional/south, +/obj/item/seeds/cotton, +/obj/item/seeds/cotton, +/obj/item/seeds/tea{ + pixel_y = 1 + }, +/obj/item/seeds/tea{ + pixel_y = 1 + }, +/obj/item/seeds/tea/catnip, +/obj/item/seeds/bamboo, +/obj/item/seeds/ambrosia, +/obj/item/seeds/eggplant, +/turf/open/misc/dirt/icemoon, +/area/ruin/unpowered/primitive_catgirl_den) "ka" = ( /obj/effect/turf_decal/siding/wood/corner{ dir = 8 @@ -598,12 +607,13 @@ }, /turf/open/misc/dirt/icemoon, /area/ruin/unpowered/primitive_catgirl_den) -"nq" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 6 +"nx" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 5 + }, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 8 }, -/obj/structure/reagent_water_basin, -/obj/structure/wall_torch/spawns_lit/directional/north, /turf/open/misc/dirt/icemoon, /area/ruin/unpowered/primitive_catgirl_den) "op" = ( @@ -660,6 +670,14 @@ }, /turf/open/misc/dirt/icemoon, /area/ruin/unpowered/primitive_catgirl_den) +"oN" = ( +/obj/structure/table/wood, +/obj/structure/throwing_wheel{ + pixel_y = 10 + }, +/obj/structure/wall_torch/spawns_lit/directional/west, +/turf/open/floor/wood/icemoon, +/area/ruin/unpowered/primitive_catgirl_den) "oW" = ( /obj/effect/turf_decal/siding/wood, /obj/structure/wall_torch/spawns_lit/directional/north, @@ -774,6 +792,15 @@ }, /turf/open/misc/dirt/icemoon, /area/ruin/unpowered/primitive_catgirl_den) +"qB" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/turf/open/misc/dirt/icemoon, +/area/ruin/unpowered/primitive_catgirl_den) "qM" = ( /obj/effect/turf_decal/siding/wood{ dir = 8 @@ -923,6 +950,14 @@ /obj/item/food/raw_headcheese, /turf/open/floor/stone/icemoon, /area/ruin/unpowered/primitive_catgirl_den) +"uu" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/obj/structure/wall_torch/spawns_lit/directional/north, +/obj/structure/reagent_dispensers/reagent_smithing_basin/prefilled, +/turf/open/misc/dirt/icemoon, +/area/ruin/unpowered/primitive_catgirl_den) "uH" = ( /obj/structure/stairs/wood{ dir = 4 @@ -951,14 +986,6 @@ /obj/item/seeds/peas, /turf/open/misc/dirt/icemoon, /area/ruin/unpowered/primitive_catgirl_den) -"vr" = ( -/obj/structure/table/wood, -/obj/structure/throwing_wheel{ - pixel_y = 10 - }, -/obj/structure/wall_torch/spawns_lit/directional/west, -/turf/open/floor/wood/icemoon, -/area/ruin/unpowered/primitive_catgirl_den) "vx" = ( /obj/effect/turf_decal/weather/dirt{ dir = 1 @@ -990,23 +1017,6 @@ }, /turf/open/misc/asteroid/snow/icemoon, /area/ruin/unpowered/primitive_catgirl_den) -"wt" = ( -/obj/structure/closet/crate/wooden/storage_barrel, -/obj/structure/wall_torch/spawns_lit/directional/south, -/obj/item/seeds/cotton, -/obj/item/seeds/cotton, -/obj/item/seeds/tea{ - pixel_y = 1 - }, -/obj/item/seeds/tea{ - pixel_y = 1 - }, -/obj/item/seeds/tea/catnip, -/obj/item/seeds/bamboo, -/obj/item/seeds/ambrosia, -/obj/item/seeds/eggplant, -/turf/open/misc/dirt/icemoon, -/area/ruin/unpowered/primitive_catgirl_den) "wF" = ( /obj/effect/turf_decal/weather/dirt{ dir = 8 @@ -1069,13 +1079,6 @@ /obj/structure/stairs/wood, /turf/open/floor/stone/icemoon, /area/ruin/unpowered/primitive_catgirl_den) -"yp" = ( -/obj/machinery/primitive_stove, -/obj/item/storage/bag/tray{ - pixel_y = 4 - }, -/turf/open/floor/stone/icemoon, -/area/ruin/unpowered/primitive_catgirl_den) "yD" = ( /obj/structure/flora/ash/chilly, /turf/open/misc/asteroid/snow/icemoon, @@ -1164,28 +1167,17 @@ /obj/structure/bonfire/grill_pre_attached, /turf/open/floor/stone/icemoon, /area/ruin/unpowered/primitive_catgirl_den) -"AV" = ( -/obj/structure/closet/crate/wooden/storage_barrel, -/obj/item/stack/ore/glass/thirty{ - pixel_y = 5; - amount = 50 - }, -/obj/effect/turf_decal/weather/snow/corner{ - dir = 10 - }, -/turf/open/misc/dirt/icemoon, -/area/ruin/unpowered/primitive_catgirl_den) "Bc" = ( /obj/structure/rack/wooden, -/obj/item/forging/reagent_weapon/axe/fake_copper{ +/obj/item/melee/forged_reagent_weapon/axe/fake_copper{ pixel_x = -8; pixel_y = -4 }, -/obj/item/forging/reagent_weapon/axe/fake_copper{ +/obj/item/melee/forged_reagent_weapon/axe/fake_copper{ pixel_x = -2; pixel_y = -4 }, -/obj/item/forging/reagent_weapon/axe/fake_copper{ +/obj/item/melee/forged_reagent_weapon/axe/fake_copper{ pixel_x = 4; pixel_y = -4 }, @@ -1239,7 +1231,7 @@ /obj/item/shield/goliath{ pixel_x = -6 }, -/obj/item/forging/reagent_weapon/axe/fake_copper{ +/obj/item/melee/forged_reagent_weapon/axe/fake_copper{ pixel_x = 4; pixel_y = -4 }, @@ -1277,35 +1269,22 @@ }, /turf/open/misc/dirt/icemoon, /area/ruin/unpowered/primitive_catgirl_den) -"Eu" = ( -/obj/effect/turf_decal/weather/snow/corner{ - dir = 4 - }, -/obj/effect/turf_decal/siding/wood{ - dir = 8 - }, -/turf/open/misc/dirt/icemoon, -/area/ruin/unpowered/primitive_catgirl_den) "EA" = ( /obj/structure/rack/wooden, /obj/item/gun/ballistic/bow/longbow, /obj/item/storage/bag/quiver, /turf/open/misc/dirt/icemoon, /area/ruin/unpowered/primitive_catgirl_den) -"EU" = ( -/obj/structure/closet/crate/wooden{ - name = "glassblowing crate" +"Fn" = ( +/obj/structure/closet/crate/wooden/storage_barrel, +/obj/item/stack/ore/glass/thirty{ + pixel_y = 5; + amount = 50 }, -/obj/item/glassblowing/blowing_rod, -/obj/item/glassblowing/jacks{ - pixel_x = 6 +/obj/effect/turf_decal/weather/snow/corner{ + dir = 10 }, -/obj/item/glassblowing/paddle{ - pixel_y = 6 - }, -/obj/item/glassblowing/shears, -/obj/item/glassblowing/metal_cup, -/turf/open/misc/asteroid/snow/icemoon, +/turf/open/misc/dirt/icemoon, /area/ruin/unpowered/primitive_catgirl_den) "FB" = ( /obj/structure/mannequin/wood, @@ -1446,6 +1425,14 @@ }, /turf/open/misc/dirt/icemoon, /area/ruin/unpowered/primitive_catgirl_den) +"Jb" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/structure/water_source/puddle, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/misc/dirt/icemoon, +/area/ruin/unpowered/primitive_catgirl_den) "Jl" = ( /obj/effect/turf_decal/weather/dirt{ dir = 8 @@ -1666,22 +1653,6 @@ }, /turf/open/misc/dirt/icemoon, /area/ruin/unpowered/primitive_catgirl_den) -"Pq" = ( -/obj/effect/turf_decal/siding/wood, -/obj/structure/rack/wooden, -/obj/item/stack/sheet/mineral/stone/five{ - pixel_y = -5; - pixel_x = -4 - }, -/obj/item/stack/sheet/mineral/stone/five{ - pixel_y = -5; - pixel_x = 7 - }, -/obj/effect/turf_decal/weather/snow/corner{ - dir = 1 - }, -/turf/open/misc/dirt/icemoon, -/area/ruin/unpowered/primitive_catgirl_den) "PB" = ( /obj/effect/turf_decal/weather/snow/corner{ dir = 6 @@ -1886,6 +1857,13 @@ }, /turf/open/floor/stone/icemoon, /area/ruin/unpowered/primitive_catgirl_den) +"TH" = ( +/obj/machinery/primitive_stove, +/obj/item/storage/bag/tray{ + pixel_y = 4 + }, +/turf/open/floor/stone/icemoon, +/area/ruin/unpowered/primitive_catgirl_den) "Ug" = ( /obj/effect/turf_decal/weather/snow/corner, /turf/open/misc/dirt/icemoon, @@ -1973,6 +1951,21 @@ /obj/structure/chair/wood, /turf/open/misc/dirt/icemoon, /area/ruin/unpowered/primitive_catgirl_den) +"VS" = ( +/obj/structure/closet/crate/wooden{ + name = "glassblowing crate" + }, +/obj/item/glassblowing/blowing_rod, +/obj/item/glassblowing/jacks{ + pixel_x = 6 + }, +/obj/item/glassblowing/paddle{ + pixel_y = 6 + }, +/obj/item/glassblowing/shears, +/obj/item/glassblowing/metal_cup, +/turf/open/misc/asteroid/snow/icemoon, +/area/ruin/unpowered/primitive_catgirl_den) "VT" = ( /obj/structure/closet/crate/wooden/storage_barrel, /obj/item/ammo_casing/arrow/bone, @@ -1992,6 +1985,22 @@ /obj/machinery/smartfridge/drying/rack, /turf/open/misc/dirt/icemoon, /area/ruin/unpowered/primitive_catgirl_den) +"Wv" = ( +/obj/effect/turf_decal/siding/wood, +/obj/structure/rack/wooden, +/obj/item/stack/sheet/mineral/stone/five{ + pixel_y = -5; + pixel_x = -4 + }, +/obj/item/stack/sheet/mineral/stone/five{ + pixel_y = -5; + pixel_x = 7 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/misc/dirt/icemoon, +/area/ruin/unpowered/primitive_catgirl_den) "WM" = ( /obj/structure/mineral_door/wood/large_gate{ dir = 8 @@ -2001,15 +2010,6 @@ }, /turf/open/misc/dirt/icemoon, /area/ruin/unpowered/primitive_catgirl_den) -"Xn" = ( -/obj/effect/turf_decal/weather/snow/corner{ - dir = 5 - }, -/obj/effect/turf_decal/siding/wood/corner{ - dir = 8 - }, -/turf/open/misc/dirt/icemoon, -/area/ruin/unpowered/primitive_catgirl_den) "Xv" = ( /obj/structure/rack/wooden, /obj/item/plate/blowing_glass{ @@ -2388,7 +2388,7 @@ Yj oJ UV ZJ -wt +jY yF yF oJ @@ -3417,9 +3417,9 @@ Rq yF GN GN -Pq -vr -eY +Wv +oN +Jb GN pa hA @@ -3459,10 +3459,10 @@ jN GN GN GN -Xn -Eu +nx +qB aK -AV +Fn pa kF ZJ @@ -3501,7 +3501,7 @@ vZ pa GN yF -EU +VS yD JN zS @@ -3753,7 +3753,7 @@ pa qu oJ yF -nq +uu bT su cs @@ -3802,7 +3802,7 @@ mh pa ua GU -yp +TH su vx AG diff --git a/_maps/bubber/automapper/templates/lavaland/lavaland_ashwalker_fortress.dmm b/_maps/bubber/automapper/templates/lavaland/lavaland_ashwalker_fortress.dmm index 328f93ba40c..090ddeffc89 100644 --- a/_maps/bubber/automapper/templates/lavaland/lavaland_ashwalker_fortress.dmm +++ b/_maps/bubber/automapper/templates/lavaland/lavaland_ashwalker_fortress.dmm @@ -1630,14 +1630,13 @@ /turf/open/misc/asteroid/basalt/lava_land_surface, /area/ruin/unpowered/ash_walkers) "xb" = ( -/obj/item/forging/reagent_weapon/bokken, -/obj/item/forging/reagent_weapon/bokken{ +/obj/item/melee/forged_reagent_weapon/bokken{ pixel_x = -7 }, -/obj/item/forging/reagent_weapon/bokken{ +/obj/item/melee/forged_reagent_weapon/bokken{ pixel_x = 14 }, -/obj/item/forging/reagent_weapon/bokken{ +/obj/item/melee/forged_reagent_weapon/bokken{ pixel_x = 7 }, /obj/structure/rack/wooden, @@ -1697,8 +1696,8 @@ /turf/open/misc/asteroid/basalt/lava_land_surface, /area/ruin/unpowered/ash_walkers) "xF" = ( -/obj/structure/reagent_water_basin, /obj/effect/decal/cleanable/dirt, +/obj/structure/reagent_dispensers/reagent_smithing_basin/prefilled, /turf/open/floor/stone/lavaland, /area/ruin/unpowered/ash_walkers) "xW" = ( diff --git a/_maps/bubber/automapper/templates/lavaland/lavaland_ashwalker_nest.dmm b/_maps/bubber/automapper/templates/lavaland/lavaland_ashwalker_nest.dmm index 3772341e510..f27ba83388c 100644 --- a/_maps/bubber/automapper/templates/lavaland/lavaland_ashwalker_nest.dmm +++ b/_maps/bubber/automapper/templates/lavaland/lavaland_ashwalker_nest.dmm @@ -519,7 +519,7 @@ /turf/open/misc/asteroid/basalt/lava_land_surface, /area/ruin/unpowered/ash_walkers) "sD" = ( -/obj/structure/reagent_water_basin, +/obj/structure/reagent_dispensers/reagent_smithing_basin, /obj/structure/stone_tile/slab, /turf/open/misc/asteroid/basalt/lava_land_surface, /area/ruin/unpowered/ash_walkers) diff --git a/_maps/bubber/automapper/templates/lavaland/lavaland_smithy.dmm b/_maps/bubber/automapper/templates/lavaland/lavaland_smithy.dmm index 8a2a232d427..b9e449924db 100644 --- a/_maps/bubber/automapper/templates/lavaland/lavaland_smithy.dmm +++ b/_maps/bubber/automapper/templates/lavaland/lavaland_smithy.dmm @@ -12,7 +12,7 @@ /area/mine/blacksmith) "l" = ( /obj/effect/decal/cleanable/dirt, -/obj/structure/reagent_water_basin, +/obj/structure/reagent_dispensers/reagent_smithing_basin, /turf/open/floor/stone, /area/mine/blacksmith) "n" = ( diff --git a/_maps/map_files/biodome/biodome.dmm b/_maps/map_files/biodome/biodome.dmm index 5da93c2522d..d4f3675fe84 100644 --- a/_maps/map_files/biodome/biodome.dmm +++ b/_maps/map_files/biodome/biodome.dmm @@ -5976,6 +5976,10 @@ }, /turf/open/floor/iron/grimy, /area/station/hallway/secondary/entry) +"cfV" = ( +/obj/structure/cable, +/turf/closed/wall/r_wall, +/area/station/ai/satellite/chamber) "cgh" = ( /obj/machinery/duct, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -10766,14 +10770,6 @@ }, /turf/open/floor/carpet/green, /area/station/command/heads_quarters/nt_rep) -"dPu" = ( -/obj/effect/turf_decal/siding/blue, -/obj/effect/turf_decal/siding/blue/corner{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/dark, -/area/station/ai/satellite/chamber) "dPD" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -12438,6 +12434,14 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/department/cargo) +"ets" = ( +/obj/effect/turf_decal/siding/blue, +/obj/effect/turf_decal/siding/blue/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/dark, +/area/station/ai/satellite/chamber) "etu" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/item/radio/intercom/directional/south, @@ -13719,16 +13723,6 @@ /obj/structure/filingcabinet, /turf/open/floor/iron/smooth_large, /area/station/security/detectives_office) -"ePG" = ( -/obj/machinery/power/apc/auto_name/directional/east, -/obj/structure/cable, -/obj/effect/turf_decal/siding/wood{ - dir = 6 - }, -/obj/structure/reagent_water_basin, -/obj/structure/wall_torch/spawns_lit/directional/south, -/turf/open/floor/stone, -/area/station/cargo/blacksmith) "ePS" = ( /obj/effect/turf_decal/trimline/dark_green/filled/line, /obj/effect/turf_decal/trimline/dark_green/filled/mid_joiner, @@ -16663,20 +16657,6 @@ /obj/structure/cable, /turf/closed/wall, /area/station/science/breakroom) -"fVI" = ( -/obj/item/kirbyplants/photosynthetic{ - pixel_y = 6 - }, -/obj/machinery/requests_console/directional/west{ - department = "AI Chamber"; - name = "AI Chamber Requests Console" - }, -/obj/effect/mapping_helpers/requests_console/assistance, -/obj/effect/mapping_helpers/requests_console/information, -/obj/machinery/firealarm/directional/north, -/obj/structure/cable, -/turf/open/floor/circuit, -/area/station/ai/satellite/chamber) "fVJ" = ( /obj/machinery/door/airlock/engineering{ name = "Telecommunications" @@ -20258,6 +20238,20 @@ "hmV" = ( /turf/open/floor/wood, /area/station/service/abandoned_gambling_den) +"hna" = ( +/obj/item/kirbyplants/photosynthetic{ + pixel_y = 6 + }, +/obj/machinery/requests_console/directional/west{ + department = "AI Chamber"; + name = "AI Chamber Requests Console" + }, +/obj/effect/mapping_helpers/requests_console/assistance, +/obj/effect/mapping_helpers/requests_console/information, +/obj/machinery/firealarm/directional/north, +/obj/structure/cable, +/turf/open/floor/circuit, +/area/station/ai/satellite/chamber) "hne" = ( /obj/structure/sign/painting/library_secure{ pixel_x = -32 @@ -25002,6 +24996,16 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/security/checkpoint/customs) +"iVu" = ( +/obj/machinery/holopad/secure, +/obj/effect/turf_decal/siding/blue/corner, +/obj/effect/turf_decal/siding/blue/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/dark, +/area/station/ai/satellite/chamber) "iVz" = ( /obj/structure/table, /obj/item/screwdriver, @@ -30333,14 +30337,6 @@ /obj/structure/closet/crate, /turf/open/floor/iron, /area/station/cargo/storage) -"kJv" = ( -/obj/effect/turf_decal/siding/blue{ - dir = 8 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/obj/structure/cable, -/turf/open/floor/iron/dark, -/area/station/ai/satellite/chamber) "kJT" = ( /obj/item/paper_bin/bundlenatural, /turf/open/misc/asteroid/airless, @@ -34303,6 +34299,11 @@ /obj/effect/mapping_helpers/airlock/access/all/security/entrance, /turf/open/floor/iron/dark/textured, /area/station/security/brig/entrance) +"lZh" = ( +/obj/structure/cable, +/obj/machinery/power/smes/super/full, +/turf/open/floor/circuit, +/area/station/ai/satellite/chamber) "lZk" = ( /obj/effect/decal/cleanable/blood/gibs, /turf/open/floor/plating/reinforced, @@ -37263,11 +37264,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/port/lower) -"naC" = ( -/obj/structure/cable, -/obj/machinery/power/smes/super/full, -/turf/open/floor/circuit, -/area/station/ai/satellite/chamber) "naO" = ( /obj/structure/chair/sofa/bench/right{ dir = 4 @@ -50531,10 +50527,6 @@ /obj/item/folder/yellow, /turf/open/floor/iron/dark, /area/station/tcommsat/computer) -"rCO" = ( -/obj/structure/cable, -/turf/closed/wall/r_wall, -/area/station/ai/satellite/chamber) "rCP" = ( /obj/effect/turf_decal/siding/dark/corner{ dir = 1 @@ -58723,16 +58715,6 @@ }, /turf/open/floor/iron/white/smooth_large, /area/station/science/robotics/augments) -"ulw" = ( -/obj/machinery/holopad/secure, -/obj/effect/turf_decal/siding/blue/corner, -/obj/effect/turf_decal/siding/blue/corner{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/dark, -/area/station/ai/satellite/chamber) "ulx" = ( /obj/structure/cable, /turf/open/floor/iron/dark, @@ -63994,6 +63976,16 @@ /obj/effect/spawner/random/structure/girder, /turf/open/floor/plating, /area/station/maintenance/aft) +"wha" = ( +/obj/structure/reagent_dispensers/reagent_smithing_basin, +/obj/machinery/power/apc/auto_name/directional/east, +/obj/structure/cable, +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/obj/structure/wall_torch/spawns_lit/directional/south, +/turf/open/floor/stone, +/area/station/cargo/blacksmith) "whg" = ( /obj/effect/turf_decal/siding/brown{ dir = 8 @@ -64218,6 +64210,14 @@ /obj/machinery/holopad, /turf/open/misc/asteroid, /area/station/cargo/miningdock) +"wkU" = ( +/obj/effect/turf_decal/siding/blue{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/structure/cable, +/turf/open/floor/iron/dark, +/area/station/ai/satellite/chamber) "wlo" = ( /obj/effect/turf_decal/tile/brown/half/contrasted{ dir = 4 @@ -156141,7 +156141,7 @@ oCa oCa oCa sjc -fVI +hna vtb qEP qEP @@ -156398,8 +156398,8 @@ mbR mbR iKu sjc -kJv -dPu +wkU +ets puM sjc sjc @@ -156656,11 +156656,11 @@ saz nId ddy yiK -ulw +iVu npE lRp -rCO -naC +cfV +lZh uio nKg uTZ @@ -180092,7 +180092,7 @@ uHg xfB nzM xyN -ePG +wha rPl bzD dSu diff --git a/_maps/map_files/generic/CentCom_skyrat_z2.dmm b/_maps/map_files/generic/CentCom_skyrat_z2.dmm index 0e10013dcb9..b76bed8870e 100644 --- a/_maps/map_files/generic/CentCom_skyrat_z2.dmm +++ b/_maps/map_files/generic/CentCom_skyrat_z2.dmm @@ -1106,6 +1106,17 @@ /obj/structure/flora/tree/jungle/small, /turf/open/misc/grass/planet, /area/centcom/holding/cafe/park) +"azJ" = ( +/obj/structure/closet/secure_closet/personal/cabinet, +/obj/item/clothing/neck/large_scarf/green, +/obj/item/clothing/head/hats/intern{ + pixel_y = 9 + }, +/obj/item/clothing/under/rank/centcom/intern{ + pixel_y = -3 + }, +/turf/open/floor/wood/large, +/area/centcom/central_command_areas/admin/interlink) "azO" = ( /obj/effect/turf_decal/siding/white/corner{ dir = 1 @@ -2034,17 +2045,6 @@ "aXG" = ( /turf/open/floor/iron/dark, /area/centcom/interlink) -"aXQ" = ( -/obj/structure/closet/secure_closet/personal/cabinet, -/obj/item/clothing/neck/large_scarf/green, -/obj/item/clothing/head/hats/intern{ - pixel_y = 9 - }, -/obj/item/clothing/under/rank/centcom/intern{ - pixel_y = -3 - }, -/turf/open/floor/wood/large, -/area/centcom/central_command_areas/admin/interlink) "aYc" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 8 @@ -2512,6 +2512,12 @@ /obj/machinery/bookbinder, /turf/open/floor/wood, /area/centcom/holding/cafe/station/service/library) +"bAh" = ( +/obj/machinery/door/poddoor/shutters/indestructible{ + id = "admin_shutters" + }, +/turf/closed/indestructible/fakeglass, +/area/centcom/central_command_areas/admin/interlink) "bAr" = ( /obj/effect/turf_decal/siding/wood, /obj/item/flashlight/flare/candle/infinite{ @@ -5666,6 +5672,43 @@ }, /turf/open/floor/plating/abductor, /area/centcom/holding/cafe/dorms) +"eNt" = ( +/obj/structure/table/wood, +/obj/item/stamp/denied{ + pixel_x = 8; + pixel_y = 10 + }, +/obj/machinery/requests_console/auto_name/directional/north{ + pixel_x = 3; + pixel_y = 31 + }, +/obj/effect/mapping_helpers/requests_console/assistance, +/obj/effect/mapping_helpers/requests_console/information, +/obj/machinery/button/door/directional/north{ + name = "Admin Shutter Control"; + id = "admin_shutters"; + pixel_x = -5; + pixel_y = 21 + }, +/obj/item/folder/blue{ + pixel_x = 1; + pixel_y = -3 + }, +/obj/item/folder/red{ + pixel_x = -3; + pixel_y = -3 + }, +/obj/item/folder/yellow{ + pixel_x = -7; + pixel_y = -3 + }, +/obj/effect/mapping_helpers/requests_console/announcement, +/obj/item/stamp/granted{ + pixel_y = 10; + pixel_x = -4 + }, +/turf/open/floor/carpet/executive, +/area/centcom/central_command_areas/admin/interlink) "eNI" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 1 @@ -5690,10 +5733,6 @@ /obj/effect/decal/remains/human, /turf/open/misc/dirt/planet, /area/centcom/holding/cafe/ruin/xenonest) -"ePo" = ( -/obj/structure/reagent_water_basin, -/turf/open/misc/dirt/planet, -/area/centcom/holding/cafe/ruin/ash_walkers) "eRz" = ( /obj/effect/turf_decal/siding/white{ dir = 4 @@ -12970,43 +13009,6 @@ /obj/machinery/light/directional/south, /turf/open/floor/iron/white, /area/centcom/interlink/dorm_rooms) -"mEr" = ( -/obj/structure/table/wood, -/obj/item/stamp/denied{ - pixel_x = 8; - pixel_y = 10 - }, -/obj/machinery/requests_console/auto_name/directional/north{ - pixel_x = 3; - pixel_y = 31 - }, -/obj/effect/mapping_helpers/requests_console/assistance, -/obj/effect/mapping_helpers/requests_console/information, -/obj/machinery/button/door/directional/north{ - name = "Admin Shutter Control"; - id = "admin_shutters"; - pixel_x = -5; - pixel_y = 21 - }, -/obj/item/folder/blue{ - pixel_x = 1; - pixel_y = -3 - }, -/obj/item/folder/red{ - pixel_x = -3; - pixel_y = -3 - }, -/obj/item/folder/yellow{ - pixel_x = -7; - pixel_y = -3 - }, -/obj/effect/mapping_helpers/requests_console/announcement, -/obj/item/stamp/granted{ - pixel_y = 10; - pixel_x = -4 - }, -/turf/open/floor/carpet/executive, -/area/centcom/central_command_areas/admin/interlink) "mEA" = ( /obj/structure/cable/layer3, /obj/machinery/light/dim/directional/north, @@ -13085,6 +13087,11 @@ /obj/structure/fans/tiny/invisible, /turf/open/water/beach, /area/centcom/holding/cafe/beach) +"mJM" = ( +/obj/structure/bed/double, +/obj/item/bedsheet/centcom/double, +/turf/open/floor/carpet/executive, +/area/centcom/central_command_areas/admin/interlink) "mKq" = ( /obj/structure/chair/sofa/corp{ dir = 1 @@ -14541,12 +14548,6 @@ /obj/structure/cable, /turf/open/indestructible/plating, /area/centcom/holding/cafe/station/maint) -"oeg" = ( -/obj/machinery/door/poddoor/shutters/indestructible{ - id = "admin_shutters" - }, -/turf/closed/indestructible/fakeglass, -/area/centcom/central_command_areas/admin/interlink) "ogq" = ( /obj/structure/chair/comfy/brown{ dir = 4 @@ -14610,6 +14611,19 @@ }, /turf/open/floor/carpet/black, /area/centcom/interlink) +"oke" = ( +/obj/structure/table/wood, +/obj/item/paper_bin{ + papertype = /obj/item/paper/paperslip/corporate; + pixel_x = 6; + pixel_y = 2 + }, +/obj/item/pen/fourcolor{ + pixel_x = -7; + pixel_y = 7 + }, +/turf/open/floor/carpet/executive, +/area/centcom/central_command_areas/admin/interlink) "olz" = ( /obj/structure/window/reinforced/plasma/plastitanium/indestructible, /turf/open/indestructible/hoteltile{ @@ -15780,14 +15794,6 @@ /obj/structure/bookcase/random/reference, /turf/open/indestructible/hotelwood, /area/centcom/holding/cafe/station/medical/psychology) -"pFm" = ( -/obj/structure/closet/secure_closet/personal/cabinet, -/obj/item/modular_computer/pda/clear, -/obj/item/paper_bin, -/obj/item/storage/toolbox/mechanical, -/obj/item/multitool, -/turf/open/floor/carpet/executive, -/area/centcom/central_command_areas/admin/interlink) "pFr" = ( /obj/machinery/door/airlock/security{ name = "Interlink Security Processing" @@ -16147,10 +16153,6 @@ }, /turf/open/floor/plating, /area/centcom/interlink) -"pVD" = ( -/obj/structure/dresser, -/turf/open/floor/carpet/executive, -/area/centcom/central_command_areas/admin/interlink) "pWH" = ( /obj/structure/showcase/fakeid{ dir = 4; @@ -20357,11 +20359,6 @@ }, /turf/open/floor/carpet/black, /area/centcom/interlink) -"uAY" = ( -/obj/structure/bed/double, -/obj/item/bedsheet/centcom/double, -/turf/open/floor/carpet/executive, -/area/centcom/central_command_areas/admin/interlink) "uCK" = ( /obj/structure/reagent_dispensers/watertank, /turf/open/indestructible/plating, @@ -22543,6 +22540,14 @@ }, /turf/open/floor/grass, /area/centcom/interlink) +"wKu" = ( +/obj/structure/closet/secure_closet/personal/cabinet, +/obj/item/modular_computer/pda/clear, +/obj/item/paper_bin, +/obj/item/storage/toolbox/mechanical, +/obj/item/multitool, +/turf/open/floor/carpet/executive, +/area/centcom/central_command_areas/admin/interlink) "wKG" = ( /obj/structure/railing/unbreakable{ dir = 10 @@ -22967,6 +22972,10 @@ /obj/effect/turf_decal/siding/thinplating_new, /turf/open/floor/iron, /area/centcom/interlink) +"xoU" = ( +/obj/structure/dresser, +/turf/open/floor/carpet/executive, +/area/centcom/central_command_areas/admin/interlink) "xpM" = ( /obj/structure/stone_tile/center, /obj/structure/stone_tile/surrounding_tile{ @@ -23081,19 +23090,6 @@ /obj/effect/turf_decal/siding/wood, /turf/open/floor/wood/tile, /area/centcom/interlink) -"xve" = ( -/obj/structure/table/wood, -/obj/item/paper_bin{ - papertype = /obj/item/paper/paperslip/corporate; - pixel_x = 6; - pixel_y = 2 - }, -/obj/item/pen/fourcolor{ - pixel_x = -7; - pixel_y = 7 - }, -/turf/open/floor/carpet/executive, -/area/centcom/central_command_areas/admin/interlink) "xvu" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/indestructible/hoteltile{ @@ -42355,9 +42351,9 @@ rPg tvw lEu lEu -oeg +bAh dgK -oeg +bAh lEu lEu fTE @@ -42616,7 +42612,7 @@ rxZ rxZ rhf mSx -oeg +bAh vat vat vat @@ -42873,7 +42869,7 @@ hbe hbe hbe hYD -oeg +bAh vat vat fVr @@ -43897,7 +43893,7 @@ rbr tvw lEu lEu -mEr +eNt luM kHQ cAd @@ -44156,13 +44152,13 @@ aaa lEu fSE apw -xve +oke gpr lEu anH wUC -pFm -pVD +wKu +xoU lEu aaa vLx @@ -44673,10 +44669,10 @@ ycX iFA rPG lEu -aXQ +azJ fIk cAd -uAY +mJM lEu aaa vLx @@ -81142,7 +81138,7 @@ uMS sUu sUu nXK -ePo +nXK nXK nXK sUu diff --git a/_maps/map_files/moonstation/moonstation.dmm b/_maps/map_files/moonstation/moonstation.dmm index 3530abd8e36..bc6752b4f8c 100644 --- a/_maps/map_files/moonstation/moonstation.dmm +++ b/_maps/map_files/moonstation/moonstation.dmm @@ -147,13 +147,6 @@ }, /turf/open/floor/engine, /area/station/engineering/supermatter/room) -"acj" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/air_sensor/engine_chamber, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "acp" = ( /obj/structure/window/reinforced/spawner/directional/south, /obj/structure/table, @@ -755,6 +748,13 @@ /obj/structure/railing, /turf/open/floor/catwalk_floor/rust/moonstation, /area/moonstation/surface) +"ajy" = ( +/obj/machinery/door/poddoor/shutters/radiation/preopen{ + id = "engsm"; + name = "Radiation Chamber Shutters" + }, +/turf/open/floor/plating, +/area/station/engineering/supermatter/engine) "ajD" = ( /obj/effect/spawner/random/burgerstation/atmos, /turf/open/floor/plating, @@ -1752,21 +1752,6 @@ /obj/structure/sign/warning/directional/west, /turf/open/floor/plating/lavaland_atmos, /area/lavaland/surface/outdoors) -"avN" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/obj/effect/mapping_helpers/airlock/access/all/engineering/general, -/obj/effect/mapping_helpers/airlock/locked, -/obj/machinery/door/airlock/engineering/glass/critical{ - heat_proof = 1; - name = "Supermatter Chamber"; - id_tag = "sm_west" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/green/visible, -/obj/machinery/meter, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "avP" = ( /obj/effect/turf_decal/stripes/asteroid/line{ dir = 9 @@ -3408,6 +3393,11 @@ /obj/structure/chair/comfy, /turf/open/floor/carpet, /area/station/security/processing) +"aPP" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, +/obj/machinery/atmospherics/components/unary/delam_scram/directional/east, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "aPS" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ @@ -5189,6 +5179,11 @@ /obj/item/binoculars, /turf/open/floor/plating, /area/station/maintenance/department/prison) +"bnO" = ( +/obj/structure/window/reinforced/plasma/spawner/directional/south, +/obj/machinery/power/energy_accumulator/grounding_rod/anchored, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/engineering/supermatter/engine) "bnV" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /obj/effect/turf_decal/tile/red/half/contrasted{ @@ -5505,6 +5500,10 @@ /obj/structure/ladder, /turf/open/floor/plastic, /area/station/commons/public_xenoarch) +"bsn" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "bsC" = ( /obj/structure/table, /obj/machinery/dish_drive/bullet{ @@ -6692,15 +6691,6 @@ }, /turf/open/lava/smooth/lava_land_surface, /area/ruin/unpowered/ash_walkers) -"bJg" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "bJj" = ( /obj/machinery/atmospherics/pipe/smart/simple/green/visible, /obj/effect/turf_decal/tile/blue/half/contrasted, @@ -9795,6 +9785,17 @@ }, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) +"cAX" = ( +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=8"; + location = "QM #1"; + name = "QM #1" + }, +/mob/living/basic/bot/mulebot, +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/tile/brown/anticorner/contrasted, +/turf/open/floor/iron, +/area/station/cargo/storage) "cAY" = ( /obj/effect/turf_decal/siding/dark{ dir = 4 @@ -10849,6 +10850,10 @@ /obj/structure/extinguisher_cabinet/directional/north, /turf/open/floor/wood, /area/station/service/chapel/office) +"cOX" = ( +/obj/effect/spawner/structure/window/reinforced/plasma, +/turf/open/floor/plating, +/area/station/engineering/supermatter/engine) "cPc" = ( /obj/effect/turf_decal/stripes/asteroid/line{ dir = 5 @@ -12384,13 +12389,6 @@ /obj/effect/decal/cleanable/cobweb/cobweb2, /turf/open/floor/wood, /area/station/maintenance/rus_gambling) -"dig" = ( -/obj/machinery/door/poddoor/shutters/radiation/preopen{ - id = "engsm"; - name = "Radiation Chamber Shutters" - }, -/turf/open/floor/plating, -/area/station/engineering/supermatter/engine) "dii" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -13353,6 +13351,14 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron/dark, /area/station/command/gateway) +"duq" = ( +/obj/machinery/door/poddoor/shutters/radiation/preopen{ + id = "engsm"; + name = "Radiation Chamber Shutters" + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/engineering/supermatter/engine) "dux" = ( /obj/machinery/light/floor, /turf/open/floor/plating, @@ -13950,6 +13956,15 @@ }, /turf/open/floor/iron/dark, /area/station/hallway/primary/central/fore) +"dBJ" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "dBM" = ( /obj/effect/turf_decal/vg_decals/numbers/two, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -14710,6 +14725,20 @@ /obj/structure/extinguisher_cabinet/directional/west, /turf/open/floor/iron/dark, /area/station/security/checkpoint/science) +"dMT" = ( +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=8"; + location = "QM #3"; + name = "QM #3" + }, +/mob/living/basic/bot/mulebot, +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron, +/area/station/cargo/storage) "dMY" = ( /obj/effect/decal/cleanable/cobweb/cobweb2, /obj/structure/reagent_dispensers/plumbed{ @@ -16438,6 +16467,15 @@ }, /turf/open/floor/engine, /area/station/engineering/atmos/hfr_room) +"ekD" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "ekE" = ( /obj/effect/turf_decal/tile/green/half/contrasted{ dir = 8 @@ -16664,6 +16702,15 @@ /obj/machinery/camera/autoname/toxins/directional/west, /turf/open/floor/iron/dark, /area/station/science/ordnance/testlab) +"emM" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "emO" = ( /obj/structure/closet/crate/hydroponics, /obj/effect/spawner/random/food_or_drink/seed, @@ -19057,25 +19104,6 @@ /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plating, /area/station/maintenance/abandon_exam) -"eTC" = ( -/obj/machinery/airalarm/directional/north, -/obj/effect/mapping_helpers/airalarm/engine_access, -/obj/machinery/button/door/directional/west{ - id = "sm_east"; - name = "Supermatter Chamber Bolt Control"; - normaldoorcontrol = 1; - specialfunctions = 4; - req_access = list("engineering") - }, -/obj/effect/turf_decal/stripes/end{ - dir = 1 - }, -/obj/effect/mapping_helpers/airalarm/link{ - chamber_id = "engine" - }, -/obj/effect/mapping_helpers/airalarm/tlv_no_checks, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "eTH" = ( /obj/structure/cable, /obj/machinery/atmospherics/components/binary/pump{ @@ -20648,12 +20676,6 @@ /obj/structure/fluff/fokoff_sign, /turf/open/floor/fake_snow/safe, /area/station/science/ordnance) -"foh" = ( -/obj/structure/window/reinforced/plasma/spawner/directional/south, -/obj/machinery/power/energy_accumulator/tesla_coil/anchored, -/obj/structure/cable, -/turf/open/floor/catwalk_floor/iron_dark, -/area/station/engineering/supermatter/engine) "foj" = ( /obj/effect/turf_decal/tile/purple/half/contrasted{ dir = 8 @@ -21067,6 +21089,17 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/maintenance/aft) +"ftr" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, +/obj/machinery/meter, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "ftJ" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -22689,22 +22722,6 @@ }, /turf/open/floor/engine, /area/station/science/ordnance/burnchamber) -"fMW" = ( -/obj/structure/table/reinforced, -/obj/machinery/button/door/directional/west{ - id = "ce_officer_shutters"; - name = "Privacy Shutters Control"; - req_access = list("ce") - }, -/obj/machinery/requests_console/auto_name/directional/north, -/obj/effect/mapping_helpers/requests_console/assistance, -/obj/effect/mapping_helpers/requests_console/supplies, -/obj/effect/mapping_helpers/requests_console/information, -/obj/effect/mapping_helpers/requests_console/announcement, -/obj/effect/turf_decal/tile/neutral, -/obj/machinery/fax/heads/ce, -/turf/open/floor/iron, -/area/station/command/heads_quarters/ce) "fNd" = ( /obj/effect/turf_decal/tile/dark_blue/opposingcorners{ dir = 8 @@ -23496,14 +23513,6 @@ }, /turf/open/floor/iron/smooth, /area/mine/laborcamp/quarters) -"fWW" = ( -/obj/machinery/light/small/red/directional/west, -/obj/structure/sign/warning/radiation/directional/west, -/obj/structure/window/reinforced/plasma/spawner/directional/south, -/obj/machinery/power/energy_accumulator/tesla_coil/anchored, -/obj/structure/cable, -/turf/open/floor/catwalk_floor/iron_dark, -/area/station/engineering/supermatter/engine) "fXn" = ( /obj/effect/turf_decal/tile/blue/half/contrasted{ dir = 4 @@ -28402,6 +28411,10 @@ /obj/machinery/fax/auto_name, /turf/open/floor/wood, /area/station/command/heads_quarters/blueshield) +"hnF" = ( +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "hnG" = ( /obj/effect/turf_decal/tile/yellow/half/contrasted{ dir = 8 @@ -29348,6 +29361,15 @@ }, /turf/open/floor/engine/co2, /area/station/engineering/atmos) +"hAk" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "hAr" = ( /obj/structure/tank_dispenser/oxygen, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -36954,6 +36976,20 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/dark, /turf/open/floor/catwalk_floor/iron_dark, /area/station/maintenance/starboard/aft) +"juU" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/effect/mapping_helpers/airlock/access/all/engineering/general, +/obj/effect/mapping_helpers/airlock/locked, +/obj/machinery/door/airlock/engineering/glass/critical{ + heat_proof = 1; + name = "Supermatter Chamber"; + id_tag = "sm_east" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "juW" = ( /obj/effect/turf_decal/tile/yellow/anticorner/contrasted{ dir = 8 @@ -37272,6 +37308,13 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/maintenance/port) +"jzv" = ( +/obj/machinery/light/small/directional/south, +/obj/item/radio/intercom/directional/west, +/obj/effect/turf_decal/stripes/end, +/obj/machinery/camera/autoname/engineering/directional/south, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "jzL" = ( /turf/open/floor/glass/reinforced/scrape_below, /area/station/hallway/primary/port) @@ -38273,11 +38316,6 @@ /obj/effect/mapping_helpers/requests_console/supplies, /turf/open/floor/wood/parquet, /area/station/command/heads_quarters/rd) -"jOr" = ( -/obj/effect/turf_decal/stripes/full, -/obj/machinery/power/supermatter_crystal/engine, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "jOC" = ( /obj/effect/turf_decal/bot, /obj/machinery/portable_atmospherics/canister/nitrogen, @@ -38585,11 +38623,6 @@ /obj/effect/decal/cleanable/cobweb, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"jSv" = ( -/obj/effect/spawner/structure/window/reinforced/plasma, -/obj/effect/mapping_helpers/burnt_floor, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "jSz" = ( /turf/open/floor/stone, /area/station/service/hydroponics) @@ -39103,20 +39136,6 @@ /obj/item/flashlight/flare/candle/infinite, /turf/open/lava/smooth/lava_land_surface, /area/ruin/unpowered/ash_walkers) -"jZx" = ( -/mob/living/basic/bot/mulebot, -/obj/machinery/navbeacon{ - codes_txt = "delivery;dir=8"; - location = "QM #2"; - name = "QM #2" - }, -/obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt/dust, -/turf/open/floor/iron, -/area/station/cargo/storage) "jZJ" = ( /obj/effect/mapping_helpers/airlock/access/all/command/captain, /obj/machinery/door/airlock/captain{ @@ -41426,15 +41445,6 @@ /obj/structure/extinguisher_cabinet/directional/east, /turf/open/floor/iron/dark/corner, /area/station/hallway/primary/aft) -"kCy" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 8 - }, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "kCz" = ( /obj/machinery/door/poddoor/shutters/window{ id = "armory"; @@ -43362,21 +43372,6 @@ "lbr" = ( /turf/closed/wall/mineral/wood, /area/station/hallway/secondary/service) -"lbw" = ( -/obj/structure/table/glass, -/obj/effect/turf_decal/tile/blue/half/contrasted{ - dir = 1 - }, -/obj/machinery/keycard_auth/wall_mounted/directional/north, -/obj/machinery/button/door/directional/north{ - id = "cmo_officer_shutters"; - name = "Privacy Shutters Control"; - pixel_y = 34; - req_access = list("cmo") - }, -/obj/machinery/fax/heads/cmo, -/turf/open/floor/iron/white, -/area/station/command/heads_quarters/cmo) "lbH" = ( /obj/effect/turf_decal/tile/purple/half/contrasted{ dir = 8 @@ -44366,6 +44361,15 @@ /obj/effect/landmark/navigate_destination/autoname, /turf/open/floor/plating, /area/station/engineering/supermatter/room) +"lnz" = ( +/obj/machinery/light/small/red/directional/east, +/obj/structure/sign/warning/radiation/directional/east, +/obj/structure/window/reinforced/plasma/spawner/directional/south, +/obj/machinery/power/energy_accumulator/tesla_coil/anchored, +/obj/structure/cable, +/obj/machinery/camera/autoname/engineering/directional/east, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/engineering/supermatter/engine) "lnC" = ( /obj/machinery/porta_turret/ai, /turf/open/floor/circuit/red, @@ -45962,6 +45966,9 @@ }, /turf/open/floor/iron/checker, /area/station/hallway/primary/central/aft) +"lHI" = ( +/turf/closed/wall/r_wall, +/area/station/engineering/supermatter/engine) "lHP" = ( /obj/structure/table/wood, /obj/machinery/newscaster/directional/east, @@ -47531,6 +47538,11 @@ }, /turf/open/floor/plating, /area/station/maintenance/department/crew_quarters/dorms) +"mbq" = ( +/obj/effect/spawner/structure/window/reinforced/plasma, +/obj/effect/mapping_helpers/burnt_floor, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "mbr" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/effect/spawner/random/trash/box, @@ -47632,6 +47644,13 @@ /obj/structure/disposalpipe/trunk, /turf/open/floor/iron/showroomfloor, /area/station/terminal/cryo) +"mbV" = ( +/obj/machinery/light/small/directional/south, +/obj/item/radio/intercom/directional/east, +/obj/effect/turf_decal/stripes/end, +/obj/machinery/camera/autoname/engineering/directional/south, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "mcd" = ( /obj/machinery/meter, /obj/machinery/atmospherics/pipe/smart/manifold/general/visible{ @@ -47666,6 +47685,12 @@ /obj/structure/chair/office/light, /turf/open/floor/plastic, /area/station/commons/public_xenoarch) +"mcw" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted, +/obj/structure/cable, +/obj/structure/reagent_dispensers/reagent_smithing_basin, +/turf/open/floor/iron/checker, +/area/station/cargo/blacksmith) "mcx" = ( /obj/effect/turf_decal/tile/dark_blue/half/contrasted{ dir = 8 @@ -47785,19 +47810,6 @@ /obj/machinery/autolathe, /turf/open/floor/iron, /area/station/cargo/office) -"met" = ( -/obj/structure/table/wood, -/obj/structure/cable, -/obj/machinery/fax/heads/hos, -/turf/open/floor/wood, -/area/station/command/heads_quarters/hos) -"meB" = ( -/obj/machinery/light/small/directional/south, -/obj/item/radio/intercom/directional/west, -/obj/effect/turf_decal/stripes/end, -/obj/machinery/camera/autoname/engineering/directional/south, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "meD" = ( /obj/effect/turf_decal/siding/yellow{ dir = 1 @@ -47927,20 +47939,6 @@ "mfS" = ( /turf/open/floor/iron/dark, /area/station/hallway/primary/central/aft) -"mfT" = ( -/obj/effect/turf_decal/siding/dark{ - dir = 9 - }, -/obj/structure/table/wood, -/obj/machinery/button/door/directional/north{ - id = "qm_privacy_shutters"; - name = "Privacy Shutters Control"; - req_access = list("qm") - }, -/obj/machinery/firealarm/directional/west, -/obj/machinery/fax/heads/qm, -/turf/open/floor/mineral/gold, -/area/station/command/heads_quarters/qm) "mga" = ( /obj/structure/closet/emcloset/anchored, /turf/open/floor/plating, @@ -48884,20 +48882,6 @@ /obj/machinery/light_switch/directional/east, /turf/open/floor/iron/dark, /area/station/security/corrections_officer) -"mti" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 8 - }, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) -"mtp" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, -/obj/machinery/atmospherics/components/unary/delam_scram/directional/east, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "mtz" = ( /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 4 @@ -50747,17 +50731,6 @@ }, /turf/open/floor/iron, /area/station/engineering/storage_shared) -"mTq" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, -/obj/machinery/meter, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "mTr" = ( /obj/machinery/door/airlock/maintenance_hatch, /obj/effect/mapping_helpers/airlock/access/all/medical/surgery, @@ -53393,6 +53366,12 @@ "nFN" = ( /turf/closed/wall, /area/station/maintenance/department/medical/chemistry) +"nFO" = ( +/obj/structure/window/reinforced/plasma/spawner/directional/south, +/obj/machinery/power/energy_accumulator/tesla_coil/anchored, +/obj/structure/cable, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/engineering/supermatter/engine) "nFS" = ( /obj/effect/turf_decal/tile/green/half/contrasted, /obj/structure/disposalpipe/segment{ @@ -55065,15 +55044,6 @@ /obj/structure/extinguisher_cabinet/directional/north, /turf/open/floor/iron/dark, /area/station/commons/dorms) -"ocd" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "ocg" = ( /obj/effect/turf_decal/tile/brown{ dir = 4 @@ -56632,6 +56602,21 @@ }, /turf/open/indestructible/boss, /area/lavaland/surface/outdoors) +"ouq" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/effect/mapping_helpers/airlock/access/all/engineering/general, +/obj/effect/mapping_helpers/airlock/locked, +/obj/machinery/door/airlock/engineering/glass/critical{ + heat_proof = 1; + name = "Supermatter Chamber"; + id_tag = "sm_west" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/green/visible, +/obj/machinery/meter, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "out" = ( /obj/structure/stone_tile/block{ dir = 1 @@ -58462,13 +58447,6 @@ /obj/effect/mapping_helpers/airalarm/tlv_no_checks, /turf/open/floor/circuit/telecomms, /area/station/ai/satellite/chamber) -"oUj" = ( -/obj/machinery/light/small/directional/south, -/obj/item/radio/intercom/directional/east, -/obj/effect/turf_decal/stripes/end, -/obj/machinery/camera/autoname/engineering/directional/south, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "oUn" = ( /obj/structure/table, /obj/item/radio/intercom, @@ -58484,6 +58462,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/captain) +"oUw" = ( +/obj/machinery/power/apc/auto_name/directional/east, +/obj/effect/mapping_helpers/apc/full_charge, +/obj/effect/mapping_helpers/apc/cell_10k, +/obj/structure/cable, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/engineering/supermatter/engine) "oUz" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -58873,6 +58858,14 @@ "oZt" = ( /turf/closed/wall/rust, /area/station/engineering/atmos) +"oZw" = ( +/obj/machinery/light/small/red/directional/west, +/obj/structure/sign/warning/radiation/directional/west, +/obj/structure/window/reinforced/plasma/spawner/directional/north, +/obj/machinery/power/energy_accumulator/grounding_rod/anchored, +/obj/structure/cable, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/engineering/supermatter/engine) "oZy" = ( /obj/effect/turf_decal/stripes/asteroid/line{ dir = 1 @@ -59279,6 +59272,13 @@ /obj/machinery/suit_storage_unit/atmos, /turf/open/floor/iron, /area/station/engineering/atmos/pumproom) +"pea" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/air_sensor/engine_chamber, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "peq" = ( /obj/structure/table, /obj/item/storage/toolbox/mechanical, @@ -59888,13 +59888,6 @@ }, /turf/open/floor/iron/dark, /area/station/engineering/storage/eva) -"pkC" = ( -/obj/machinery/power/apc/auto_name/directional/east, -/obj/effect/mapping_helpers/apc/full_charge, -/obj/effect/mapping_helpers/apc/cell_10k, -/obj/structure/cable, -/turf/open/floor/catwalk_floor/iron_dark, -/area/station/engineering/supermatter/engine) "pkE" = ( /obj/machinery/door/airlock/external{ name = "External Airlock" @@ -60297,6 +60290,13 @@ /obj/effect/turf_decal/tile/purple/half/contrasted, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/rd) +"ppD" = ( +/obj/effect/turf_decal/stripes/corner, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "ppH" = ( /obj/structure/table/wood, /obj/machinery/computer/security/telescreen/entertainment/directional/east, @@ -61705,12 +61705,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, /turf/open/floor/plating, /area/station/maintenance/department/engine/atmos) -"pJo" = ( -/obj/structure/table/wood, -/obj/machinery/keycard_auth/wall_mounted/directional/west, -/obj/machinery/fax/heads/hop, -/turf/open/floor/wood/parquet, -/area/station/command/heads_quarters/hop) "pJr" = ( /obj/effect/turf_decal/tile/holiday/rainbow/half/contrasted{ dir = 4 @@ -62273,6 +62267,15 @@ }, /turf/open/floor/glass/reinforced/scrape_below, /area/station/hallway/secondary/exit/departure_lounge) +"pRf" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "pRm" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /obj/machinery/power/apc/auto_name/directional/north, @@ -62358,15 +62361,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/purple/hidden/layer5, /turf/open/floor/plating, /area/station/maintenance/department/engine) -"pSI" = ( -/obj/machinery/light/small/red/directional/east, -/obj/structure/sign/warning/radiation/directional/east, -/obj/structure/window/reinforced/plasma/spawner/directional/south, -/obj/machinery/power/energy_accumulator/tesla_coil/anchored, -/obj/structure/cable, -/obj/machinery/camera/autoname/engineering/directional/east, -/turf/open/floor/catwalk_floor/iron_dark, -/area/station/engineering/supermatter/engine) "pST" = ( /obj/effect/spawner/random/burgerstation/atmos, /turf/open/floor/plating, @@ -63472,6 +63466,25 @@ luminosity = 2 }, /area/station/command/vault) +"qfb" = ( +/obj/machinery/airalarm/directional/north, +/obj/effect/mapping_helpers/airalarm/engine_access, +/obj/machinery/button/door/directional/west{ + id = "sm_east"; + name = "Supermatter Chamber Bolt Control"; + normaldoorcontrol = 1; + specialfunctions = 4; + req_access = list("engineering") + }, +/obj/effect/turf_decal/stripes/end{ + dir = 1 + }, +/obj/effect/mapping_helpers/airalarm/link{ + chamber_id = "engine" + }, +/obj/effect/mapping_helpers/airalarm/tlv_no_checks, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "qfx" = ( /obj/effect/turf_decal/trimline/dark/filled/warning, /obj/structure/extinguisher_cabinet/directional/south, @@ -63936,10 +63949,6 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plating, /area/station/terminal/interlink) -"qkO" = ( -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "qkW" = ( /obj/structure/steps/directional/north, /turf/open/floor/plating, @@ -64857,6 +64866,14 @@ /obj/structure/extinguisher_cabinet/directional/east, /turf/open/floor/iron/dark/corner, /area/station/hallway/primary/aft) +"qyo" = ( +/obj/machinery/light/small/red/directional/west, +/obj/structure/sign/warning/radiation/directional/west, +/obj/structure/window/reinforced/plasma/spawner/directional/south, +/obj/machinery/power/energy_accumulator/tesla_coil/anchored, +/obj/structure/cable, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/engineering/supermatter/engine) "qys" = ( /obj/effect/turf_decal/tile/brown/half/contrasted{ dir = 8 @@ -66426,6 +66443,12 @@ }, /turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) +"qSr" = ( +/obj/structure/table/wood, +/obj/item/radio/intercom/command/directional/west, +/obj/machinery/fax/heads/captain, +/turf/open/floor/iron/dark, +/area/station/command/heads_quarters/captain) "qSC" = ( /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 1 @@ -68386,6 +68409,18 @@ "rrl" = ( /turf/open/openspace, /area/station/service/hydroponics/upper) +"rrJ" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/machinery/door/airlock/engineering/glass/critical{ + heat_proof = 1; + name = "Supermatter Chamber" + }, +/obj/effect/mapping_helpers/airlock/access/all/engineering/general, +/obj/machinery/atmospherics/pipe/smart/manifold4w/green/visible, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "rrU" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, /turf/open/floor/engine, @@ -68611,20 +68646,6 @@ }, /turf/open/floor/iron/dark, /area/station/security/eva) -"rvp" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/obj/effect/mapping_helpers/airlock/access/all/engineering/general, -/obj/effect/mapping_helpers/airlock/locked, -/obj/machinery/door/airlock/engineering/glass/critical{ - heat_proof = 1; - name = "Supermatter Chamber"; - id_tag = "sm_east" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "rvx" = ( /obj/effect/landmark/start/librarian, /turf/open/floor/carpet/red, @@ -68744,17 +68765,6 @@ /obj/machinery/light/small/directional/west, /turf/open/floor/engine, /area/station/science/ordnance/freezerchamber) -"rxi" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/green/visible, -/obj/machinery/meter, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "rxl" = ( /obj/item/storage/bag/plants/portaseeder, /obj/item/plant_analyzer, @@ -69136,6 +69146,20 @@ /obj/machinery/light/directional/north, /turf/open/floor/wood, /area/station/commons/vacant_room/office) +"rCB" = ( +/obj/effect/turf_decal/siding/dark{ + dir = 9 + }, +/obj/structure/table/wood, +/obj/machinery/button/door/directional/north{ + id = "qm_privacy_shutters"; + name = "Privacy Shutters Control"; + req_access = list("qm") + }, +/obj/machinery/firealarm/directional/west, +/obj/machinery/fax/heads/qm, +/turf/open/floor/mineral/gold, +/area/station/command/heads_quarters/qm) "rCH" = ( /obj/machinery/atmospherics/pipe/multiz/scrubbers/visible/layer2{ dir = 1 @@ -69469,6 +69493,12 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/department/crew_quarters/dorms) +"rHs" = ( +/obj/structure/table/glass/plasmaglass, +/obj/machinery/fax/heads/rd, +/obj/item/radio/intercom/directional/west, +/turf/open/floor/carpet/purple, +/area/station/command/heads_quarters/rd) "rHx" = ( /obj/effect/mapping_helpers/broken_floor, /obj/item/kirbyplants/random/dead, @@ -70173,6 +70203,12 @@ /obj/item/clothing/glasses/meson, /turf/open/floor/iron/dark, /area/station/engineering/main) +"rQL" = ( +/obj/structure/window/reinforced/plasma/spawner/directional/north, +/obj/machinery/power/energy_accumulator/tesla_coil/anchored, +/obj/structure/cable, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/engineering/supermatter/engine) "rQM" = ( /obj/structure/rack, /obj/item/gps, @@ -70587,10 +70623,6 @@ }, /turf/open/floor/iron/dark, /area/station/medical/surgery) -"rWv" = ( -/obj/effect/spawner/structure/window/reinforced/plasma, -/turf/open/floor/plating, -/area/station/engineering/supermatter/engine) "rWE" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/engine, @@ -72302,6 +72334,25 @@ /obj/item/toy/figure/miner, /turf/open/floor/iron/dark, /area/station/cargo/miningdock) +"sui" = ( +/obj/machinery/airalarm/directional/north, +/obj/effect/mapping_helpers/airalarm/engine_access, +/obj/machinery/button/door/directional/east{ + id = "sm_west"; + name = "Supermatter Chamber Bolt Control"; + normaldoorcontrol = 1; + specialfunctions = 4; + req_access = list("engineering") + }, +/obj/effect/turf_decal/stripes/end{ + dir = 1 + }, +/obj/effect/mapping_helpers/airalarm/link{ + chamber_id = "engine" + }, +/obj/effect/mapping_helpers/airalarm/tlv_no_checks, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "suj" = ( /obj/effect/spawner/random/maintenance, /obj/structure/cable, @@ -73368,6 +73419,18 @@ /obj/effect/spawner/random/trash/grille_or_waste, /turf/open/floor/plating, /area/station/maintenance/department/chapel) +"sKG" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/machinery/door/airlock/engineering/glass/critical{ + heat_proof = 1; + name = "Supermatter Chamber" + }, +/obj/effect/mapping_helpers/airlock/access/all/engineering/general, +/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "sKH" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -73420,14 +73483,6 @@ }, /turf/open/floor/iron/checker, /area/station/hallway/primary/aft) -"sLA" = ( -/obj/machinery/light/small/red/directional/east, -/obj/structure/sign/warning/radiation/directional/east, -/obj/structure/window/reinforced/plasma/spawner/directional/north, -/obj/machinery/power/energy_accumulator/grounding_rod/anchored, -/obj/structure/cable, -/turf/open/floor/catwalk_floor/iron_dark, -/area/station/engineering/supermatter/engine) "sLE" = ( /obj/structure/sign/warning/directional/west, /turf/open/misc/moonstation_rock, @@ -73591,13 +73646,6 @@ }, /turf/open/floor/wood, /area/station/service/chapel) -"sNG" = ( -/obj/effect/turf_decal/stripes/corner, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 8 - }, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "sNI" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/tile/yellow{ @@ -75327,18 +75375,6 @@ }, /turf/open/floor/iron, /area/station/engineering/break_room) -"tlF" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/obj/machinery/door/airlock/engineering/glass/critical{ - heat_proof = 1; - name = "Supermatter Chamber" - }, -/obj/effect/mapping_helpers/airlock/access/all/engineering/general, -/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "tlH" = ( /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/wood, @@ -76053,10 +76089,6 @@ /obj/effect/mapping_helpers/airlock/access/all/engineering/general, /turf/open/floor/plating, /area/station/ai/satellite/maintenance) -"ttW" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "tug" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 4 @@ -76371,6 +76403,22 @@ /obj/effect/turf_decal/tile/neutral/half/contrasted, /turf/open/floor/iron/dark, /area/station/science/server) +"tyy" = ( +/obj/structure/table/reinforced, +/obj/machinery/button/door/directional/west{ + id = "ce_officer_shutters"; + name = "Privacy Shutters Control"; + req_access = list("ce") + }, +/obj/machinery/requests_console/auto_name/directional/north, +/obj/effect/mapping_helpers/requests_console/assistance, +/obj/effect/mapping_helpers/requests_console/supplies, +/obj/effect/mapping_helpers/requests_console/information, +/obj/effect/mapping_helpers/requests_console/announcement, +/obj/effect/turf_decal/tile/neutral, +/obj/machinery/fax/heads/ce, +/turf/open/floor/iron, +/area/station/command/heads_quarters/ce) "tyA" = ( /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/engine, @@ -77377,6 +77425,21 @@ /obj/structure/closet/toolcloset, /turf/open/floor/plating, /area/station/construction) +"tKP" = ( +/obj/structure/table/glass, +/obj/effect/turf_decal/tile/blue/half/contrasted{ + dir = 1 + }, +/obj/machinery/keycard_auth/wall_mounted/directional/north, +/obj/machinery/button/door/directional/north{ + id = "cmo_officer_shutters"; + name = "Privacy Shutters Control"; + pixel_y = 34; + req_access = list("cmo") + }, +/obj/machinery/fax/heads/cmo, +/turf/open/floor/iron/white, +/area/station/command/heads_quarters/cmo) "tKS" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -78263,6 +78326,20 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron/dark, /area/station/commons/lounge) +"tWl" = ( +/mob/living/basic/bot/mulebot, +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=8"; + location = "QM #2"; + name = "QM #2" + }, +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron, +/area/station/cargo/storage) "tWp" = ( /obj/machinery/door/airlock/maintenance_hatch, /obj/effect/mapping_helpers/airlock/access/all/medical/paramedic, @@ -78574,6 +78651,11 @@ /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plating, /area/station/maintenance/port/aft) +"uax" = ( +/obj/effect/turf_decal/stripes/full, +/obj/machinery/power/supermatter_crystal/engine, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "uaI" = ( /obj/machinery/camera/autoname/directional/west, /obj/effect/turf_decal/stripes/line{ @@ -79750,11 +79832,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/department/engine/atmos) -"uqI" = ( -/obj/structure/window/reinforced/plasma/spawner/directional/south, -/obj/machinery/power/energy_accumulator/grounding_rod/anchored, -/turf/open/floor/catwalk_floor/iron_dark, -/area/station/engineering/supermatter/engine) "uqS" = ( /obj/effect/spawner/structure/window/reinforced/plasma, /turf/open/floor/plating, @@ -79948,6 +80025,12 @@ /obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible, /turf/closed/wall/r_wall/rust, /area/station/science/ordnance/burnchamber) +"utx" = ( +/obj/structure/table/wood, +/obj/machinery/keycard_auth/wall_mounted/directional/west, +/obj/machinery/fax/heads/hop, +/turf/open/floor/wood/parquet, +/area/station/command/heads_quarters/hop) "utS" = ( /obj/effect/turf_decal/siding/wood, /obj/structure/table/wood, @@ -80178,6 +80261,10 @@ /obj/structure/closet/emcloset, /turf/open/floor/plating, /area/station/maintenance/department/chapel) +"uxC" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/green/visible, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "uxH" = ( /obj/effect/turf_decal/tile/green/diagonal_centre, /obj/structure/cable, @@ -80273,6 +80360,12 @@ }, /turf/open/floor/iron/dark, /area/station/hallway/secondary/exit/departure_lounge) +"uyq" = ( +/obj/structure/table/wood, +/obj/structure/cable, +/obj/machinery/fax/heads/hos, +/turf/open/floor/wood, +/area/station/command/heads_quarters/hos) "uyA" = ( /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 1 @@ -80489,6 +80582,17 @@ }, /turf/open/floor/iron/dark, /area/station/science/ordnance/testlab) +"uAU" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/green/visible, +/obj/machinery/meter, +/turf/open/floor/engine, +/area/station/engineering/supermatter/engine) "uAY" = ( /obj/effect/turf_decal/siding/dark_blue, /obj/effect/turf_decal/tile/dark_blue/opposingcorners{ @@ -80962,9 +81066,6 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/iron/smooth, /area/mine/laborcamp/production) -"uHs" = ( -/turf/closed/wall/r_wall, -/area/station/engineering/supermatter/engine) "uHy" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/machinery/light/directional/west, @@ -81119,25 +81220,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/department/chapel) -"uIZ" = ( -/obj/machinery/airalarm/directional/north, -/obj/effect/mapping_helpers/airalarm/engine_access, -/obj/machinery/button/door/directional/east{ - id = "sm_west"; - name = "Supermatter Chamber Bolt Control"; - normaldoorcontrol = 1; - specialfunctions = 4; - req_access = list("engineering") - }, -/obj/effect/turf_decal/stripes/end{ - dir = 1 - }, -/obj/effect/mapping_helpers/airalarm/link{ - chamber_id = "engine" - }, -/obj/effect/mapping_helpers/airalarm/tlv_no_checks, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "uJf" = ( /obj/machinery/mech_bay_recharge_port, /obj/effect/mapping_helpers/broken_machine, @@ -82500,10 +82582,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/station/maintenance/fore) -"vdZ" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/green/visible, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "vef" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -82802,12 +82880,6 @@ "vih" = ( /turf/closed/wall/r_wall, /area/station/maintenance/department/engine) -"vik" = ( -/obj/structure/table/glass/plasmaglass, -/obj/machinery/fax/heads/rd, -/obj/item/radio/intercom/directional/west, -/turf/open/floor/carpet/purple, -/area/station/command/heads_quarters/rd) "vin" = ( /obj/machinery/atmospherics/pipe/smart/simple/supply/visible{ dir = 4 @@ -83698,14 +83770,6 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos/control_center) -"vuw" = ( -/obj/machinery/door/poddoor/shutters/radiation/preopen{ - id = "engsm"; - name = "Radiation Chamber Shutters" - }, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/engineering/supermatter/engine) "vux" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -85699,17 +85763,6 @@ }, /turf/open/floor/iron/white, /area/station/security/medical) -"vUM" = ( -/obj/machinery/navbeacon{ - codes_txt = "delivery;dir=8"; - location = "QM #1"; - name = "QM #1" - }, -/mob/living/basic/bot/mulebot, -/obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted, -/turf/open/floor/iron, -/area/station/cargo/storage) "vUN" = ( /obj/structure/table/wood, /obj/effect/landmark/start/hangover, @@ -87215,18 +87268,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/security/prison/upper) -"wph" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/obj/machinery/door/airlock/engineering/glass/critical{ - heat_proof = 1; - name = "Supermatter Chamber" - }, -/obj/effect/mapping_helpers/airlock/access/all/engineering/general, -/obj/machinery/atmospherics/pipe/smart/manifold4w/green/visible, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "wpv" = ( /obj/machinery/holopad, /obj/structure/cable, @@ -87646,6 +87687,14 @@ /obj/item/skillchip/chefs_kiss, /turf/open/floor/iron/kitchen_coldroom/freezerfloor, /area/station/service/kitchen/coldroom) +"wvd" = ( +/obj/machinery/light/small/red/directional/east, +/obj/structure/sign/warning/radiation/directional/east, +/obj/structure/window/reinforced/plasma/spawner/directional/north, +/obj/machinery/power/energy_accumulator/grounding_rod/anchored, +/obj/structure/cable, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/engineering/supermatter/engine) "wvs" = ( /obj/machinery/washing_machine, /obj/effect/turf_decal/tile/neutral/opposingcorners, @@ -87778,14 +87827,6 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/science/robotics/mechbay) -"wxS" = ( -/obj/machinery/light/small/red/directional/west, -/obj/structure/sign/warning/radiation/directional/west, -/obj/structure/window/reinforced/plasma/spawner/directional/north, -/obj/machinery/power/energy_accumulator/grounding_rod/anchored, -/obj/structure/cable, -/turf/open/floor/catwalk_floor/iron_dark, -/area/station/engineering/supermatter/engine) "wxU" = ( /obj/machinery/light/small/directional/west, /obj/machinery/button/door/directional/west{ @@ -88155,20 +88196,6 @@ /obj/effect/landmark/start/science_guard, /turf/open/floor/iron/dark, /area/station/security/checkpoint/science) -"wDe" = ( -/obj/machinery/navbeacon{ - codes_txt = "delivery;dir=8"; - location = "QM #3"; - name = "QM #3" - }, -/mob/living/basic/bot/mulebot, -/obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt/dust, -/turf/open/floor/iron, -/area/station/cargo/storage) "wDl" = ( /obj/effect/spawner/structure/window/reinforced/plasma, /turf/open/floor/plating, @@ -88976,12 +89003,6 @@ /obj/machinery/portable_atmospherics/canister/nitrous_oxide, /turf/open/floor/iron/dark, /area/station/engineering/atmos/storage/gas) -"wOU" = ( -/obj/structure/window/reinforced/plasma/spawner/directional/north, -/obj/machinery/power/energy_accumulator/tesla_coil/anchored, -/obj/structure/cable, -/turf/open/floor/catwalk_floor/iron_dark, -/area/station/engineering/supermatter/engine) "wPk" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -92055,12 +92076,6 @@ /obj/effect/spawner/random/trash/graffiti, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"xDz" = ( -/obj/structure/table/wood, -/obj/item/radio/intercom/command/directional/west, -/obj/machinery/fax/heads/captain, -/turf/open/floor/iron/dark, -/area/station/command/heads_quarters/captain) "xDD" = ( /obj/effect/turf_decal/bot, /obj/machinery/portable_atmospherics/canister/miasma, @@ -92812,15 +92827,6 @@ /obj/effect/decal/cleanable/cobweb/cobweb2, /turf/open/floor/plating, /area/station/maintenance/department/public_mining) -"xOz" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/turf/open/floor/engine, -/area/station/engineering/supermatter/engine) "xOJ" = ( /obj/structure/sign/warning/docking, /turf/closed/wall, @@ -93673,12 +93679,6 @@ }, /turf/open/floor/catwalk_floor/iron_dark, /area/station/maintenance/department/engine/atmos) -"xYe" = ( -/obj/effect/turf_decal/tile/brown/half/contrasted, -/obj/structure/cable, -/obj/structure/reagent_water_basin, -/turf/open/floor/iron/checker, -/area/station/cargo/blacksmith) "xYh" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/machinery/light_switch/directional/west, @@ -246725,7 +246725,7 @@ lYr kCN nCa fAd -mfT +rCB aAE hsu bno @@ -248254,9 +248254,9 @@ tgm lge qWX iQk -wDe -jZx -vUM +dMT +tWl +cAX mQt rVk qRH @@ -250585,7 +250585,7 @@ tGu vJk vJk fhd -xYe +mcw rdH qVN tOR @@ -252560,7 +252560,7 @@ gBj xig fKe bGa -xDz +qSr gcI aoh mfG @@ -253445,7 +253445,7 @@ fxU giJ fxU tdD -pkC +oUw wtd elk gWw @@ -253698,11 +253698,11 @@ wtd wtd tiO dNU -uHs -uHs -wph -uHs -uHs +lHI +lHI +rrJ +lHI +lHI qqz ykI gWw @@ -253955,11 +253955,11 @@ wtd wtd xNF hBt -uHs -uIZ -rxi -oUj -uHs +lHI +sui +uAU +mbV +lHI eVl elk gWw @@ -254211,13 +254211,13 @@ qDR wtd wtd wtd -uHs -uHs -uHs -avN -uHs -uHs -uHs +lHI +lHI +lHI +ouq +lHI +lHI +lHI wtd gWw nur @@ -254438,7 +254438,7 @@ kzR rdH atd rdH -fMW +tyy wMc mEV deR @@ -254468,13 +254468,13 @@ uSo xLD wtd wtd -dig -fWW -vdZ -vdZ -vdZ -wxS -dig +ajy +qyo +uxC +uxC +uxC +oZw +ajy wtd gWw nur @@ -254725,13 +254725,13 @@ kZr wtd wtd sei -vuw -foh -sNG -kCy -mti -wOU -vuw +duq +nFO +ppD +ekD +pRf +rQL +duq dTF ryH mda @@ -254982,13 +254982,13 @@ kZr wtd nmH sei -uHs -uqI -qkO -jOr -acj -jSv -rWv +lHI +bnO +hnF +uax +pea +mbq +cOX nsx gWw aHl @@ -255239,13 +255239,13 @@ kZr wtd sei sei -vuw -foh -bJg -ocd -xOz -wOU -vuw +duq +nFO +emM +hAk +dBJ +rQL +duq hai srP cYu @@ -255496,13 +255496,13 @@ qaW qQW sei wtd -dig -pSI -mtp -ttW -ttW -sLA -dig +ajy +lnz +aPP +bsn +bsn +wvd +ajy sei gWw jqr @@ -255753,13 +255753,13 @@ qDR wtd sei wtd -uHs -uHs -uHs -rvp -uHs -uHs -uHs +lHI +lHI +lHI +juU +lHI +lHI +lHI sei gWw rWE @@ -256011,11 +256011,11 @@ wtd sei lYW nkI -uHs -eTC -mTq -meB -uHs +lHI +qfb +ftr +jzv +lHI vnb sei gWw @@ -256268,11 +256268,11 @@ wtd sei kAA jWl -uHs -uHs -tlF -uHs -uHs +lHI +lHI +sKG +lHI +lHI ofy sei gWw @@ -258211,7 +258211,7 @@ eEr hEi rzN vdv -pJo +utx oPE fJp mni @@ -267769,7 +267769,7 @@ xKu sUv jDL ogo -lbw +tKP txR elY cET @@ -270554,7 +270554,7 @@ stM stM stM eSx -met +uyq lLg lLg lLg @@ -275502,7 +275502,7 @@ dHE nMz jQe cJF -vik +rHs kOd lGH mUA diff --git a/code/__DEFINES/~skyrat_defines/_globalvars/bitfields.dm b/code/__DEFINES/~skyrat_defines/_globalvars/bitfields.dm index 878d62f86ed..79a71e70fa9 100644 --- a/code/__DEFINES/~skyrat_defines/_globalvars/bitfields.dm +++ b/code/__DEFINES/~skyrat_defines/_globalvars/bitfields.dm @@ -1,7 +1,3 @@ -DEFINE_BITFIELD(skyrat_obj_flags, list( - "ANVIL_REPAIR" = ANVIL_REPAIR, -)) - DEFINE_BITFIELD(chemical_flags_skyrat, list( "REAGENT_BLOOD_REGENERATING" = REAGENT_BLOOD_REGENERATING, )) diff --git a/code/__DEFINES/~skyrat_defines/atom_hud.dm b/code/__DEFINES/~skyrat_defines/atom_hud.dm index 9da86c17f4a..cfb8f434dea 100644 --- a/code/__DEFINES/~skyrat_defines/atom_hud.dm +++ b/code/__DEFINES/~skyrat_defines/atom_hud.dm @@ -10,6 +10,8 @@ //SR Nanotrasen #define SECHUD_BLUESHIELD "hudblueshield" #define SECHUD_NT_CONSULTANT "hudnanotrasenconsultant" +//blacksmith +#define SECHUD_BLACKSMITH "hudblacksmith" //SR DS2 #define SECHUD_DS2_DOCTOR "hud_ds2doctor" #define SECHUD_DS2_RESEARCHER "hud_ds2researcher" diff --git a/code/__DEFINES/~skyrat_defines/obj_flags.dm b/code/__DEFINES/~skyrat_defines/obj_flags.dm index a284b21fdc9..279a8637a03 100644 --- a/code/__DEFINES/~skyrat_defines/obj_flags.dm +++ b/code/__DEFINES/~skyrat_defines/obj_flags.dm @@ -2,6 +2,3 @@ #define GENITAL_NEVER_SHOW 1 #define GENITAL_HIDDEN_BY_CLOTHES 2 #define GENITAL_ALWAYS_SHOW 3 - -/// Whether something is repairable by the anvil -#define ANVIL_REPAIR (1<<0) diff --git a/code/__DEFINES/~~bubber_defines/traits/declarations.dm b/code/__DEFINES/~~bubber_defines/traits/declarations.dm index 996a3604681..60e61d96e5d 100644 --- a/code/__DEFINES/~~bubber_defines/traits/declarations.dm +++ b/code/__DEFINES/~~bubber_defines/traits/declarations.dm @@ -14,6 +14,11 @@ // For light weight borgs #define TRAIT_R_LIGHT_WEIGHT "lightweight_borg" +///Characters that know how to make advanced smithing equipment +#define TRAIT_KNOW_ADVANCED_SMITHING "know_advanced_smithing" +#define TRAIT_KNOW_GUNSMITHING "know_gunsmithing" +#define TRAIT_KNOW_CIRCUIT_SMITHING "know_circuit_smithing" + //For the hemophage quirk that allows hemophages to eat/drink normal food/drink. #define TRAIT_MASQUERADE_FOOD "masquerade_food" diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 9252fb0d123..281bdeb9684 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -385,6 +385,9 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_KNOCKEDOUT" = TRAIT_KNOCKEDOUT, "TRAIT_KNOW_ENGI_WIRES" = TRAIT_KNOW_ENGI_WIRES, "TRAIT_KNOW_ROBO_WIRES" = TRAIT_KNOW_ROBO_WIRES, + "TRAIT_KNOW_ADVANCED_SMITHING" = TRAIT_KNOW_ADVANCED_SMITHING, // BUBBER EDIT + "TRAIT_KNOW_GUNSMITHING" = TRAIT_KNOW_GUNSMITHING, // BUBBER EDIT + "TRAIT_KNOW_CIRCUIT_SMITHING" = TRAIT_KNOW_CIRCUIT_SMITHING, // BUBBER EDIT "TRAIT_LIGHTBULB_REMOVER" = TRAIT_LIGHTBULB_REMOVER, "TRAIT_LIGHT_DRINKER" = TRAIT_LIGHT_DRINKER, "TRAIT_LIGHT_STEP" = TRAIT_LIGHT_STEP, diff --git a/code/datums/id_trim/jobs.dm b/code/datums/id_trim/jobs.dm index 9cb057e946e..306ec28398b 100644 --- a/code/datums/id_trim/jobs.dm +++ b/code/datums/id_trim/jobs.dm @@ -1181,6 +1181,7 @@ assignment = JOB_SECURITY_OFFICER_SUPPLY subdepartment_color = COLOR_CARGO_BROWN department_access = list( + ACCESS_BLACKSMITH, //BUBBER EDIT ACCESS_BIT_DEN, ACCESS_CARGO, ACCESS_MINING, diff --git a/code/modules/mob/living/carbon/human/species_types/felinid.dm b/code/modules/mob/living/carbon/human/species_types/felinid.dm index 54af1a4852f..48198757ccc 100644 --- a/code/modules/mob/living/carbon/human/species_types/felinid.dm +++ b/code/modules/mob/living/carbon/human/species_types/felinid.dm @@ -17,6 +17,7 @@ TRAIT_HATED_BY_DOGS, TRAIT_USES_SKINTONES, TRAIT_WATER_HATER, + TRAIT_KNOW_ADVANCED_SMITHING, //BUBBER EDIT ) changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT species_language_holder = /datum/language_holder/felinid 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 6bec6cf0ccd..0dadb131dd0 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -182,6 +182,7 @@ Lizard subspecies: ASHWALKERS inherent_traits = list( TRAIT_MUTANT_COLORS, TRAIT_VIRUSIMMUNE, + TRAIT_KNOW_ADVANCED_SMITHING, //BUBBER EDIT ) inherent_factions = list(FACTION_ASHWALKER) species_language_holder = /datum/language_holder/lizard/ash diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm index 34afa3e4f74..28f61cb29a5 100644 --- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm @@ -6,6 +6,7 @@ inherent_traits = list( TRAIT_MUTANT_COLORS, TRAIT_PLANT_SAFE, + TRAIT_KNOW_ADVANCED_SMITHING, //BUBBER EDIT ) mutant_organs = list( // /obj/item/organ/pod_hair = "None", // SKYRAT EDIT REMOVAL - Customization diff --git a/modular_skyrat/master_files/code/game/objects/items/stacks/sheets/sheet_types.dm b/modular_skyrat/master_files/code/game/objects/items/stacks/sheets/sheet_types.dm index 39c6a565224..46cf798d5e3 100644 --- a/modular_skyrat/master_files/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/modular_skyrat/master_files/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -30,7 +30,6 @@ GLOBAL_LIST_INIT(skyrat_metal_recipes, list( new/datum/stack_recipe("wrestling turnbuckle", /obj/structure/wrestling_corner, 3, time = 2.5 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_STRUCTURE), new/datum/stack_recipe("metal barricade", /obj/structure/deployable_barricade/metal, 2, time = 1 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ON_SOLID_GROUND | CRAFT_CHECK_DIRECTION, category = CAT_STRUCTURE), new/datum/stack_recipe("metal shelf", /obj/structure/rack/shelf, 1, time = 2 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_STRUCTURE), - new/datum/stack_recipe("anvil", /obj/structure/reagent_anvil, 10, time = 2 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_TOOLS), new/datum/stack_recipe("forge", /obj/structure/reagent_forge, 10, time = 2 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_TOOLS), new/datum/stack_recipe("throwing wheel", /obj/structure/throwing_wheel, 10, time = 2 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_TOOLS), )) @@ -71,7 +70,7 @@ GLOBAL_LIST_INIT(skyrat_rod_recipes, list( // Wood GLOBAL_LIST_INIT(skyrat_wood_recipes, list( - new/datum/stack_recipe("water basin", /obj/structure/reagent_water_basin, 5, time = 2 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_TOOLS), + new/datum/stack_recipe("smithing quenching basin", /obj/structure/reagent_dispensers/reagent_smithing_basin, 5, time = 2 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_TOOLS), new/datum/stack_recipe("forging work bench", /obj/structure/reagent_crafting_bench, 5, time = 2 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_TOOLS), new/datum/stack_recipe("wooden half-barricade", /obj/structure/deployable_barricade/wooden, 5, time = 2 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ON_SOLID_GROUND | CRAFT_CHECK_DIRECTION, category = CAT_STRUCTURE), new/datum/stack_recipe("sauna oven", /obj/structure/sauna_oven, 30, time = 1.5 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_ENTERTAINMENT), @@ -161,3 +160,13 @@ GLOBAL_LIST_INIT(skyrat_sand_recipes, list( /obj/item/stack/ore/glass/get_main_recipes() . = ..() . += GLOB.skyrat_sand_recipes + +// Plastitanium + +GLOBAL_LIST_INIT(skyrat_plastitanium_recipes, list( + new/datum/stack_recipe("anvil", /obj/structure/reagent_anvil, 10, time = 2 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_TOOLS), +)) + +/obj/item/stack/sheet/mineral/plastitanium/get_main_recipes() + . = ..() + . += GLOB.skyrat_plastitanium_recipes diff --git a/modular_skyrat/master_files/code/game/objects/objs.dm b/modular_skyrat/master_files/code/game/objects/objs.dm deleted file mode 100644 index 24befc59031..00000000000 --- a/modular_skyrat/master_files/code/game/objects/objs.dm +++ /dev/null @@ -1,3 +0,0 @@ -/obj - ///the skyrat version of obj_flags, to prevent any potential future conflict - var/skyrat_obj_flags = null diff --git a/modular_skyrat/master_files/icons/mob/huds/hud.dmi b/modular_skyrat/master_files/icons/mob/huds/hud.dmi index be0ccdb31a8da546e11d7b7e8ddc1fab932bac91..8b04ebf7573d5c78d331e98e91257d3b1a6190c3 100644 GIT binary patch literal 13584 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 Md2qW#%kIVh03eo(D*ylh literal 14474 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

iw;eg*Z|)q3-n2ua1x^QYgu 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 literal 6094 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 NQ(fm$!3FF4{{e`>>(T%K diff --git a/modular_skyrat/master_files/icons/obj/clothing/belts.dmi b/modular_skyrat/master_files/icons/obj/clothing/belts.dmi index 3f0c755739ef4a81a147a4923860500703f9883a..4470f293b1618ac4740e29cff03bc97cfdf4d913 100644 GIT binary patch literal 8694 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 SKILL_LEVEL_MASTER) +#define USER_CAN_SEE_SMITHING_INFO(user) (user.mind.get_skill_level(/datum/skill/smithing) >= SKILL_LEVEL_JOURNEYMAN) +/// Minimum and maximum force multiplier if a weapon contains incomplete parts +#define MIN_INCOMPLETE_FORGING_SCALING_PENALTY 0.1 +#define MAX_INCOMPLETE_FORGING_SCALING_PENALTY 0.5 +/// The maximum force that can be given to a weapon via perfect hits +#define MAX_PERFECT_FORCE_BONUS 3 +/// maximum force that can be given to a reagent staff via perfect hits +#define MAX_PERFECT_STAFF_INTEG_BONUS 20 +///amount of chems that can be stored into the result +#define MAX_PRE_IMBUE_STORAGE 60 +///amount of chems that the result reads as +#define DEFAULT_IMBUE_STORAGE 10 +#define REAGENT_CLOTHING_INJECT_AMOUNT 0.5 +#define REAGENT_WEAPON_INJECT_AMOUNT 4 +#define REAGENT_STAFF_INJECT_AMOUNT 10 +#define MAX_OIL_AP_AMOUNT 10 +#define PERFECT_ACCESSORY_DURABILITY_BONUS 50 +#define PERFECT_HANDCUFFS_UNLOCK_SPEED_BONUS 2 SECONDS + +#define MAX_QUENCH_HEAT 600 +#define HEAT_GIVEN_FROM_QUENCHING_METAL 300 +#define MIN_VOLUME_TO_QUENCH 300 +#define SMITHING_BASIN_HEATLOSS_COEFFICIENT 0.7 + +#define FORGE_EFFECT_FORCE "forge_effect_force" +#define FORGE_EFFECT_ARMORPEN "forge_effect_armorpen" +#define FORGE_EFFECT_ARMOR "forge_effect_armor" +#define FORGE_EFFECT_DURABILITY "forge_effect_durability" +#define FORGE_EFFECT_BLOCKCHANCE "forge_effect_block" +#define FORGE_EFFECT_REAGENT_INJECT "forge_effect_reagent_inject" +#define FORGE_EFFECT_TOOLSPEED "forge_effect_toolspeed" + +///helper function - given two ratios, a forge effect, an item, and a maximal value, it gives a new modifier and resets the old modifier to the item +/proc/give_added_modifying_effect_to_item(forge_effect, old_modifier, new_modifier, obj/item/item, max_effect) + switch(forge_effect) + if(FORGE_EFFECT_ARMOR) + var/datum/armor/indexed_armor + if(ispath(max_effect)) + indexed_armor = get_armor_by_type(max_effect) + else + indexed_armor = max_effect + + ///WHY does the tgstation implementation have 0-multipler return the source armor? and not return armor/none? + var/datum/armor/new_armor_modifier + if(new_modifier == 0) + new_armor_modifier = new /datum/armor/none + else + new_armor_modifier = indexed_armor.generate_new_with_multipliers(list(ARMOR_ALL = new_modifier)) + var/datum/armor/previous_armor_modifier + if(old_modifier == 0) + previous_armor_modifier = new /datum/armor/none + else + previous_armor_modifier = indexed_armor.generate_new_with_modifiers(list(ARMOR_ALL = new_modifier)) + + var/datum/armor/newarmor = item.get_armor() + newarmor = newarmor.add_other_armor(new_armor_modifier) + newarmor = newarmor.subtract_other_armor(previous_armor_modifier) + item.set_armor(newarmor) + if(FORGE_EFFECT_ARMORPEN) + var/new_armorpen_modifier = new_modifier * max_effect + var/previous_armorpen_modifier = old_modifier * max_effect + item.armour_penetration += new_armorpen_modifier - previous_armorpen_modifier + if(FORGE_EFFECT_BLOCKCHANCE) + var/new_blockchance_modifier = new_modifier * max_effect + var/previous_blockchance_modifier = old_modifier * max_effect + item.block_chance += new_blockchance_modifier - previous_blockchance_modifier + if(FORGE_EFFECT_DURABILITY) + var/new_durability_modifier = new_modifier * max_effect + var/previous_durability_modifier = old_modifier * max_effect + item.modify_max_integrity(item.max_integrity + new_durability_modifier - previous_durability_modifier) + if(FORGE_EFFECT_FORCE) + var/new_force_modifier = new_modifier * max_effect + var/previous_force_modifier = old_modifier * max_effect + item.force += new_force_modifier - previous_force_modifier + if(FORGE_EFFECT_TOOLSPEED) + var/new_toolspeed_modifier = new_modifier * max_effect + var/previous_toolspeed_modifier = old_modifier * max_effect + item.toolspeed += new_toolspeed_modifier - previous_toolspeed_modifier + if(FORGE_EFFECT_REAGENT_INJECT) + var/datum/component/reagent_imbued/reagent_component = item.GetComponent(/datum/component/reagent_imbued/) + if(isnull(reagent_component)) + stack_trace("Reagent inject amount was increased via forging for an item that does not have reagent imbuing!") + + var/new_inject_modifier = new_modifier * max_effect + var/previous_inject_modifier = old_modifier * max_effect + reagent_component.inject_amount += new_inject_modifier - previous_inject_modifier + else + stack_trace("Tried to modify [item] with an invalid effect [forge_effect]!") + +/proc/blacksmithing_change_material_integrity(obj/item/my_item, datum/material/material, amount, multiplier, removing = FALSE) + var/base_modifier = material.get_property(MATERIAL_INTEGRITY) + if(isnull(base_modifier)) + return + + var/integrity_mod = GET_MATERIAL_MODIFIER(base_modifier, multiplier) + var/integrity_change = removing ? floor(my_item.max_integrity / integrity_mod) : ceil(my_item.max_integrity * integrity_mod) + my_item.modify_max_integrity(integrity_change) + + var/list/armor_mods = material.get_armor_modifiers(multiplier) + + //with blacksmithing everything has to be addition based + var/datum/armor/new_armor = get_armor_by_type(my_item.get_initial_armor_type()) + new_armor = new_armor.generate_new_with_multipliers(armor_mods) + new_armor = new_armor.subtract_other_armor(my_item.get_initial_armor_type()) + new_armor = new_armor.generate_new_with_multipliers(list(ARMOR_ALL = 0.3)) //reduce effect because existing armor mults can be too much + + // Invert if we're removing our material + if(!removing) + new_armor = my_item.get_armor().add_other_armor(new_armor) + else + new_armor = my_item.get_armor().subtract_other_armor(new_armor) + my_item.set_armor(new_armor) + +/proc/blacksmithing_change_material_strength(obj/item/my_item, datum/material/material, mat_amount, multiplier, remove = FALSE) + var/density = material.get_property(MATERIAL_DENSITY) + var/hardness = material.get_property(MATERIAL_HARDNESS) + var/flexibility = material.get_property(MATERIAL_FLEXIBILITY) + if(isnull(density) || isnull(hardness) || isnull(flexibility)) + return + + // Item force calculation depends on its initial (assumed to be main) sharpness + // Transforming component doesn't work with materials at all and will need a refactor to change that, so we don't care about it here. + + var/force_mod = 1 + var/throwforce_mod = 1 + + switch (my_item.sharpness) + if (NONE) + // Blunt items are really hurt by all the flexing + force_mod = (1 + (density - 4) * 0.1) / (1 + flexibility * 0.1) + throwforce_mod = 1 + (density - 4) * 0.1 - flexibility * 0.1 + + if (SHARP_EDGED) + // Sharp items don't care about density and need high hardness to get a real bonus, but can tolerate (and benefit from) some flex + force_mod = 1 + (hardness - 4) * 0.1 + throwforce_mod = 1 + (hardness - 4) * 0.1 + + // Peaks out at 20% at flexibility of 1, drops off up to -80% at 10 + if (flexibility < 2) + force_mod *= 1 + (1 - abs(1 - flexibility)) * 0.2 + throwforce_mod += (1 - abs(1 - flexibility)) * 0.2 + else + force_mod *= 1 - (flexibility - 2) * 0.1 + throwforce_mod -= (flexibility - 2) * 0.1 + + if (SHARP_POINTY) + // Pointy items care about both density and hardness + force_mod = 1 + MATERIAL_PROPERTY_DIVERGENCE(density, 4, 6) * 0.05 + (hardness - 4) * 0.1 + throwforce_mod = 1 + MATERIAL_PROPERTY_DIVERGENCE(density, 4, 6) * 0.05 * 0.05 + (hardness - 4) * 0.1 + // But are not affected by flexibility until higher values, although they don't benefit from it either + if (flexibility > 4) + force_mod *= (1 - (flexibility - 4) * 0.2) + throwforce_mod -= (flexibility - 4) * 0.2 + + // Just for sanity in case something breaks + force_mod = clamp(force_mod, MATERIAL_MIN_FORCE_MULTIPLIER, MATERIAL_MAX_FORCE_MULTIPLIER) + throwforce_mod = clamp(throwforce_mod, MATERIAL_MIN_FORCE_MULTIPLIER, MATERIAL_MAX_FORCE_MULTIPLIER) + + // change the forcemod to an added factor instead of a whole multiplier, then reduce the sum effect of the force mod because they currently go too fuggin hard + force_mod = round((force_mod - 1) / 3.5, 0.01) + throwforce_mod = round((throwforce_mod - 1) / 3.5, 0.01) + if (!remove) + my_item.force += initial(my_item.force) * GET_MATERIAL_MODIFIER(force_mod, multiplier) + my_item.throwforce += initial(my_item.force) * GET_MATERIAL_MODIFIER(throwforce_mod, multiplier) + else + my_item.force -= initial(my_item.force) * GET_MATERIAL_MODIFIER(force_mod, multiplier) + my_item.throwforce -= initial(my_item.force) * GET_MATERIAL_MODIFIER(throwforce_mod, multiplier) + +/proc/get_material_quality_points_mult(datum/material/item_material) + //material properties affect forging; high thermal conductivity and flexibility are a bonus while high density and hardness take away + var/density = item_material.get_property(MATERIAL_DENSITY) + var/hardness = item_material.get_property(MATERIAL_HARDNESS) + var/flexibility = item_material.get_property(MATERIAL_FLEXIBILITY) + var/thermal = item_material.get_property(MATERIAL_THERMAL) + + if(isnull(density) || isnull(hardness) || isnull(flexibility) || isnull(thermal)) + return 1 + else + return ((flexibility * 3) + thermal) / (density + hardness) + +///urgh tg needs a get_armor_initial proc, working around protected/private vars is really annoying here +/atom/proc/get_initial_armor_type() + RETURN_TYPE(/datum/armor) + return initial(armor_type) diff --git a/modular_skyrat/modules/reagent_forging/code/anvil.dm b/modular_skyrat/modules/reagent_forging/code/anvil.dm index 1a48e3e4db6..2f954f2ea3f 100644 --- a/modular_skyrat/modules/reagent_forging/code/anvil.dm +++ b/modular_skyrat/modules/reagent_forging/code/anvil.dm @@ -1,3 +1,5 @@ +#define AUTO_SMITHING_SPEED_PENALTY 8 DECISECONDS + /obj/structure/reagent_anvil name = "smithing anvil" desc = "Essentially a big block of metal that you can hammer other metals on top of, crucial for anyone working metal by hand." @@ -6,11 +8,12 @@ anchored = TRUE density = TRUE - custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 10) + custom_materials = list(/datum/material/alloy/plastitanium = SHEET_MATERIAL_AMOUNT * 10) /obj/structure/reagent_anvil/Initialize(mapload) . = ..() - + if(!mapload) + anchored = FALSE AddElement(/datum/element/falling_hazard, damage = 40, wound_bonus = 10, hardhat_safety = FALSE, crushes = TRUE) /obj/structure/reagent_anvil/update_appearance() @@ -26,10 +29,35 @@ /obj/structure/reagent_anvil/examine(mob/user) . = ..() . += span_notice("You can place hot metal objects on this using some tongs.") - . += span_notice("It can be (un)secured with Right Click") + . += span_notice("It can be (un)secured by Right Clicking with your bare hand.") if(length(contents)) - . += span_notice("It has [contents[1]] sitting on it.") + var/obj/my_contents = contents[1] + . += span_notice("It has [my_contents] sitting on it.") + . += span_notice("Left Click with a forging mallet to hammer the metal with precise strikes.") + if(USER_CAN_SEE_SMITHING_INFO(user) && !isnull(my_contents?.GetComponent(/datum/component/forge_smithable))) + var/datum/component/forge_smithable/my_component = my_contents.GetComponent(/datum/component/forge_smithable) + . += span_notice("You'd estimate that it's about [round(my_component.get_completion_ratio() * 100)]% complete.") + . += span_notice("The careful smithing makes it look about [round(my_component.get_perfect_ratio() * 100)]% perfected.") + if(HAS_TRAIT(user, TRAIT_KNOW_ADVANCED_SMITHING)) + . += span_notice("If you strike precisely enough, you can get a perfect hit!") + else + . += span_notice("If you had the right skillchip, you could work the metal to a higher quality...") + . += span_notice("Right Click with a forging mallet to hammer the metal with a steady tempo.") + . += span_notice("You could remove [contents[1]] with some tongs, or your bare hands.") + . += span_notice("You could cut it apart with a welder.") + +/obj/structure/reagent_anvil/attack_hand(mob/living/user, list/modifiers) + . = ..() + if(user.combat_mode) + return SECONDARY_ATTACK_CALL_NORMAL + + if(length(contents) > 0) + var/obj/item/contained_item = contents[1] + user.put_in_hands(contained_item) + balloon_alert(user, "[contained_item] retrieved") + update_appearance() + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN /obj/structure/reagent_anvil/attack_hand_secondary(mob/user, list/modifiers) . = ..() @@ -39,33 +67,49 @@ if(!can_interact(user) || !user.can_perform_action(src)) return + add_fingerprint(user) set_anchored(!anchored) balloon_alert_to_viewers(anchored ? "secured" : "unsecured") return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN -/obj/structure/reagent_anvil/wrench_act(mob/living/user, obj/item/tool) - balloon_alert_to_viewers("deconstructing...") - - if(!do_after(user, 2 SECONDS, src)) - balloon_alert_to_viewers("stopped deconstructing") +/obj/structure/reagent_anvil/welder_act(mob/living/user, obj/item/tool) + if(!tool.tool_start_check(user, amount=2)) return TRUE + add_fingerprint(user) + + if(tool.use_tool(src, user, 2 SECONDS, volume=2)) + new /obj/item/sliced_pipe(drop_location()) + user.visible_message( \ + "[user] welds \the [src] into base components.", \ + span_notice("You weld \the [src] into base components."), \ + span_hear("You hear welding.")) + + deconstruct(TRUE) - tool.play_tool_sound(src) - deconstruct(TRUE) return TRUE /obj/structure/reagent_anvil/atom_deconstruct(disassembled = TRUE) - new /obj/item/stack/sheet/iron/ten(get_turf(src)) + var/obj/item/stack/sheet/my_drop = new /obj/item/stack/sheet/mineral/plastitanium(get_turf(src)) + my_drop.add(9) + if(length(contents)) + for(var/obj/contained in contents) + contained.forceMove(get_turf(src)) return ..() +/obj/structure/reagent_anvil/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(user.combat_mode) + return NONE + + if(!isnull(tool.GetComponent(/datum/component/forge_smithable))) + tool.forceMove(src) + update_appearance() + return ITEM_INTERACT_SUCCESS + return NONE + /obj/structure/reagent_anvil/tong_act(mob/living/user, obj/item/tool) var/obj/item/forging/forge_item = tool + add_fingerprint(user) var/obj/obj_anvil_search = locate() in contents - - if(forge_item.in_use) - balloon_alert(user, "already in use") - return ITEM_INTERACT_SUCCESS - var/obj/obj_tong_search = locate() in forge_item.contents if(obj_anvil_search && !obj_tong_search) obj_anvil_search.forceMove(forge_item) @@ -74,87 +118,57 @@ return ITEM_INTERACT_SUCCESS if(!obj_anvil_search && obj_tong_search) - obj_tong_search.forceMove(src) - update_appearance() - forge_item.icon_state = "tong_empty" - return ITEM_INTERACT_SUCCESS + var/returner = item_interaction(user, obj_tong_search) + if(length(tool.contents) < 1) + forge_item.icon_state = "tong_empty" + return returner + return NONE /obj/structure/reagent_anvil/hammer_act(mob/living/user, obj/item/tool) - conditional_pref_sound(src, 'modular_skyrat/modules/reagent_forging/sound/forge.ogg', vol = 35, vary = TRUE, extrarange = MEDIUM_RANGE_SOUND_EXTRARANGE, ignore_walls = FALSE, pref_to_check = /datum/preference/numeric/volume/sound_ambience_volume) - - //do we have an incomplete item to hammer out? if so, here is our block of code - var/obj/item/forging/incomplete/locate_incomplete = locate() in contents - if(locate_incomplete) - if(locate_incomplete.times_hit >= locate_incomplete.average_hits) //to prevent people from getting perfect perfects - user.balloon_alert(user, "[locate_incomplete] sounds ready") - return ITEM_INTERACT_SUCCESS - - if(COOLDOWN_FINISHED(locate_incomplete, heating_remainder)) - balloon_alert(user, "metal too cool") - locate_incomplete.times_hit -= 3 - return ITEM_INTERACT_SUCCESS - - if(COOLDOWN_FINISHED(locate_incomplete, striking_cooldown)) - var/skill_modifier = user.mind.get_skill_modifier(/datum/skill/smithing, SKILL_SPEED_MODIFIER) * locate_incomplete.average_wait - COOLDOWN_START(locate_incomplete, striking_cooldown, skill_modifier) - locate_incomplete.times_hit++ - if(prob(user.mind.get_skill_modifier(/datum/skill/smithing, SKILL_PROBS_MODIFIER))) - balloon_alert(user, "perfect hit!") - locate_incomplete.current_perfects++ - user.mind.adjust_experience(/datum/skill/smithing, 10) //A perfect hit gives good experience - return ITEM_INTERACT_SUCCESS - - balloon_alert(user, "good hit") - user.mind.adjust_experience(/datum/skill/smithing, 1) //A good hit gives minimal experience - return ITEM_INTERACT_SUCCESS - - locate_incomplete.times_hit -= 3 - balloon_alert(user, "bad hit") - - if(locate_incomplete.times_hit <= -locate_incomplete.average_hits) - balloon_alert_to_viewers("[locate_incomplete] breaks") - qdel(locate_incomplete) - update_appearance() - - return ITEM_INTERACT_SUCCESS - - //okay, so we didn't find an incomplete item to hammer, do we have a hammerable item? + //do we have a hammerable item? + add_fingerprint(user) var/obj/locate_obj = locate() in contents - if(locate_obj && (locate_obj.skyrat_obj_flags & ANVIL_REPAIR)) - // Repairing weapons with imbued reagents takes skill - // God this code is so terrible who the fuck wrote it in two different components that dont share a parent - // I doubt this can be made pretty without skyrat refactoring whatever the fuck all of the stuff around this codeblock is - // BUBBER TODO - Refactor this into two components with same parent! - // - // I'll give you hugs if you refactor it yourself - // ~Waterpig - if(locate_obj.GetComponent(/datum/component/reagent_clothing)) - var/datum/component/reagent_clothing/reagent_component = locate_obj.GetComponent(/datum/component/reagent_clothing) - if(length(reagent_component.imbued_reagent) && user.mind.get_skill_level(/datum/skill/smithing) < SKILL_LEVEL_EXPERT) - to_chat(user, span_danger("You need more experience to repair imbued weapons!")) - return ITEM_INTERACT_SUCCESS - else if(locate_obj.GetComponent(/datum/component/reagent_weapon)) - var/datum/component/reagent_weapon/reagent_component = locate_obj.GetComponent(/datum/component/reagent_weapon) - if(length(reagent_component.imbued_reagent) && user.mind.get_skill_level(/datum/skill/smithing) < SKILL_LEVEL_EXPERT) - to_chat(user, span_danger("You need more experience to repair imbued weapons!")) - return ITEM_INTERACT_SUCCESS - if(locate_obj.get_integrity() >= locate_obj.max_integrity) - balloon_alert(user, "already repaired") + if(!isnull(locate_obj)) + var/datum/component/forge_smithable/smith_component = locate_obj.GetComponent(/datum/component/forge_smithable/) + if(!isnull(smith_component)) + smith_component.anvil_work(user, tool) + update_appearance() return ITEM_INTERACT_SUCCESS - - while(locate_obj.get_integrity() < locate_obj.max_integrity) - if(!do_after(user, 1 SECONDS, src)) - balloon_alert(user, "stopped repairing") - return ITEM_INTERACT_SUCCESS - - locate_obj.repair_damage(locate_obj.get_integrity() + 10) - user.mind.adjust_experience(/datum/skill/smithing, 5) //repairing does give some experience - conditional_pref_sound(src, 'modular_skyrat/modules/reagent_forging/sound/forge.ogg', vol = 35, vary = TRUE, extrarange = MEDIUM_RANGE_SOUND_EXTRARANGE, ignore_walls = FALSE, pref_to_check = /datum/preference/numeric/volume/sound_ambience_volume) - - return ITEM_INTERACT_SUCCESS + update_appearance() + return ITEM_INTERACT_BLOCKING /obj/structure/reagent_anvil/hammer_act_secondary(mob/living/user, obj/item/tool) - hammer_act(user, tool) + if(DOING_INTERACTION(user, DOAFTER_SMITHING_ANVIL)) + return + + var/obj/item/my_anvil_item = contents[1] + var/datum/component/forge_smithable/smith_component = my_anvil_item.GetComponent(/datum/component/forge_smithable) + if(!isnull(my_anvil_item) && !isnull(smith_component)) + if(!should_stop_autohammering()) + balloon_alert_to_viewers("hammering steadily...") + while(!should_stop_autohammering()) + var/wait_between_swings = COOLDOWN_TIMELEFT(user, striking_cooldown) DECISECONDS + wait_between_swings += AUTO_SMITHING_SPEED_PENALTY + + if(!do_after(user, wait_between_swings, target = src, interaction_key = DOAFTER_SMITHING_ANVIL)) + balloon_alert_to_viewers("stopped hammering") + break + else + hammer_act(user, tool) + + return ITEM_INTERACT_SUCCESS + return ITEM_INTERACT_BLOCKING + +/obj/structure/reagent_anvil/proc/should_stop_autohammering() + var/obj/item/forging/incomplete/my_incomplete_item = contents[1] + var/datum/component/forge_smithable/my_forge_component = my_incomplete_item.GetComponent(/datum/component/forge_smithable/) + if(!isnull(my_forge_component)) + if(my_forge_component.is_finished_smithing()) + return TRUE + if(COOLDOWN_FINISHED(my_forge_component, heating_remainder)) + return TRUE + return FALSE + return TRUE /obj/structure/reagent_anvil/onZImpact(turf/impacted_turf, levels, message = TRUE) var/mob/living/poor_target = locate(/mob/living) in impacted_turf @@ -177,3 +191,5 @@ playsound(poor_target, 'sound/effects/magic/clockwork/fellowship_armory.ogg', 50, TRUE) add_memory_in_range(poor_target, 7, /datum/memory/witness_vendor_crush, protagonist = poor_target, antognist = src) return TRUE + +#undef AUTO_SMITHING_SPEED_PENALTY diff --git a/modular_skyrat/modules/reagent_forging/code/cargo_orders.dm b/modular_skyrat/modules/reagent_forging/code/cargo_orders.dm new file mode 100644 index 00000000000..37b748add60 --- /dev/null +++ b/modular_skyrat/modules/reagent_forging/code/cargo_orders.dm @@ -0,0 +1,28 @@ +/datum/supply_pack/misc/smithing_skillchips + name = "Smithing Skillchips Pack" + desc = "Learn the art of metalworking and build your own weapons! Contains two smithing skillchips." + cost = CARGO_CRATE_VALUE * 3 + access = list(ACCESS_WEAPONS) + contains = list(/obj/item/storage/box/skillchips/supply,) + +/datum/supply_pack/misc/singular_smithing_chip + name = "Single Smithing Skillchip" + desc = "Learn the art of metalworking and build your own weapons! Contains one smithing skillchip." + cost = CARGO_CRATE_VALUE * 2 + order_flags = ORDER_GOODY + access = list(ACCESS_WEAPONS) + contains = list(/obj/item/skillchip/job/blacksmith,) + +/datum/supply_pack/misc/blacksmith_starter_pack + name = "Blacksmithing Starter Pack" + desc = "Almost everything one person needs to get to a basic blacksmithing setup. Contains a forge, anvil, cooling basin, crafting bench, two jerrycans of smithing oil, a wall-mounted A/C unit, and a wrench to secure everything to the floor." + cost = CARGO_CRATE_VALUE * 4 + access = list(ACCESS_WEAPONS) + crate_type = /obj/structure/closet/crate/wooden/blacksmith + +/datum/supply_pack/misc/smithing_oil + name = "Smithing Oil Jerrycans" + desc = "Two jerrycans of smithing oil, perfect for quenching freshly-forged metal items." + cost = CARGO_CRATE_VALUE * 2 + access = list(ACCESS_WEAPONS) + contains = list(/obj/item/reagent_containers/cup/jerrycan/smithing_oil,/obj/item/reagent_containers/cup/jerrycan/smithing_oil,) diff --git a/modular_skyrat/modules/reagent_forging/code/container_boxes.dm b/modular_skyrat/modules/reagent_forging/code/container_boxes.dm new file mode 100644 index 00000000000..4b01ca6ecf8 --- /dev/null +++ b/modular_skyrat/modules/reagent_forging/code/container_boxes.dm @@ -0,0 +1,35 @@ +/obj/structure/closet/crate/large/smithing + name = "smithing equipment crate" + desc = "A hefty wooden crate full of smithing equipment. You'll need a crowbar to get it open." + +/obj/structure/closet/crate/large/smithing/PopulateContents() + new /obj/structure/reagent_anvil(src) + new /obj/structure/reagent_crafting_bench(src) + new /obj/structure/reagent_dispensers/reagent_smithing_basin(src) + new /obj/structure/reagent_forge(src) + new /obj/item/reagent_containers/cup/jerrycan/smithing_oil(src) + new /obj/item/reagent_containers/cup/jerrycan/smithing_oil(src) + new /obj/item/wallframe/wall_heater(src) + new /obj/item/wrench + +/obj/structure/closet/crate/wooden/blacksmith + name = "blacksmith's equipment crate" + +/obj/structure/closet/crate/wooden/blacksmith/PopulateContents() + new /obj/item/forging/tongs(src) + new /obj/item/forging/hammer(src) + new /obj/item/forging/billow(src) + var/obj/item/stack/sheet/tempstack = new /obj/item/stack/sheet/mineral/wood(src) + tempstack.add(9) + new /obj/item/stack/sheet/mineral/coal/five(src) + tempstack = new /obj/item/stack/sheet/glass(src) + tempstack.add(9) + new /obj/item/stack/sheet/iron/ten(src) + +/obj/item/storage/box/blacksmith + name = "box of smithing tools" + +/obj/item/storage/box/blacksmith/PopulateContents() + new /obj/item/forging/tongs(src) + new /obj/item/forging/hammer(src) + new /obj/item/forging/billow(src) diff --git a/modular_skyrat/modules/reagent_forging/code/crafting_bench.dm b/modular_skyrat/modules/reagent_forging/code/crafting_bench.dm index cbcf6d536f8..fbfdf7040ee 100644 --- a/modular_skyrat/modules/reagent_forging/code/crafting_bench.dm +++ b/modular_skyrat/modules/reagent_forging/code/crafting_bench.dm @@ -4,6 +4,11 @@ /// The number of hits you are set back when a bad hit is made #define BAD_HIT_PENALTY 3 +#define WEAPON_ASSEMBLY_SPEED 3 SECONDS + +/// how many chains/smithing plates can be contained? +#define MAX_FORGING_COMPLETE_ITEMS 50 + /obj/structure/reagent_crafting_bench name = "forging workbench" desc = "A crafting bench fitted with tools, securing mechanisms, and a steady surface for blacksmithing." @@ -16,113 +21,158 @@ /// What the currently picked recipe is var/datum/crafting_bench_recipe/selected_recipe - /// How many successful hits towards completion of the item have we done - var/current_hits_to_completion = 0 /// Is this bench able to complete forging items? Exists to allow non-forging workbenches to exist var/finishes_forging_weapons = TRUE /// The cooldown from the last hit before we allow another 'good hit' to happen COOLDOWN_DECLARE(hit_cooldown) + /// holds stackables + var/list/stack_item_container = list() + /// holds misc. forging items + var/list/forging_complete_container = list(/obj/item/forging/complete/chain = list(), /obj/item/forging/complete/plate = list()) + /// holds forge item placed on the table via hand, or placed on it via weapon completion + var/obj/item/forged_item_on_surface + /// What recipes are we allowed to choose from? var/list/allowed_choices = list( - /datum/crafting_bench_recipe/plate_helmet, - /datum/crafting_bench_recipe/plate_vest, - /datum/crafting_bench_recipe/plate_gloves, - /datum/crafting_bench_recipe/plate_boots, - /datum/crafting_bench_recipe/horse_shoes, - /datum/crafting_bench_recipe/ring, - /datum/crafting_bench_recipe/collar, - /datum/crafting_bench_recipe/handcuffs, - /datum/crafting_bench_recipe/borer_cage, + /datum/crafting_bench_recipe/wearable/plate_armor/plate_helmet, + /datum/crafting_bench_recipe/wearable/plate_armor/plate_vest, + /datum/crafting_bench_recipe/wearable/plate_armor/plate_gloves, + /datum/crafting_bench_recipe/wearable/plate_armor/plate_boots, + /datum/crafting_bench_recipe/wearable/plate_armor/horse_shoes, + /datum/crafting_bench_recipe/wearable/ring, + /datum/crafting_bench_recipe/wearable/collar, + /datum/crafting_bench_recipe/cowboy_holster, + /datum/crafting_bench_recipe/charging_holster, + /datum/crafting_bench_recipe/crusader_belt, + /datum/crafting_bench_recipe/multi_scabbard, + /datum/crafting_bench_recipe/repairing_scabbard, + /datum/crafting_bench_recipe/knifethrower, + /datum/crafting_bench_recipe/bluespace_plants, /datum/crafting_bench_recipe/pavise, /datum/crafting_bench_recipe/buckler, + /datum/crafting_bench_recipe/bow, + /datum/crafting_bench_recipe/wearable/handcuffs, + /datum/crafting_bench_recipe/revolver, + ////datum/crafting_bench_recipe/borer_cage, /datum/crafting_bench_recipe/coil, /datum/crafting_bench_recipe/seed_mesh, /datum/crafting_bench_recipe/centrifuge, /datum/crafting_bench_recipe/bokken, - /datum/crafting_bench_recipe/bow, /datum/crafting_bench_recipe/empty_circuit, ) /// Radial options for recipes in the allowed_choices list, populated by populate_radial_choice_list var/list/radial_choice_list = list() /// An associative list of names --> recipe path that the radial recipe picker will choose from later var/list/recipe_names_to_path = list() + /// Filters the radial choice list by required skill + var/list/choice_list_skill_filter = list() + /// Filters the radial choice list by required level in its skill; true means corresponding element requires it + var/list/choice_list_skill_level_filter = list() + /// Filters the radial choice list by if it requires the smithing skillchip; true means corresponding element requires it + var/list/choice_list_trait_filter = list() /obj/structure/reagent_crafting_bench/Initialize(mapload) . = ..() + if(!mapload) + anchored = FALSE populate_radial_choice_list() /obj/structure/reagent_crafting_bench/proc/populate_radial_choice_list() - if(!length(allowed_choices)) - return - - if(length(radial_choice_list) && length(recipe_names_to_path)) // We already have both of these and don't need it, if this is called after these are generated for some reason - return + var/datum/radial_menu_choice/option for(var/recipe in allowed_choices) var/datum/crafting_bench_recipe/recipe_to_take_from = new recipe() var/obj/recipe_resulting_item = recipe_to_take_from.resulting_item - radial_choice_list[recipe_to_take_from.recipe_name] = image(icon = initial(recipe_resulting_item.icon), icon_state = initial(recipe_resulting_item.icon_state)) + + option = new + option.image = image(icon = initial(recipe_resulting_item.icon), icon_state = initial(recipe_resulting_item.icon_state)) + option.name = initial(recipe_resulting_item.name) + option.info = initial(recipe_resulting_item.desc) + radial_choice_list[recipe_to_take_from.recipe_name] = option + recipe_names_to_path[recipe_to_take_from.recipe_name] = recipe + choice_list_skill_filter[recipe_to_take_from.recipe_name] = initial(recipe_to_take_from.relevant_skill) + choice_list_skill_level_filter[recipe_to_take_from.recipe_name] = initial(recipe_to_take_from.relevant_skill_level) + choice_list_trait_filter[recipe_to_take_from.recipe_name] = initial(recipe_to_take_from.required_traits) qdel(recipe_to_take_from) /obj/structure/reagent_crafting_bench/examine(mob/user) . = ..() + . += span_notice("You could secure or unsecure it with a wrench.") + . += span_notice("You could pry it apart with a crowbar.") + . += span_notice("You could insert a stack of material into the drawers, or right click to retrieve it later.") - if(length(contents)) - if(istype(contents[1], /obj/item/forging/complete)) - var/obj/item/forging/complete/contained_forge_item = contents[1] - - . += span_notice("[src] has a [initial(contained_forge_item.name)] sitting on it, awaiting completion.
") - var/obj/item/completion_item = contained_forge_item.spawning_item + if(!isnull(forged_item_on_surface)) + if(istype(forged_item_on_surface, /obj/item/forging/complete)) + var/obj/item/forging/complete/complete_item + . += span_notice("[src] has a [initial(complete_item.name)] sitting on it, awaiting completion.
") + var/obj/item/completion_item = complete_item.spawning_item . += span_notice("With [WEAPON_COMPLETION_WOOD_AMOUNT] sheets of wood nearby, and some hammering, it could be completed into a [initial(completion_item.name)].") return // We don't want to show any selected recipes if there's weapon head on the bench + else + if(selected_recipe) + var/obj/resulting_item = selected_recipe.resulting_item + . += span_notice("The selected recipe's resulting item is: [initial(resulting_item.name)]
") + . += span_notice("Gather the required materials, listed below, near the bench, then start hammering to complete it!
") - if(!selected_recipe) - return - - var/obj/resulting_item = selected_recipe.resulting_item - . += span_notice("The selected recipe's resulting item is: [initial(resulting_item.name)]
") - . += span_notice("Gather the required materials, listed below, near the bench, then start hammering to complete it!
") - - if(!length(selected_recipe.recipe_requirements)) - . += span_boldwarning("Somehow, this recipe has no requirements, report this as this shouldn't happen.") - return - - for(var/obj/requirement_item as anything in selected_recipe.recipe_requirements) - if(!selected_recipe.recipe_requirements[requirement_item]) - . += span_boldwarning("[requirement_item] does not have an amount required set, this should not happen, report it.") - continue - - . += span_notice("[selected_recipe.recipe_requirements[requirement_item]] - [initial(requirement_item.name)]") + if(!length(selected_recipe.recipe_requirements)) + . += span_boldwarning("Somehow, this recipe has no requirements, report this as this shouldn't happen.") + return + . += selected_recipe.get_recipe_requirements_description() return . /obj/structure/reagent_crafting_bench/update_appearance(updates) . = ..() cut_overlays() - if(!length(contents)) + if(isnull(forged_item_on_surface)) return - var/image/overlayed_item = image(icon = contents[1].icon, icon_state = contents[1].icon_state) + var/image/overlayed_item + if(isnull(forged_item_on_surface.icon_preview)) + overlayed_item = image(icon = forged_item_on_surface.icon, icon_state = forged_item_on_surface.icon_state) + else + overlayed_item = image(icon = forged_item_on_surface.icon_preview, icon_state = forged_item_on_surface.icon_state_preview) add_overlay(overlayed_item) /obj/structure/reagent_crafting_bench/attack_hand(mob/living/user, list/modifiers) . = ..() select_recipe(user) +/obj/structure/reagent_crafting_bench/attack_hand_secondary(mob/living/user, list/modifiers) + var/temp_list = generate_stack_held_list_radial() + var/option = show_radial_menu(user, src, temp_list, radius = 38, require_near = TRUE, tooltips = TRUE) + + if(!isnull(forging_complete_container[option])) + for(var/obj/item/stored_item in forging_complete_container[option]) + if(stored_item.loc == src) + stored_item.forceMove(get_turf(src)) + else if(!isnull(stack_item_container[option])) + var/obj/item/stack/sheet/output_stack = stack_item_container[option] + stack_item_container[option] = null + if(output_stack.loc == src) + output_stack.forceMove(get_turf(src)) + + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + /obj/structure/reagent_crafting_bench/attack_robot(mob/living/user) . = ..() select_recipe(user) +/obj/structure/reagent_crafting_bench/proc/add_completed_forged_item(obj/item/new_item) + forged_item_on_surface = new_item + forged_item_on_surface.forceMove(src) + /obj/structure/reagent_crafting_bench/proc/select_recipe(mob/living/user) update_appearance() - if(length(contents)) - var/obj/item/contained_item = contents[1] - user.put_in_hands(contained_item) - balloon_alert(user, "[contained_item] retrieved") + if(!isnull(forged_item_on_surface)) + user.put_in_hands(forged_item_on_surface) + forged_item_on_surface = null + balloon_alert(user, "[forged_item_on_surface] retrieved") update_appearance() return @@ -132,7 +182,7 @@ update_appearance() return - var/chosen_recipe = show_radial_menu(user, src, radial_choice_list, radius = 38, require_near = TRUE, tooltips = TRUE) + var/chosen_recipe = show_radial_menu(user, src, get_filtered_radial_choices(user), radius = 38, require_near = TRUE, tooltips = TRUE) if(!chosen_recipe) balloon_alert(user, "no recipe choice") @@ -144,18 +194,86 @@ balloon_alert(user, "recipe chosen") update_appearance() +///Exclusively gives all the radial choices that the user can know how to make. +/obj/structure/reagent_crafting_bench/proc/get_filtered_radial_choices(mob/living/user) + var/returner = list() + if(isnull(user?.mind)) + return returner + + for(var/key,value in radial_choice_list) + if(user_can_craft(user, key)) + returner[key] = value + + return returner + +/obj/structure/reagent_crafting_bench/proc/user_can_craft(mob/living/user, key) + if(isnull(user?.mind)) + return FALSE + if(!isnull(choice_list_skill_filter[key]) && user.mind.get_skill_level(choice_list_skill_filter[key]) < choice_list_skill_level_filter[key]) + return FALSE + if(!isnull(choice_list_trait_filter[key])) + for(var/my_trait in choice_list_trait_filter[key]) + if (!HAS_TRAIT(user, my_trait)) + return FALSE + return TRUE + /// Clears the current recipe and sets hits to completion to zero /obj/structure/reagent_crafting_bench/proc/clear_recipe() QDEL_NULL(selected_recipe) - current_hits_to_completion = 0 -/obj/structure/reagent_crafting_bench/attackby(obj/item/attacking_item, mob/user, params) - if(istype(attacking_item, /obj/item/forging/complete)) - attempt_place(attacking_item, user) +/obj/structure/reagent_crafting_bench/item_interaction(mob/living/user, obj/item/attacking_item, params) + if(istype(attacking_item, /obj/item/forging/complete) && user.combat_mode == FALSE) + var/obj/item/forging/complete/complete_item = attacking_item + if(!isnull(complete_item.spawning_item)) + attempt_place(attacking_item, user) + return TRUE + + if(istype(attacking_item, /obj/item/stack/sheet)) + attempt_stack_storage(attacking_item, user) + return TRUE + + if(!isnull(forging_complete_container[attacking_item.type])) + attempt_complete_item_storage(attacking_item, user) return TRUE return ..() +/obj/structure/reagent_crafting_bench/tong_act(mob/living/user, obj/item/tool) + var/obj/item/forging/forge_item = tool + add_fingerprint(user) + var/obj/obj_tong_search = locate() in forge_item.contents + if(obj_tong_search) + var/returner = item_interaction(user, obj_tong_search) + if(length(tool.contents) < 1) + forge_item.icon_state = "tong_empty" + return returner + else + if(!isnull(forged_item_on_surface)) + if(forged_item_on_surface.loc != src) + forged_item_on_surface.forceMove(forge_item) + forge_item.icon_state = "tong_full" + balloon_alert(user, "took [forged_item_on_surface]") + forged_item_on_surface = null + return ITEM_INTERACT_SUCCESS + else + var/temp_list = generate_stack_held_list_radial() + var/option = show_radial_menu(user, src, temp_list, radius = 38, require_near = TRUE, tooltips = TRUE) + if(user.get_active_held_item() != tool) + if(!isnull(stack_item_container[option])) + var/obj/item/stack/sheet/output_stack = stack_item_container[option] + if(!isnull(output_stack) && output_stack.loc == src) + output_stack.tong_act(user, tool) + return ITEM_INTERACT_SUCCESS + else if(!isnull(forging_complete_container[option]) && length(forging_complete_container[option]) > 0) + var/obj/item/stack/sheet/output_complete = forging_complete_container[option][1] + if(!isnull(output_complete) && output_complete.loc == src) + output_complete.tong_act(user, tool) + return ITEM_INTERACT_SUCCESS + else + balloon_alert(user, "you let go of [tool]!") + + return NONE + /obj/structure/reagent_crafting_bench/mouse_drop_receive(atom/movable/attacking_item, mob/living/user, params) . = ..() if(!isliving(user)) @@ -168,10 +286,11 @@ attempt_place(attacking_item, user) /obj/structure/reagent_crafting_bench/proc/attempt_place(obj/item/attacking_item, mob/user) - if(length(contents)) + if(!isnull(forged_item_on_surface)) balloon_alert(user, "already full") return + forged_item_on_surface = attacking_item attacking_item.forceMove(src) balloon_alert_to_viewers("placed [attacking_item]") update_appearance() @@ -179,76 +298,97 @@ /obj/structure/reagent_crafting_bench/wrench_act(mob/living/user, obj/item/tool) tool.play_tool_sound(src) - deconstruct(disassembled = TRUE) - return ITEM_INTERACT_SUCCESS + set_anchored(!anchored) + balloon_alert_to_viewers(anchored ? "secured" : "unsecured") + return TRUE + +/obj/structure/reagent_crafting_bench/crowbar_act(mob/living/user, obj/item/tool) + tool.play_tool_sound(src) + balloon_alert(user, "pried apart") + deconstruct(TRUE) + return TRUE + +/obj/structure/reagent_crafting_bench/atom_deconstruct(disassembled = TRUE) + if(length(contents)) + for(var/obj/contained in contents) + contained.forceMove(get_turf(src)) + return ..() /obj/structure/reagent_crafting_bench/hammer_act(mob/living/user, obj/item/tool) - conditional_pref_sound(src, 'modular_skyrat/modules/reagent_forging/sound/forge.ogg', vol = 35, vary = TRUE, extrarange = MEDIUM_RANGE_SOUND_EXTRARANGE, ignore_walls = FALSE, pref_to_check = /datum/preference/numeric/volume/sound_ambience_volume) - if(length(contents)) - if(!istype(contents[1], /obj/item/forging/complete)) - balloon_alert(user, "invalid item") - return ITEM_INTERACT_SUCCESS + if(DOING_INTERACTION(user, DOAFTER_SMITHING_ANVIL)) + return - var/obj/item/forging/complete/weapon_to_finish = contents[1] + if(!isnull(forged_item_on_surface)) + return try_weapon_completion(user, tool) - if(!weapon_to_finish.spawning_item) - balloon_alert(user, "[weapon_to_finish] cannot be completed") - return ITEM_INTERACT_SUCCESS + if(check_craftability_general(user, tool) == ITEM_INTERACT_BLOCKING) + return ITEM_INTERACT_BLOCKING - var/list/wood_required_for_weapons = list( - /obj/item/stack/sheet/mineral/wood = WEAPON_COMPLETION_WOOD_AMOUNT, - ) + var/skill_modifier = user.mind.get_skill_modifier(selected_recipe.relevant_skill, SKILL_SPEED_MODIFIER) - if(!can_we_craft_this(wood_required_for_weapons)) - balloon_alert(user, "not enough wood") - return ITEM_INTERACT_SUCCESS - - var/list/things_to_use = can_we_craft_this(wood_required_for_weapons, TRUE) - var/obj/thing_just_made = create_thing_from_requirements(things_to_use, user = user, skill_to_grant = /datum/skill/smithing, skill_amount = 30, completing_a_weapon = TRUE) - - if(!thing_just_made) - message_admins("[src] just tried to finish a weapon but somehow created nothing! This is not working as intended!") - return ITEM_INTERACT_SUCCESS - - balloon_alert_to_viewers("[thing_just_made] created") - update_appearance() - return ITEM_INTERACT_SUCCESS - - if(!selected_recipe) - balloon_alert(user, "no recipe selected") - return ITEM_INTERACT_SUCCESS - - if(!can_we_craft_this(selected_recipe.recipe_requirements)) - balloon_alert(user, "missing ingredients") - return ITEM_INTERACT_SUCCESS - - var/skill_modifier = user.mind.get_skill_modifier(selected_recipe.relevant_skill, SKILL_SPEED_MODIFIER) * 1 SECONDS - - if(!COOLDOWN_FINISHED(src, hit_cooldown)) // If you hit it before the cooldown is done, you get a bad hit, setting you back three good hits - current_hits_to_completion -= BAD_HIT_PENALTY - - if(current_hits_to_completion <= -(selected_recipe.required_good_hits)) - balloon_alert_to_viewers("recipe failed") - clear_recipe() - return ITEM_INTERACT_SUCCESS - - balloon_alert(user, "bad hit") - return ITEM_INTERACT_SUCCESS - - COOLDOWN_START(src, hit_cooldown, skill_modifier) - - if((current_hits_to_completion >= selected_recipe.required_good_hits) && !length(contents)) + playsound(src, 'sound/items/hammering_wood.ogg', 50, vary = TRUE) + if(do_after(user, selected_recipe.time_to_assemble * skill_modifier,target = src, interaction_key = DOAFTER_SMITHING_TABLE) && isnull(forged_item_on_surface)) var/list/things_to_use = can_we_craft_this(selected_recipe.recipe_requirements, TRUE) create_thing_from_requirements(things_to_use, selected_recipe, user, selected_recipe.relevant_skill, selected_recipe.relevant_skill_reward) return ITEM_INTERACT_SUCCESS - current_hits_to_completion++ - balloon_alert(user, "good hit") - user.mind.adjust_experience(selected_recipe.relevant_skill, selected_recipe.relevant_skill_reward / 15) // Good hits towards the current item grants experience in that skill + return ITEM_INTERACT_BLOCKING +/// Takes the given list of item requirements and checks the surroundings for them, returns TRUE unless return_ingredients_list is set, in which case a list of all the items to use is returned +/obj/structure/reagent_crafting_bench/proc/try_weapon_completion(mob/living/user, obj/item/tool) + if(DOING_INTERACTION(user, DOAFTER_SMITHING_TABLE)) + return + + if(!istype(forged_item_on_surface, /obj/item/forging/complete)) + balloon_alert(user, "invalid item") + return ITEM_INTERACT_BLOCKING + + var/obj/item/forging/complete/complete_item = forged_item_on_surface + if(!complete_item.spawning_item) + balloon_alert(user, "[forged_item_on_surface] cannot be completed") + return ITEM_INTERACT_BLOCKING + + var/list/wood_required_for_weapons = list( + /obj/item/stack/sheet/mineral/wood = WEAPON_COMPLETION_WOOD_AMOUNT, + ) + + if(!can_we_craft_this(wood_required_for_weapons)) + balloon_alert(user, "not enough wood") + return ITEM_INTERACT_BLOCKING + + playsound(src, 'sound/items/hammering_wood.ogg', 50, vary = TRUE) + if(!do_after(user, WEAPON_ASSEMBLY_SPEED, target = src, interaction_key = DOAFTER_SMITHING_TABLE)) + return ITEM_INTERACT_BLOCKING + + var/list/things_to_use = can_we_craft_this(wood_required_for_weapons, TRUE) + if(!can_we_craft_this(wood_required_for_weapons)) + balloon_alert(user, "not enough wood") + return ITEM_INTERACT_BLOCKING + + var/obj/thing_just_made = create_thing_from_requirements(things_to_use, user = user, skill_to_grant = /datum/skill/smithing, skill_amount = 30, completing_a_weapon = TRUE) + + if(!thing_just_made) + message_admins("[src] just tried to finish a weapon but somehow created nothing! This is not working as intended!") + return ITEM_INTERACT_SUCCESS + + balloon_alert_to_viewers("[thing_just_made] created") + update_appearance() return ITEM_INTERACT_SUCCESS -/// Takes the given list of item requirements and checks the surroundings for them, returns TRUE unless return_ingredients_list is set, in which case a list of all the items to use is returned +/obj/structure/reagent_crafting_bench/proc/check_craftability_general(mob/living/user, obj/item/tool) + if(!selected_recipe) + balloon_alert(user, "no recipe selected") + return ITEM_INTERACT_BLOCKING + + if(!user_can_craft(user, selected_recipe.recipe_name)) + balloon_alert(user, "you're not skilled enough!") + return ITEM_INTERACT_BLOCKING + + if(!can_we_craft_this(selected_recipe.recipe_requirements)) + balloon_alert(user, "missing ingredients") + return ITEM_INTERACT_BLOCKING + + return ITEM_INTERACT_SUCCESS /obj/structure/reagent_crafting_bench/proc/can_we_craft_this(list/required_items, return_ingredients_list = FALSE) if(!length(required_items)) message_admins("[src] just tried to check for ingredients nearby without having a list of items to check for!") @@ -292,7 +432,7 @@ message_admins("[src] just tried to complete a recipe without having a recipe, and without it being the completion of a forging weapon!") return FALSE - if(completing_a_weapon && (!length(contents) || !istype(contents[1], /obj/item/forging/complete))) + if(completing_a_weapon && isnull(forged_item_on_surface)) message_admins("[src] just tried to complete a forge weapon without there being a weapon head inside it to complete!") return FALSE @@ -303,76 +443,79 @@ if(completing_a_weapon) recipe_to_follow = new /datum/crafting_bench_recipe/weapon_completion_recipe - var/materials_to_transfer = list() - var/list/temporary_materials_list = use_or_delete_recipe_requirements(things_to_use, recipe_to_follow) - for(var/material in temporary_materials_list) - materials_to_transfer[material] += temporary_materials_list[material] - var/obj/newly_created_thing if(completing_a_weapon) - var/obj/item/forging/complete/completed_forge_item = contents[1] - newly_created_thing = new completed_forge_item.spawning_item(src) - if(newly_created_thing.force > 0) //we don't want the staff to get added damage - newly_created_thing.force += min(round(completed_forge_item.current_perfects * INVERSE(10)), 3) //adds a maximum of 3 force, and 6 if dual-wielded - - if(completed_forge_item.custom_materials) // We need to add the weapon head's materials to the completed item, too - for(var/custom_material in completed_forge_item.custom_materials) - materials_to_transfer[custom_material] += completed_forge_item.custom_materials[custom_material] - - qdel(completed_forge_item) // And then we also need to 'use' the item - - else - newly_created_thing = new recipe_to_follow.resulting_item(src) + things_to_use.Add(forged_item_on_surface) + newly_created_thing = recipe_to_follow.create_using_item_list(things_to_use, user, src) if(!newly_created_thing) message_admins("[src] just failed to create something while crafting!") return FALSE - if(recipe_to_follow.transfers_materials) - newly_created_thing.set_custom_materials(materials_to_transfer, multiplier = 1) - user.mind.adjust_experience(skill_to_grant, skill_amount) clear_recipe() update_appearance() return newly_created_thing -/// Takes the given list, things_to_use, compares it to recipe_to_follow's requirements, then either uses items from a stack, or deletes them otherwise. Returns custom material of forge items in the end. -/obj/structure/reagent_crafting_bench/proc/use_or_delete_recipe_requirements(list/things_to_use, datum/crafting_bench_recipe/recipe_to_follow) - var/list/materials_to_transfer = list() - - for(var/obj/requirement_item as anything in things_to_use) - if(isstack(requirement_item)) - var/stack_type - for(var/recipe_thing_to_reference in recipe_to_follow.recipe_requirements) - if(!istype(requirement_item, recipe_thing_to_reference)) - continue - stack_type = recipe_thing_to_reference - break - - var/obj/item/stack/requirement_stack = requirement_item - - if(requirement_stack.amount < recipe_to_follow.recipe_requirements[stack_type]) - recipe_to_follow.recipe_requirements[stack_type] -= requirement_stack.amount - requirement_stack.use(requirement_stack.amount) - continue - - requirement_stack.use(recipe_to_follow.recipe_requirements[stack_type]) - - else if(istype(requirement_item, /obj/item/forging/complete)) - if(!requirement_item.custom_materials || !recipe_to_follow.transfers_materials) - qdel(requirement_item) - continue - - for(var/custom_material in requirement_item.custom_materials) - materials_to_transfer += custom_material - qdel(requirement_item) - +/obj/structure/reagent_crafting_bench/proc/attempt_stack_storage(obj/item/stack/sheet/my_stack, mob/living/user) + var/obj/item/stack/sheet/existing_stack = stack_item_container[my_stack.merge_type] + if(isnull(existing_stack)) + stack_item_container[my_stack.merge_type] = my_stack + my_stack.forceMove(src) + balloon_alert(user, "stashed [my_stack]") + else + if(existing_stack.amount >= existing_stack.max_amount) + balloon_alert(user, "[my_stack] drawer is full!") else - qdel(requirement_item) + my_stack.merge(stack_item_container[my_stack.merge_type]) + balloon_alert(user, "stashed [my_stack]") - return materials_to_transfer +/obj/structure/reagent_crafting_bench/proc/attempt_complete_item_storage(obj/item/forging/complete/complete_item, mob/living/user) + if(length(forging_complete_container[complete_item.type]) >= MAX_FORGING_COMPLETE_ITEMS) + balloon_alert(user, "[initial(complete_item.name)] drawer is full!") + else + forging_complete_container[complete_item.type] += complete_item + complete_item.forceMove(src) + balloon_alert(user, "stashed [initial(complete_item.name)]") + +/obj/structure/reagent_crafting_bench/proc/clear_empty_stacks() + var/obj/item/stack/sheet/my_stack + var/list/my_list + for(var/stack_type in stack_item_container) + my_stack = stack_item_container[stack_type] + if(isnull(my_stack) || my_stack.amount < 1) + stack_item_container.Remove(stack_type) + + for(var/complete_item_type in forging_complete_container) + for(var/obj/item/my_item in forging_complete_container[complete_item_type]) + if(isnull(my_item) || my_item.loc != src) + my_list = forging_complete_container[complete_item_type] + my_list.Remove(my_item) + +/obj/structure/reagent_crafting_bench/proc/generate_stack_held_list_radial() + clear_empty_stacks() + var/list/returner = list() + var/datum/radial_menu_choice/option + var/obj/item/stack/sheet/my_sheet + var/obj/item/forging/complete/my_complete + for(var/complete_type in forging_complete_container) + if(length(forging_complete_container[complete_type]) > 0) + option = new + my_complete = forging_complete_container[complete_type][1] + option.image = image(icon = initial(my_complete.icon), icon_state = initial(my_complete.icon_state)) + option.name = initial(my_complete.name) + option.info = length(forging_complete_container[complete_type]) + returner[complete_type] = option + for(var/stack_type in stack_item_container) + option = new + my_sheet = stack_item_container[stack_type] + option.image = image(icon = initial(my_sheet.icon), icon_state = initial(my_sheet.icon_state)) + option.name = initial(my_sheet.name) + option.info = my_sheet.amount + returner[stack_type] = option + return returner /// Gets movable atoms within one tile of range of the crafting bench /obj/structure/reagent_crafting_bench/proc/get_environment() @@ -389,3 +532,5 @@ #undef WEAPON_COMPLETION_WOOD_AMOUNT #undef BAD_HIT_PENALTY +#undef WEAPON_ASSEMBLY_SPEED +#undef MAX_FORGING_COMPLETE_ITEMS diff --git a/modular_skyrat/modules/reagent_forging/code/crafting_bench_recipes.dm b/modular_skyrat/modules/reagent_forging/code/crafting_bench_recipes.dm index 3699a85ac1f..ae1fb0c215b 100644 --- a/modular_skyrat/modules/reagent_forging/code/crafting_bench_recipes.dm +++ b/modular_skyrat/modules/reagent_forging/code/crafting_bench_recipes.dm @@ -1,18 +1,190 @@ /datum/crafting_bench_recipe + abstract_type = /datum/crafting_bench_recipe /// The name of the recipe to show var/recipe_name = "generic debug recipe" + /// What appears in the infobox when viewed in the crafting menu + var/recipe_desc = "generic debug recipe" /// The items required to create the resulting item var/list/recipe_requirements /// What the end result of this recipe should be var/resulting_item = /obj/item/forging /// If we use the materials from the component parts var/transfers_materials = TRUE - /// How many times should you have to swing the hammer to finish this item - var/required_good_hits = 6 + /// How long it takes at the crafting bench to assemble + var/time_to_assemble = 2 SECONDS /// What skill is relevant to the creation of this item? var/relevant_skill = /datum/skill/smithing + /// How much EXP to give to relevant_skill? + var/exp_give = 5 + /// What skill level is required in that creation? + var/relevant_skill_level = 0 + /// Does the recipe also require a specific trait? + var/required_traits = null /// How much experience in our relevant skill do we give upon completion? var/relevant_skill_reward = 30 + /// Do the crafting pieces go into the result item, or get qdel'd? + var/insert_ingredients_into_product_contents + /// What memory to give upon completion + var/completion_memory_given = null + /// Exp bonus if the player doesn't have a memory of making this + var/first_time_completion_exp_bonus = 70 + /// Is this a multiple item product? + var/multiple_item_result = FALSE + +///Creates the item using the given list of ingredients -- it's assumed that this is only called after the list is verified to contain all ingredients. Probably shouldn't be parent called due to ingredient deletion. +/datum/crafting_bench_recipe/proc/create_using_item_list(list/item_list, mob/living/user, construction_location) + var/obj/item/returner = new resulting_item(construction_location) + apply_perfect_and_completion_bonuses(item_list, returner) + transfer_reagent_imbues_from_ingredients_to_product(item_list, returner, user) + put_materials_in_product_from_ingredients(item_list, returner) + consume_crafting_ingredients(item_list, returner) + move_to_world(returner, construction_location) + give_experience(user) + return returner + +/datum/crafting_bench_recipe/proc/transfer_reagent_imbues_from_ingredients_to_product(list/ingredients, obj/item/product, mob/living/user) + //imbued of the final product should be approx. imbued of all containing products + var/datum/component/reagent_imbued/output_reagent_component = product.GetComponent(/datum/component/reagent_imbued) + var/datum/reagents/my_reagents = combine_reagent_imbues(ingredients) + if(!isnull(output_reagent_component) && USER_CAN_REAGENT_IMBUE(user)) + output_reagent_component.set_reagent_imbue(my_reagents, clear_source_reagents = TRUE) + +/datum/crafting_bench_recipe/proc/combine_reagent_imbues(list/reagent_imbued_items) + var/datum/reagents/reagents_sum = new(maximum = 4096, new_flags = NO_REACT) + var/datum/component/reagent_imbued/current_reagent_component + for(var/obj/item in reagent_imbued_items) + current_reagent_component = item.GetComponent(/datum/component/reagent_imbued) + if(!isnull(current_reagent_component)) + current_reagent_component.imbued_reagent.trans_to(reagents_sum, current_reagent_component.imbued_reagent.total_volume, copy_only = TRUE) + reagents_sum.maximum_volume = reagents_sum.total_volume + return reagents_sum + +/datum/crafting_bench_recipe/proc/put_materials_in_product_from_ingredients(list/ingredients, obj/item/product) + if(transfers_materials) + var/materials_to_transfer = list() + for(var/obj/requirement_item as anything in ingredients) + if(istype(requirement_item, /obj/item/forging/complete)) + if(!requirement_item.custom_materials || !transfers_materials) + continue + + for(var/custom_material in requirement_item.custom_materials) + materials_to_transfer[custom_material] += requirement_item.custom_materials[custom_material] + + product.set_custom_materials(materials_to_transfer, multiplier = 1) + + +/datum/crafting_bench_recipe/proc/consume_crafting_ingredients(list/things_to_use, obj/item/product) + for(var/obj/item/thing in things_to_use) + if(isstack(thing)) + var/obj/item/stack/stack_thing + stack_thing = thing + var/stack_type = stack_thing.merge_type + var/amount_to_subtract = recipe_requirements[stack_type] + if(insert_ingredients_into_product_contents) + var/obj/item/stack/temp_stack = stack_thing.split_stack(amount_to_subtract) + temp_stack.forceMove(product) + else + stack_thing.use(amount_to_subtract, transfer = FALSE, check = TRUE) + else + if(insert_ingredients_into_product_contents) + thing.forceMove(product) + else + qdel(thing) + +/datum/crafting_bench_recipe/proc/count_forgeable_items(things_to_use) + var/total_forge_items = 0 + for(var/obj/item/i in things_to_use) + if(istype(i, /obj/item/forging/complete)) + total_forge_items ++ + else if(!isnull(i.GetComponent(/datum/component/forge_smithable))) + total_forge_items ++ + return total_forge_items + + +/datum/crafting_bench_recipe/proc/get_total_completion_amount(list/things_to_use) + var/total_completion = 0 + for(var/obj/item/i in things_to_use) + if(istype(i, /obj/item/forging/complete)) + var/obj/item/forging/complete/complete_forging_item = i + total_completion += complete_forging_item.hammer_completion_amount + else if(!isnull(i.GetComponent(/datum/component/forge_smithable))) + var/datum/component/forge_smithable/smithing_component = i.GetComponent(/datum/component/forge_smithable) + total_completion += smithing_component.quality_points + return total_completion + +/datum/crafting_bench_recipe/proc/get_total_completion_ratio(list/things_to_use) + if (count_forgeable_items(things_to_use) == 0) + return 1 + return get_total_completion_amount(things_to_use) / count_forgeable_items(things_to_use) + +/datum/crafting_bench_recipe/proc/get_total_perfection_amount(list/things_to_use) + var/total_perfection = 0 + for(var/obj/item/i in things_to_use) + if(istype(i, /obj/item/forging/complete)) + var/obj/item/forging/complete/complete_forging_item = i + total_perfection += complete_forging_item.perfect_ratio + else if(!isnull(i.GetComponent(/datum/component/forge_smithable))) + var/datum/component/forge_smithable/smithing_component = i.GetComponent(/datum/component/forge_smithable) + total_perfection += smithing_component.get_perfect_ratio() + return total_perfection + +/datum/crafting_bench_recipe/proc/get_total_perfection_ratio(list/things_to_use) + if (count_forgeable_items(things_to_use) == 0) + return 1 + return get_total_perfection_amount(things_to_use) / count_forgeable_items(things_to_use) + +/datum/crafting_bench_recipe/proc/find_from_list(list/item_list, type) + for(var/obj/item/forging/complete/temp_item in item_list) + if(istype(temp_item, type)) + return temp_item + return null + +/datum/crafting_bench_recipe/proc/apply_perfect_and_completion_bonuses(list/things_to_use, obj/item/product) + var/pieces_completion_ratio = get_total_completion_ratio(things_to_use) + var/pieces_perfection_ratio = get_total_perfection_ratio(things_to_use) + var/datum/component/forge_smithable/smith_component = product.GetComponent(/datum/component/forge_smithable) + if(!isnull(smith_component)) + smith_component.set_completion_and_perfection_ratios(pieces_completion_ratio, pieces_perfection_ratio) + +/datum/crafting_bench_recipe/proc/get_recipe_requirements_description() + var/list/returner = list() + for(var/obj/requirement_item as anything in recipe_requirements) + if(!recipe_requirements[requirement_item]) + returner += span_boldwarning("[requirement_item] does not have an amount required set, this should not happen, report it.") + continue + + returner += get_ingredient_description(requirement_item) + return returner + +/datum/crafting_bench_recipe/proc/get_ingredient_description(obj/requirement_item) + return span_notice("[recipe_requirements[requirement_item]] - [initial(requirement_item.name)]") + +/datum/crafting_bench_recipe/proc/get_smithing_memory(obj/item/product) + return completion_memory_given + +/datum/crafting_bench_recipe/proc/give_experience(mob/user, item_list, obj/item/product) + if(!isnull(user?.mind)) + var/completion = get_total_completion_ratio(item_list) + var/memory_type = get_smithing_memory(product) + var/memory_bonus_exp = 0 + if(completion >= 1) + if(!isnull(memory_type) && isnull(user?.mind?.memories[memory_type])) + user.add_mob_memory(memory_type, protagonist = user) + memory_bonus_exp = first_time_completion_exp_bonus + + var/exp_give_mult = completion * get_material_quality_points_mult(product.get_master_material()) + user.mind.adjust_experience(relevant_skill, exp_give * exp_give_mult + memory_bonus_exp) + +/datum/crafting_bench_recipe/proc/move_to_world(obj/item/product, place_to_move_to) + if(istype(place_to_move_to, /obj/structure/reagent_crafting_bench)) + var/obj/structure/reagent_crafting_bench/my_bench = place_to_move_to + my_bench.add_completed_forged_item(product) + else + product.forceMove(place_to_move_to) + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////// WEAPON COMPLETION ///////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////// /datum/crafting_bench_recipe/weapon_completion_recipe //Exists so I don't have to modify the code too much for weapon completion recipe_name = "generic weapon completion recipe (should not be visible)" @@ -20,140 +192,377 @@ /obj/item/stack/sheet/mineral/wood = 2, ) -/datum/crafting_bench_recipe/plate_helmet +/datum/crafting_bench_recipe/weapon_completion_recipe/create_using_item_list(list/item_list, mob/living/user, construction_location) + //apparently i fuggin have to write my own version of is_type_in_list + var/obj/item/forging/complete/weapon_head = find_from_list(item_list, /obj/item/forging/complete) + if(isnull(weapon_head)) + stack_trace("[src] didn't contain a valid reagent smithing weapon head when its recipe was completed!") + return + var/obj/item/returner = new weapon_head.spawning_item(construction_location) + apply_perfect_and_completion_bonuses(item_list, returner) + transfer_reagent_imbues_from_ingredients_to_product(item_list, returner, user) + put_materials_in_product_from_ingredients(item_list, returner, user) + give_experience(user, item_list, returner) + move_to_world(returner, construction_location) + + consume_crafting_ingredients(item_list, returner) + return returner + +/datum/crafting_bench_recipe/weapon_completion_recipe/get_smithing_memory(obj/item/product) + //o, the humanity (of code debt that i don't want to bother refactoring) + var/datum/memory/smithing/actual_memory + for(var/smithing_subtype in subtypesof(/datum/memory/smithing)) + actual_memory = new smithing_subtype + if(istype(product, initial(actual_memory.smithed_item_type))) + qdel(actual_memory) + return smithing_subtype + else + qdel(actual_memory) + stack_trace("[product] doesn't have an assigned brain memory type in modular_skyrat/modules/reagent_forging/code/memories.dm !") + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////// ARMOR COMPLETION ////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////// + +/datum/crafting_bench_recipe/wearable/plate_armor/plate_helmet recipe_name = "plate helmet" + recipe_desc = "Protective headgear. Smithing oil and perfected metalworking will make it even more protective." recipe_requirements = list( - /obj/item/forging/complete/plate = 4, + /obj/item/stack/sheet/leather = 1, + /obj/item/forging/complete/plate = 1, ) resulting_item = /obj/item/clothing/head/helmet/forging_plate_helmet - required_good_hits = 8 + time_to_assemble = 1.5 SECONDS + completion_memory_given = /datum/memory/smithing/helmet -/datum/crafting_bench_recipe/plate_vest + +/datum/crafting_bench_recipe/wearable/plate_armor/plate_vest recipe_name = "plate vest" + recipe_desc = "Protective chestplating. Smithing oil and perfected metalworking will make it even more protective." recipe_requirements = list( - /obj/item/forging/complete/plate = 6, + /obj/item/stack/sheet/leather = 1, + /obj/item/forging/complete/plate = 1, ) resulting_item = /obj/item/clothing/suit/armor/forging_plate_armor - required_good_hits = 12 + time_to_assemble = 3 SECONDS + completion_memory_given = /datum/memory/smithing/plate_vest -/datum/crafting_bench_recipe/plate_gloves +/datum/crafting_bench_recipe/wearable/plate_armor/plate_gloves recipe_name = "plate gloves" + recipe_desc = "Protective bracers. Smithing oil and perfected metalworking will make it even more protective." recipe_requirements = list( - /obj/item/forging/complete/plate = 2, + /obj/item/stack/sheet/leather = 1, + /obj/item/forging/complete/plate = 1, ) resulting_item = /obj/item/clothing/gloves/forging_plate_gloves - required_good_hits = 4 + time_to_assemble = 2 SECONDS + completion_memory_given = /datum/memory/smithing/gloves -/datum/crafting_bench_recipe/plate_boots +/datum/crafting_bench_recipe/wearable/plate_armor/plate_boots recipe_name = "plate boots" + recipe_desc = "Protective greaves. Smithing oil and perfected metalworking will make it even more protective." recipe_requirements = list( - /obj/item/forging/complete/plate = 4, + /obj/item/stack/sheet/leather = 1, + /obj/item/forging/complete/plate = 1, ) resulting_item = /obj/item/clothing/shoes/forging_plate_boots - required_good_hits = 8 + time_to_assemble = 2 SECONDS + completion_memory_given = /datum/memory/smithing/boots -/datum/crafting_bench_recipe/horse_shoes +/datum/crafting_bench_recipe/wearable/plate_armor/horse_shoes recipe_name = "horse shoes" + recipe_desc = "Protective... horse shoes? Smithing oil and perfected metalworking will make it even more protective." recipe_requirements = list( - /obj/item/forging/complete/chain = 4, + /obj/item/forging/complete/chain = 1, + /obj/item/stack/sheet/iron = 2, ) resulting_item = /obj/item/clothing/shoes/horseshoe/reagent_clothing - required_good_hits = 8 + time_to_assemble = 1.5 SECONDS + completion_memory_given = /datum/memory/smithing/horseshoes -/datum/crafting_bench_recipe/ring +/datum/crafting_bench_recipe/wearable/ring recipe_name = "ring" + recipe_desc = "A small ring that imbues the wearer with reagents. Perfected metalworking will make it imbue more reagents at once. Smithing oil increases its durability." recipe_requirements = list( - /obj/item/forging/complete/chain = 2, + /obj/item/forging/complete/chain = 1, ) resulting_item = /obj/item/clothing/gloves/ring/reagent_clothing - required_good_hits = 4 + time_to_assemble = 4 SECONDS + completion_memory_given = /datum/memory/smithing/ring -/datum/crafting_bench_recipe/collar +/datum/crafting_bench_recipe/wearable/collar recipe_name = "collar" + recipe_desc = "A small collar that imbues the wearer with reagents. Perfected metalworking will make it imbue more reagents at once. Smithing oil increases its durability." recipe_requirements = list( - /obj/item/forging/complete/chain = 3, + /obj/item/forging/complete/chain = 1, ) resulting_item = /obj/item/clothing/neck/collar/reagent_clothing - required_good_hits = 6 + time_to_assemble = 3 SECONDS + completion_memory_given = /datum/memory/smithing/collar -/datum/crafting_bench_recipe/handcuffs +/datum/crafting_bench_recipe/wearable/handcuffs recipe_name = "handcuffs" + recipe_desc = "A pair of handcuffs; they need to be purged of reagents before they can be used." recipe_requirements = list( - /obj/item/forging/complete/chain = 5, + /obj/item/forging/complete/chain = 1, ) resulting_item = /obj/item/restraints/handcuffs/reagent_clothing - required_good_hits = 10 + time_to_assemble = 5 SECONDS -/datum/crafting_bench_recipe/borer_cage - recipe_name = "cortical borer cage" - recipe_requirements = list( - /obj/item/forging/complete/plate = 6, - ) - resulting_item = /obj/item/cortical_cage - required_good_hits = 12 - -/datum/crafting_bench_recipe/pavise - recipe_name = "pavise" - recipe_requirements = list( - /obj/item/forging/complete/plate = 8, - ) - resulting_item = /obj/item/shield/buckler/reagent_weapon/pavise - required_good_hits = 16 +/////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////// SPECIAL WEAPONS /////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////// /datum/crafting_bench_recipe/buckler recipe_name = "buckler" + recipe_desc = "A small shield. Perfected metalworking will make it more protective. Smithing oil will enhance its stopping power." recipe_requirements = list( - /obj/item/forging/complete/plate = 5, + /obj/item/forging/complete/plate = 1, + /obj/item/stack/sheet/mineral/wood = 2, ) resulting_item = /obj/item/shield/buckler/reagent_weapon - required_good_hits = 10 + time_to_assemble = 3 SECONDS + completion_memory_given = /datum/memory/smithing/buckler -/datum/crafting_bench_recipe/coil - recipe_name = "coil" - recipe_requirements = list( - /obj/item/forging/complete/chain = 2, - ) - resulting_item = /obj/item/forging/coil - required_good_hits = 4 - -/datum/crafting_bench_recipe/seed_mesh - recipe_name = "seed mesh" +/datum/crafting_bench_recipe/pavise + recipe_name = "pavise" + recipe_desc = "A large shield. Perfected metalworking will make it more protective. Smithing oil will enhance its stopping power." recipe_requirements = list( /obj/item/forging/complete/plate = 1, - /obj/item/forging/complete/chain = 2, + /obj/item/stack/sheet/mineral/wood = 4, ) - resulting_item = /obj/item/seed_mesh - required_good_hits = 10 - -/datum/crafting_bench_recipe/centrifuge - recipe_name = "centrifuge" - recipe_requirements = list( - /obj/item/forging/complete/plate = 1, - ) - resulting_item = /obj/item/reagent_containers/cup/primitive_centrifuge - required_good_hits = 4 + resulting_item = /obj/item/shield/buckler/reagent_weapon/pavise + time_to_assemble = 6 SECONDS + completion_memory_given = /datum/memory/smithing/pavise /datum/crafting_bench_recipe/bokken recipe_name = "bokken" + recipe_desc = "A wooden sword, typically meant for practice swordfighting." recipe_requirements = list( /obj/item/stack/sheet/mineral/wood = 4, ) - resulting_item = /obj/item/forging/reagent_weapon/bokken - required_good_hits = 8 + resulting_item = /obj/item/melee/forged_reagent_weapon/bokken + time_to_assemble = 3 SECONDS /datum/crafting_bench_recipe/bow recipe_name = "bow" + recipe_desc = "A length of curved wood attached at both ends with string. Launches arrows." recipe_requirements = list( /obj/item/stack/sheet/mineral/wood = 4, ) resulting_item = /obj/item/forging/incomplete_bow - required_good_hits = 8 + time_to_assemble = 4 SECONDS + +/datum/crafting_bench_recipe/revolver + recipe_name = "revolver" + recipe_desc = "A classical single-action revolver." + recipe_requirements = list( + /obj/item/stack/sheet/mineral/wood = 1, + /obj/item/forging/complete/revolver_cylinder = 1, + /obj/item/forging/complete/revolver_frame = 1 + ) + resulting_item = /obj/item/gun/ballistic/revolver/handcrafted_single_action + time_to_assemble = 4 SECONDS + completion_memory_given = /datum/memory/smithing/revolver + relevant_skill_level = 7 + required_traits = list(TRAIT_KNOW_GUNSMITHING) + +/datum/crafting_bench_recipe/revolver/consume_crafting_ingredients(list/things_to_use, obj/item/product) + var/obj/item/gun/ballistic/revolver/handcrafted_single_action/gun = product + for(var/obj/item/thing in things_to_use) + if(isstack(thing)) + var/obj/item/stack/stack_thing + stack_thing = thing + var/stack_type = stack_thing.type + var/amount_to_subtract = recipe_requirements[stack_type] + if(insert_ingredients_into_product_contents) + var/obj/item/stack/temp_stack = stack_thing.split_stack(amount_to_subtract) + temp_stack.forceMove(product) + else + stack_thing.use(amount_to_subtract, transfer = FALSE, check = TRUE) + else if(istype(thing, /obj/item/forging/complete/revolver_cylinder)) + thing.forceMove(product) + gun.cylinder = thing + else if(istype(thing, /obj/item/forging/complete/revolver_frame)) + thing.forceMove(product) + gun.frame = thing + else + qdel(thing) + product.update_appearance() + +/datum/crafting_bench_recipe/revolver/put_materials_in_product_from_ingredients(list/ingredients, obj/item/product) + if(transfers_materials) + var/materials_to_transfer = list() + for(var/obj/requirement_item as anything in ingredients) + if(istype(requirement_item, /obj/item/forging/complete)) + if(!requirement_item.custom_materials || !transfers_materials) + continue + if(istype(requirement_item, /obj/item/forging/complete/revolver_cylinder)) + product.set_material_slot(/datum/material_slot/revolver/cylinder, requirement_item.get_master_material()) + else + for(var/custom_material in requirement_item.custom_materials) + materials_to_transfer[custom_material] += requirement_item.custom_materials[custom_material] + + product.set_custom_materials(materials_to_transfer, multiplier = 1) + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////// BELT COMPLETION /////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////// +/datum/crafting_bench_recipe/cowboy_holster + recipe_name = "cowboy holster" + recipe_desc = "A quickdraw holster-belt that can additionally store extra ammo boxes." + recipe_requirements = list( + /obj/item/stack/sheet/leather = 3, + /obj/item/stack/sheet/mineral/gold = 1, + /obj/item/stack/sheet/mineral/silver = 1, + ) + resulting_item = /obj/item/storage/belt/hip_holster/cowboy + relevant_skill_level = 5 + time_to_assemble = 3 SECONDS + completion_memory_given = /datum/memory/smithing/cowboy_holster + required_traits = list(TRAIT_KNOW_GUNSMITHING) + +/datum/crafting_bench_recipe/charging_holster + recipe_name = "charging holster" + recipe_desc = "A bluespace holster-belt that can charge electric guns stored in it." + recipe_requirements = list( + /obj/item/stack/sheet/plastic = 1, + /obj/item/stack/sheet/mineral/gold = 1, + /obj/item/stack/sheet/bluespace_crystal = 1, + /obj/item/circuitboard/machine/recharger = 1, + ) + resulting_item = /obj/item/storage/belt/hip_holster/charging + relevant_skill_level = 7 + exp_give = 20 + time_to_assemble = 3 SECONDS + completion_memory_given = /datum/memory/smithing/charging_holster + required_traits = list(TRAIT_KNOW_GUNSMITHING, TRAIT_KNOW_CIRCUIT_SMITHING) + +/datum/crafting_bench_recipe/charging_holster/get_ingredient_description(requirement_item) + //machine boards for weapon rechargers are just called "weapon recharger" so this needs to be clarified + if(requirement_item != /obj/item/circuitboard/machine/recharger) + . = ..() + else + return span_notice("[recipe_requirements[requirement_item]] - machine board (weapon recharger)") + +/datum/crafting_bench_recipe/crusader_belt + recipe_name = "scabbard-utility belt" + recipe_desc = "A belt that holds one sword and has a number of side-pouches for holding miscellaneous items." + recipe_requirements = list( + /obj/item/stack/sheet/leather = 3, + /obj/item/stack/sheet/cloth = 2, + /obj/item/stack/sheet/mineral/gold = 1, + ) + resulting_item = /obj/item/storage/belt/crusader + relevant_skill_level = 4 + time_to_assemble = 3 SECONDS + completion_memory_given = /datum/memory/smithing/crusader_belt + required_traits = list(TRAIT_KNOW_ADVANCED_SMITHING) + +/datum/crafting_bench_recipe/multi_scabbard + recipe_name = "multi-scabbard harness" + recipe_desc = "A set of harnesses that allow the wearer to carry multiple bulky weapons." + recipe_requirements = list( + /obj/item/stack/sheet/leather = 6, + /obj/item/stack/sheet/cloth = 6, + ) + resulting_item = /obj/item/storage/belt/sheath/multi + relevant_skill_level = 4 + time_to_assemble = 3 SECONDS + completion_memory_given = /datum/memory/smithing/multi_scabbard + required_traits = list(TRAIT_KNOW_ADVANCED_SMITHING) + +/datum/crafting_bench_recipe/repairing_scabbard + recipe_name = "repairing scabbard" + recipe_desc = "A belt that holds one weapon and slowly restores its integrity over time." + recipe_requirements = list( + /obj/item/stack/sheet/leather = 3, + /obj/item/stack/sheet/mineral/silver = 1, + /obj/item/stack/sheet/bluespace_crystal = 1, + ) + resulting_item = /obj/item/storage/belt/sheath/repairing + relevant_skill_level = 5 + time_to_assemble = 3 SECONDS + completion_memory_given = /datum/memory/smithing/repairing_scabbard + required_traits = list(TRAIT_KNOW_ADVANCED_SMITHING) + +/datum/crafting_bench_recipe/knifethrower + recipe_name = "knifethrower's belt" + recipe_desc = "A belt that can hold a ton of knives." + recipe_requirements = list( + /obj/item/stack/sheet/leather = 3, + /obj/item/stack/sheet/cloth = 2, + ) + resulting_item = /obj/item/storage/belt/knifethrowers_belt + relevant_skill_level = 4 + time_to_assemble = 3 SECONDS + completion_memory_given = /datum/memory/smithing/knifethrower + required_traits = list(TRAIT_KNOW_ADVANCED_SMITHING) + +/datum/crafting_bench_recipe/bluespace_plants + recipe_name = "bluespace plant bag" + recipe_desc = "A bluespace bag specially designed for holding plants." + recipe_requirements = list( + /obj/item/stack/sheet/cloth = 5, + /obj/item/grown/bananapeel/bluespace = 1, + /obj/item/stack/sheet/bluespace_crystal = 1, + ) + exp_give = 30 + resulting_item = /obj/item/storage/bag/plants/bluespace + relevant_skill_level = 2 + time_to_assemble = 3 SECONDS + completion_memory_given = /datum/memory/smithing/bluespace_plants + required_traits = list(TRAIT_KNOW_CIRCUIT_SMITHING) + + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////// MISC COMPLETION ////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////// + +/datum/crafting_bench_recipe/borer_cage + recipe_name = "cortical borer cage" + recipe_requirements = list( + /obj/item/forging/complete/plate = 3, + ) + resulting_item = /obj/item/cortical_cage + time_to_assemble = 2 SECONDS + + +/datum/crafting_bench_recipe/coil + recipe_name = "coil" + recipe_desc = "A helically-shaped length of metal. Purged of reagents, it is used for crafting other materials." + recipe_requirements = list( + /obj/item/forging/complete/chain = 1, + ) + resulting_item = /obj/item/forging/coil + time_to_assemble = 2 SECONDS + +/datum/crafting_bench_recipe/seed_mesh + recipe_name = "seed mesh" + recipe_desc = "A sifting mesh used to pull seeds from sand. Reagents have no effect on this." + recipe_requirements = list( + /obj/item/forging/complete/plate = 1, + /obj/item/forging/complete/chain = 1, + ) + resulting_item = /obj/item/seed_mesh + time_to_assemble = 10 SECONDS + +/datum/crafting_bench_recipe/centrifuge + recipe_name = "centrifuge" + recipe_desc = "A centrifuge is used to separate reagents in a solution. It typically must be purged of reagents to keep the solution clean." + recipe_requirements = list( + /obj/item/forging/complete/plate = 1, + ) + resulting_item = /obj/item/reagent_containers/cup/primitive_centrifuge + time_to_assemble = 7 SECONDS /datum/crafting_bench_recipe/empty_circuit recipe_name = "circuit" + recipe_desc = "Hand-made circuitry that can be used in electronic devices. Reagents are usually cleaned out before it can function correctly." recipe_requirements = list( /obj/item/forging/complete/plate = 1, /obj/item/forging/coil = 1, ) resulting_item = /obj/item/empty_circuit - required_good_hits = 4 + time_to_assemble = 20 SECONDS + required_traits = list(TRAIT_KNOW_CIRCUIT_SMITHING) diff --git a/modular_skyrat/modules/reagent_forging/code/forge.dm b/modular_skyrat/modules/reagent_forging/code/forge.dm index 7e4263a402f..f0781de4cf0 100644 --- a/modular_skyrat/modules/reagent_forging/code/forge.dm +++ b/modular_skyrat/modules/reagent_forging/code/forge.dm @@ -28,6 +28,10 @@ /// The chance per piece of wood added that charcoal will form later #define CHARCOAL_CHANCE 45 +/// Stats for the expelled gas from running the forge +#define FORGE_FUMES_HEAT FIRE_MINIMUM_TEMPERATURE_TO_EXIST +#define FORGE_FUMES_VOLUME 1 + /// The minimum units of a reagent rerquired to imbue it into a weapon #define MINIMUM_IMBUING_REAGENT_AMOUNT 100 @@ -64,8 +68,6 @@ var/reagent_forging = FALSE /// Cooldown time for processing on the forge COOLDOWN_DECLARE(forging_cooldown) - /// Is the forge in use or not? If true, prevents most interactions with the forge - var/in_use = FALSE /// The current 'level' of the forge, how upgraded is it from zero to three var/forge_level = FORGE_LEVEL_YOU_PLAY_LIKE_A_NOOB /// What smoke particles should be coming out of the forge @@ -76,26 +78,46 @@ var/static/list/choice_list = list( "Chain" = /obj/item/forging/incomplete/chain, "Plate" = /obj/item/forging/incomplete/plate, + "Rapier" = /obj/item/forging/incomplete/rapier, "Sword" = /obj/item/forging/incomplete/sword, "Katana" = /obj/item/forging/incomplete/katana, "Dagger" = /obj/item/forging/incomplete/dagger, - "Rapier" = /obj/item/forging/incomplete/rapier, - "Staff" = /obj/item/forging/incomplete/staff, "Spear" = /obj/item/forging/incomplete/spear, - "Axe" = /obj/item/forging/incomplete/axe, "Hammer" = /obj/item/forging/incomplete/hammer, + "Axe" = /obj/item/forging/incomplete/axe, + "Arrowhead" = /obj/item/forging/incomplete/arrowhead, + "Revolver Frame" = /obj/item/forging/incomplete/revolver_frame, + "Revolver Cylinder" = /obj/item/forging/incomplete/revolver_cylinder, + "Staff" = /obj/item/forging/incomplete/staff, "Pickaxe" = /obj/item/forging/incomplete/pickaxe, "Shovel" = /obj/item/forging/incomplete/shovel, - "Arrowhead" = /obj/item/forging/incomplete/arrowhead, "Rail Nail" = /obj/item/forging/incomplete/rail_nail, "Rail Cart" = /obj/item/forging/incomplete/rail_cart, ) /// List of possible choices for the selection radial var/list/radial_choice_list = list() + /// Filters the radial choice list by required skill + var/list/choice_list_skill_filter = list( + "Revolver Frame" = /datum/skill/smithing, + "Revolver Cylinder" = /datum/skill/smithing, + ) + /// Filters the radial choice list by required level in its skill; true means corresponding element requires it + var/list/choice_list_skill_level_filter = list( + "Revolver Frame" = 7, + "Revolver Cylinder" = 7, + ) + /// Filters the radial choice list by if it requires the smithing skillchip; true means corresponding element requires it + var/list/choice_list_trait_filter = list( + "Revolver Frame" = list(TRAIT_KNOW_GUNSMITHING), + "Revolver Cylinder" = list(TRAIT_KNOW_GUNSMITHING), + ) + /// Descriptions of the forging items in hint bubbles for the radial menu + var/list/radial_choice_hinttext = list() /obj/structure/reagent_forge/examine(mob/user) . = ..() - + . += span_notice("You could secure or unsecure it with a wrench.") + . += span_notice("You could pry it apart with a crowbar.") if(used_tray) . += span_notice("It has [used_tray] in it, which can be removed with an empty hand.") else @@ -149,6 +171,8 @@ /obj/structure/reagent_forge/Initialize(mapload) . = ..() + if(!mapload) + anchored = FALSE START_PROCESSING(SSobj, src) populate_radial_choice_list() update_appearance() @@ -162,9 +186,38 @@ if(length(radial_choice_list)) return + var/obj/resulting_item + var/datum/radial_menu_choice/option for(var/forge_option in choice_list) - var/obj/resulting_item = choice_list[forge_option] - radial_choice_list[forge_option] = image(icon = initial(resulting_item.icon), icon_state = initial(resulting_item.icon_state)) + resulting_item = choice_list[forge_option] + option = new + option.image = image(icon = initial(resulting_item.icon), icon_state = initial(resulting_item.icon_state)) + option.name = initial(resulting_item.name) + option.info = initial(resulting_item.desc) + radial_choice_list[forge_option] = option + +///Exclusively gives all the radial choices that the user can know how to make. +/obj/structure/reagent_forge/proc/get_filtered_radial_choices(mob/living/user) + var/returner = list() + if(isnull(user?.mind)) + return returner + + for(var/key,value in radial_choice_list) + if(user_can_craft(user, key)) + returner[key] = value + + return returner + +/obj/structure/reagent_forge/proc/user_can_craft(mob/living/user, key) + if(isnull(user?.mind)) + return FALSE + if(!isnull(choice_list_skill_filter[key]) && user.mind.get_skill_level(choice_list_skill_filter[key]) < choice_list_skill_level_filter[key]) + return FALSE + if(!isnull(choice_list_trait_filter[key])) + for(var/my_trait in choice_list_trait_filter[key]) + if (!HAS_TRAIT(user, my_trait)) + return FALSE + return TRUE /obj/structure/reagent_forge/Destroy() STOP_PROCESSING(SSobj, src) @@ -182,30 +235,23 @@ add_overlay(gold_overlay) if(used_tray) // If we have a tray inside, check if the forge is on or not, then give the corresponding tray overlay - var/image/tray_overlay = image(icon = icon, icon_state = "forge_tray_[check_fuel(just_checking = TRUE) ? "active" : "inactive"]") + var/image/tray_overlay = image(icon = icon, icon_state = "forge_tray_[check_fuel(0) ? "active" : "inactive"]") add_overlay(tray_overlay) /// Checks if the forge has fuel, if so what type. If it has either type of fuel, returns TRUE, otherwise returns FALSE. just_checking will check if there is fuel without taking actions -/obj/structure/reagent_forge/proc/check_fuel(just_checking = FALSE) - if(forge_fuel_strong) // Check for strong fuel (coal) first, as it has more power over weaker fuels - if(just_checking) - return TRUE +/obj/structure/reagent_forge/proc/check_fuel(time_to_reduce_by = 0) + if(forge_fuel_strong > 0) // Check for strong fuel (coal) first, as it has more power over weaker fuels - forge_fuel_strong -= 5 SECONDS + forge_fuel_strong -= time_to_reduce_by target_temperature = 100 return TRUE - if(forge_fuel_weak) // If there's no strong fuel, maybe we have weak fuel (wood) - if(just_checking) - return TRUE + if(forge_fuel_weak > 0) // If there's no strong fuel, maybe we have weak fuel (wood) - forge_fuel_weak -= 5 SECONDS + forge_fuel_weak -= time_to_reduce_by target_temperature = 50 return TRUE - if(just_checking) - return FALSE - target_temperature = minimum_target_temperature // If the forge has no fuel, then we should lowly return to the minimum lowest temp we can do return FALSE @@ -216,32 +262,17 @@ reagent_forging = TRUE update_appearance() -/// Creates both a fail message balloon alert, and sets in_use to false -/obj/structure/reagent_forge/proc/fail_message(mob/living/user, message) - balloon_alert(user, message) - in_use = FALSE /// Adjust the temperature to head towards the target temperature, changing icon and creating light if the temperature is rising -/obj/structure/reagent_forge/proc/check_temp() +/obj/structure/reagent_forge/proc/check_temp(seconds_per_tick) if(forge_temperature > target_temperature) // Being above the target temperature will cause the forge to cool down - forge_temperature -= (FORGE_DEFAULT_TEMPERATURE_CHANGE - temperature_loss_reduction) + forge_temperature -= (FORGE_DEFAULT_TEMPERATURE_CHANGE - temperature_loss_reduction) * seconds_per_tick return else if((forge_temperature < target_temperature) && (forge_fuel_weak || forge_fuel_strong)) // Being below the target temp, and having fuel, will cause the temp to rise - forge_temperature += FORGE_DEFAULT_TEMPERATURE_CHANGE + forge_temperature += FORGE_DEFAULT_TEMPERATURE_CHANGE * seconds_per_tick return -/// If the forge is in use, checks if there is an oven tray, then if there are any mobs actually in use range. If not sets the forge to not be in use. -/obj/structure/reagent_forge/proc/check_in_use() - if(!in_use) - return - - if(used_tray) // We check if there's a tray because trays inside of the forge count as it being in use, even if nobody is around - return - - for(var/mob/living/living_mob in range(1,src)) - if(!living_mob) - in_use = FALSE /// Spawns a piece of coal at the forge and renames it to charcoal /obj/structure/reagent_forge/proc/spawn_coal() @@ -249,26 +280,29 @@ spawn_coal.name = "charcoal" /obj/structure/reagent_forge/process(seconds_per_tick) + /* if(!COOLDOWN_FINISHED(src, forging_cooldown)) return - COOLDOWN_START(src, forging_cooldown, 5 SECONDS) - check_fuel() - check_temp() - check_in_use() // This is here to ensure the forge doesn't remain in_use if it really isn't + COOLDOWN_START(src, forging_cooldown, 5 SECONDS) */ + check_fuel(seconds_per_tick) + check_temp(seconds_per_tick) + try_expel_gas(seconds_per_tick) - - - if(!used_tray && check_fuel(just_checking = TRUE)) + if(!used_tray && check_fuel()) set_smoke_state(SMOKE_STATE_NOT_COOKING) // If there is no tray but we have fuel, use the not cooking smoke state return - if(!check_fuel(just_checking = TRUE)) // If there's no fuel, remove it all + if(!check_fuel()) // If there's no fuel, remove it all set_smoke_state(SMOKE_STATE_NONE) return handle_baking_things(seconds_per_tick) +/obj/structure/reagent_forge/proc/try_expel_gas(seconds_per_tick) + if(check_fuel()) + atmos_spawn_air("[GAS_CO2]=[FORGE_FUMES_VOLUME * seconds_per_tick];[TURF_TEMPERATURE(FORGE_FUMES_HEAT)]") + /// Sends signals to bake and items on the used tray, setting the smoke state of the forge according to the most cooked item in it /obj/structure/reagent_forge/proc/handle_baking_things(seconds_per_tick) if(forge_temperature < MIN_FORGE_TEMP) // If we are below minimum forge temp, don't continue on to cooking @@ -422,12 +456,8 @@ smelt_ore(attacking_item, user) return - if(attacking_item.GetComponent(/datum/component/reagent_weapon)) - handle_weapon_imbue(attacking_item, user) - return - - if(attacking_item.GetComponent(/datum/component/reagent_clothing)) - handle_clothing_imbue(attacking_item, user) + if(attacking_item.GetComponent(/datum/component/reagent_imbued/weapon)) + handle_reagent_imbue(attacking_item, user) return /obj/structure/reagent_forge/attackby(obj/item/attacking_item, mob/living/user, params) @@ -435,10 +465,8 @@ add_tray_to_forge(user, attacking_item) return TRUE - if(in_use) // If the forge is currently in use by someone (or there is a tray in it) then we cannot use it - if(used_tray) - balloon_alert(user, "remove [used_tray] first") - balloon_alert(user, "forge busy") + if(used_tray) + balloon_alert(user, "remove [used_tray] first") return TRUE if(istype(attacking_item, /obj/item/stack/sheet/mineral/wood)) // Wood is a weak fuel, and will only get the forge up to 50 temperature @@ -453,12 +481,14 @@ smelt_ore(attacking_item, user) return TRUE - if(attacking_item.GetComponent(/datum/component/reagent_weapon)) - handle_weapon_imbue(attacking_item, user) + if(attacking_item.GetComponent(/datum/component/reagent_imbued) && attacking_item.reagents.total_volume > 1) + handle_reagent_imbue(attacking_item, user) return TRUE - if(attacking_item.GetComponent(/datum/component/reagent_clothing)) - handle_clothing_imbue(attacking_item, user) + if(attacking_item.GetComponent(/datum/component/forge_smithable)) + var/datum/component/forge_smithable/mycomponent = attacking_item.GetComponent(/datum/component/forge_smithable) + mycomponent.heat_for_smithing(FORGE_HEATING_DURATION) + balloon_alert(user, "heated [attacking_item]") return TRUE if(istype(attacking_item, /obj/item/ceramic)) @@ -473,6 +503,9 @@ handle_metal_cup_melting(attacking_item, user) return TRUE + if(istype(attacking_item, /obj/item/stack)) + stack_item_to_forgeable(user, attacking_item, burn_hand = TRUE) + return TRUE return ..() /// Take the given tray and place it inside the forge, updating everything relevant to that @@ -490,7 +523,6 @@ balloon_alert_to_viewers("put [tray] in [src]") used_tray = tray - in_use = TRUE // You can't use the forge if there's a tray sitting in it update_appearance() /// Take the used_tray and spit it out, updating everything relevant to that @@ -506,34 +538,28 @@ else used_tray.forceMove(get_turf(src)) used_tray = null - in_use = FALSE /// Adds to either the strong or weak fuel timers from the given stack /obj/structure/reagent_forge/proc/refuel(obj/item/stack/refueling_stack, mob/living/user, is_strong_fuel = FALSE) - in_use = TRUE if(is_strong_fuel) if(forge_fuel_strong >= 5 MINUTES) - fail_message(user, "[src] is full on coal") + balloon_alert(user, "[src] is full on coal") return if(forge_fuel_weak >= 5 MINUTES) - fail_message(user, "[src] is full on wood") + balloon_alert(user, "[src] is full on wood") return - balloon_alert_to_viewers("refueling...") - var/obj/item/stack/sheet/stack_sheet = refueling_stack - if(!do_after(user, 3 SECONDS, target = src) || !stack_sheet.use(1)) - fail_message(user, "stopped fueling") + if(!stack_sheet.use(1)) + balloon_alert(user, "not enough fuel") return if(is_strong_fuel) forge_fuel_strong += 5 MINUTES else forge_fuel_weak += 5 MINUTES - in_use = FALSE balloon_alert(user, "fueled [src]") - user.mind.adjust_experience(/datum/skill/smithing, 5) // You gain small amounts of experience from useful fueling if(prob(CHARCOAL_CHANCE) && !is_strong_fuel) to_chat(user, span_notice("[src]'s fuel is packed densely enough to have made some charcoal!")) @@ -541,22 +567,22 @@ /// Takes given ore and smelts it, possibly producing extra sheets if upgraded /obj/structure/reagent_forge/proc/smelt_ore(obj/item/stack/ore/ore_item, mob/living/user) - in_use = TRUE - + if(DOING_INTERACTION(user, DOAFTER_SMITHING_FORGE)) + return if(forge_temperature < MIN_FORGE_TEMP) - fail_message(user, "forge too cool") + balloon_alert(user, "forge too cool") return var/skill_modifier = user.mind.get_skill_modifier(/datum/skill/smithing, SKILL_SPEED_MODIFIER) if(!ore_item.refined_type) - fail_message(user, "cannot smelt [ore_item]") + balloon_alert(user, "cannot smelt [ore_item]") return balloon_alert_to_viewers("smelting...") - if(!do_after(user, skill_modifier * 3 SECONDS, target = src)) - fail_message(user, "stopped smelting [ore_item]") + if(!do_after(user, skill_modifier * 3 SECONDS, target = src, interaction_key = DOAFTER_SMITHING_FORGE)) + balloon_alert(user, "stopped smelting [ore_item]") return var/src_turf = get_turf(src) @@ -566,119 +592,60 @@ for(var/spawn_ore in 1 to ore_to_sheet_amount) new spawning_item(src_turf) - in_use = FALSE qdel(ore_item) return -/// Handles weapon reagent imbuing -/obj/structure/reagent_forge/proc/handle_weapon_imbue(obj/attacking_item, mob/living/user) - if(user.mind.get_skill_level(/datum/skill/smithing) < SKILL_LEVEL_MASTER) - to_chat(user, span_danger("You need more experience to understand the fine workings of imbuing!")) - return - //This code will refuse all non-ashwalkers & non-icecats from imbuing - if(!ishuman(user)) - to_chat(user, span_danger("It is impossible for you to imbue!")) //maybe remove (ashwalkers & icecats only) after some time +/// Handles reagent imbuing +/obj/structure/reagent_forge/proc/handle_reagent_imbue(obj/attacking_item, mob/living/user) + if(!USER_CAN_REAGENT_IMBUE(user)) + to_chat(user, span_danger("You don't know the right trick to imbue this weapon!")) return - in_use = TRUE - balloon_alert_to_viewers("imbuing...") + if(attacking_item?.reagents?.total_volume < 1) + to_chat(user, span_danger("You need to coat the blade in a reagent before you can imbue it!")) + return - var/obj/item/attacking_weapon = attacking_item + if(DOING_INTERACTION(user, DOAFTER_SMITHING_FORGE)) + return - var/datum/component/reagent_weapon/weapon_component = attacking_weapon.GetComponent(/datum/component/reagent_weapon) + var/datum/component/reagent_imbued/weapon_component = attacking_item.GetComponent(/datum/component/reagent_imbued) if(!weapon_component) - fail_message(user, "cannot imbue") + balloon_alert(user, "[attacking_item] is unimbueable!") return - if(length(weapon_component.imbued_reagent)) - fail_message(user, "already imbued") - return - - if(!do_after(user, 10 SECONDS, target = src)) - fail_message(user, "stopped imbuing") - return - - for(var/datum/reagent/weapon_reagent as anything in attacking_weapon.reagents.reagent_list) - if(weapon_reagent.volume < MINIMUM_IMBUING_REAGENT_AMOUNT) - attacking_weapon.reagents.remove_reagent(weapon_reagent.type) - continue - - weapon_component.imbued_reagent += weapon_reagent.type - attacking_weapon.name = "[weapon_reagent.name] [attacking_weapon.name]" - - attacking_weapon.color = mix_color_from_reagents(attacking_weapon.reagents.reagent_list) - if(attacking_weapon.armour_penetration < 10) - attacking_weapon.armour_penetration = 0 - else - attacking_weapon.armour_penetration -= 10 - balloon_alert_to_viewers("imbued [attacking_weapon]") - user.mind.adjust_experience(/datum/skill/smithing, 60) - playsound(src, 'sound/effects/magic/demon_consume.ogg', 50, TRUE) - in_use = FALSE - return TRUE - -/// Handles clothing imbuing, extremely similar to weapon imbuing but not in the same proc because of how uhh... goofy the way this has to be done is -/obj/structure/reagent_forge/proc/handle_clothing_imbue(obj/attacking_item, mob/living/user) - if(user.mind.get_skill_level(/datum/skill/smithing) < SKILL_LEVEL_MASTER) - to_chat(user, span_danger("You need more experience to understand the fine workings of imbuing!")) - return - //This code will refuse all non-ashwalkers & non-icecats from imbuing - if(!ishuman(user)) - to_chat(user, span_danger("It is impossible for you to imbue!")) //maybe remove (ashwalkers & icecats only) after some time - return - - in_use = TRUE balloon_alert_to_viewers("imbuing...") - var/obj/item/attacking_clothing = attacking_item - - var/datum/component/reagent_clothing/clothing_component = attacking_clothing.GetComponent(/datum/component/reagent_clothing) - if(!clothing_component) - fail_message(user, "cannot imbue") + if(!do_after(user, 10 SECONDS, target = src, interaction_key = DOAFTER_SMITHING_FORGE)) + balloon_alert(user, "stopped imbuing") return - if(length(clothing_component.imbued_reagent)) - fail_message(user, "already imbued") - return + if(USER_CAN_REAGENT_IMBUE(user)) + weapon_component.set_reagent_imbue(attacking_item.reagents, clear_source_reagents = TRUE) - if(!do_after(user, 10 SECONDS, target = src)) - fail_message(user, "stopped imbuing") - return - - for(var/datum/reagent/clothing_reagent as anything in attacking_clothing.reagents.reagent_list) - if(clothing_reagent.volume < MINIMUM_IMBUING_REAGENT_AMOUNT) - attacking_clothing.reagents.remove_reagent(clothing_reagent.type, include_subtypes = TRUE) - continue - - clothing_component.imbued_reagent += clothing_reagent.type - attacking_clothing.name = "[clothing_reagent.name] [attacking_clothing.name]" - - attacking_clothing.color = mix_color_from_reagents(attacking_clothing.reagents.reagent_list) - balloon_alert_to_viewers("imbued [attacking_clothing]") - user.mind.adjust_experience(/datum/skill/smithing, 60) + balloon_alert_to_viewers("imbued [attacking_item]") playsound(src, 'sound/effects/magic/demon_consume.ogg', 50, TRUE) - in_use = FALSE return TRUE /// Sets ceramic items from their unusable state into their finished form /obj/structure/reagent_forge/proc/handle_ceramics(obj/attacking_item, mob/living/user) - in_use = TRUE + if(DOING_INTERACTION(user, DOAFTER_SMITHING_FORGE)) + return if(forge_temperature < MIN_FORGE_TEMP) - fail_message(user, "forge too cool") + balloon_alert(user, "forge too cool") return var/obj/item/ceramic/ceramic_item = attacking_item var/ceramic_speed = user.mind.get_skill_modifier(/datum/skill/production, SKILL_SPEED_MODIFIER) * BASELINE_ACTION_TIME if(!ceramic_item.forge_item) - fail_message(user, "cannot set [ceramic_item]") + balloon_alert(user, "cannot set [ceramic_item]") return balloon_alert_to_viewers("setting [ceramic_item]") - if(!do_after(user, ceramic_speed, target = src)) - fail_message("stopped setting [ceramic_item]") + if(!do_after(user, ceramic_speed, target = src, interaction_key = DOAFTER_SMITHING_FORGE)) + balloon_alert(user, "stopped setting [ceramic_item]") return balloon_alert(user, "finished setting [ceramic_item]") @@ -686,14 +653,13 @@ user.mind.adjust_experience(/datum/skill/production, 50) spawned_ceramic.color = ceramic_item.color qdel(ceramic_item) - in_use = FALSE /// Handles the creation of molten glass from glass sheets /obj/structure/reagent_forge/proc/handle_glass_sheet_melting(obj/attacking_item, mob/living/user) - in_use = TRUE - + if(DOING_INTERACTION(user, DOAFTER_SMITHING_FORGE)) + return if(forge_temperature < MIN_FORGE_TEMP) - fail_message(user, "forge too cool") + balloon_alert(user, "forge too cool") return var/obj/item/stack/sheet/glass/glass_item = attacking_item @@ -702,11 +668,10 @@ balloon_alert_to_viewers("heating...") - if(!do_after(user, glassblowing_speed, target = src) || !glass_item.use(1)) - fail_message(user, "stopped heating [glass_item]") + if(!do_after(user, glassblowing_speed, target = src, interaction_key = DOAFTER_SMITHING_FORGE) || !glass_item.use(1)) + balloon_alert(user, "stopped heating [glass_item]") return - in_use = FALSE var/obj/item/glassblowing/molten_glass/spawned_glass = new /obj/item/glassblowing/molten_glass(get_turf(src)) user.mind.adjust_experience(/datum/skill/production, 10) COOLDOWN_START(spawned_glass, remaining_heat, glassblowing_amount) @@ -714,10 +679,10 @@ /// Handles creating molten glass from a metal cup filled with sand /obj/structure/reagent_forge/proc/handle_metal_cup_melting(obj/attacking_item, mob/living/user) - in_use = TRUE - + if(DOING_INTERACTION(user, DOAFTER_SMITHING_FORGE)) + return if(forge_temperature < MIN_FORGE_TEMP) - fail_message(user, "forge too cool") + balloon_alert(user, "forge too cool") return var/obj/item/glassblowing/metal_cup/metal_item = attacking_item @@ -725,16 +690,15 @@ var/glassblowing_amount = BASELINE_HEATING_DURATION / user.mind.get_skill_modifier(/datum/skill/production, SKILL_SPEED_MODIFIER) if(!metal_item.has_sand) - fail_message(user, "[metal_item] has no sand") + balloon_alert(user, "[metal_item] has no sand") return balloon_alert_to_viewers("heating...") - if(!do_after(user, glassblowing_speed, target = src)) - fail_message(user, "stopped heating [metal_item]") + if(!do_after(user, glassblowing_speed, target = src, interaction_key = DOAFTER_SMITHING_FORGE)) + balloon_alert(user, "stopped heating [metal_item]") return - in_use = FALSE metal_item.has_sand = FALSE metal_item.icon_state = "metal_cup_empty" // This should be handled a better way but presently this is how it works var/obj/item/glassblowing/molten_glass/spawned_glass = new /obj/item/glassblowing/molten_glass(get_turf(src)) @@ -743,160 +707,183 @@ spawned_glass.total_time = glassblowing_amount /obj/structure/reagent_forge/billow_act(mob/living/user, obj/item/tool) - if(in_use) // Preventing billow use if the forge is in use to prevent spam - fail_message(user, "forge busy") - return ITEM_INTERACT_SUCCESS + if(DOING_INTERACTION(user, DOAFTER_SMITHING_FORGE)) + return var/skill_modifier = user.mind.get_skill_modifier(/datum/skill/smithing, SKILL_SPEED_MODIFIER) var/obj/item/forging/forge_item = tool - in_use = TRUE - if(!forge_fuel_strong && !forge_fuel_weak) - fail_message(user, "no fuel in [src]") + balloon_alert(user, "no fuel in [src]") return ITEM_INTERACT_SUCCESS if(forge_temperature >= MAX_FORGE_TEMP) - fail_message(user, "[src] cannot heat further") + balloon_alert(user, "[src] cannot heat further") return ITEM_INTERACT_SUCCESS balloon_alert_to_viewers("billowing...") while(forge_temperature < 91) - if(!do_after(user, skill_modifier * forge_item.toolspeed, target = src)) + if(!do_after(user, skill_modifier * forge_item.toolspeed * 15 DECISECONDS, target = src, interaction_key = DOAFTER_SMITHING_FORGE)) balloon_alert_to_viewers("stopped billowing") return ITEM_INTERACT_SUCCESS forge_temperature += 10 - user.mind.adjust_experience(/datum/skill/smithing, 5) // Billowing, like fueling, gives you some experience in forging - in_use = FALSE balloon_alert(user, "successfully heated [src]") return ITEM_INTERACT_SUCCESS /obj/structure/reagent_forge/tong_act(mob/living/user, obj/item/tool) - var/skill_modifier = user.mind.get_skill_modifier(/datum/skill/smithing, SKILL_SPEED_MODIFIER) - var/obj/item/forging/forge_item = tool - - if(in_use || forge_item.in_use) - fail_message(user, "forge busy") - return ITEM_INTERACT_SUCCESS - - in_use = TRUE - forge_item.in_use = TRUE + if(DOING_INTERACTION(user, DOAFTER_SMITHING_FORGE)) + return + var/obj/item/tongs_contents = locate(/obj/item/) in tool.contents if(forge_temperature < MIN_FORGE_TEMP) - fail_message(user, "forge too cool") - forge_item.in_use = FALSE - return ITEM_INTERACT_SUCCESS + balloon_alert(user, "forge too cool") + return ITEM_INTERACT_BLOCKING // Here we check the item used on us (tongs) for an incomplete forge item of some kind to heat - var/obj/item/forging/incomplete/search_incomplete = locate(/obj/item/forging/incomplete) in forge_item.contents - if(search_incomplete) - balloon_alert_to_viewers("heating [search_incomplete]") - - if(!do_after(user, skill_modifier * forge_item.toolspeed, target = src)) - balloon_alert_to_viewers("stopped heating [search_incomplete]") - forge_item.in_use = FALSE - return ITEM_INTERACT_SUCCESS - - COOLDOWN_START(search_incomplete, heating_remainder, FORGE_HEATING_DURATION) - in_use = FALSE - forge_item.in_use = FALSE - user.mind.adjust_experience(/datum/skill/smithing, 5) // Heating up forge items grants some experience - balloon_alert(user, "successfully heated [search_incomplete]") + var/datum/component/forge_smithable/smithable = tongs_contents?.GetComponent(/datum/component/forge_smithable) + if(!isnull(smithable)) + smithable.heat_for_smithing(FORGE_HEATING_DURATION) + balloon_alert(user, "heated [tongs_contents]") return ITEM_INTERACT_SUCCESS // Here we check the item used on us (tongs) for a stack of some kind to create an object from - var/obj/item/stack/search_stack = locate(/obj/item/stack) in forge_item.contents + var/obj/item/stack/search_stack = locate(/obj/item/stack) in tool.contents if(search_stack) - var/user_choice = show_radial_menu(user, src, radial_choice_list, radius = 38, require_near = TRUE, tooltips = TRUE) - if(!user_choice) - fail_message(user, "nothing chosen") - forge_item.in_use = FALSE - return ITEM_INTERACT_SUCCESS + return stack_item_to_forgeable(user, search_stack, tool) - // Sets up a list of the materials to give to the item later - var/list/material_list = list() - - if(search_stack.material_type) - material_list[SSmaterials.get_material(search_stack.material_type)] = SHEET_MATERIAL_AMOUNT - - else - for(var/material in search_stack.custom_materials) - material_list[material] = SHEET_MATERIAL_AMOUNT - - if(!search_stack.use(1)) - fail_message(user, "not enough of [search_stack]") - forge_item.in_use = FALSE - return ITEM_INTERACT_SUCCESS - - balloon_alert_to_viewers("heating [search_stack]") - - if(!do_after(user, skill_modifier * forge_item.toolspeed, target = src)) - balloon_alert_to_viewers("stopped heating [search_stack]") - forge_item.in_use = FALSE - return ITEM_INTERACT_SUCCESS - - var/spawn_item = choice_list[user_choice] - var/obj/item/forging/incomplete/incomplete_item = new spawn_item(get_turf(src)) - - if(material_list) - incomplete_item.set_custom_materials(material_list) - - COOLDOWN_START(incomplete_item, heating_remainder, FORGE_HEATING_DURATION) - in_use = FALSE - forge_item.in_use = FALSE - balloon_alert(user, "prepared [search_incomplete] into [user_choice]") - search_stack = locate(/obj/item/stack) in forge_item.contents - - if(!search_stack) - forge_item.icon_state = "tong_empty" - return ITEM_INTERACT_SUCCESS - - in_use = FALSE - forge_item.in_use = FALSE return ITEM_INTERACT_SUCCESS +/obj/structure/reagent_forge/proc/stack_item_to_forgeable(mob/living/user, obj/item/stack/search_stack, obj/item/tool = null, burn_hand = FALSE) + if(DOING_INTERACTION(user, DOAFTER_SMITHING_FORGE)) + return + + if(forge_temperature < MIN_FORGE_TEMP) + balloon_alert(user, "forge too cool") + return ITEM_INTERACT_BLOCKING + + if(values_sum(search_stack.mats_per_unit) < SHEET_MATERIAL_AMOUNT) + balloon_alert(user, "not enough material in [search_stack]") + return ITEM_INTERACT_BLOCKING + + var/list/my_list = get_filtered_radial_choices(user) + var/user_choice = show_radial_menu(user, src, my_list, radius = 38, require_near = TRUE, tooltips = TRUE) + var/skill_modifier = user.mind.get_skill_modifier(/datum/skill/smithing, SKILL_SPEED_MODIFIER) + + if(!user_choice) + balloon_alert(user, "nothing chosen") + return ITEM_INTERACT_BLOCKING + + // Sets up a list of the materials to give to the item later + var/list/material_list = list() + + if(search_stack.material_type) + material_list[SSmaterials.get_material(search_stack.material_type)] = SHEET_MATERIAL_AMOUNT + + else + for(var/material in search_stack.custom_materials) + material_list[material] = SHEET_MATERIAL_AMOUNT + + if(search_stack.amount < 1) + balloon_alert(user, "not enough of [search_stack]") + return ITEM_INTERACT_BLOCKING + + balloon_alert_to_viewers("heating [search_stack]") + + if(!burn_hand) + if(!isnull(tool)) + if(!do_after(user, skill_modifier * tool.toolspeed * 2 SECONDS, target = src, interaction_key = DOAFTER_SMITHING_FORGE)) + balloon_alert_to_viewers("stopped heating [search_stack]") + return ITEM_INTERACT_BLOCKING + else + stack_trace("[src] had its 'make forgeable item' function called, with burn_hand = false and tool = null! This should never happen!") + else + to_chat(user, span_warning("Heating the [search_stack] without equipment seems like a bad idea...")) + if(!do_after(user, skill_modifier * 5 SECONDS, target = src, interaction_key = DOAFTER_SMITHING_FORGE)) + balloon_alert_to_viewers("stopped heating [search_stack]") + return ITEM_INTERACT_BLOCKING + + var/hand_protected = FALSE + var/mob/living/carbon/human/human_user = user + if(!istype(human_user) || HAS_TRAIT(human_user, TRAIT_RESISTHEAT) || HAS_TRAIT(human_user, TRAIT_RESISTHEATHANDS)) + hand_protected = TRUE + else if(!istype(human_user.gloves, /obj/item/clothing/gloves)) + hand_protected = FALSE + else + var/obj/item/clothing/gloves/gloves = human_user.gloves + if(gloves.max_heat_protection_temperature) + hand_protected = (gloves.max_heat_protection_temperature > 360) + if(!hand_protected) + var/hitzone = user.held_index_to_dir(user.active_hand_index) == "r" ? BODY_ZONE_PRECISE_R_HAND : BODY_ZONE_PRECISE_L_HAND + user.apply_damage(35, BURN, hitzone) + playsound(src, 'sound/effects/wounds/sizzle1.ogg', 50, TRUE) + to_chat(user, span_danger("You burn your hand putting [search_stack] in [src]!")) + user.add_mood_event("burnt_thumb", /datum/mood_event/burnt_thumb) + + if(!search_stack.use(1)) + balloon_alert(user, "not enough of [search_stack]") + return ITEM_INTERACT_BLOCKING + + var/spawn_item = choice_list[user_choice] + var/obj/item/forging/incomplete/incomplete_item = new spawn_item(get_turf(src)) + + if(material_list) + incomplete_item.set_custom_materials(material_list) + + var/datum/component/forge_smithable/smith_component = incomplete_item.GetComponent(/datum/component/forge_smithable) + if(!isnull(smith_component)) + COOLDOWN_START(smith_component, heating_remainder, FORGE_HEATING_DURATION) + + balloon_alert(user, "prepared [search_stack] into [user_choice]") + if(!isnull(tool) && length(tool.contents) > 0) + tool.icon_state = "tong_empty" + + return ITEM_INTERACT_SUCCESS + + /obj/structure/reagent_forge/blowrod_act(mob/living/user, obj/item/tool) + if(DOING_INTERACTION(user, DOAFTER_SMITHING_FORGE)) + return var/obj/item/glassblowing/blowing_rod/blowing_item = tool var/glassblowing_speed = user.mind.get_skill_modifier(/datum/skill/production, SKILL_SPEED_MODIFIER) * BASELINE_ACTION_TIME var/glassblowing_amount = BASELINE_HEATING_DURATION / user.mind.get_skill_modifier(/datum/skill/production, SKILL_SPEED_MODIFIER) - if(in_use) - to_chat(user, span_warning("You cannot do multiple things at the same time!")) - return ITEM_INTERACT_SUCCESS - in_use = TRUE - if(forge_temperature < MIN_FORGE_TEMP) - fail_message(user, "The temperature is not hot enough to start heating [blowing_item].") + balloon_alert(user, "not hot enough to start heating [blowing_item]") return ITEM_INTERACT_SUCCESS var/obj/item/glassblowing/molten_glass/find_glass = locate() in blowing_item.contents if(!find_glass) - fail_message(user, "[blowing_item] does not have any glass to heat up.") + balloon_alert(user, "[blowing_item] does not have any glass to heat up.") return ITEM_INTERACT_SUCCESS if(!COOLDOWN_FINISHED(find_glass, remaining_heat)) - fail_message(user, "[find_glass] is still has remaining heat.") + balloon_alert(user, "[find_glass] is still has remaining heat.") return ITEM_INTERACT_SUCCESS to_chat(user, span_notice("You begin heating up [blowing_item].")) - if(!do_after(user, glassblowing_speed, target = src)) - fail_message(user, "[blowing_item] is interrupted in its heating process.") + if(!do_after(user, glassblowing_speed, target = src, interaction_key = DOAFTER_SMITHING_FORGE)) + balloon_alert(user, "[blowing_item] is interrupted in its heating process.") return ITEM_INTERACT_SUCCESS COOLDOWN_START(find_glass, remaining_heat, glassblowing_amount) find_glass.total_time = glassblowing_amount to_chat(user, span_notice("You finish heating up [blowing_item].")) - user.mind.adjust_experience(/datum/skill/smithing, 5) user.mind.adjust_experience(/datum/skill/production, 10) - in_use = FALSE return ITEM_INTERACT_SUCCESS /obj/structure/reagent_forge/wrench_act(mob/living/user, obj/item/tool) tool.play_tool_sound(src) + set_anchored(!anchored) + balloon_alert_to_viewers(anchored ? "secured" : "unsecured") + return TRUE + +/obj/structure/reagent_forge/crowbar_act(mob/living/user, obj/item/tool) + tool.play_tool_sound(src) + balloon_alert(user, "pried apart") deconstruct(TRUE) return TRUE @@ -959,3 +946,6 @@ #undef SMOKE_STATE_NEUTRAL #undef SMOKE_STATE_BAD #undef SMOKE_STATE_NOT_COOKING + +#undef FORGE_FUMES_HEAT +#undef FORGE_FUMES_VOLUME diff --git a/modular_skyrat/modules/reagent_forging/code/forge_belts.dm b/modular_skyrat/modules/reagent_forging/code/forge_belts.dm new file mode 100644 index 00000000000..78a031cc7d5 --- /dev/null +++ b/modular_skyrat/modules/reagent_forging/code/forge_belts.dm @@ -0,0 +1,542 @@ +//////////////////////////////////////////////////////////////////////////// +////////////////////////////// HOLSTERS //////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// + +//can't be a subtype of item/storage/belt/holster -- that can be suit storaged per \code\__DEFINES\inventory.dm +//hip holsters SHOULDN'T be able to be suit storaged. +/obj/item/storage/belt/hip_holster + name = "hip holster" + desc = "you shouldn't be seeing this." + abstract_type = /obj/item/storage/belt/hip_holster + icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_clothing.dmi' + icon_state = "cowboy_holster" + inhand_icon_state = "holster" + worn_icon_state = "holster" + alternate_worn_layer = null + storage_type = /datum/storage/holster + +/obj/item/storage/belt/hip_holster/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs) + . = ..() + update_label() +/obj/item/storage/belt/hip_holster/Exited(atom/movable/gone, direction) + . = ..() + update_label() +/obj/item/storage/belt/hip_holster/proc/update_label(list/contents_to_check = null) + if(isnull(contents_to_check)) + contents_to_check = contents + var/list/noteworthy_contents = list() + for(var/obj/item/I in contents_to_check) + if(!istype(I, /obj/item/ammo_box)) + noteworthy_contents += I + + if(length(noteworthy_contents) > 0) + name = "[src::name] containing [english_list(noteworthy_contents)]" + else + name = src::name + +//copy of the holster/equipped proc. +/obj/item/storage/belt/hip_holster/equipped(mob/user, slot) + . = ..() + if(slot & (ITEM_SLOT_BELT|ITEM_SLOT_SUITSTORE)) + ADD_CLOTHING_TRAIT(user, TRAIT_GUNFLIP) + +/obj/item/storage/belt/hip_holster/update_overlays() + . = ..() + . += get_guns_contained_overlays() + +/obj/item/storage/belt/hip_holster/proc/get_guns_contained_overlays(list/contents_to_check = null) + var/list/returner = list() + if(contents_to_check == null) + contents_to_check = contents + for(var/obj/item/I in contents_to_check) + if(istype(I, /obj/item/gun/ballistic/revolver)) + returner += mutable_appearance('modular_skyrat/modules/reagent_forging/icons/obj/forge_clothing.dmi', "belt_gun_wood") + return returner + if(istype(I, /obj/item/gun)) + returner += mutable_appearance('modular_skyrat/modules/reagent_forging/icons/obj/forge_clothing.dmi', "belt_gun_black") + return returner + if(istype(I, /obj/item/melee/baton/security)) + returner += mutable_appearance('modular_skyrat/modules/reagent_forging/icons/obj/forge_clothing.dmi', "belt_gun_baton") + return returner + +/obj/item/storage/belt/hip_holster/cowboy + name = "quickdraw holster" + desc = "A rugged leather belt. Can carry a handgun; the holster pouch makes it like reflex to draw your gun. Also comes with some side pockets for speedloaders and magazines." + icon_state = "cowboy_holster" + inhand_icon_state = "utility" + worn_icon_state = "utility" + storage_type = /datum/storage/cowboy_holster + +/datum/storage/cowboy_holster + max_slots = 4 + max_total_storage = 6 + open_sound = 'sound/items/handling/holster_open.ogg' + open_sound_vary = TRUE + +/datum/storage/cowboy_holster/New(atom/parent, max_slots, max_specific_storage, max_total_storage, rustle_sound, remove_rustle_sound, list/holdables) + . = ..() + if(length(holdables)) + set_holdable(holdables) + return + + set_holdable(list( + /obj/item/food/grown/banana, + /obj/item/gun/ballistic/automatic/pistol, + /obj/item/gun/ballistic/revolver, + /obj/item/gun/energy/disabler, + /obj/item/gun/energy/dueling, + /obj/item/gun/energy/e_gun/hos, + /obj/item/gun/energy/e_gun/mini, + /obj/item/gun/energy/laser/captain, + /obj/item/gun/energy/laser/pistol, + /obj/item/gun/energy/laser/thermal, + /obj/item/ammo_box/advanced/s12gauge, + /obj/item/ammo_box/magazine, + /obj/item/ammo_box/speedloader, + )) + +/datum/storage/cowboy_holster/attempt_insert(obj/item/to_insert, mob/user, override = FALSE, force = STORAGE_NOT_LOCKED, messages = TRUE) + . = ..() + sort_contents() + refresh_views() + //parent.update_appearance() + +//resorts the contents so that guns are always the first thing pulled. +/datum/storage/cowboy_holster/proc/sort_contents() + var/list/gunz = list() + var/list/everything_else = list() + var/obj/parent_obj = parent + if(!isnull(parent_obj)) + for(var/obj/item/i in parent_obj.contents) + if(istype(i, /obj/item/gun/)) + gunz += i + else + everything_else += i + parent_obj.contents = everything_else + gunz + +///////////////////////////////////////////////// + +/obj/item/storage/belt/hip_holster/charging + name = "charging holster" + desc = "A sophisticated plastic holster belt. Bluespace tech allows it to store almost anything a standard weapon charger can; it can slowly charge that item." + icon_state = "charger_belt" + inhand_icon_state = "security" + worn_icon_state = "security" + storage_type = /datum/storage/charging_holster //null //datum/storage/charging_holster + var/obj/machinery/recharger/belt_charger/my_charger + var/obj/item/storage/box/real_storage + +/obj/item/storage/belt/hip_holster/charging/Initialize(mapload) + my_charger = new(src) + my_charger.my_belt = src + real_storage = new(src) + . = ..() + +/obj/item/storage/belt/hip_holster/charging/Destroy() + QDEL_NULL(my_charger) + QDEL_NULL(real_storage) + . = ..() + +/obj/item/storage/belt/hip_holster/charging/update_label(list/contents_to_check = null) + . = ..(real_storage.contents) + +/obj/item/storage/belt/hip_holster/charging/get_guns_contained_overlays(list/contents_to_check = null) + . = ..(real_storage.contents) + +/obj/item/storage/belt/hip_holster/charging/update_overlays() + . = ..() + if(length(real_storage?.contents) > 0) + if(!isnull(my_charger?.charging)) + var/icon_to_use = "charger_belt_[(my_charger.using_power ? "charging" : "fullcharge")]" + . += mutable_appearance(icon, icon_to_use, alpha = src.alpha) + else + . += mutable_appearance(icon, "charger_belt_precharging") + +/datum/storage/charging_holster + max_slots = 1 + max_total_storage = 12 + open_sound = 'sound/items/handling/holster_open.ogg' + open_sound_vary = TRUE + max_specific_storage = WEIGHT_CLASS_BULKY + var/delay_before_charging = 20 SECONDS + var/timer_id + var/obj/machinery/recharger/belt_charger/my_charger + +/datum/storage/charging_holster/New() + . = ..() + if(istype(parent, /obj/item/storage/belt/hip_holster/charging)) + var/obj/item/storage/belt/hip_holster/charging/my_belt = parent + my_charger = my_belt.my_charger + set_real_location(my_belt.real_storage) + set_holdable(list( + /obj/item/gun/energy, + /obj/item/melee/baton/security, + /obj/item/ammo_box/magazine/recharge, + /obj/item/modular_computer,)) + +/datum/storage/charging_holster/can_insert(obj/item/to_insert, mob/user, messages = TRUE, force = STORAGE_NOT_LOCKED) + if(istype(to_insert, /obj/item/gun/energy)) + var/obj/item/gun/energy/energy_gun = to_insert + if(!energy_gun.can_charge) + to_chat(user, span_notice("Your gun has no external power connector.")) + return FALSE + . = ..() + +/datum/storage/charging_holster/attempt_insert(obj/item/to_insert, mob/user, override = FALSE, force = STORAGE_NOT_LOCKED, messages = TRUE) + . = ..() + if(.) + parent.update_overlays() + timer_id = addtimer(CALLBACK(my_charger, TYPE_PROC_REF(/obj/machinery/recharger/belt_charger, activate_with_item)), delay_before_charging, TIMER_STOPPABLE | TIMER_UNIQUE | TIMER_OVERRIDE | TIMER_DELETE_ME) + +/datum/storage/charging_holster/attempt_remove(obj/item/thing, atom/remove_to_loc, silent = FALSE, visual_updates = TRUE) + . = ..() + if(.) + my_charger.charging = null + parent.update_overlays() + deltimer(timer_id) + +/obj/machinery/recharger/belt_charger + name = "belt charger" + desc = "the fact that you can see this means there's an error, call a dev!" + recharge_coeff = 0.2 + var/obj/item/storage/belt/hip_holster/charging/my_belt + +/obj/machinery/recharger/belt_charger/Destroy() + my_belt = null + . = ..() + +/obj/machinery/recharger/belt_charger/RefreshParts() + . = ..() + recharge_coeff = initial(recharge_coeff) + +/obj/machinery/recharger/belt_charger/proc/activate_with_item() + if(length(my_belt?.real_storage?.contents) > 0) + say("charging...") + charging = my_belt.real_storage.contents[1] + playsound(src, 'sound/machines/ping.ogg', 30, TRUE, frequency = 0.8) + START_PROCESSING(SSmachines, src) + update_use_power(ACTIVE_POWER_USE) + using_power = TRUE + update_appearance() + my_belt.update_overlays() + +/obj/machinery/recharger/belt_charger/process(seconds_per_tick) + if(length(my_belt?.real_storage?.contents) != 1 || my_belt?.real_storage.contents[1] != charging) + charging = null + return PROCESS_KILL + . = ..() + my_belt.update_appearance() + charging.update_appearance() + +/obj/machinery/recharger/belt_charger/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + to_chat(user, span_warning("You should insert the [tool] into the connected holster pouch, not the charging device itself!")) + return ITEM_INTERACT_BLOCKING + +//////////////////////////////////////////////////////////////////////////// +////////////////////////////// SHEATHS ///////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// + +/obj/item/storage/belt/crusader //Belt + sheath combination - still only holds one sword at a time though + icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_clothing.dmi' + worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/belt.dmi' + name = "scabbard-utility belt" + desc = "Holds an assortment of equipment for whatever situation an adventurer may encounter, as well as having an attached scabbard to hold a sword or bladed weapon." + icon_state = "crusader_belt" + worn_icon_state = "crusader_belt" + inhand_icon_state = "utility" + w_class = WEIGHT_CLASS_BULKY //Cant fit a sheath in your bag + interaction_flags_click = NEED_DEXTERITY + custom_materials = list(/datum/material/gold = SHEET_MATERIAL_AMOUNT) + +/obj/item/storage/belt/crusader/Initialize(mapload) + . = ..() + + create_storage( + max_slots = 2, + max_specific_storage = WEIGHT_CLASS_BULKY, //This makes sure swords and the pouches can fit in here - the whitelist keeps the bad stuff out + storage_type = /datum/storage/belt/crusader, + canhold = list( + /obj/item/storage/belt/storage_pouch, + /obj/item/melee/forged_reagent_weapon/sword, + /obj/item/melee/forged_reagent_weapon/rapier, + /obj/item/melee/forged_reagent_weapon/dagger, + /obj/item/melee/forged_reagent_weapon/katana, + /obj/item/melee/forged_reagent_weapon/bokken, + /obj/item/melee/sabre, + /obj/item/melee/parsnip_sabre, + /obj/item/claymore, + /obj/item/melee/cleric_mace, + /obj/item/knife, + /obj/item/melee/baton, + /obj/item/nullrod, //holds any subset of nullrod in the sheath-storage - - - + /obj/item/melee/energy/sword/nullrod, + ), + canthold = list( // - - - except the second list's items (no fedora in the sheath) + /obj/item/nullrod/armblade, + /obj/item/toy/plush/carpplushie/nullrod, + /obj/item/nullrod/chainsaw, + /obj/item/nullrod/bostaff, + /obj/item/nullrod/hammer, + /obj/item/nullrod/pitchfork, + /obj/item/nullrod/pride_hammer, + /obj/item/nullrod/spear, + /obj/item/nullrod/staff, + /obj/item/nullrod/fedora, + /obj/item/nullrod/godhand, + /obj/item/nullrod/whip, + ), + ) + atom_storage.allow_big_nesting = TRUE // Lets the pouch work + AddElement(/datum/element/update_icon_updates_onmob) + +//Overrides normal dumping code to instead dump from the pouch item inside +/datum/storage/belt/crusader/dump_content_at(atom/dest_object, mob/dumping_mob) + var/atom/used_belt = parent + if(!used_belt) + return + var/obj/item/storage/belt/storage_pouch/pouch = locate() in real_location + if(!pouch) + pouch.balloon_alert(dumping_mob, "no pouch!") + return //oopsie!! If we don't have a pouch! You're fucked! + if(locked) + pouch.balloon_alert(dumping_mob, "locked!") + return + pouch.atom_storage.dump_content_at(dest_object, dumping_mob) + +/obj/item/storage/belt/crusader/item_ctrl_click(mob/user) //Makes ctrl-click also open the inventory, so that you can open it with full hands without dropping the sword + . = ..() + atom_storage.show_contents(user) + return + +/obj/item/storage/belt/crusader/click_alt(mob/user) //This is basically the same as the normal sheath, but because there's always an item locked in the first slot it uses the second slot for swords + if(contents.len == 2) + var/obj/item/drawn_item = contents[2] + add_fingerprint(user) + playsound(src, 'sound/items/unsheath.ogg', 50, TRUE, -5) + if(!user.put_in_hands(drawn_item)) + to_chat(user, span_notice("You fumble for [drawn_item] and it falls on the floor.")) + update_appearance() + return CLICK_ACTION_SUCCESS + user.visible_message( + span_notice("[user] takes [drawn_item] out of [src]."), + span_notice("You take [drawn_item] out of [src].")) + update_appearance() + else + to_chat(user, span_warning("[src] is empty!")) + return CLICK_ACTION_SUCCESS + +/obj/item/storage/belt/crusader/update_icon(updates) + if(contents.len == 2) //Checks for a sword/rod in the sheath slot, changes the sprite accordingly + icon_state = "crusader_belt_sheathed" + worn_icon_state = "crusader_belt_sheathed" + else + icon_state = "crusader_belt" + worn_icon_state = "crusader_belt" + . = ..() + +/obj/item/storage/belt/crusader/examine(mob/user) + . = ..() + .+= span_notice("Ctrl-click it to easily open its inventory.") + if(contents.len == 2) //If there's no sword/rod in the sheath slot it doesnt display the alt-click instruction + . += span_notice("Alt-click it to quickly draw the blade.") + return + + +/obj/item/storage/belt/crusader/PopulateContents() + . = ..() + new /obj/item/storage/belt/storage_pouch(src) + +/obj/item/storage/belt/storage_pouch //seperate mini-storage inside the belt, leaving room for only one sword. Inspired by a (very poorly implemented) belt on Desert Rose + icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_clothing.dmi' + worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/belt.dmi' + name = "storage pouch" + desc = span_notice("Click on this to open your belt's inventory!") + icon_state = "storage_pouch_icon" + worn_icon_state = "no_name" //Intentionally sets the worn icon to an error + w_class = WEIGHT_CLASS_BULKY //Still cant put it in your bags, its technically a belt + anchored = 1 //Dont want people taking it out with their hands + +/obj/item/storage/belt/storage_pouch/attack_hand(mob/user, list/modifiers) //Opens the bag on click - considering it's already anchored, this makes it function similar to how ghosts can open all nested inventories + . = ..() + atom_storage.show_contents(user) + +/obj/item/storage/belt/storage_pouch/Initialize(mapload) + . = ..() + atom_storage.max_slots = 6 + atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL //Rather than have a huge whitelist, the belt can simply hold anything a pocket can hold - Can easily be changed if it somehow becomes an issue + +///////////////////////////////////////////////// + +/obj/item/storage/belt/sheath/multi + name = "multi-scabbard" + desc = "A set of harnesses that enable carrying multiple bulky swords and/or shields." + icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_clothing.dmi' + icon_state = "multiscabbard_swords_0" + inhand_icon_state = "sheath" + worn_icon_state = "sheath" + actions_types = null + storage_type = /datum/storage/multi_scabbard + +/obj/item/storage/belt/sheath/multi/update_icon(updates) + . = ..() + var/numswords = 0 + if(!isnull(contents) && contents.len > 0) + for(var/obj/item/i in contents) + if(istype(i, /obj/item/melee)) + numswords ++ + numswords = clamp(numswords, 0, 2) + icon_state = "multiscabbard_swords_[numswords]" + +/obj/item/storage/belt/sheath/multi/update_overlays() + . = ..() + var/obj/item/shield/my_shield = null + for(var/obj/item/i in contents) + if(istype(i, /obj/item/shield)) + my_shield = i + break + if(!isnull(my_shield)) + . += mutable_appearance(my_shield.icon, my_shield.icon_state) + +/datum/storage/multi_scabbard + max_slots = 2 + do_rustle = TRUE + max_specific_storage = WEIGHT_CLASS_HUGE + click_alt_open = FALSE + +/datum/storage/multi_scabbard/New(atom/parent, max_slots, max_specific_storage, max_total_storage, rustle_sound, remove_rustle_sound) + . = ..() + set_holdable(list( + /obj/item/melee/forged_reagent_weapon, + /obj/item/shield, + /obj/item/melee/sabre, + /obj/item/melee/parsnip_sabre, + /obj/item/claymore, + /obj/item/melee/cleric_mace, + /obj/item/knife, + /obj/item/melee/baton, + /obj/item/nullrod, + /obj/item/melee/energy/sword/nullrod, + )) + +////////////////////////////////////////////////////////////////// + +/obj/item/storage/belt/sheath/repairing + name = "repairing scabbard" + desc = "A bluespace crystal in this scabbard causes it to slowly rejuvenate whatever's stored inside it." + icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_clothing.dmi' + icon_state = "repairsheath" + inhand_icon_state = "sheath" + worn_icon_state = "sheath" + actions_types = null + storage_type = /datum/storage/repairing_scabbard + + var/integ_restoration_amount_per_seconds = 0.5 + +/obj/item/storage/belt/sheath/repairing/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs) + . = ..() + START_PROCESSING(SSdcs, src) + +/obj/item/storage/belt/sheath/repairing/process(seconds_per_tick) + if(contents.len == 0) + return PROCESS_KILL + + var/obj/item/my_item = contents[1] + if(isnull(my_item)) + return PROCESS_KILL + + if(my_item.get_integrity() < my_item.max_integrity) + my_item.repair_damage(integ_restoration_amount_per_seconds * seconds_per_tick) + +/datum/storage/repairing_scabbard + max_slots = 1 + do_rustle = FALSE + max_specific_storage = WEIGHT_CLASS_BULKY + click_alt_open = FALSE + +/datum/storage/repairing_scabbard/New(atom/parent, max_slots, max_specific_storage, max_total_storage, rustle_sound, remove_rustle_sound) + . = ..() + set_holdable(list( + /obj/item/melee/forged_reagent_weapon, + /obj/item/shield, + /obj/item/melee/sabre, + /obj/item/melee/parsnip_sabre, + /obj/item/claymore, + /obj/item/melee/cleric_mace, + /obj/item/knife, + /obj/item/melee/baton, + /obj/item/nullrod, + /obj/item/melee/energy/sword/nullrod, + )) + +///////////////////////////////////////////////// + +/obj/item/storage/belt/knifethrowers_belt + name = "knifethrower's belt" + desc = "Stores a frankly ridiculous number of knives and comparable short, bladed weapons. The shallow pocket depth makes it poor at storing other objects." + icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_clothing.dmi' + icon_state = "knifethrowers" + inhand_icon_state = "utility" + worn_icon_state = "utility" + drop_sound = 'sound/items/handling/toolbelt_drop.ogg' + pickup_sound = 'sound/items/handling/toolbelt_pickup.ogg' + storage_type = /datum/storage/knifethrowers + +/obj/item/storage/belt/knifethrowers_belt/update_overlays() + . = ..() + if(contents.len > 0) + var/icon_to_use = "belt_knives_[(contents.len > 8 ? 8 : contents.len)]" + . += mutable_appearance(icon, icon_to_use, alpha = src.alpha) + +/datum/storage/knifethrowers + max_slots = 14 + max_total_storage = 60 + open_sound = 'sound/items/handling/holster_open.ogg' + open_sound_vary = TRUE + +/datum/storage/knifethrowers/New() + . = ..() + set_holdable(list( + /obj/item/melee/forged_reagent_weapon/dagger, + /obj/item/knife, + /obj/item/pen, + /obj/item/scalpel, + /obj/item/shard, + /obj/item/spess_knife, + /obj/item/toy/toy_dagger, + )) + +///////////////////////////////////////////////// + +/obj/item/storage/bag/plants/bluespace + name = "bluespace plant bag" + desc = "A bluespace banana peel grants much larger storage capacity here. It malfunctions when trying to store specific mutant plants -- ironically, bluespace bananas are one such plant..." + icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_clothing.dmi' + icon_state = "bluespace_botany_bag" + worn_icon_state = "plantbag" + storage_type = /datum/storage/bag/plants_bluespace + +/datum/storage/bag/plants_bluespace + max_total_storage = 1000 + max_slots = 300 + +/datum/storage/bag/plants_bluespace/New(atom/parent, max_slots, max_specific_storage, max_total_storage, rustle_sound, remove_rustle_sound) + . = ..() + set_holdable(list( + /obj/item/food/grown, + /obj/item/graft, + /obj/item/grown, + /obj/item/food/honeycomb, + /obj/item/seeds, + ), list( + /obj/item/food/grown/banana/bluespace, + /obj/item/grown/bananapeel/bluespace, + /obj/item/food/grown/cherry_bomb, + /obj/item/food/grown/firelemon, + /obj/item/food/grown/gatfruit, + /obj/item/food/grown/holymelon, + /obj/item/food/grown/barrelmelon, + /obj/item/food/grown/tomato/blue/bluespace, + /obj/item/food/grown/tomato/killer, + ) + ) + diff --git a/modular_skyrat/modules/reagent_forging/code/forge_clothing.dm b/modular_skyrat/modules/reagent_forging/code/forge_clothing.dm index 781ca88788a..93ee36fbc95 100644 --- a/modular_skyrat/modules/reagent_forging/code/forge_clothing.dm +++ b/modular_skyrat/modules/reagent_forging/code/forge_clothing.dm @@ -1,3 +1,24 @@ +/datum/armor/perfect_forged_armor_bonus + melee = 20 + bullet = 20 + fire = 25 + laser = 10 + wound = 20 + +/datum/armor/smithing_oil_armor_bonus + melee = 10 + bullet = 10 + +/datum/armor/armor_forging_plate_armor + melee = 20 + bullet = 10 + fire = 50 + wound = 10 + laser = 15 + bomb = 25 + acid = 50 + wound = 50 + // Vests /obj/item/clothing/suit/armor/forging_plate_armor name = "reagent plate vest" @@ -10,22 +31,27 @@ icon_state = "plate_vest" supports_variations_flags = CLOTHING_DIGITIGRADE_VARIATION_NO_NEW_ICON resistance_flags = FIRE_PROOF - skyrat_obj_flags = ANVIL_REPAIR armor_type = /datum/armor/armor_forging_plate_armor - material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR - -/datum/armor/armor_forging_plate_armor - melee = 40 - bullet = 40 - fire = 50 - wound = 30 + material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS /obj/item/clothing/suit/armor/forging_plate_armor/Initialize(mapload) . = ..() - AddComponent(/datum/component/armor_plate, 4) - AddComponent(/datum/component/reagent_clothing, ITEM_SLOT_OCLOTHING) + allowed += /obj/item/melee/forged_reagent_weapon + AddComponent(/datum/component/reagent_imbued/clothing, list(FORGE_EFFECT_ARMOR = /datum/armor/smithing_oil_armor_bonus), set_slot = ITEM_SLOT_OCLOTHING) + AddComponent(/datum/component/forge_smithable, \ + FORGING_CLOTHING_REFORGING_MAX_QUALITY, \ + TRUE, \ + FORGING_CLOTHING_REFORGING_MAX_PERFECT_HITS, \ + FORGING_CLOTHING_REFORGING_MAX_BAD_HITS, \ + FORGING_CLOTHING_REFORGING_AVERAGE_WAIT, \ + perfection_effects = list(FORGE_EFFECT_ARMOR = /datum/armor/perfect_forged_armor_bonus), \ + incompletion_effects = list(FORGE_EFFECT_ARMOR, FORGE_EFFECT_DURABILITY)) - allowed += /obj/item/forging/reagent_weapon +/obj/item/clothing/suit/armor/forging_plate_armor/change_material_integrity(datum/material/material, amount, multiplier, removing = FALSE) + blacksmithing_change_material_integrity(src, material, amount, multiplier, removing) + +/obj/item/clothing/suit/armor/forging_plate_armor/change_material_strength(datum/material/material, mat_amount, multiplier, remove = FALSE) + blacksmithing_change_material_strength(src, material, mat_amount, multiplier, remove) // Gloves /obj/item/clothing/gloves/forging_plate_gloves @@ -38,22 +64,28 @@ worn_icon_teshari = 'modular_skyrat/modules/reagent_forging/icons/mob/clothing/forge_clothing_teshari.dmi' icon_state = "plate_gloves" resistance_flags = FIRE_PROOF - skyrat_obj_flags = ANVIL_REPAIR body_parts_covered = parent_type::body_parts_covered | ARMS - armor_type = /datum/armor/gloves_forging_plate_gloves - material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR - -/datum/armor/gloves_forging_plate_gloves - melee = 40 - bullet = 40 - fire = 50 - wound = 30 + armor_type = /datum/armor/armor_forging_plate_armor + material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS /obj/item/clothing/gloves/forging_plate_gloves/Initialize(mapload) . = ..() - AddComponent(/datum/component/armor_plate, 4) - AddComponent(/datum/component/reagent_clothing, ITEM_SLOT_GLOVES) + AddComponent(/datum/component/reagent_imbued/clothing, list(FORGE_EFFECT_ARMOR = /datum/armor/smithing_oil_armor_bonus), set_slot = ITEM_SLOT_GLOVES) + AddComponent(/datum/component/forge_smithable, \ + FORGING_CLOTHING_REFORGING_MAX_QUALITY, \ + TRUE, \ + FORGING_CLOTHING_REFORGING_MAX_PERFECT_HITS, \ + FORGING_CLOTHING_REFORGING_MAX_BAD_HITS, \ + FORGING_CLOTHING_REFORGING_AVERAGE_WAIT, \ + perfection_effects = list(FORGE_EFFECT_ARMOR = /datum/armor/perfect_forged_armor_bonus), \ + incompletion_effects = list(FORGE_EFFECT_ARMOR, FORGE_EFFECT_DURABILITY)) + +/obj/item/clothing/gloves/forging_plate_gloves/change_material_integrity(datum/material/material, amount, multiplier, removing = FALSE) + blacksmithing_change_material_integrity(src, material, amount, multiplier, removing) + +/obj/item/clothing/gloves/forging_plate_gloves/change_material_strength(datum/material/material, mat_amount, multiplier, remove = FALSE) + blacksmithing_change_material_strength(src, material, mat_amount, multiplier, remove) // Helmets /obj/item/clothing/head/helmet/forging_plate_helmet @@ -68,20 +100,26 @@ supports_variations_flags = CLOTHING_SNOUTED_VARIATION_NO_NEW_ICON resistance_flags = FIRE_PROOF flags_inv = null - skyrat_obj_flags = ANVIL_REPAIR - armor_type = /datum/armor/helmet_forging_plate_helmet - material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR - -/datum/armor/helmet_forging_plate_helmet - melee = 40 - bullet = 40 - fire = 50 - wound = 30 + armor_type = /datum/armor/armor_forging_plate_armor + material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS /obj/item/clothing/head/helmet/forging_plate_helmet/Initialize(mapload) . = ..() - AddComponent(/datum/component/armor_plate, 4) - AddComponent(/datum/component/reagent_clothing, ITEM_SLOT_HEAD) + AddComponent(/datum/component/reagent_imbued/clothing, list(FORGE_EFFECT_ARMOR = /datum/armor/smithing_oil_armor_bonus), set_slot = ITEM_SLOT_HEAD) + AddComponent(/datum/component/forge_smithable, \ + FORGING_CLOTHING_REFORGING_MAX_QUALITY, \ + TRUE, \ + FORGING_CLOTHING_REFORGING_MAX_PERFECT_HITS, \ + FORGING_CLOTHING_REFORGING_MAX_BAD_HITS, \ + FORGING_CLOTHING_REFORGING_AVERAGE_WAIT, \ + perfection_effects = list(FORGE_EFFECT_ARMOR = /datum/armor/perfect_forged_armor_bonus), \ + incompletion_effects = list(FORGE_EFFECT_ARMOR, FORGE_EFFECT_DURABILITY)) + +/obj/item/clothing/head/helmet/forging_plate_helmet/change_material_integrity(datum/material/material, amount, multiplier, removing = FALSE) + blacksmithing_change_material_integrity(src, material, amount, multiplier, removing) + +/obj/item/clothing/head/helmet/forging_plate_helmet/change_material_strength(datum/material/material, mat_amount, multiplier, remove = FALSE) + blacksmithing_change_material_strength(src, material, mat_amount, multiplier, remove) // Boots /obj/item/clothing/shoes/forging_plate_boots @@ -97,39 +135,57 @@ supports_variations_flags = CLOTHING_DIGITIGRADE_VARIATION body_parts_covered = parent_type::body_parts_covered | LEGS - armor_type = /datum/armor/shoes_forging_plate_boots - material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR + armor_type = /datum/armor/armor_forging_plate_armor + material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS resistance_flags = FIRE_PROOF - skyrat_obj_flags = ANVIL_REPAIR fastening_type = SHOES_SLIPON -/datum/armor/shoes_forging_plate_boots - melee = 20 - bullet = 20 - /obj/item/clothing/shoes/forging_plate_boots/Initialize(mapload) . = ..() - AddComponent(/datum/component/armor_plate, 2) - AddComponent(/datum/component/reagent_clothing, ITEM_SLOT_FEET) + AddComponent(/datum/component/reagent_imbued/clothing, list(FORGE_EFFECT_ARMOR = /datum/armor/smithing_oil_armor_bonus), set_slot = ITEM_SLOT_FEET) + AddComponent(/datum/component/forge_smithable, \ + FORGING_CLOTHING_REFORGING_MAX_QUALITY, \ + TRUE, \ + FORGING_CLOTHING_REFORGING_MAX_PERFECT_HITS, \ + FORGING_CLOTHING_REFORGING_MAX_BAD_HITS, \ + FORGING_CLOTHING_REFORGING_AVERAGE_WAIT, \ + perfection_effects = list(FORGE_EFFECT_ARMOR = /datum/armor/perfect_forged_armor_bonus), \ + incompletion_effects = list(FORGE_EFFECT_ARMOR, FORGE_EFFECT_DURABILITY)) + +/obj/item/clothing/shoes/forging_plate_boots/change_material_integrity(datum/material/material, amount, multiplier, removing = FALSE) + blacksmithing_change_material_integrity(src, material, amount, multiplier, removing) + +/obj/item/clothing/shoes/forging_plate_boots/change_material_strength(datum/material/material, mat_amount, multiplier, remove = FALSE) + blacksmithing_change_material_strength(src, material, mat_amount, multiplier, remove) /obj/item/clothing/shoes/horseshoe/reagent_clothing name = "reagent horseshoes" desc = "A pair of horseshoes made out of chains." - - armor_type = /datum/armor/shoes_horseshoe - material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR - skyrat_obj_flags = ANVIL_REPAIR - -/datum/armor/shoes_horseshoe - melee = 20 - bullet = 20 + armor_type = /datum/armor/armor_forging_plate_armor + material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS /obj/item/clothing/shoes/horseshoe/reagent_clothing/Initialize(mapload) . = ..() - AddComponent(/datum/component/armor_plate, 2) - AddComponent(/datum/component/reagent_clothing, ITEM_SLOT_FEET) + AddComponent(/datum/component/reagent_imbued/clothing, list(FORGE_EFFECT_ARMOR = /datum/armor/smithing_oil_armor_bonus), set_slot = ITEM_SLOT_FEET) + AddComponent(/datum/component/forge_smithable, \ + FORGING_CLOTHING_REFORGING_MAX_QUALITY, \ + TRUE, \ + FORGING_CLOTHING_REFORGING_MAX_PERFECT_HITS, \ + FORGING_CLOTHING_REFORGING_MAX_BAD_HITS, \ + FORGING_CLOTHING_REFORGING_AVERAGE_WAIT, \ + perfection_effects = list(FORGE_EFFECT_ARMOR = /datum/armor/perfect_forged_armor_bonus), \ + incompletion_effects = list(FORGE_EFFECT_ARMOR, FORGE_EFFECT_DURABILITY)) + +/obj/item/clothing/shoes/horseshoe/reagent_clothing/change_material_integrity(datum/material/material, amount, multiplier, removing = FALSE) + blacksmithing_change_material_integrity(src, material, amount, multiplier, removing) + +/obj/item/clothing/shoes/horseshoe/reagent_clothing/change_material_strength(datum/material/material, mat_amount, multiplier, remove = FALSE) + blacksmithing_change_material_strength(src, material, mat_amount, multiplier, remove) + +//////////////////////////////////////////////////////////////////////////// +////////////////////////////// MISC //////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// -// Misc /obj/item/clothing/gloves/ring/reagent_clothing name = "reagent ring" desc = "A tiny ring, sized to wrap around a finger." @@ -137,15 +193,26 @@ worn_icon_state = "sring" inhand_icon_state = null material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR - skyrat_obj_flags = ANVIL_REPAIR + var/current_perfection_bonus = 0 + var/current_completion_penalty = 0 /obj/item/clothing/gloves/ring/reagent_clothing/Initialize(mapload) . = ..() - AddComponent(/datum/component/reagent_clothing, ITEM_SLOT_GLOVES) + AddComponent(/datum/component/reagent_imbued/clothing, list(FORGE_EFFECT_DURABILITY = 50), set_slot = ITEM_SLOT_GLOVES) + AddComponent(/datum/component/forge_smithable, \ + FORGING_CLOTHING_REFORGING_MAX_QUALITY, \ + TRUE, \ + FORGING_CLOTHING_REFORGING_MAX_PERFECT_HITS, \ + FORGING_CLOTHING_REFORGING_MAX_BAD_HITS, \ + FORGING_CLOTHING_REFORGING_AVERAGE_WAIT, \ + perfection_effects = list(FORGE_EFFECT_REAGENT_INJECT = 0.2), \ + incompletion_effects = list(FORGE_EFFECT_REAGENT_INJECT, FORGE_EFFECT_DURABILITY)) + +//////////////////////////////////////////////////////////////////////////// /obj/item/clothing/neck/collar/reagent_clothing name = "reagent collar" - desc = "A collar that is ready to be worn for certain individuals." + desc = "A collar that is ready to be worn for... certain individuals." icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_neck.dmi' worn_icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_clothing/lewd_neck.dmi' icon_state = "collar_cyan" @@ -154,18 +221,24 @@ slot_flags = ITEM_SLOT_NECK w_class = WEIGHT_CLASS_SMALL material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR - skyrat_obj_flags = ANVIL_REPAIR /obj/item/clothing/neck/collar/reagent_clothing/Initialize(mapload) . = ..() - AddComponent(/datum/component/reagent_clothing, ITEM_SLOT_NECK) + AddComponent(/datum/component/reagent_imbued/clothing, list(FORGE_EFFECT_DURABILITY = 50), set_slot = ITEM_SLOT_NECK) + AddComponent(/datum/component/forge_smithable, \ + FORGING_CLOTHING_REFORGING_MAX_QUALITY, \ + TRUE, \ + FORGING_CLOTHING_REFORGING_MAX_PERFECT_HITS, \ + FORGING_CLOTHING_REFORGING_MAX_BAD_HITS, \ + FORGING_CLOTHING_REFORGING_AVERAGE_WAIT, \ + perfection_effects = list(FORGE_EFFECT_REAGENT_INJECT = 0.2), \ + incompletion_effects = list(FORGE_EFFECT_REAGENT_INJECT, FORGE_EFFECT_DURABILITY)) /obj/item/restraints/handcuffs/reagent_clothing name = "reagent handcuffs" desc = "A pair of handcuffs that are ready to keep someone captive." material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR - skyrat_obj_flags = ANVIL_REPAIR /obj/item/restraints/handcuffs/reagent_clothing/Initialize(mapload) . = ..() - AddComponent(/datum/component/reagent_clothing, ITEM_SLOT_HANDCUFFED) + AddComponent(/datum/component/reagent_imbued/clothing, ITEM_SLOT_HANDCUFFED) diff --git a/modular_skyrat/modules/reagent_forging/code/forge_equipment.dm b/modular_skyrat/modules/reagent_forging/code/forge_equipment.dm new file mode 100644 index 00000000000..2335385bde2 --- /dev/null +++ b/modular_skyrat/modules/reagent_forging/code/forge_equipment.dm @@ -0,0 +1,60 @@ +/obj/item/forging + abstract_type = /obj/item/forging + icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_items.dmi' + lefthand_file = 'modular_skyrat/modules/reagent_forging/icons/mob/forge_weapon_l.dmi' + righthand_file = 'modular_skyrat/modules/reagent_forging/icons/mob/forge_weapon_r.dmi' + toolspeed = 1 + +/obj/item/forging/tongs + name = "forging tongs" + desc = "A set of tongs specifically crafted for use in forging. A wise man once said 'I lift things up and put them down.'" + icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_items.dmi' + icon_state = "tong_empty" + tool_behaviour = TOOL_TONG + +/obj/item/forging/tongs/primitive + name = "primitive forging tongs" + toolspeed = 1.2 + custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 5) + +/obj/item/forging/tongs/attack_self(mob/user, modifiers) + . = ..() + var/obj/search_obj = locate(/obj) in contents + if(search_obj) + search_obj.forceMove(get_turf(src)) + icon_state = "tong_empty" + return + +/obj/item/forging/hammer + name = "forging mallet" + desc = "A mallet specifically crafted for use in forging. Used to slowly shape metal; careful, you could break something with it!" + icon_state = "hammer" + inhand_icon_state = "hammer" + worn_icon_state = "hammer_back" + tool_behaviour = TOOL_HAMMER + ///the list of things that, if attacked, will set the attack speed to rapid + var/static/list/fast_attacks = list( + /obj/structure/reagent_anvil, + /obj/structure/reagent_crafting_bench + ) + + +/obj/item/forging/hammer/primitive + name = "primitive forging hammer" + custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 5) + +/obj/item/forging/hammer/debug + name = "debugging fast forging hammer" + toolspeed = 0.1 + +/obj/item/forging/billow + name = "forging billow" + desc = "A billow specifically crafted for use in forging. Used to stoke the flames and keep the forge lit." + icon_state = "billow" + tool_behaviour = TOOL_BILLOW + +/obj/item/forging/billow/primitive + name = "primitive forging billow" + toolspeed = 1.2 + custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT * 5) + diff --git a/modular_skyrat/modules/reagent_forging/code/forge_items.dm b/modular_skyrat/modules/reagent_forging/code/forge_items.dm index 197120e2411..0fa93ec1a94 100644 --- a/modular_skyrat/modules/reagent_forging/code/forge_items.dm +++ b/modular_skyrat/modules/reagent_forging/code/forge_items.dm @@ -1,187 +1,262 @@ -/obj/item/forging - icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_items.dmi' - lefthand_file = 'modular_skyrat/modules/reagent_forging/icons/mob/forge_weapon_l.dmi' - righthand_file = 'modular_skyrat/modules/reagent_forging/icons/mob/forge_weapon_r.dmi' - toolspeed = 1 SECONDS - ///whether the item is in use or not - var/in_use = FALSE - -/obj/item/forging/tongs - name = "forging tongs" - desc = "A set of tongs specifically crafted for use in forging. A wise man once said 'I lift things up and put them down.'" - icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_items.dmi' - icon_state = "tong_empty" - tool_behaviour = TOOL_TONG - -/obj/item/forging/tongs/primitive - name = "primitive forging tongs" - toolspeed = 2 SECONDS - custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 5) - -/obj/item/forging/tongs/attack_self(mob/user, modifiers) - . = ..() - var/obj/search_obj = locate(/obj) in contents - if(search_obj) - search_obj.forceMove(get_turf(src)) - icon_state = "tong_empty" - return - -/obj/item/forging/hammer - name = "forging mallet" - desc = "A mallet specifically crafted for use in forging. Used to slowly shape metal; careful, you could break something with it!" - icon_state = "hammer" - inhand_icon_state = "hammer" - worn_icon_state = "hammer_back" - tool_behaviour = TOOL_HAMMER - ///the list of things that, if attacked, will set the attack speed to rapid - var/static/list/fast_attacks = list( - /obj/structure/reagent_anvil, - /obj/structure/reagent_crafting_bench - ) - -/obj/item/forging/hammer/primitive - name = "primitive forging hammer" - custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 5) - -/obj/item/forging/billow - name = "forging billow" - desc = "A billow specifically crafted for use in forging. Used to stoke the flames and keep the forge lit." - icon_state = "billow" - tool_behaviour = TOOL_BILLOW - -/obj/item/forging/billow/primitive - name = "primitive forging billow" - toolspeed = 2 SECONDS - custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT * 5) - //incomplete pre-complete items /obj/item/forging/incomplete - name = "parent dev item" - desc = "An incomplete forge item, continue to work hard to be rewarded for your efforts." - //the time remaining that you can hammer before too cool - COOLDOWN_DECLARE(heating_remainder) - //the time between each strike - COOLDOWN_DECLARE(striking_cooldown) - ///the amount of times it takes for the item to become ready - var/average_hits = 30 - ///the amount of times the item has been hit currently - var/times_hit = 0 + name = "incomplete forging item" + desc = "you shouldn't be seeing this!" + abstract_type = /obj/item/forging/incomplete + + ///the quality points required for it to be considered usable for crafting + var/completion_quality_points = 40 ///the required time before each strike to prevent spamming var/average_wait = 1 SECONDS - ///the number of current perfect hits (really only impacts weapons atm) - var/current_perfects = 0 + ///the bad hits required for it to break; exceeding this will break the item + var/bad_hit_maximum = 5 + ///maximum number of perfect hits before perfect hits no longer improve the quality + var/max_perfect_hits = 20 + ///the path of the item that will be spawned upon completion var/spawn_item + ///does this item break if it's not finished hammering when it's quenched? + //this is mostly for working on stuff that has no effect based on completion amount, preventing cheesing + var/break_on_early_quench = FALSE //because who doesn't want to have a plasma sword? material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR -/obj/item/forging/incomplete/tong_act(mob/living/user, obj/item/tool) +/obj/item/forging/incomplete/Initialize(mapload) . = ..() + AddComponent(/datum/component/forge_smithable, completion_quality_points, TRUE, max_perfect_hits, bad_hit_maximum, average_wait, CALLBACK(src, TYPE_PROC_REF(/obj/item/forging/incomplete, quench_item)), color = "")// TYPE_PROC_REF(/obj/item/forging/incomplete/, quench_item)) + +/obj/item/forging/incomplete/proc/quench_item(datum/reagents/dunk_reagents, dunk_object, mob/living/quencher) + SIGNAL_HANDLER + + var/datum/component/forge_smithable/forge_component = GetComponent(/datum/component/forge_smithable) + if(forge_component.is_finished_smithing()) + to_chat(quencher, span_notice("You cool down [src].")) + quencher.mind.adjust_experience(/datum/skill/smithing, 5) + else + if(break_on_early_quench) + to_chat(quencher, span_warning("The [src] breaks from the thermal shock! Metalworking this type of object requires it to be hammered into completion.")) + qdel(src) + return + else + to_chat(quencher, span_warning("You cool down [src]. You're not sure if it was ready yet...")) + + var/obj/spawned_obj = new spawn_item(get_turf(dunk_object)) + if(custom_materials) + spawned_obj.set_custom_materials(custom_materials, 1) //lets set its material + + if(istype(spawned_obj, /obj/item/forging/complete)) + var/obj/item/forging/complete/complete_spawned = spawned_obj + complete_spawned.perfect_ratio = forge_component.get_perfect_ratio() + complete_spawned.hammer_completion_amount = forge_component.get_completion_ratio() + + var/datum/component/reagent_imbued/new_reagent_component = spawned_obj.GetComponent(/datum/component/reagent_imbued) + if(!isnull(new_reagent_component) && USER_CAN_REAGENT_IMBUE(quencher)) + new_reagent_component.set_reagent_imbue(dunk_reagents, FALSE, TRUE) + to_chat(quencher, span_notice("The [spawned_obj] is imbued with reagents.")) + + qdel(src) + return spawned_obj + +/obj/item/forging/incomplete/tong_act(mob/living/user, obj/item/tool) if(length(tool.contents) > 0) user.balloon_alert(user, "tongs are full already!") return forceMove(tool) tool.icon_state = "tong_full" + +/obj/item/forging/incomplete/pickup(mob/living/user) + var/hand_protected = FALSE + var/mob/living/carbon/human/human_user = user + if(!istype(human_user) || HAS_TRAIT(human_user, TRAIT_RESISTHEAT) || HAS_TRAIT(human_user, TRAIT_RESISTHEATHANDS)) + hand_protected = TRUE + else if(!istype(human_user.gloves, /obj/item/clothing/gloves)) + hand_protected = FALSE + else + var/obj/item/clothing/gloves/gloves = human_user.gloves + if(gloves.max_heat_protection_temperature) + hand_protected = (gloves.max_heat_protection_temperature > 360) + + ..() + if(!hand_protected) + var/hitzone = user.held_index_to_dir(user.active_hand_index) == "r" ? BODY_ZONE_PRECISE_R_HAND : BODY_ZONE_PRECISE_L_HAND + user.apply_damage(5, BURN, hitzone) + to_chat(user, span_danger("You burn your hand trying to pick up [src]!")) + user.add_mood_event("burnt_thumb", /datum/mood_event/burnt_thumb) + user.dropItemToGround(src) + +/obj/item/forging/incomplete/can_be_pulled(user, force) // no drag memes + return FALSE + /obj/item/forging/incomplete/chain name = "incomplete chain" icon_state = "hot_chain" - average_hits = 10 - average_wait = 0.5 SECONDS + completion_quality_points = 40 + max_perfect_hits = 15 spawn_item = /obj/item/forging/complete/chain + break_on_early_quench = TRUE + desc = "A length of chain. Used in crafting recipes at your crafting table." /obj/item/forging/incomplete/plate name = "incomplete plate" icon_state = "hot_plate" - average_hits = 10 - average_wait = 0.5 SECONDS + completion_quality_points = 40 + max_perfect_hits = 15 spawn_item = /obj/item/forging/complete/plate + desc = "A sturdy plate of material. Used in many crafting recipies at your crafting table, most notably that of armor." /obj/item/forging/incomplete/sword name = "incomplete sword blade" icon_state = "hot_blade" spawn_item = /obj/item/forging/complete/sword + desc = "A longsword. Practically requires a two-handed stance for effective use, but is very adept at blocking strikes." /obj/item/forging/incomplete/katana name = "incomplete katana blade" icon_state = "hot_katanablade" spawn_item = /obj/item/forging/complete/katana + desc = "A katana blade. Unwieldy if not carried with both hands, but careful metalworking makes it cut through armor more effectively." /obj/item/forging/incomplete/rapier name = "incomplete rapier blade" icon_state = "hot_rapierblade" spawn_item = /obj/item/forging/complete/rapier + desc = "A rapier blade. A classical go-to self-defense weapon, it requires only one hand to use." /obj/item/forging/incomplete/dagger name = "incomplete dagger blade" icon_state = "hot_daggerblade" + completion_quality_points = 22 + max_perfect_hits = 10 spawn_item = /obj/item/forging/complete/dagger + desc = "A small, sleek dagger. Can be easily hid, and can critially-strike vulnerable opponents." /obj/item/forging/incomplete/staff name = "incomplete staff head" icon_state = "hot_staffhead" spawn_item = /obj/item/forging/complete/staff + desc = "A staff that can be imbued with reagents. Not very useful in direct combat." /obj/item/forging/incomplete/spear name = "incomplete spear head" + completion_quality_points = 18 ///crazy low completion required (spears are historically an easy weapon to make that are used for widespread arming) + max_perfect_hits = 8 icon_state = "hot_spearhead" spawn_item = /obj/item/forging/complete/spear + desc = "A short spearhead. The weapon of commoners, it strikes from further away and can be made extremely quickly compared to other weapons." /obj/item/forging/incomplete/axe name = "incomplete axe head" icon_state = "hot_axehead" + completion_quality_points = 22 + max_perfect_hits = 14 spawn_item = /obj/item/forging/complete/axe + desc = "A heavy axehead. Hits from this can potentially bypass shields and other forms of protection." /obj/item/forging/incomplete/hammer name = "incomplete hammer head" icon_state = "hot_hammerhead" spawn_item = /obj/item/forging/complete/hammer + desc = "A heavy hammerhead. Can be used like a forging hammer -- and a two-handed stance can bust through doors." /obj/item/forging/incomplete/pickaxe name = "incomplete pickaxe head" icon_state = "hot_pickaxehead" spawn_item = /obj/item/forging/complete/pickaxe + desc = "A pickaxe. Used for digging." /obj/item/forging/incomplete/shovel name = "incomplete shovel head" icon_state = "hot_shovelhead" spawn_item = /obj/item/forging/complete/shovel + desc = "A shovel. Used for digging." /obj/item/forging/incomplete/arrowhead name = "incomplete arrowhead" icon_state = "hot_arrowhead" - average_hits = 12 - average_wait = 0.5 SECONDS + completion_quality_points = 12 spawn_item = /obj/item/forging/complete/arrowhead + desc = "A number of small arrowheads, used to create arrows." + +/obj/item/forging/incomplete/revolver_cylinder + name = "incomplete revolver cylinder" + icon_state = "hot_revolver_cylinder" + completion_quality_points = 60 + max_perfect_hits = 70 + spawn_item = /obj/item/forging/complete/revolver_cylinder + desc = "The cylinder of a classical single-action revolver." + +/obj/item/forging/incomplete/revolver_frame + name = "incomplete revolver frame" + icon_state = "hot_revolver_frame" + completion_quality_points = 90 + max_perfect_hits = 110 + spawn_item = /obj/item/forging/complete/revolver_frame + desc = "The frame of a classical single-action revolver." /obj/item/forging/incomplete/rail_nail name = "incomplete rail nail" icon = 'modular_skyrat/modules/ashwalkers/icons/railroad.dmi' icon_state = "hot_nail" - average_hits = 10 - average_wait = 0.5 SECONDS + completion_quality_points = 10 spawn_item = /obj/item/forging/complete/rail_nail + break_on_early_quench = TRUE + desc = "A rail nail used to build rail tracks." /obj/item/forging/incomplete/rail_cart name = "incomplete rail cart" icon = 'modular_skyrat/modules/ashwalkers/icons/railroad.dmi' icon_state = "hot_cart" spawn_item = /obj/vehicle/ridden/rail_cart + break_on_early_quench = TRUE + desc = "A minecart that can be ridden along rail tracks." //"complete" pre-complete items /obj/item/forging/complete + abstract_type = /obj/item/forging/complete ///the path of the item that will be created var/spawning_item - ///the amount of perfect hits on the item, if it was allowed - var/current_perfects = 0 + ///how many perfect hits did we get, out of the max? + var/perfect_ratio = 0 + ///when this was worked at an anvil, how many hits were actually applied of the max? + var/hammer_completion_amount = 0 //because who doesn't want to have a plasma sword? material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR + ///does it cut the user's hand when used as a weapon? + var/double_edged_damage = 0 + var/has_reagent_component = TRUE + +/obj/item/forging/complete/Initialize(mapload) + . = ..() + if(has_reagent_component) + AddComponent(/datum/component/reagent_imbued) /obj/item/forging/complete/examine(mob/user) . = ..() if(spawning_item) . += span_notice("
In order to finish this item, a workbench will be necessary!") +/obj/item/forging/complete/afterattack(atom/target, mob/user, list/modifiers, list/attack_modifiers) + if(double_edged_damage <= 0) + return + + if(!iscarbon(user) || !user.is_holding(src)) + return + + var/mob/living/carbon/jab = user + if(jab.get_all_covered_flags() & HANDS) + return + + to_chat(user, span_warning("[src] cuts into your hand!")) + jab.apply_damage(double_edged_damage * hammer_completion_amount, BRUTE, user.get_active_hand(), attacking_item = src) + +/obj/item/forging/complete/tong_act(mob/living/user, obj/item/tool) + if(length(tool.contents) > 0) + user.balloon_alert(user, "tongs are full already!") + return + forceMove(tool) + tool.icon_state = "tong_full" + /obj/item/forging/complete/chain name = "chain" desc = "A singular chain, best used in combination with multiple chains." @@ -196,55 +271,68 @@ name = "sword blade" desc = "A sword blade, ready to get some wood for completion." icon_state = "blade" - spawning_item = /obj/item/forging/reagent_weapon/sword + spawning_item = /obj/item/melee/forged_reagent_weapon/sword + force = 5 + double_edged_damage = 3 /obj/item/forging/complete/katana name = "katana blade" desc = "A katana blade, ready to get some wood for completion." icon_state = "katanablade" - spawning_item = /obj/item/forging/reagent_weapon/katana + spawning_item = /obj/item/melee/forged_reagent_weapon/katana + force = 5 + double_edged_damage = 3 /obj/item/forging/complete/rapier name = "rapier blade" desc = "A rapier blade, ready to get some wood for completion." icon_state = "rapierblade" - spawning_item = /obj/item/forging/reagent_weapon/rapier + spawning_item = /obj/item/melee/forged_reagent_weapon/rapier + force = 5 + double_edged_damage = 3 /obj/item/forging/complete/dagger name = "dagger blade" desc = "A dagger blade, ready to get some wood for completion." icon_state = "daggerblade" - spawning_item = /obj/item/forging/reagent_weapon/dagger + spawning_item = /obj/item/melee/forged_reagent_weapon/dagger + force = 3 + double_edged_damage = 2 /obj/item/forging/complete/staff name = "staff head" desc = "A staff head, ready to get some wood for completion." icon_state = "staffhead" - spawning_item = /obj/item/forging/reagent_weapon/staff + spawning_item = /obj/item/melee/forged_reagent_weapon/staff /obj/item/forging/complete/spear name = "spear head" desc = "A spear head, ready to get some wood for completion." icon_state = "spearhead" - spawning_item = /obj/item/forging/reagent_weapon/spear + spawning_item = /obj/item/melee/forged_reagent_weapon/spear + force = 3 + double_edged_damage = 2 /obj/item/forging/complete/axe name = "axe head" desc = "An axe head, ready to get some wood for completion." icon_state = "axehead" - spawning_item = /obj/item/forging/reagent_weapon/axe + spawning_item = /obj/item/melee/forged_reagent_weapon/axe + force = 5 /obj/item/forging/complete/hammer name = "hammer head" desc = "A hammer head, ready to get some wood for completion." icon_state = "hammerhead" - spawning_item = /obj/item/forging/reagent_weapon/hammer + spawning_item = /obj/item/melee/forged_reagent_weapon/hammer + force = 5 /obj/item/forging/complete/pickaxe name = "pickaxe head" desc = "A pickaxe head, ready to get some wood for completion." icon_state = "pickaxehead" spawning_item = /obj/item/pickaxe/reagent_weapon + force = 5 /obj/item/forging/complete/shovel name = "shovel head" @@ -257,6 +345,16 @@ desc = "An arrowhead, ready to get some wood for completion." icon_state = "arrowhead" spawning_item = /obj/item/arrow_spawner + force = 3 + double_edged_damage = 2 + +/obj/item/forging/complete/revolver_cylinder + name = "single-action revolver cylinder" + icon_state = "revolver_cylinder" + +/obj/item/forging/complete/revolver_frame + name = "single-action revolver frame" + icon_state = "revolver_frame" /obj/item/forging/complete/rail_nail name = "rail nail" @@ -264,6 +362,7 @@ icon = 'modular_skyrat/modules/ashwalkers/icons/railroad.dmi' icon_state = "nail" spawning_item = /obj/item/stack/rail_track/ten + force = 3 /obj/item/forging/coil name = "coil" @@ -284,7 +383,7 @@ return ..() /obj/item/arrow_spawner - name = "arrow spawner" + name = "arrows" desc = "You shouldn't see this." /// the amount of arrows that are spawned from the spawner var/spawning_amount = 4 @@ -307,24 +406,38 @@ return ..() /obj/item/stack/tong_act(mob/living/user, obj/item/tool) - . = ..() + if(amount < 1) + user.balloon_alert(user, "not enough material in the stack!") + return FALSE if(length(tool.contents) > 0) user.balloon_alert(user, "tongs are full already!") return FALSE if(!material_type && !custom_materials) user.balloon_alert(user, "invalid material!") return - forceMove(tool) - tool.icon_state = "tong_full" + + var/obj/item/stack/stack_to_move + if(amount == 1) + stack_to_move = src + else + stack_to_move = split_stack(1) + + if(!isnull(stack_to_move)) + stack_to_move.forceMove(tool) + user.balloon_alert(user, "took one") + tool.icon_state = "tong_full" + else + stack_trace("[src] was grabbed by [tool] and couldn't pull one sheet!") /obj/tong_act(mob/living/user, obj/item/tool) . = ..() if(length(tool.contents)) user.balloon_alert(user, "tongs are full already!") return FALSE - if(skyrat_obj_flags & ANVIL_REPAIR) + if(!isnull(GetComponent(/datum/component/forge_smithable/)) || !isnull(GetComponent(/datum/component/reagent_imbued))) forceMove(tool) tool.icon_state = "tong_full" + user.balloon_alert(user, "took [src]") /obj/item/empty_circuit name = "empty circuit" @@ -365,3 +478,5 @@ return return ..() + +/obj/item/ diff --git a/modular_skyrat/modules/reagent_forging/code/forge_revolver.dm b/modular_skyrat/modules/reagent_forging/code/forge_revolver.dm new file mode 100644 index 00000000000..94dabfe6a37 --- /dev/null +++ b/modular_skyrat/modules/reagent_forging/code/forge_revolver.dm @@ -0,0 +1,225 @@ +// COMSIG_ATOM_WAS_ATTACKED check out this signal's implementation + +/obj/item/gun/ballistic/revolver/handcrafted_single_action + name = "\improper handcrafted revolver" + desc = "A traditional-style cowboy revolver. It's single-action, so the hammer must be manually cocked back to cycle the round." + icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_items.dmi' + icon_state = "revolver_preview" + icon_preview = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_items.dmi' + icon_state_preview = "revolver_preview" + accepted_magazine_type = /obj/item/ammo_box/magazine/internal/cylinder/handcrafted_single_action + fire_sound_volume = 90 + bolt_type = BOLT_TYPE_NO_BOLT + semi_auto = FALSE + mag_display = FALSE + bolt_wording = "hammer" + rack_delay = 1 + fire_delay = 1 + //just a little extra damage as a treat + projectile_damage_multiplier = 1.2 + ///below stats should match or exceed the murphy's + throwforce = 14 + force = 8 + material_flags = MATERIAL_EFFECTS | MATERIAL_AFFECT_STATISTICS | MATERIAL_ADD_PREFIX + + //is the hammer primed (ready to fire) or released (safe)? + var/hammer_is_primed = FALSE + var/hammer_pull_speed_fanning = 0 DECISECONDS + var/hammer_pull_speed_onehanded = 5 DECISECONDS + var/static/holster_misfire_chance = 70 + + //forging base components + var/obj/item/forging/complete/revolver_frame/frame + var/obj/item/forging/complete/revolver_cylinder/cylinder + +/obj/item/gun/ballistic/revolver/handcrafted_single_action/Initialize(mapload) + . = ..() + AddComponent(/datum/component/reagent_imbued/weapon, oil_effects = list(FORGE_EFFECT_FORCE = 4)) + AddComponent(/datum/component/forge_smithable, \ + FORGING_WEAPON_REFORGING_MAX_QUALITY, \ + TRUE, \ + FORGING_WEAPON_REFORGING_MAX_PERFECT_HITS, \ + FORGING_WEAPON_REFORGING_MAX_BAD_HITS, \ + FORGING_WEAPON_REFORGING_AVERAGE_WAIT, \ + perfection_effects = list(FORGE_EFFECT_FORCE = MAX_PERFECT_FORCE_BONUS)) + + RegisterSignal(src, COMSIG_MOVABLE_THROW_LANDED, PROC_REF(try_throw_misfire)) + +/obj/item/gun/ballistic/revolver/handcrafted_single_action/change_material_strength(datum/material/material, mat_amount, multiplier, remove = FALSE) + blacksmithing_change_material_strength(src, material, mat_amount, multiplier, remove) + + var/density = material.get_property(MATERIAL_DENSITY) + var/hardness = material.get_property(MATERIAL_HARDNESS) + var/flexibility = material.get_property(MATERIAL_FLEXIBILITY) + var/inaccuracy_modifier = max(0, ((flexibility * 2) - (density + hardness)) * 40 ) + var/damage_modifier = min(0, ((density + hardness) - (flexibility * 2)) / 20) + + if(!remove) + spread += inaccuracy_modifier + projectile_damage_multiplier += damage_modifier + else + spread -= inaccuracy_modifier + projectile_damage_multiplier -= damage_modifier + +/obj/item/gun/ballistic/revolver/handcrafted_single_action/give_manufacturer_examine() + return + + +/obj/item/gun/ballistic/revolver/handcrafted_single_action/update_icon(updates) + . = ..() + icon_state = "revolver_handle" + +/obj/item/gun/ballistic/revolver/handcrafted_single_action/update_overlays() + . = ..() + + var/mutable_appearance/temp_mutable + if(hammer_is_primed) + temp_mutable = mutable_appearance(icon, "revolver_frame_primed") + else + temp_mutable = mutable_appearance(icon, "revolver_frame") + + if(!isnull(frame)) + temp_mutable.color = frame?.color + . += temp_mutable + + temp_mutable = mutable_appearance(icon,"revolver_cylinder_inserted") + if(!isnull(cylinder)) + temp_mutable.color = cylinder?.color + . += temp_mutable + +///Can't be toggled safety -- you need to manage the hammer +/obj/item/gun/ballistic/revolver/handcrafted_single_action/give_gun_safeties() + return + +/obj/item/gun/ballistic/revolver/handcrafted_single_action/shoot_with_empty_chamber() + . = ..() + set_hammer_cock(FALSE) + +///go my snowflake code for handling the revolver's hammer!!! +/obj/item/gun/ballistic/revolver/handcrafted_single_action/attack_self(mob/living/user) + if(recent_rack > world.time) + return + + var/rack_delay_to_use + var/obj/item/bodypart/other_hand = user.has_hand_for_held_index(user.get_inactive_hand_index()) // + if(user.get_inactive_held_item() || !other_hand) //if both hands occupied, one-handed rack + rack_delay_to_use = hammer_pull_speed_onehanded + else + rack_delay_to_use = hammer_pull_speed_fanning + recent_rack = world.time + rack_delay_to_use + rack(user) + +/obj/item/gun/ballistic/revolver/handcrafted_single_action/rack(mob/user = null) + if(DOING_INTERACTION(user, DOAFTER_REVOLVER_HAMMER_COCK)) + return + + if(!hammer_is_primed) + set_hammer_cock(TRUE) + balloon_alert(user, "cocked the hammer") + playsound(src, 'sound/items/weapons/gun_mode_switch1.ogg', vol = 35, vary = TRUE, frequency = 1.8, extrarange = SHORT_RANGE_SOUND_EXTRARANGE) + if(!istype(magazine,/obj/item/ammo_box/magazine/internal/cylinder)) + stack_trace("[usr] has a magazine that isn't a revolver cylinder!") + var/obj/item/ammo_box/magazine/internal/cylinder/my_cylinder = magazine + my_cylinder.rotate() + chamber_round() + else + set_hammer_cock(FALSE) + balloon_alert(user, "decocked the hammer") + playsound(src, 'sound/items/weapons/gun_mode_switch1.ogg', vol = 35, vary = TRUE, frequency = 1.6, extrarange = SHORT_RANGE_SOUND_EXTRARANGE) + +/obj/item/gun/ballistic/revolver/handcrafted_single_action/proc/set_hammer_cock(cock) + hammer_is_primed = cock + update_appearance() + +/obj/item/gun/ballistic/revolver/handcrafted_single_action/try_fire_gun(atom/target, mob/living/user, params) + if(hammer_is_primed) + return ..() + else + balloon_alert(user, "hammer isn't cocked!") + return FALSE + +////////////////////////// MISFIRE WHEN SHOVED OR ATTACKED /////////////////////////////////////// + +/obj/item/gun/ballistic/revolver/handcrafted_single_action/process_fire(atom/target, mob/living/user, message, params, zone_override, bonus_spread) + set_hammer_cock(FALSE) + . = ..() + +/obj/item/gun/ballistic/revolver/handcrafted_single_action/equipped(mob/user, slot, initial) + . = ..() + var/static/list/connections = list( + COMSIG_ATOM_WAS_ATTACKED = PROC_REF(try_attack_misfire)//, + ///COMSIG_CARBON_HELP_ACT = PROC_REF(try_hug_misfire), + //COMSIG_LIVING_Z_IMPACT = PROC_REF(try_fall_misfire), + ) + if(slot != ITEM_SLOT_HANDS) + AddComponent(/datum/component/connect_inventory, user, connections, allowed_slots = ALL ^ ITEM_SLOT_HANDS) + +/obj/item/gun/ballistic/revolver/handcrafted_single_action/dropped(mob/user, silent) + . = ..() + qdel(GetComponent(/datum/component/connect_inventory)) + + +/obj/item/gun/ballistic/revolver/handcrafted_single_action/proc/try_attack_misfire(mob/victim, mob/attacker, attack_flags) + if(attack_flags & ATTACKER_SHOVING && prob(50)) + if(holster_misfire(victim, attacker) == TRUE) + victim.visible_message(span_warning("[victim]'s [src] goes off from [attacker]'s attack!"), + span_danger("Your primed [src] triggers from [attacker]'s strike! "), ignored_mobs = victim) + +/* +/obj/item/gun/ballistic/revolver/handcrafted_single_action/proc/try_hug_misfire(mob/living/source) + if(prob(3)) + if(holster_misfire(victim, attacker) == TRUE) + user.visible_message(span_warning("[victim]'s [src] goes off from [attacker]'s hug!"), + span_danger("Your primed [src] triggers from [attacker]'s hug! "), ignored_mobs = victim) + + +/obj/item/gun/ballistic/revolver/handcrafted_single_action/proc/try_fall_misfire(datum/source, levels, turf/fell_on) + if(prob(70)) + if(holster_misfire(victim, attacker) == TRUE) + user.visible_message(span_warning("[victim]'s [src] goes off from [attacker]'s hug!"), + span_danger("Your primed [src] triggers from the sharp fall! "), ignored_mobs = victim) +*/ +/obj/item/gun/ballistic/revolver/handcrafted_single_action/proc/holster_misfire(mob/victim, mob/attacker) + return try_fire_gun(victim, attacker, null, FALSE) + +/obj/item/gun/ballistic/revolver/handcrafted_single_action/proc/try_throw_misfire(datum/source, datum/thrownthing/throwingdatum) + SIGNAL_HANDLER + //todo: gun fires in random direction if it's thrown + //if(prob(100)) + return + +////////////////////////////////////// MISC RELATED STUFF ////////////////////////////////////// + +/obj/item/ammo_box/magazine/internal/cylinder/handcrafted_single_action + name = "handcrafted revolver cylinder" + start_empty = TRUE + ammo_type = /obj/item/ammo_casing/c38 + caliber = CALIBER_38 + max_ammo = 6 + +///cause apparently tgcode doesn't have a bug check against if start_empty = false +/obj/item/ammo_box/magazine/internal/cylinder/handcrafted_single_action/Initialize(mapload) + . = ..() + while(stored_ammo.len < max_ammo) + stored_ammo += null + +///get round doesn't spin the cylinder; cocking the hammer (from rack()) must be used to spin the cylinder +/obj/item/ammo_box/magazine/internal/cylinder/handcrafted_single_action/get_round() + var/casing = null + if(length(stored_ammo) >= 1) + casing = stored_ammo[1] + if (ispath(casing)) + casing = new casing(src) + stored_ammo[1] = casing + return casing + +/obj/item/ammo_box/magazine/internal/cylinder/handcrafted_single_action/spin() + . = ..() + +/datum/material_slot/revolver/frame + name = "frame" + material_amount = 1 + +/datum/material_slot/revolver/cylinder + name = "frame" + material_amount = 0.9 diff --git a/modular_skyrat/modules/reagent_forging/code/forge_smithable_component.dm b/modular_skyrat/modules/reagent_forging/code/forge_smithable_component.dm new file mode 100644 index 00000000000..ac712bf42ee --- /dev/null +++ b/modular_skyrat/modules/reagent_forging/code/forge_smithable_component.dm @@ -0,0 +1,376 @@ +#define ANVIL_HAMMER_HIT_GOOD 1 +#define ANVIL_HAMMER_HIT_BAD 0 +#define ANVIL_HAMMER_HIT_PERFECT 2 +#define ANVIL_HAMMER_HIT_CANNOT_WORK 3 +#define ANVIL_SMITHING_CHIP_QUALITY_BONUS 0.5 + +/datum/component/forge_smithable + ///the item that the component is attached to + var/obj/item/parent_item + ///required type to attach to + var/obj/item/required_type = /obj/item + + ///the quality points of the incomplete item; goes up on good/perfect hits + var/quality_points = 0 + ///the quality points required for it to be considered usable for crafting + var/completion_quality_points = 1 + ///the required time before each strike to prevent spamming + var/average_wait = 100 SECONDS + ///total current bad hits + var/bad_hits_total = 0 + ///the bad hits required for it to break; exceeding this will break the item + var/bad_hit_maximum = 1 + ///the number of current perfect hits + var/current_perfects = 0 + ///maximum number of perfect hits before perfect hits no longer improve the quality + var/max_perfect_hits = 1 + var/can_perfect_hit = TRUE + //what color does the parent item turn when heated? if null, then parent item doesn't change color when heated + var/heat_color = null + + //what happens when quenched or cooled? + var/datum/callback/quench_callback = null + var/datum/callback/passive_cool_callback = null + //do we change the reagents imbued? + var/quench_causes_reimbue = TRUE + //index: what type of effect (ex. increase armor, increase AP, increase force) + //element: by how much to increase + var/list/quench_effects_perfection = list() + var/list/quench_effects_incompletion = list() + //use this to track the completion/perfection amounts last applied upon quench + var/perfection_ratio_applied = 0 + var/completion_applied_multiplier = 0 + COOLDOWN_DECLARE(heating_remainder) + +/* Gives a given item the smithable component -- which allows it to be picked up with tongs, smithed with a hammer, and quenched in reagent. + * + * completion_needed: The number of quality points (increased by hammer strikes) required to finish the item. + * can_perfect: If perfect strikes are possible on this equipment piece. + * max_perfection: Maximum perfection points to fully perfect this piece of equipment. + * max_breakage: How many bad hits can be done before it breaks + * wait_time: Time between strikes needed for it to no longer be considered a bad hit + * on_quench: What function on the parent item to call when this item is quenched. + * on_passive_cool: What function on the parent item to call when this item loses all heat. + * on_forging_heat: What function on the parent item to call when this item is heated in a forge. + * color: The color to use when the parent item is heated. + * perfection_effects: What effects to apply based on the % perfection. (Associative list.) + * incompletion_effects: What penalties to apply based on how incomplete this item is at quench. (Associative list.) + */ +/datum/component/forge_smithable/Initialize(completion_needed, can_perfect, max_perfection, max_breakage, wait_time, datum/callback/on_quench = null, datum/callback/on_passive_cool = null, datum/callback/on_forging_heat = null, color = "#FF4400", list/perfection_effects = null, list/incompletion_effects = null) + if(!istype(parent, required_type)) + return COMPONENT_INCOMPATIBLE + parent_item = parent + average_wait = wait_time + completion_quality_points = completion_needed + max_perfect_hits = max_perfection + bad_hit_maximum = max_breakage + can_perfect_hit = can_perfect + + quench_callback = on_quench + passive_cool_callback = on_passive_cool + if(!isnull(on_quench)) + RegisterSignal(parent_item, COMSIG_SMITHING_QUENCH, on_quench) + if(!isnull(on_passive_cool)) + RegisterSignal(parent_item, COMSIG_SMITHING_PASSIVE_COOLED, on_passive_cool)//TYPE_PROC_REF(parent_item.type, on_passive_cool)) + if(length(color) > 0) + heat_color = color + if(!isnull(perfection_effects)) + quench_effects_perfection = perfection_effects + if(!isnull(incompletion_effects)) + quench_effects_incompletion = incompletion_effects + RegisterSignal(parent_item, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + +/datum/component/forge_smithable/proc/on_examine(datum/source, mob/user, list/examine_list) + SIGNAL_HANDLER + examine_list += span_notice("It can be safely picked up with tongs.") + examine_list += span_notice("It can be heated by being inserted into a forge.") + examine_list += span_notice("It can be quenched in any open container that's large enough.") + if(USER_CAN_SEE_SMITHING_INFO(user)) + examine_list += span_notice("You'd estimate that it's about [round(get_completion_ratio() * 100)]% complete.") + examine_list += span_notice("The careful smithing makes it look about [round(get_perfect_ratio() * 100)]% perfected.") + if(COOLDOWN_FINISHED(src, heating_remainder)) + examine_list += span_notice("The metal needs to be reheated before it is malleable again.") + else + examine_list += span_notice("The metal is hot enough to work.") + + else + examine_list += span_notice("If you were more skilled at smithing you could discern more information from it...") + + +/datum/component/forge_smithable/proc/good_hit(amount = 1, playsound = FALSE) + quality_points = clamp(amount + quality_points, 0, completion_quality_points) + if(playsound) + playsound(parent_item, 'sound/items/weapons/parry.ogg', vol = 45, vary = TRUE, frequency = 1.3, extrarange = MEDIUM_RANGE_SOUND_EXTRARANGE, volume_preference = /datum/preference/numeric/volume/sound_ambience_volume) + +/datum/component/forge_smithable/proc/perfect_hit(amount = 1, playsound = FALSE) + good_hit(amount, FALSE) + if(playsound) + playsound(parent_item, 'sound/items/weapons/parry.ogg', vol = 45, vary = TRUE, frequency = 1.0, extrarange = MEDIUM_RANGE_SOUND_EXTRARANGE, volume_preference = /datum/preference/numeric/volume/sound_ambience_volume) + if(current_perfects < max_perfect_hits) + current_perfects = clamp(current_perfects + amount, 0, max_perfect_hits) + +/datum/component/forge_smithable/proc/bad_hit(amount = 2, playsound = FALSE) + bad_hits_total += amount + if(check_for_breakage()) + forging_breakage() + else + if(playsound) + playsound(parent_item, 'sound/items/weapons/parry.ogg', vol = 35, vary = TRUE, frequency = 0.4, extrarange = MEDIUM_RANGE_SOUND_EXTRARANGE, volume_preference = /datum/preference/numeric/volume/sound_ambience_volume) + +/datum/component/forge_smithable/proc/check_for_breakage() + if(bad_hits_total > bad_hit_maximum) + return TRUE + return FALSE + +/datum/component/forge_smithable/proc/forging_breakage(playsound = TRUE) + if(playsound) + conditional_pref_sound(parent_item, 'modular_skyrat/modules/reagent_forging/sound/forge.ogg', vol = 35, vary = TRUE, extrarange = MEDIUM_RANGE_SOUND_EXTRARANGE, ignore_walls = FALSE, pref_to_check = /datum/preference/numeric/volume/sound_ambience_volume) + + parent_item.balloon_alert_to_viewers("the [parent_item] shattered!") + qdel(parent_item) + qdel(src) + +/datum/component/forge_smithable/proc/is_finished_smithing() + if(quality_points >= completion_quality_points) + return TRUE + return FALSE + +/datum/component/forge_smithable/proc/get_completion_ratio() + return quality_points / completion_quality_points + +/datum/component/forge_smithable/proc/is_perfected() + if(current_perfects >= max_perfect_hits) + return TRUE + return FALSE + +/datum/component/forge_smithable/proc/get_perfect_ratio() + return current_perfects / max_perfect_hits + +/datum/component/forge_smithable/proc/show_balloon_alert(mob/living/user, hit_quality) + if(!HAS_TRAIT(user, TRAIT_DEAF)) + switch(hit_quality) + if(ANVIL_HAMMER_HIT_CANNOT_WORK) + parent_item.balloon_alert(user,"can't work!") + if(ANVIL_HAMMER_HIT_BAD) + parent_item.balloon_alert(user,"bad hit") + if(ANVIL_HAMMER_HIT_GOOD) + if(is_finished_smithing()) + if(is_perfected()) + parent_item.balloon_alert(user,"[parent_item] is perfected!") + else + parent_item.balloon_alert(user,"[parent_item] sounds done") + else + parent_item.balloon_alert(user, "good hit") + if(ANVIL_HAMMER_HIT_PERFECT) + if(is_finished_smithing() && is_perfected()) + parent_item.balloon_alert(user,"[parent_item] is perfected!") + else + parent_item.balloon_alert(user, "perfect hit!") + +/datum/component/forge_smithable/proc/get_hit_quality(mob/living/user, obj/item/forging/hammer/tool) + if(parent_item.GetComponent(/datum/component/reagent_imbued)) + var/datum/component/reagent_imbued/reagent_component = parent_item.GetComponent(/datum/component/reagent_imbued) + if(reagent_component.imbued_reagent.reagent_list.len >= 1 && !USER_CAN_REAGENT_IMBUE(user)) + return ANVIL_HAMMER_HIT_CANNOT_WORK + + if(!COOLDOWN_FINISHED(user, striking_cooldown)) + return ANVIL_HAMMER_HIT_BAD + + if(can_perfect_hit) + if(user.mind.get_skill_level(/datum/skill/smithing) >= SKILL_LEVEL_LEGENDARY) + return ANVIL_HAMMER_HIT_PERFECT + if(!COOLDOWN_FINISHED(user, perfect_strike_window) && COOLDOWN_FINISHED(user, striking_cooldown)) + return ANVIL_HAMMER_HIT_PERFECT + + return ANVIL_HAMMER_HIT_GOOD + +/datum/component/forge_smithable/proc/get_quality_points(mob/living/user, obj/item/tool) + var/total_quality_points = 1 + + total_quality_points *= get_material_quality_points_mult(parent_item.get_master_material()) + + //toolspeed doesn't affect the speed at which you strike the anvil, but it DOES affect the quality points gained (and thus how quickly the item is finished completion) + total_quality_points /= tool.toolspeed + + //if the user has advanced smithing, then they also get a smithing hit bonus + if(HAS_TRAIT(user, TRAIT_KNOW_ADVANCED_SMITHING)) + total_quality_points += ANVIL_SMITHING_CHIP_QUALITY_BONUS + + //finally, all hits have a minimum quality amount + total_quality_points = max(MINIMUM_SMITHING_QUALITY_POINTS, total_quality_points) + + return total_quality_points + +/datum/component/forge_smithable/proc/reset(reset_perfects = FALSE) + quality_points = 0 + bad_hits_total = 0 + if(reset_perfects) + current_perfects = 0 + +////////////////////// FOR ACTUAL SMITHING ACTIONS ///////////////////////// + +/* Tries to apply a hit onto the item using the tool. Will calculate the appropriate hit quality and increase the completion based on that. + * + * user: The user who is trying to smith. + * tool: The tool they are using to smith with. + */ +/datum/component/forge_smithable/proc/anvil_work(mob/living/user, obj/item/tool) + if(COOLDOWN_FINISHED(src, heating_remainder)) + bad_hit() + user.balloon_alert(user, "metal too cool") + return ITEM_INTERACT_SUCCESS + + var/quality_points_to_give = get_quality_points(user, tool) + var/hit_quality = get_hit_quality(user, tool) + switch(hit_quality) + if(ANVIL_HAMMER_HIT_CANNOT_WORK) + bad_hit(playsound = TRUE) + to_chat(user, span_warning("You don't know how to work with reagent imbued items!")) + if(ANVIL_HAMMER_HIT_BAD) + bad_hit(playsound = TRUE) + if(ANVIL_HAMMER_HIT_GOOD) + good_hit(amount = quality_points_to_give, playsound = TRUE) + user.mind.adjust_experience(/datum/skill/smithing, 1) //A good hit gives mild experience + do_sparks(1, FALSE, src) + if(ANVIL_HAMMER_HIT_PERFECT) + perfect_hit(amount = quality_points_to_give, playsound = TRUE) + user.mind.adjust_experience(/datum/skill/smithing, 5) //A perfect hit gives good experience + do_sparks(2, FALSE, parent_item) + + show_balloon_alert(user, hit_quality) + + var/skill_modifier = user.mind.get_skill_modifier(/datum/skill/smithing, SKILL_SPEED_MODIFIER) * average_wait + COOLDOWN_START(user, striking_cooldown, skill_modifier) + COOLDOWN_START(user, perfect_strike_window, skill_modifier + (user.mind.get_skill_level(/datum/skill/smithing) DECISECONDS / 2)) + +/* Attempts to quench the item using the given reagents. The reagents source must fill certain criteria to be elligible to do this -- and various effects can apply depending on the reagents used and their temp. + * + * dunk_reagents: The reagents source to try and use. + * dunk_object: The container of the reagents source. + * user: The person trying to quench the item. + * show_message: Should we show a message of the quench outcome? + */ +/datum/component/forge_smithable/proc/try_quench(datum/reagents/dunk_reagents, dunk_object, mob/living/user, show_message = TRUE) + if(COOLDOWN_FINISHED(src, heating_remainder)) + if(show_message) + parent_item.balloon_alert(user, "[parent_item] is too cool to successfully quench!") + return FALSE + if(!(dunk_reagents.flags & DUNKABLE)) + if(show_message) + parent_item.balloon_alert(user, "[dunk_object] doesn't have a large enough hole to immerse [parent_item]!") + return FALSE + if(dunk_reagents.chem_temp > MAX_QUENCH_HEAT) + if(show_message) + parent_item.balloon_alert(user, "[dunk_object] is too hot to cool [parent_item]!") + return FALSE + if(dunk_reagents.total_volume < MIN_VOLUME_TO_QUENCH) + if(show_message) + parent_item.balloon_alert(user, "[dunk_object] doesn't contain enough fluid to immerse [parent_item]!") + return FALSE + + dunk_reagents.expose_temperature(HEAT_GIVEN_FROM_QUENCHING_METAL) + COOLDOWN_RESET(src, heating_remainder) + playsound(parent_item, 'modular_skyrat/modules/reagent_forging/sound/hot_hiss.ogg', 50, TRUE) + + if(!isnull(heat_color)) + parent_item.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY) + parent_item.update_integrity(max(round(lerp(0, parent_item.max_integrity, get_completion_ratio())), parent_item.get_integrity())) + if(quench_causes_reimbue && USER_CAN_REAGENT_IMBUE(user)) + var/datum/component/reagent_imbued/my_imbue = parent_item.GetComponent(/datum/component/reagent_imbued) + if(!isnull(my_imbue)) + my_imbue.set_reagent_imbue(dunk_reagents, FALSE, TRUE) + if(show_message) + parent_item.balloon_alert(user, "[parent_item] is imbued!") + else if(show_message) + parent_item.balloon_alert(user, "[parent_item] is quenched!") + + if(!isnull(quench_callback)) + quench_callback.Invoke(dunk_reagents, dunk_object, user) + return TRUE + +/* Heats the item up for smithing -- and also colors the item with heat colors if applicable. + * + * heat_time: The time until the item cools again. + * additive: If reheating an already-hot item extends the time or not. + */ +/datum/component/forge_smithable/proc/heat_for_smithing(heat_time, additive = FALSE) + if(!isnull(heat_color)) + parent_item.add_atom_colour(color_transition_filter(heat_color, SATURATION_OVERRIDE), TEMPORARY_COLOUR_PRIORITY) + if(additive) + COOLDOWN_START(src, heating_remainder, heat_time + COOLDOWN_TIMELEFT(src, heating_remainder)) + else + COOLDOWN_START(src, heating_remainder, heat_time) + +/* Sets the item's completion and perfection amount -- and applies the bonuses and penalties based on that. + * + * completion_amount: The completion points amount to set. + * perfection_amount: The perfection points amount to set. + */ +/datum/component/forge_smithable/proc/set_completion_and_perfection(completion_amount, perfection_amount) + quality_points = completion_amount + current_perfects = perfection_amount + apply_completion_perfection_modifiers(get_completion_ratio(), get_perfect_ratio()) + +/* Sets the item's completion and perfection amount perentage -- and applies the bonus and penalties based on that. + * + * completion_ratio: The completion amount to set (as a decimal from 0.0 - 1.0 inclusive) + * perfection_ratio: The perfection amount to set (as a decimal from 0.0 - 1.0 inclusive) + */ +/datum/component/forge_smithable/proc/set_completion_and_perfection_ratios(completion_ratio, perfection_ratio) + quality_points = round(completion_ratio * completion_quality_points) + current_perfects = round(perfection_ratio * max_perfect_hits) + apply_completion_perfection_modifiers(completion_ratio, perfection_ratio) + +/* Applies the incompletion penalty and perfection bonus to the item with the given amounts. + * + * completion_ratio: The completion amount to set (as a decimal from 0.0 - 1.0 inclusive) + * perfection_ratio: The perfection amount to set (as a decimal from 0.0 - 1.0 inclusive) + */ +/datum/component/forge_smithable/proc/apply_completion_perfection_modifiers(completion_ratio, perfection_ratio) + for(var/index in quench_effects_perfection) + give_added_modifying_effect_to_item(index, perfection_ratio_applied, perfection_ratio, parent_item, quench_effects_perfection[index]) + + var/incompletion_multiplier + var/incomplete_maximum_penalty + if(completion_ratio < 1) + incompletion_multiplier = 1 - lerp(MIN_INCOMPLETE_FORGING_SCALING_PENALTY, MAX_INCOMPLETE_FORGING_SCALING_PENALTY, completion_ratio) + else + incompletion_multiplier = 0 + for(var/index in quench_effects_incompletion) + switch(index) + if(FORGE_EFFECT_ARMOR) + var/datum/armor/temp_armor = get_armor_by_type(parent_item.get_initial_armor_type()) + incomplete_maximum_penalty = temp_armor.generate_new_with_multipliers(list(ARMOR_ALL = -1)) + if(FORGE_EFFECT_ARMORPEN) + incomplete_maximum_penalty = initial(parent_item.armour_penetration) * -1 + if(FORGE_EFFECT_BLOCKCHANCE) + incomplete_maximum_penalty = initial(parent_item.block_chance) * -1 + if(FORGE_EFFECT_DURABILITY) + incomplete_maximum_penalty = initial(parent_item.max_integrity) * -1 + if(FORGE_EFFECT_FORCE) + incomplete_maximum_penalty = initial(parent_item.force) * -1 + if(FORGE_EFFECT_REAGENT_INJECT) + var/datum/component/reagent_imbued/reagent_component = parent_item.GetComponent(/datum/component/reagent_imbued) + if(!isnull(reagent_component)) + stack_trace("[parent_item] has an invalid reagent imbue-enhancing effect, because it has no reagent component!") + incomplete_maximum_penalty = initial(reagent_component.inject_amount) * -1 + if(FORGE_EFFECT_TOOLSPEED) + incomplete_maximum_penalty = initial(parent_item.toolspeed) * 2 + else + stack_trace("Tried to modify [parent_item] with an invalid effect [index]!") + give_added_modifying_effect_to_item(index, completion_applied_multiplier, incompletion_multiplier, parent_item, incomplete_maximum_penalty) + + perfection_ratio_applied = perfection_ratio + completion_applied_multiplier = incompletion_multiplier + +/mob/living + //the time between each strike + COOLDOWN_DECLARE(striking_cooldown) + //the time it takes to prepare a perfect strike. should always be > striking_cooldown + COOLDOWN_DECLARE(perfect_strike_window) + +#undef ANVIL_HAMMER_HIT_GOOD +#undef ANVIL_HAMMER_HIT_BAD +#undef ANVIL_HAMMER_HIT_PERFECT +#undef ANVIL_HAMMER_HIT_CANNOT_WORK +#undef ANVIL_SMITHING_CHIP_QUALITY_BONUS diff --git a/modular_skyrat/modules/reagent_forging/code/forge_weapons.dm b/modular_skyrat/modules/reagent_forging/code/forge_weapons.dm index c93172c14d8..a8179943b37 100644 --- a/modular_skyrat/modules/reagent_forging/code/forge_weapons.dm +++ b/modular_skyrat/modules/reagent_forging/code/forge_weapons.dm @@ -1,18 +1,196 @@ +#define STUN_ATTACK "stun attack" + // Damage is technically 10 by default since that's the max you get from perfect hits when crafting. Find a non-third-of-sth value for the multiplier to get to 18, I'll wait -/obj/item/forging/reagent_weapon +/obj/item/melee/forged_reagent_weapon + name = "forged reagent weapon" icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_items.dmi' lefthand_file = 'modular_skyrat/modules/reagent_forging/icons/mob/forge_weapon_l.dmi' righthand_file = 'modular_skyrat/modules/reagent_forging/icons/mob/forge_weapon_r.dmi' worn_icon = 'modular_skyrat/modules/reagent_forging/icons/mob/forge_weapon_worn.dmi' - material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR + integrity_failure = 0.5 + material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS obj_flags = UNIQUE_RENAME - skyrat_obj_flags = ANVIL_REPAIR + abstract_type = /obj/item/melee/forged_reagent_weapon -/obj/item/forging/reagent_weapon/examine(mob/user) + //keeps track of how much force was taken away from incomplete forging + var/completion_force_penalty = 0 + //keeps track of how much force was given from perfect hammering + var/perfect_forging_bonus = 0 + + //chance to self damage from being clumsy + var/clumsy_backfire_chance = 70 + + //vars for nonlethal strikes + //can this item nonlethal attack? + var/can_nonlethal_altfire = TRUE + //time between nonlethal attacks + var/nonlethal_strike_cooldown = 4 SECONDS + COOLDOWN_DECLARE(nonlethal_strike_cooldown_timer) + /// The path of the default sound to play when we stun something. + var/on_stun_sound = 'sound/effects/woodhit.ogg' + //verbs to use when secondary attacking + var/list/secondary_attack_verb_continuous = list("shaft-strikes") + var/list/secondary_attack_verb_simple = list("shaft-strike") + + //below numbers are multiplied by the weapon's force + //how much stamina damage to apply on a rightclick + var/stamina_damage_multiplier = 2 + //how long the victim should be knockdowned + var/knockdown_time_multiplier = 0.5 DECISECONDS + + +/obj/item/melee/forged_reagent_weapon/examine(mob/user) . = ..() - . += span_notice("Using a hammer on [src] will repair its damage!") + var/healthpercent = round((atom_integrity/max_integrity) * 100, 1) + switch(healthpercent) + if(50 to 99) + . += span_info("It looks slightly damaged.") + if(25 to 50) + . += span_info("It appears heavily damaged.") + if(0 to 25) + . += span_warning("It's falling apart!") -/obj/item/forging/reagent_weapon/sword +/obj/item/melee/forged_reagent_weapon/Initialize(mapload) + . = ..() + if (length(secondary_attack_verb_continuous) != length(secondary_attack_verb_simple)) + stack_trace("[src] doesn't have equal secondary attack verb lengths, please fix!") + apply_reagent_component() + apply_smithing_component() + +/* needs updating to the new bane component, todo later by the person who actually knows how to handle such a thing +/obj/item/melee/forged_reagent_weapon/set_custom_materials(list/materials, multiplier = 1) + if(/datum/material/silver in materials) + AddComponent(/datum/component/bane, affected_biotypes = MOB_MINING, added_damage = 80) //For killing really big monsters. + AddElement(/datum/element/bane, /datum/species/lycan, damage_multiplier = 3, requires_combat_mode = FALSE) + else + RemoveComponent(/datum/component/bane) + */ + +/obj/item/melee/forged_reagent_weapon/change_material_integrity(datum/material/material, amount, multiplier, removing = FALSE) + blacksmithing_change_material_integrity(src, material, amount, multiplier, removing) + +/obj/item/melee/forged_reagent_weapon/change_material_strength(datum/material/material, mat_amount, multiplier, remove = FALSE) + blacksmithing_change_material_strength(src, material, mat_amount, multiplier, remove) + +/obj/item/melee/forged_reagent_weapon/proc/apply_reagent_component() + AddComponent(/datum/component/reagent_imbued/weapon, oil_effects = list(FORGE_EFFECT_ARMORPEN = 10)) + +/obj/item/melee/forged_reagent_weapon/proc/apply_smithing_component() + AddComponent(/datum/component/forge_smithable, \ + FORGING_WEAPON_REFORGING_MAX_QUALITY, \ + TRUE, \ + FORGING_WEAPON_REFORGING_MAX_PERFECT_HITS, \ + FORGING_WEAPON_REFORGING_MAX_BAD_HITS, \ + FORGING_WEAPON_REFORGING_AVERAGE_WAIT, \ + perfection_effects = list(FORGE_EFFECT_FORCE = MAX_PERFECT_FORCE_BONUS), \ + incompletion_effects = list(FORGE_EFFECT_FORCE, FORGE_EFFECT_ARMORPEN)) + +// nonlethal secondary attack +/obj/item/melee/forged_reagent_weapon/pre_attack(atom/target, mob/living/user, list/modifiers, list/attack_modifiers) + . = ..() + if(.) + return TRUE + if(!ishuman(target)) + return FALSE // bashing objects + + // clumsy people redirect this attack - yes, this bypasses IWASBATONED and such + if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) + user.visible_message( + span_danger("[user] accidentally hits [user.p_them()]self over the head with [src]! What a doofus!"), + span_userdanger("You accidentally hit yourself over the head with [src]!"), + visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE, + ) + + finalize_nonlethal_strike(user, user, clumsy = TRUE) + user.apply_damage(2 * force, BRUTE, BODY_ZONE_HEAD, attacking_item = src) + log_combat(user, user, "accidentally stun attacked [user.p_them()]self due to their clumsiness", src) + user.do_attack_animation(user) + user.changeNext_move(attack_speed) + return TRUE // you hit yourself, nerd + + var/right_clicked = LAZYACCESS(modifiers, RIGHT_CLICK) + if(can_nonlethal_altfire && right_clicked) + if(COOLDOWN_FINISHED(src, nonlethal_strike_cooldown_timer)) + // when we continue to attack, deal 0 (brute) damage (just stun) + SET_ATTACK_FORCE(attack_modifiers, 0) + MUTE_ATTACK_HITSOUND(attack_modifiers) + HIDE_ATTACK_MESSAGES(attack_modifiers) + LAZYSET(attack_modifiers, STUN_ATTACK, TRUE) + else + return TRUE //if we cannot nonlethal and the player is attempting, cancel the attack + return FALSE + +/obj/item/melee/forged_reagent_weapon/afterattack(atom/target, mob/user, list/modifiers, list/attack_modifiers) + if(QDELETED(target) || !LAZYACCESS(attack_modifiers, STUN_ATTACK)) + return + + finalize_nonlethal_strike(target, user) + + var/list/desc = get_stun_description(target, user) + + if(desc) + target.visible_message(desc["visible"], desc["local"], visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE) + +/// Wrapper for calling "stun()" and doing relevant vfx/sfx +/obj/item/melee/forged_reagent_weapon/proc/finalize_nonlethal_strike(mob/living/target, mob/living/user, clumsy = FALSE) + COOLDOWN_START(src, nonlethal_strike_cooldown_timer, nonlethal_strike_cooldown) + if(on_stun_sound) + playsound(src, on_stun_sound, 30, TRUE, -1) + if(baton_effect(target, user, null, clumsy) && user) + set_batoned(target, user, nonlethal_strike_cooldown) + log_combat(user, target, "stunned", src.name) + +/obj/item/melee/forged_reagent_weapon/proc/baton_effect(mob/living/target, mob/living/user, stun_override, clumsy) + if(iscyborg(target)) + return + + var/trait_check = HAS_TRAIT(target, TRAIT_BATON_RESISTANCE) + if(ishuman(target)) + var/mob/living/carbon/human/human_target = target + if(prob(70)) + human_target.force_say() + + var/stamina_damage = force * stamina_damage_multiplier + var/knockdown_time = force * knockdown_time_multiplier + var/armour_block = target.run_armor_check(BODY_ZONE_CHEST, MELEE, null, null, armour_penetration) + + target.apply_damage(stamina_damage, STAMINA, blocked = armour_block) + if(!trait_check) + target.Knockdown((isnull(stun_override) ? knockdown_time : stun_override)) + SEND_SIGNAL(target, COMSIG_MOB_BATONED, user, src) + return TRUE + +/// Used in marking a target as being hit by a baton +/obj/item/melee/forged_reagent_weapon/proc/set_batoned(mob/living/target, mob/living/user, cooldown) + PRIVATE_PROC(TRUE) + if(!cooldown) + return + var/user_ref = REF(user) // avoids harddels. + ADD_TRAIT(target, TRAIT_IWASBATONED, user_ref) + addtimer(TRAIT_CALLBACK_REMOVE(target, TRAIT_IWASBATONED, user_ref), cooldown) + +/obj/item/melee/forged_reagent_weapon/proc/get_stun_description(mob/living/target, mob/living/user) + PROTECTED_PROC(TRUE) + . = list() + if(length(secondary_attack_verb_continuous) >= 1) + var/random = rand(1, length(secondary_attack_verb_continuous)) + .["visible"] = span_danger("[user] [secondary_attack_verb_continuous[random]] [target] with [src]!") + .["local"] = span_userdanger("[user] [secondary_attack_verb_continuous[random]] you with [src]!") + +/obj/item/melee/forged_reagent_weapon/add_item_context(datum/source, list/context, atom/target, mob/living/user) + if (isturf(target)) + return NONE + + if (isobj(target)) + context[SCREENTIP_CONTEXT_LMB] = "Attack" + else + context[SCREENTIP_CONTEXT_LMB] = "Attack" + if(can_nonlethal_altfire && ishuman(target)) + context[SCREENTIP_CONTEXT_RMB] = "Non-lethally Attack" + + return CONTEXTUAL_SCREENTIP_SET + +/obj/item/melee/forged_reagent_weapon/sword name = "reagent sword" desc = "A sharp, maneuverable bastard sword most adept at blocking opposing melee strikes." force = 7 @@ -32,24 +210,28 @@ attack_verb_simple = list("attack", "slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut") sharpness = SHARP_EDGED max_integrity = 150 + stamina_damage_multiplier = 1.75 + knockdown_time_multiplier = 1 DECISECONDS + secondary_attack_verb_continuous = list("pommel-strikes") + secondary_attack_verb_simple = list("pommel-strike") var/wielded = FALSE var/unwielded_block_chance = 30 var/wielded_block_chance = 45 -/obj/item/forging/reagent_weapon/sword/Initialize(mapload) +/obj/item/melee/forged_reagent_weapon/sword/Initialize(mapload) . = ..() AddComponent(/datum/component/two_handed, force_multiplier = 2) AddComponent(/datum/component/mindless_killer, mindless_force_override = 0, mindless_multiplier_override = 2) -/obj/item/forging/reagent_weapon/sword/proc/on_wield() +/obj/item/melee/forged_reagent_weapon/sword/proc/on_wield() wielded = TRUE block_chance = wielded_block_chance -/obj/item/forging/reagent_weapon/sword/proc/on_unwield() +/obj/item/melee/forged_reagent_weapon/sword/proc/on_unwield() wielded = FALSE block_chance = unwielded_block_chance -/obj/item/forging/reagent_weapon/katana +/obj/item/melee/forged_reagent_weapon/katana name = "reagent katana" desc = "A katana sharp enough to penetrate body armor, but not quite million-times-folded sharp." force = 7 @@ -67,13 +249,17 @@ attack_verb_continuous = list("attacks", "slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts") attack_verb_simple = list("attack", "slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut") sharpness = SHARP_EDGED + stamina_damage_multiplier = 1.5 + knockdown_time_multiplier = 0.6 DECISECONDS + secondary_attack_verb_continuous = list("pommel-strikes") + secondary_attack_verb_simple = list("pommel-strike") -/obj/item/forging/reagent_weapon/katana/Initialize(mapload) +/obj/item/melee/forged_reagent_weapon/katana/Initialize(mapload) . = ..() AddComponent(/datum/component/two_handed, force_multiplier = 2) AddComponent(/datum/component/mindless_killer, mindless_force_override = 0, mindless_multiplier_override = 2) -/obj/item/forging/reagent_weapon/dagger +/obj/item/melee/forged_reagent_weapon/dagger name = "reagent dagger" desc = "A lightweight dagger historically used to stab at the gaps in armour of fallen knights of old." force = 5 @@ -90,6 +276,7 @@ attack_verb_continuous = list("attacks", "slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts") attack_verb_simple = list("attack", "slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut") sharpness = SHARP_EDGED + can_nonlethal_altfire = FALSE wound_bonus = 5 exposed_wound_bonus = 30 var/bonus_damage = 10 @@ -99,7 +286,7 @@ fall_chance = 1 pain_mult = 2 -/obj/item/forging/reagent_weapon/dagger/Initialize(mapload) +/obj/item/melee/forged_reagent_weapon/dagger/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, speed = 10 SECONDS, effectiveness = 70) AddComponent(/datum/component/mindless_killer, mindless_force_override = 0, mindless_multiplier_override = 2) @@ -107,7 +294,7 @@ //We're not reinventing the wheel, give it extra wounding if you land it, either you do or you dont, no dmg ups. Nullblade code but modified -/obj/item/forging/reagent_weapon/dagger/attack(atom/target, mob/user, list/modifiers, list/attack_modifiers) +/obj/item/melee/forged_reagent_weapon/dagger/attack(atom/target, mob/user, list/modifiers, list/attack_modifiers) . = ..() //Wounds scale off damage applied, so we're going to give the illusion of damaging people with the swing, when in reality it's all in the proc. if(!isliving(target)) @@ -124,7 +311,7 @@ if(check_for_sneak_attack(living_target, user) == TRUE) critical_hit(living_target) -/obj/item/forging/reagent_weapon/dagger/proc/check_for_sneak_attack(mob/living/carbon/carbon_target, mob/user) +/obj/item/melee/forged_reagent_weapon/dagger/proc/check_for_sneak_attack(mob/living/carbon/carbon_target, mob/user) // Check chaplain_nullrod.dm for original comments, I'm only leaving new ones in var/successful_sneak_attack = FALSE @@ -162,7 +349,7 @@ return FALSE return TRUE -/obj/item/forging/reagent_weapon/dagger/proc/critical_hit(mob/living/carbon/carbon_target, mob/user) +/obj/item/melee/forged_reagent_weapon/dagger/proc/critical_hit(mob/living/carbon/carbon_target, mob/user) var/obj/item/bodypart/affecting = carbon_target.get_bodypart(user.get_random_valid_zone(user.zone_selected)) var/armor_block = carbon_target.run_armor_check(affecting, MELEE, armour_penetration = armour_penetration) @@ -170,12 +357,11 @@ carbon_target.balloon_alert(user, "sneak attack!") playsound(carbon_target, 'sound/items/weapons/guillotine.ogg', 50, TRUE) -/obj/item/forging/reagent_weapon/rapier +/obj/item/melee/forged_reagent_weapon/rapier name = "reagent rapier" - desc = "A lightweight rapier with a light and quick swing, even while being so thin, you feel like you can stop all harm with this" - force = 12 - armour_penetration = 25 - block_chance = 35 + desc = "A lightweight rapier. Usually kept as a self-defense weapon; good at parrying attacks but cannot be two-handed for extra power." + force = 10 + block_chance = 30 icon_state = "rapier" inhand_icon_state = "sabre" icon_angle = -45 @@ -192,30 +378,51 @@ attack_verb_continuous = list("attacks", "slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts") attack_verb_simple = list("attack", "pierces", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut") sharpness = SHARP_POINTY + stamina_damage_multiplier = 1.5 + knockdown_time_multiplier = 1.4 + secondary_attack_verb_continuous = list("hilt-strikes") + secondary_attack_verb_simple = list("hilt-strike") -/obj/item/forging/reagent_weapon/rapier/Initialize(mapload) +/obj/item/melee/forged_reagent_weapon/rapier/Initialize(mapload) . = ..() AddComponent(/datum/component/mindless_killer, mindless_force_override = 0, mindless_multiplier_override = 2) -/obj/item/forging/reagent_weapon/staff //doesn't do damage. Useful for healing reagents. +/obj/item/melee/forged_reagent_weapon/rapier/apply_reagent_component() + AddComponent(/datum/component/reagent_imbued/weapon, list(FORGE_EFFECT_BLOCKCHANCE = 5)) + +/obj/item/melee/forged_reagent_weapon/staff //doesn't do damage. Useful for healing reagents. name = "reagent staff" desc = "A staff most notably capable of being imbued with reagents, especially useful alongside its otherwise harmless nature." force = 0 icon_state = "staff" inhand_icon_state = "staff" worn_icon_state = "staff_back" + hitsound = 'sound/effects/magic/staff_healing.ogg' throwforce = 0 slot_flags = ITEM_SLOT_BACK w_class = WEIGHT_CLASS_NORMAL resistance_flags = FIRE_PROOF - attack_verb_continuous = list("bonks", "bashes", "whacks", "pokes", "prods") - attack_verb_simple = list("bonk", "bash", "whack", "poke", "prod") + attack_verb_continuous = list("reagent casts on", "waves a staff over") + attack_verb_simple = list("reagent cast on", "wave a staff over") -/obj/item/forging/reagent_weapon/staff/attack(mob/living/M, mob/living/user, params) +/obj/item/melee/forged_reagent_weapon/staff/apply_reagent_component() + AddComponent(/datum/component/reagent_imbued/weapon, list(FORGE_EFFECT_REAGENT_INJECT = 3), 0.7) + +/obj/item/melee/forged_reagent_weapon/staff/apply_smithing_component() + AddComponent(/datum/component/forge_smithable, \ + FORGING_WEAPON_REFORGING_MAX_QUALITY, \ + TRUE, \ + FORGING_WEAPON_REFORGING_MAX_PERFECT_HITS, \ + FORGING_WEAPON_REFORGING_MAX_BAD_HITS, \ + FORGING_WEAPON_REFORGING_AVERAGE_WAIT, \ + perfection_effects = list(FORGE_EFFECT_REAGENT_INJECT = 3), \ + incompletion_effects = list(FORGE_EFFECT_REAGENT_INJECT, FORGE_EFFECT_DURABILITY)) + +/obj/item/melee/forged_reagent_weapon/staff/attack(mob/living/M, mob/living/user, params) . = ..() user.changeNext_move(CLICK_CD_RANGE) -/obj/item/forging/reagent_weapon/spear +/obj/item/melee/forged_reagent_weapon/spear name = "reagent spear" desc = "A long spear that can be wielded in two hands to boost damage at the cost of single-handed versatility." force = 7 @@ -235,8 +442,12 @@ wound_bonus = -10 exposed_wound_bonus = 20 sharpness = SHARP_POINTY + stamina_damage_multiplier = 2 + knockdown_time_multiplier = 0.2 + secondary_attack_verb_continuous = list("shaft-strikes") + secondary_attack_verb_simple = list("shaft-strike") -/obj/item/forging/reagent_weapon/spear/Initialize(mapload) +/obj/item/melee/forged_reagent_weapon/spear/Initialize(mapload) . = ..() AddComponent(/datum/component/jousting, max_tile_charge = 9, min_tile_charge = 6) AddComponent(/datum/component/butchering, speed = 10 SECONDS, effectiveness = 70) @@ -244,13 +455,13 @@ AddComponent(/datum/component/two_hand_reach, unwield_reach = 2, wield_reach = 1) AddComponent(/datum/component/mindless_killer, mindless_force_override = 0, mindless_multiplier_override = 2) -/obj/item/forging/reagent_weapon/spear/proc/on_wield(obj/item/source, mob/living/carbon/user) +/obj/item/melee/forged_reagent_weapon/spear/proc/on_wield(obj/item/source, mob/living/carbon/user) armour_penetration *= 2 -/obj/item/forging/reagent_weapon/spear/proc/on_unwield(obj/item/source, mob/living/carbon/user) +/obj/item/melee/forged_reagent_weapon/spear/proc/on_unwield(obj/item/source, mob/living/carbon/user) armour_penetration /= 2 -/obj/item/forging/reagent_weapon/axe +/obj/item/melee/forged_reagent_weapon/axe name = "reagent axe" desc = "An axe especially balanced for throwing and embedding into fleshy targets, yet also effective at destroying shields of all sorts." force = 7 @@ -268,20 +479,24 @@ attack_verb_continuous = list("slashes", "bashes") attack_verb_simple = list("slash", "bash") sharpness = SHARP_EDGED + stamina_damage_multiplier = 3 + knockdown_time_multiplier = 0.7 + secondary_attack_verb_continuous = list("blunt-strikes") + secondary_attack_verb_simple = list("blunt-strike") /datum/embedding/forged_axe embed_chance = 65 fall_chance = 10 pain_mult = 2 -/obj/item/forging/reagent_weapon/axe/Initialize(mapload) +/obj/item/melee/forged_reagent_weapon/axe/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, speed = 10 SECONDS, effectiveness = 70) AddComponent(/datum/component/two_handed, force_multiplier = 2) AddComponent(/datum/component/mindless_killer, mindless_force_override = 0, mindless_multiplier_override = 2) -/obj/item/forging/reagent_weapon/axe/pre_attack(mob/living/M, mob/living/user, params) +/obj/item/melee/forged_reagent_weapon/axe/pre_attack(mob/living/M, mob/living/user, params) . = ..() if(ishuman(M)) var/mob/living/carbon/human/H = M @@ -295,17 +510,18 @@ playsound(src, 'sound/effects/tableheadsmash.ogg', 30) H.apply_damage(15, STAMINA) -/obj/item/forging/reagent_weapon/hammer +/obj/item/melee/forged_reagent_weapon/hammer name = "reagent hammer" desc = "A heavy, weighted hammer that packs an incredible punch but can prove to be unwieldy. Useful for forging!" - force = 7 //strong when wielded, but boring. + force = 6 //strong when wielded, but boring. armour_penetration = 10 wound_bonus = -5 icon_state = "crush_hammer" inhand_icon_state = "crush_hammer" worn_icon_state = "hammer_back" throwforce = 10 - slot_flags = ITEM_SLOT_BACK + demolition_mod = 1.5 + slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_BELT w_class = WEIGHT_CLASS_BULKY resistance_flags = FIRE_PROOF attack_verb_continuous = list("bashes", "whacks") @@ -316,14 +532,38 @@ /obj/structure/reagent_anvil, /obj/structure/reagent_crafting_bench ) + stamina_damage_multiplier = 1.8 + knockdown_time_multiplier = 0.6 + secondary_attack_verb_continuous = list("shaft-strikes") + secondary_attack_verb_simple = list("shaft-strike") -/obj/item/forging/reagent_weapon/hammer/Initialize(mapload) +/obj/item/melee/forged_reagent_weapon/hammer/Initialize(mapload) . = ..() AddElement(/datum/element/kneejerk) AddComponent(/datum/component/two_handed, force_multiplier = 2.4) AddComponent(/datum/component/mindless_killer, mindless_force_override = 0, mindless_multiplier_override = 2) -/obj/item/forging/reagent_weapon/hammer/attack(mob/living/M, mob/living/user, params) +/obj/item/melee/forged_reagent_weapon/hammer/apply_smithing_component() + AddComponent(/datum/component/forge_smithable, \ + FORGING_WEAPON_REFORGING_MAX_QUALITY, \ + TRUE, \ + FORGING_WEAPON_REFORGING_MAX_PERFECT_HITS, \ + FORGING_WEAPON_REFORGING_MAX_BAD_HITS, \ + FORGING_WEAPON_REFORGING_AVERAGE_WAIT, \ + perfection_effects = list(FORGE_EFFECT_FORCE = MAX_PERFECT_FORCE_BONUS, FORGE_EFFECT_TOOLSPEED = -0.2), \ + incompletion_effects = list(FORGE_EFFECT_FORCE, FORGE_EFFECT_ARMORPEN, FORGE_EFFECT_TOOLSPEED)) + +/obj/item/melee/forged_reagent_weapon/hammer/change_material_strength(datum/material/material, mat_amount, multiplier, remove = FALSE) + . = ..() + var/density = material.get_property(MATERIAL_DENSITY) + var/hardness = material.get_property(MATERIAL_HARDNESS) + var/toolspeed_bonus = (density + hardness - 12) / 12 + if(!remove) + toolspeed -= toolspeed_bonus + else + toolspeed += toolspeed_bonus + +/obj/item/melee/forged_reagent_weapon/hammer/attack(mob/living/M, mob/living/user, params) . = ..() user.changeNext_move(CLICK_CD_SLOW) //The hammer attacks slower but has more damage, that's it's thing now @@ -343,67 +583,74 @@ transparent = FALSE max_integrity = 150 //over double that of a wooden one w_class = WEIGHT_CLASS_NORMAL - material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_AFFECT_STATISTICS - skyrat_obj_flags = ANVIL_REPAIR + material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_AFFECT_STATISTICS | MATERIAL_COLOR shield_break_sound = 'sound/effects/bang.ogg' shield_break_leftover = /obj/item/forging/complete/plate /obj/item/shield/buckler/reagent_weapon/Initialize(mapload) . = ..() - AddComponent(/datum/component/reagent_weapon) + AddComponent(/datum/component/reagent_imbued/weapon, oil_effects = list(FORGE_EFFECT_BLOCKCHANCE = 5, FORGE_EFFECT_DURABILITY = 20)) AddComponent(/datum/component/mindless_killer, mindless_force_override = 0, mindless_multiplier_override = 2) + apply_smithing_component() -/obj/item/shield/buckler/reagent_weapon/examine(mob/user) - . = ..() - . += span_notice("Using a hammer on [src] will repair its damage!") +/obj/item/shield/buckler/reagent_weapon/change_material_integrity(datum/material/material, amount, multiplier, removing = FALSE) + blacksmithing_change_material_integrity(src, material, amount, multiplier, removing) -/obj/item/shield/buckler/reagent_weapon/attackby(obj/item/attacking_item, mob/user, params) - if(atom_integrity >= max_integrity) - return ..() - if(istype(attacking_item, /obj/item/forging/hammer)) - var/obj/item/forging/hammer/attacking_hammer = attacking_item - var/skill_modifier = user.mind.get_skill_modifier(/datum/skill/smithing, SKILL_SPEED_MODIFIER) * attacking_hammer.toolspeed - while(atom_integrity < max_integrity) - if(!do_after(user, skill_modifier, src)) - return - var/fixing_amount = min(max_integrity - atom_integrity, 5) - atom_integrity += fixing_amount - user.mind.adjust_experience(/datum/skill/smithing, 5) //useful heating means you get some experience - balloon_alert(user, "partially repaired!") - return - return ..() +/obj/item/shield/buckler/reagent_weapon/change_material_strength(datum/material/material, mat_amount, multiplier, remove = FALSE) + blacksmithing_change_material_strength(src, material, mat_amount, multiplier, remove) + +/obj/item/shield/buckler/reagent_weapon/proc/apply_smithing_component() + AddComponent(/datum/component/forge_smithable, \ + FORGING_WEAPON_REFORGING_MAX_QUALITY, \ + TRUE, \ + FORGING_WEAPON_REFORGING_MAX_PERFECT_HITS, \ + FORGING_WEAPON_REFORGING_MAX_BAD_HITS, \ + FORGING_WEAPON_REFORGING_AVERAGE_WAIT, \ + perfection_effects = list(FORGE_EFFECT_BLOCKCHANCE = 5), \ + incompletion_effects = list(FORGE_EFFECT_BLOCKCHANCE, FORGE_EFFECT_FORCE)) /obj/item/shield/buckler/reagent_weapon/pavise //similar to the adamantine shield. Huge, slow, lets you soak damage and packs a wallop. name = "reagent plated pavise shield" - desc = "An oblong shield used by ancient crossbowmen as cover while reloading. Probably just as useful with an actual gun." + desc = "An large wall-like shield. Very heavy, but extremely protective." force = 10 icon_state = "pavise" inhand_icon_state = "pavise" worn_icon_state = "pavise_back" - block_chance = 75 - item_flags = SLOWS_WHILE_IN_HAND + block_chance = 55 + item_flags = SLOWS_WHILE_IN_HAND | IMMUTABLE_SLOW + slowdown = 2.0 + drag_slowdown = 3.5 w_class = WEIGHT_CLASS_HUGE slot_flags = ITEM_SLOT_BACK max_integrity = 300 //tanky /obj/item/shield/buckler/reagent_weapon/pavise/Initialize(mapload) . = ..() - AddComponent(/datum/component/two_handed, require_twohands = TRUE, force_multiplier = 1.5) AddComponent(/datum/component/mindless_killer, mindless_force_override = 0, mindless_multiplier_override = 2) +/obj/item/shield/buckler/reagent_weapon/pavise/apply_smithing_component() + AddComponent(/datum/component/forge_smithable, \ + FORGING_WEAPON_REFORGING_MAX_QUALITY, \ + TRUE, \ + FORGING_WEAPON_REFORGING_MAX_PERFECT_HITS, \ + FORGING_WEAPON_REFORGING_MAX_BAD_HITS, \ + FORGING_WEAPON_REFORGING_AVERAGE_WAIT, \ + perfection_effects = list(FORGE_EFFECT_BLOCKCHANCE = 10), \ + incompletion_effects = list(FORGE_EFFECT_BLOCKCHANCE, FORGE_EFFECT_FORCE)) + /obj/item/pickaxe/reagent_weapon name = "reagent pickaxe" /obj/item/pickaxe/reagent_weapon/Initialize(mapload) . = ..() - AddComponent(/datum/component/reagent_weapon) + AddComponent(/datum/component/reagent_imbued/weapon) /obj/item/shovel/reagent_weapon name = "reagent shovel" /obj/item/shovel/reagent_weapon/Initialize(mapload) . = ..() - AddComponent(/datum/component/reagent_weapon) + AddComponent(/datum/component/reagent_imbued/weapon) /obj/item/ammo_casing/arrow/attackby(obj/item/attacking_item, mob/user, params) var/spawned_item @@ -429,7 +676,7 @@ user.put_in_hands(converted_arrow) qdel(src) -/obj/item/forging/reagent_weapon/bokken +/obj/item/melee/forged_reagent_weapon/bokken name = "bokken" desc = "A wooden sword that is capable of wielded in two hands. It seems to be made to prevent permanent injuries." force = 10 @@ -443,13 +690,15 @@ slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_BACK w_class = WEIGHT_CLASS_BULKY resistance_flags = FLAMMABLE + stamina_damage_multiplier = 1.5 + knockdown_time_multiplier = 0.6 DECISECONDS attack_verb_continuous = list("bonks", "bashes", "whacks", "pokes", "prods") attack_verb_simple = list("bonk", "bash", "whack", "poke", "prod") var/wielded = FALSE var/unwielded_block_chance = 20 var/wielded_block_chance = 40 -/obj/item/forging/reagent_weapon/bokken/Initialize(mapload) +/obj/item/melee/forged_reagent_weapon/bokken/Initialize(mapload) . = ..() AddComponent(/datum/component/two_handed,\ force_multiplier = 2, \ @@ -457,15 +706,15 @@ unwield_callback = CALLBACK(src, PROC_REF(on_unwield)), \ ) -/obj/item/forging/reagent_weapon/bokken/proc/on_wield() +/obj/item/melee/forged_reagent_weapon/bokken/proc/on_wield() wielded = TRUE block_chance = wielded_block_chance -/obj/item/forging/reagent_weapon/bokken/proc/on_unwield() +/obj/item/melee/forged_reagent_weapon/bokken/proc/on_unwield() wielded = FALSE block_chance = unwielded_block_chance -/obj/item/forging/reagent_weapon/bokken/attack(mob/living/carbon/target_mob, mob/living/user, params) +/obj/item/melee/forged_reagent_weapon/bokken/attack(mob/living/carbon/target_mob, mob/living/user, params) . = ..() if(!iscarbon(target_mob)) user.visible_message(span_warning("The [src] seems to be ineffective against the [target_mob]!")) @@ -476,3 +725,5 @@ /obj/item/spear/Initialize(mapload) . = ..() AddComponent(/datum/component/two_hand_reach, unwield_reach = 1, wield_reach = 2) + +#undef STUN_ATTACK diff --git a/modular_skyrat/modules/reagent_forging/code/memories.dm b/modular_skyrat/modules/reagent_forging/code/memories.dm new file mode 100644 index 00000000000..718da4c5ed1 --- /dev/null +++ b/modular_skyrat/modules/reagent_forging/code/memories.dm @@ -0,0 +1,125 @@ +/// Keeps track of smithing items & what was made by who +/datum/memory/smithing + story_value = STORY_VALUE_MEH + // Protagonist - The smith making the item + /// What type of crafting it was + var/smithed_item_type = null + /// name of the item for strings + var/item_name = null + +/datum/memory/smithing/New( + datum/mind/memorizer_mind, + atom/protagonist, + atom/deuteragonist, + atom/antagonist, +) + return ..() + +/datum/memory/smithing/get_names() + return list("The time [protagonist_name] made a [initial(item_name)].") + +/datum/memory/smithing/get_starts() + return list( + "[protagonist_name] carefully assembling a [initial(item_name)].", + ) + +/datum/memory/smithing/get_moods() + return list( + "[protagonist_name] [mood_verb] after finishing [initial(item_name)].", + ) + +/datum/memory/smithing/sword + smithed_item_type = /obj/item/melee/forged_reagent_weapon/sword + item_name = "sword" + +/datum/memory/smithing/katana + smithed_item_type = /obj/item/melee/forged_reagent_weapon/katana + item_name = "katana" + +/datum/memory/smithing/dagger + smithed_item_type = /obj/item/melee/forged_reagent_weapon/dagger + item_name = "dagger" + +/datum/memory/smithing/rapier + smithed_item_type = /obj/item/melee/forged_reagent_weapon/rapier + item_name = "rapier" + +/datum/memory/smithing/spear + smithed_item_type = /obj/item/melee/forged_reagent_weapon/spear + item_name = "spear" + +/datum/memory/smithing/axe + smithed_item_type = /obj/item/melee/forged_reagent_weapon/axe + item_name = "axe" + +/datum/memory/smithing/hammer + smithed_item_type = /obj/item/melee/forged_reagent_weapon/hammer + item_name = "hammer" + +/datum/memory/smithing/buckler + smithed_item_type = /obj/item/shield/buckler/reagent_weapon + item_name = "buckler" + +/datum/memory/smithing/pavise + smithed_item_type = /obj/item/shield/buckler/reagent_weapon/pavise + item_name = "pavise" + +/datum/memory/smithing/revolver + smithed_item_type = /obj/item/gun/ballistic/revolver/handcrafted_single_action + item_name = "revolver" + +/datum/memory/smithing/helmet + smithed_item_type = /obj/item/clothing/head/helmet/forging_plate_helmet + item_name = "hammer" + +/datum/memory/smithing/plate_vest + smithed_item_type = /obj/item/clothing/suit/armor/forging_plate_armor + item_name = "plate vest" + +/datum/memory/smithing/gloves + smithed_item_type = /obj/item/clothing/gloves/forging_plate_gloves + item_name = "pair of plate gloves" + +/datum/memory/smithing/boots + smithed_item_type = /obj/item/clothing/shoes/forging_plate_boots + item_name = "pair of plate boots" + +/datum/memory/smithing/horseshoes + smithed_item_type = /obj/item/clothing/shoes/horseshoe/reagent_clothing + item_name = "set of horseshoes" + +/datum/memory/smithing/ring + smithed_item_type = /obj/item/clothing/gloves/ring/reagent_clothing + item_name = "ring" + +/datum/memory/smithing/collar + smithed_item_type = /obj/item/clothing/neck/collar/reagent_clothing + item_name = "collar" + +/datum/memory/smithing/cowboy_holster + smithed_item_type = /obj/item/storage/belt/hip_holster/cowboy + item_name = "holster" + +/datum/memory/smithing/charging_holster + smithed_item_type = /obj/item/storage/belt/hip_holster/charging + item_name = "charging holster" + +/datum/memory/smithing/crusader_belt + smithed_item_type = /obj/item/storage/belt/crusader + item_name = "utility-scabbard belt" + +/datum/memory/smithing/multi_scabbard + smithed_item_type = /obj/item/storage/belt/sheath/multi + item_name = "multi-scabbard belt" + +/datum/memory/smithing/repairing_scabbard + smithed_item_type = /obj/item/storage/belt/sheath/repairing + item_name = "repairing scabbard" + +/datum/memory/smithing/knifethrower + smithed_item_type = /obj/item/storage/belt/knifethrowers_belt + item_name = "knifethrower's belt" + +/datum/memory/smithing/bluespace_plants + smithed_item_type = /obj/item/storage/bag/plants/bluespace + item_name = "bluespace plants bag" diff --git a/modular_skyrat/modules/reagent_forging/code/mindless_killer.dm b/modular_skyrat/modules/reagent_forging/code/mindless_killer.dm index 0420c7c7d5d..e7b40e88469 100644 --- a/modular_skyrat/modules/reagent_forging/code/mindless_killer.dm +++ b/modular_skyrat/modules/reagent_forging/code/mindless_killer.dm @@ -29,6 +29,8 @@ return if(target_mob.mind) return + if(modifiers[FORCE_OVERRIDE] == 0) + return var/extra_damage = (obj_parent.force + mindless_force) * mindless_multiplier target_mob.apply_damage(extra_damage, forced = TRUE, spread_damage = TRUE) return diff --git a/modular_skyrat/modules/reagent_forging/code/reagent_component.dm b/modular_skyrat/modules/reagent_forging/code/reagent_component.dm index ca186d156dd..bbb98146634 100644 --- a/modular_skyrat/modules/reagent_forging/code/reagent_component.dm +++ b/modular_skyrat/modules/reagent_forging/code/reagent_component.dm @@ -1,116 +1,203 @@ -#define MAX_IMBUE_STORAGE 250 -#define REAGENT_CLOTHING_INJECT_AMOUNT 0.5 -#define REAGENT_WEAPON_INJECT_AMOUNT 1 -#define REAGENT_WEAPON_DAMAGE_MULTIPLIER 3 + + +///Parent component that stores shared info +/datum/component/reagent_imbued/ + ///the item that the component is attached to + var/obj/item/parent_item + ///required type to attach to + var/obj/item/required_type = /obj/item + //the imbued reagents + var/datum/reagents/imbued_reagent = new(10, NO_REACT) + ///the text to show the player what happens + var/examine_imbued_description = "It is currently imbued with the following:" + ///required parent item integrity% for reagent effects + var/integrity_required + ///how much reagent to inject per tic/proc + var/inject_amount = 0 + ///what smithing oil does to this (at 100% oil imbuing it has 100% of the listed effects) + var/list/smithing_oil_effects = list() + ///keeps track of how effective last smithing oil imbue did (% of total imbue capacity) + var/last_smithing_oil_ratio_applied = 0 + ///damage mult on parent item when reagent procs + var/integrity_loss_per_inject = 1 + +/// * set_slot: Used for clothing only, ignore if this isn't the case. +/// * integrity: what integ % is required to use the reagent imbue? +/datum/component/reagent_imbued/Initialize(list/oil_effects = list(), integrity = 0.85, set_slot = null) + if(!istype(parent, required_type)) + return COMPONENT_INCOMPATIBLE //they need to be clothing, I already said this + parent_item = parent + parent_item.create_reagents(MAX_PRE_IMBUE_STORAGE, INJECTABLE | REFILLABLE) + integrity_required = integrity + RegisterSignal(parent_item, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + RegisterSignal(parent_item, COMSIG_ATOM_EXAMINE_MORE, PROC_REF(on_examine_more)) + smithing_oil_effects = oil_effects + +/datum/component/reagent_imbued/proc/on_examine(datum/source, mob/user, list/examine_list) + SIGNAL_HANDLER + if(USER_CAN_REAGENT_IMBUE(user)) + examine_list += span_notice("[parent_item] is able to be imbued by dipping it into a container such as a quenching trough, or pouring chemicals into it and then tempering it at a forge!") + else + examine_list += span_notice("If you knew a certain smithing trick, you could imbue special chemicals into this...") + if(parent_item.get_integrity_percentage() < integrity_required) + examine_list += span_notice("It must be repaired before its imbued reagent effects can work...") + if(imbued_reagent.reagent_list.len >= 1 && (USER_CAN_REAGENT_IMBUE(user) || HAS_TRAIT(user, TRAIT_REAGENT_SCANNER))) + examine_list += span_notice("You could inspect this closer to see what is imbued into it, and what smithing oil does...") + + +/datum/component/reagent_imbued/proc/on_examine_more(obj/item/source, mob/examiner, list/examine_list) + if(imbued_reagent.reagent_list.len >= 1 && (HAS_TRAIT(examiner, TRAIT_KNOW_ADVANCED_SMITHING) || HAS_TRAIT(examiner, TRAIT_REAGENT_SCANNER))) + add_reagent_imbue_description(examine_list) + + add_oil_imbue_effect_description(examine_list) + +/datum/component/reagent_imbued/proc/add_reagent_imbue_description(list/examine_list) + examine_list += span_notice(examine_imbued_description) + for (var/datum/reagent/reagent in imbued_reagent.reagent_list) + examine_list += span_notice("[reagent.volume] units of [reagent.name]") + +/datum/component/reagent_imbued/proc/add_oil_imbue_effect_description(list/examine_list) + if(smithing_oil_effects.len > 0) + var/list/effects_list = list() + for(var/i in smithing_oil_effects) + switch(i) + if(FORGE_EFFECT_ARMOR) + effects_list += "cushion blows more effectively" + if(FORGE_EFFECT_ARMORPEN) + effects_list += "pierce through armor more efficiently" + if(FORGE_EFFECT_BLOCKCHANCE) + effects_list += "better at deflecting blows" + if(FORGE_EFFECT_DURABILITY) + effects_list += "reinforce its durability" + if(FORGE_EFFECT_FORCE) + effects_list += "enhance its destructive potential" + if(FORGE_EFFECT_REAGENT_INJECT) + effects_list += "inflict more of the other containing reagents" + if(FORGE_EFFECT_TOOLSPEED) + effects_list += "work more efficiently in its intended use" + + examine_list += span_notice("Smithing oil will make it [english_list(effects_list)].") + else + examine_list += span_notice("Smithing oil has no effect on [parent_item], but may affect things crafted with it.") + +///Replaces the imbued_reagent with the given new_reagents. +/datum/component/reagent_imbued/proc/set_reagent_imbue(datum/reagents/new_reagents, clear_source_reagents = TRUE) + //copy in the new reagents to replace the old + imbued_reagent.clear_reagents() + new_reagents.trans_to(imbued_reagent, amount = new_reagents.total_volume, copy_only = TRUE, no_react = TRUE) + + apply_smithing_oil_bonus() + parent_item.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) + if(length(imbued_reagent.reagent_list) > 0) + var/new_color = mix_color_from_reagents(imbued_reagent.reagent_list) + if(length(new_color) > 7) //remove the transparency stuff + new_color = copytext(new_color, 1, 8) + "FF" + parent_item.add_atom_colour(color_transition_filter(new_color, SATURATION_OVERRIDE), WASHABLE_COLOUR_PRIORITY) + + if(clear_source_reagents) + new_reagents.clear_reagents() + +///This function modifies the parent item based on how much smithing oil is in our imbued reagent list. Needs to be defined in child subtypes. +/datum/component/reagent_imbued/proc/apply_smithing_oil_bonus() + if(length(smithing_oil_effects) > 0) + var/new_oil_ratio = imbued_reagent.remove_reagent(/datum/reagent/fuel/oil/smithing, imbued_reagent.maximum_volume, include_subtypes = FALSE) + new_oil_ratio /= imbued_reagent.maximum_volume + for(var/index in smithing_oil_effects) + give_added_modifying_effect_to_item(index, last_smithing_oil_ratio_applied, new_oil_ratio, parent_item, smithing_oil_effects[index]) + last_smithing_oil_ratio_applied = new_oil_ratio + +/datum/component/reagent_imbued/proc/try_inject(mob/living/target, mob/living/user = null) + if(isnull(user)) + user = target + //don't have the weapon or any imbued reagents? don't try + if(isnull(parent_item) || imbued_reagent?.reagent_list?.len < 1) + return FALSE + if(imbued_reagent.total_volume == 0) + return FALSE + if(parent_item.get_integrity_percentage() < integrity_required) + return FALSE + + //lets inject that target + var/mob/living_target = target + var/new_amount_to_inject = min(inject_amount, imbued_reagent.total_volume) + imbued_reagent.trans_to(target = living_target, amount = new_amount_to_inject, transferred_by = user, methods = INJECT, copy_only = TRUE) + parent_item.take_damage(integrity_loss_per_inject * new_amount_to_inject, sound_effect = FALSE) + return TRUE //the component that is attached to clothes that allows them to be imbued //ONLY USE THIS FOR CLOTHING -/datum/component/reagent_clothing - ///the item that the component is attached to - var/obj/item/parent_clothing +/datum/component/reagent_imbued/clothing ///the slot that the item will check var/checking_slot - ///the human that is wearing the parent_clothing + ///the human that is wearing the parent_item var/mob/living/carbon/human/cloth_wearer - ///the container that will apply the chemicals - var/obj/item/reagent_containers/applying_container - ///the list of imbued reagents that will given to the human owner - var/list/imbued_reagent = list() + imbued_reagent = new(maximum = REAGENT_CLOTHING_INJECT_AMOUNT, new_flags = NO_REACT) + examine_imbued_description = "It will slowly administer the following to its wearer:" + inject_amount = REAGENT_CLOTHING_INJECT_AMOUNT //the cooldown between each imbue COOLDOWN_DECLARE(imbue_cooldown) -/datum/component/reagent_clothing/Initialize(set_slot = null) - if(!istype(parent, /obj/item)) - return COMPONENT_INCOMPATIBLE //they need to be clothing, I already said this +/datum/component/reagent_imbued/clothing/Initialize(list/oil_effects = list(), integrity = 0.85, set_slot = null) + . = ..() + if(. != COMPONENT_INCOMPATIBLE) + if(set_slot) + checking_slot = set_slot + RegisterSignal(parent_item, COMSIG_ITEM_EQUIPPED, PROC_REF(set_wearer)) + RegisterSignal(parent_item, COMSIG_ITEM_PRE_UNEQUIP, PROC_REF(remove_wearer)) + START_PROCESSING(SSdcs, src) - if(set_slot) - checking_slot = set_slot - - parent_clothing = parent - parent_clothing.create_reagents(MAX_IMBUE_STORAGE, INJECTABLE | REFILLABLE) - applying_container = new /obj/item/reagent_containers(src) - RegisterSignal(parent_clothing, COMSIG_ITEM_EQUIPPED, PROC_REF(set_wearer)) - RegisterSignal(parent_clothing, COMSIG_ITEM_PRE_UNEQUIP, PROC_REF(remove_wearer)) - RegisterSignal(parent_clothing, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) - START_PROCESSING(SSdcs, src) - -/datum/component/reagent_clothing/Destroy(force, silent) - parent_clothing = null +/datum/component/reagent_imbued/clothing/Destroy(force, silent) + parent_item = null cloth_wearer = null - QDEL_NULL(applying_container) STOP_PROCESSING(SSdcs, src) return ..() -/datum/component/reagent_clothing/proc/on_examine(datum/source, mob/user, list/examine_list) - SIGNAL_HANDLER - examine_list += span_notice("[parent_clothing] is able to be inbued with a chemical at a reagent forge!") -/datum/component/reagent_clothing/proc/set_wearer() +/datum/component/reagent_imbued/clothing/proc/set_wearer() SIGNAL_HANDLER - if(!ishuman(parent_clothing.loc)) + if(!ishuman(parent_item.loc)) return - cloth_wearer = parent_clothing.loc + cloth_wearer = parent_item.loc -/datum/component/reagent_clothing/proc/remove_wearer() +/datum/component/reagent_imbued/clothing/proc/remove_wearer() SIGNAL_HANDLER cloth_wearer = null -/datum/component/reagent_clothing/process(seconds_per_tick) - if(!parent_clothing || !cloth_wearer || !length(imbued_reagent)) +/datum/component/reagent_imbued/clothing/process(seconds_per_tick) + if(!cloth_wearer) return - if(parent_clothing != cloth_wearer.get_item_by_slot(checking_slot)) + if(parent_item != cloth_wearer.get_item_by_slot(checking_slot)) return if(!COOLDOWN_FINISHED(src, imbue_cooldown)) return - COOLDOWN_START(src, imbue_cooldown, 3 SECONDS) - - for(var/create_reagent in imbued_reagent) - applying_container.reagents.add_reagent(create_reagent, REAGENT_CLOTHING_INJECT_AMOUNT) - applying_container.reagents.trans_to(target = cloth_wearer, amount = REAGENT_CLOTHING_INJECT_AMOUNT, methods = INJECT) + if(try_inject(cloth_wearer)) + COOLDOWN_START(src, imbue_cooldown, 3 SECONDS) //the component that is attached to weapons that allows them to be imbued //ONLY USE THIS FOR WEAPONS -/datum/component/reagent_weapon - ///the item that the component is attached to - var/obj/item/parent_weapon - ///the list of imbued reagents that will given to the human owner - var/list/imbued_reagent = list() +/datum/component/reagent_imbued/weapon + imbued_reagent = new(REAGENT_WEAPON_INJECT_AMOUNT, NO_REACT) + examine_imbued_description = "Upon hit, it will inject the following to its victim:" + var/extra_force_oil_bonus = 0 + inject_amount = REAGENT_WEAPON_INJECT_AMOUNT -/datum/component/reagent_weapon/Initialize(...) - if(!istype(parent, /obj/item)) - return COMPONENT_INCOMPATIBLE //they need to be weapons, I already said this - parent_weapon = parent - parent_weapon.create_reagents(MAX_IMBUE_STORAGE, INJECTABLE | REFILLABLE) - RegisterSignal(parent_weapon, COMSIG_ITEM_ATTACK, PROC_REF(inject_attacked)) - RegisterSignal(parent_weapon, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) +/datum/component/reagent_imbued/weapon/Initialize(list/oil_effects = list(), integrity = 0.85, set_slot = null) + . = ..() + if(. != COMPONENT_INCOMPATIBLE) + RegisterSignal(parent_item, COMSIG_ITEM_ATTACK, PROC_REF(inject_attacked)) -/datum/component/reagent_weapon/Destroy(force, silent) - parent_weapon = null +/datum/component/reagent_imbued/weapon/Destroy(force, silent) + parent_item = null return ..() -/datum/component/reagent_weapon/proc/on_examine(datum/source, mob/user, list/examine_list) +/datum/component/reagent_imbued/weapon/proc/inject_attacked(datum/source, mob/living/target, mob/living/user, list/modifiers) SIGNAL_HANDLER - examine_list += span_notice("[parent_weapon] is able to be imbued with a chemical at a reagent forge!") - -/datum/component/reagent_weapon/proc/inject_attacked(datum/source, mob/living/target, mob/living/user, list/modifiers) - SIGNAL_HANDLER - - //don't have the weapon or any imbued reagents? don't try - if(!parent_weapon || !length(imbued_reagent)) - return - - //lets inject that target - var/mob/living_target = target - for(var/create_reagent in imbued_reagent) - living_target.reagents.add_reagent(create_reagent, REAGENT_WEAPON_INJECT_AMOUNT) - parent_weapon.take_damage(length(imbued_reagent) * REAGENT_WEAPON_DAMAGE_MULTIPLIER) - - -#undef MAX_IMBUE_STORAGE + try_inject(target) +#undef MAX_PRE_IMBUE_STORAGE #undef REAGENT_CLOTHING_INJECT_AMOUNT #undef REAGENT_WEAPON_INJECT_AMOUNT -#undef REAGENT_WEAPON_DAMAGE_MULTIPLIER +#undef REAGENT_STAFF_INJECT_AMOUNT diff --git a/modular_skyrat/modules/reagent_forging/code/reagent_smithing_oil.dm b/modular_skyrat/modules/reagent_forging/code/reagent_smithing_oil.dm new file mode 100644 index 00000000000..d4bea0cf4a3 --- /dev/null +++ b/modular_skyrat/modules/reagent_forging/code/reagent_smithing_oil.dm @@ -0,0 +1,16 @@ +/datum/reagent/fuel/oil/smithing + name = "Smithing Oil" + description = "A specialized type of oil with various blacksmithing applications, from quenching hot metal, to enhancing the hardness of blades and armor. Has a very high burning point, unless it's exposed to fire..." + color = "#2D2D2D" + taste_description = "oil" + burning_temperature = 6000 + burning_volume = 0.05 + chemical_flags = NONE + addiction_types = null + default_container = /obj/effect/decal/cleanable/blood/splatter/oil + +/obj/item/reagent_containers/cup/jerrycan/smithing_oil + name = "Jarnsmiour Blacksteel Foundation-brand smithing oil" + cap_type = "red" + desc = "Jarnsmiour Blacksteel's finest smithing oil; a favored ingredient of the intergalactic spacesmith's union, thanks to its ability to enhance the inherrent capabilities of nearly every form of metal." + list_reagents = list(/datum/reagent/fuel/oil/smithing = 200) diff --git a/modular_skyrat/modules/reagent_forging/code/smith_skill.dm b/modular_skyrat/modules/reagent_forging/code/smith_skill.dm index 5deb7374755..94b48d87286 100644 --- a/modular_skyrat/modules/reagent_forging/code/smith_skill.dm +++ b/modular_skyrat/modules/reagent_forging/code/smith_skill.dm @@ -3,7 +3,7 @@ title = "Smithy" desc = "The desperate artist who strives after the flames of the forge." modifiers = list( - SKILL_SPEED_MODIFIER = list(1, 0.95, 0.9, 0.85, 0.75, 0.6, 0.5), + SKILL_SPEED_MODIFIER = list(1, 0.95, 0.9, 0.85, 0.8, 0.75, 0.7), SKILL_PROBS_MODIFIER = list(0, 5, 10, 20, 40, 80, 100) ) skill_item_path = /obj/item/clothing/neck/cloak/skill_reward/smithing diff --git a/modular_skyrat/modules/reagent_forging/code/smithing_trait_and_chip.dm b/modular_skyrat/modules/reagent_forging/code/smithing_trait_and_chip.dm new file mode 100644 index 00000000000..dda0323b127 --- /dev/null +++ b/modular_skyrat/modules/reagent_forging/code/smithing_trait_and_chip.dm @@ -0,0 +1,21 @@ +/obj/item/skillchip/job/blacksmith + name = "Smithing F0RG-3M4573-R skillchip" + desc = "Grants skills related to blacksmithing and metalworking." + auto_traits = list(TRAIT_KNOW_ADVANCED_SMITHING, TRAIT_KNOW_GUNSMITHING, TRAIT_KNOW_CIRCUIT_SMITHING) + skill_name = "Advanced Smithing" + skill_description = "Contains schematics for more advanced equipment forging, as well as how to best apply it." + skill_icon = "gavel" + activate_message = span_notice("You suddenly know how to make advanced metalworking components out of raw materials.") + deactivate_message = span_notice("The memories of how to construct advanced metalworking components fade from your mind.") + +/obj/item/storage/box/skillchips/supply + name = "box of supply job skillchips" + desc = "Contains spares of every supply job skillchip." + +/obj/item/storage/box/skillchips/supply/PopulateContents() + new /obj/item/skillchip/job/blacksmith(src) + new /obj/item/skillchip/job/blacksmith(src) + +/obj/structure/closet/secure_closet/quartermaster/PopulateContents() + . = ..() + new /obj/item/storage/box/skillchips/supply(src) diff --git a/modular_skyrat/modules/reagent_forging/code/water_basin.dm b/modular_skyrat/modules/reagent_forging/code/water_basin.dm index 67f59ee903e..e889bfa13e6 100644 --- a/modular_skyrat/modules/reagent_forging/code/water_basin.dm +++ b/modular_skyrat/modules/reagent_forging/code/water_basin.dm @@ -1,110 +1,116 @@ -/obj/structure/reagent_water_basin - name = "water basin" - desc = "A basin full of water, ready to quench the hot metal." +/obj/structure/reagent_dispensers/reagent_smithing_basin + name = "smithing trough" + desc = "A basin meant to quench heated smithing equipment and cool it." icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_structures.dmi' icon_state = "water_basin" anchored = TRUE density = TRUE + can_be_tanked = FALSE custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT * 5) + reagent_id = null + //deliberate choice -- matches the volume of a bluespace beaker + tank_volume = 300 /// Tracks if you can fish from this basin var/datum/component/fishing_spot/fishable -/obj/structure/reagent_water_basin/Initialize(mapload) - . = ..() +/obj/structure/reagent_dispensers/reagent_smithing_basin/prefilled + reagent_id = /datum/reagent/fuel/oil/smithing -/obj/structure/reagent_water_basin/Destroy() +/obj/structure/reagent_dispensers/reagent_smithing_basin/update_overlays() + . = ..() + if(reagents.total_volume >= tank_volume) + var/mutable_appearance/filling = mutable_appearance(icon, "water_basin_reagent_overlay") + filling.color = mix_color_from_reagents(reagents.reagent_list) + . += filling + return + +/obj/structure/reagent_dispensers/reagent_smithing_basin/Initialize(mapload) + . = ..() + if(!mapload) + anchored = FALSE + reagents.flags = reagents.flags | REFILLABLE | DUNKABLE + check_fishable() + START_PROCESSING(SSdcs, src) + update_appearance() + +/obj/structure/reagent_dispensers/reagent_smithing_basin/proc/check_fishable() + if(isnull(fishable) && reagents.total_volume >= tank_volume) + fishable = AddComponent(/datum/component/fishing_spot, /datum/fish_source/water_basin) + else if(!isnull(fishable) && reagents.total_volume < tank_volume) + RemoveComponentSource(src, /datum/component/fishing_spot) + +/obj/structure/reagent_dispensers/reagent_smithing_basin/Destroy() QDEL_NULL(fishable) return ..() -/obj/structure/reagent_water_basin/examine(mob/user) +/obj/structure/reagent_dispensers/reagent_smithing_basin/examine(mob/user) . = ..() - if(!fishable) - . += span_notice("[src] can be upgraded through a bluespace crystal or a journeyman smithy!") - + if(HAS_TRAIT(user, TRAIT_KNOW_ADVANCED_SMITHING)) + . += span_notice("Dipping smithed items in this trough will imbue it with its chemicals!") else - . += span_notice("[src] looks to be a bottomless basin of water... You can even see fish swimming around down there!") + . += span_notice("You could use this for imbuing reagents into equipment if you knew the right trick...") + . += span_notice("You could secure or unsecure it with a wrench.") + . += span_notice("You could pry it apart with a crowbar.") -/obj/structure/reagent_water_basin/attack_hand(mob/living/user, list/modifiers) - . = ..() - attempt_upgrade(user) +//heat from the contained reagents need to go into the atmosphere over time +/obj/structure/reagent_dispensers/reagent_smithing_basin/process(seconds_per_tick) + var/datum/gas_mixture/current_air = return_air() + if(reagents.total_volume < 1 || reagents.chem_temp == current_air.temperature) + return PROCESS_KILL + var/temp_difference = reagents.chem_temp - current_air.temperature + current_air.temperature += temp_difference * seconds_per_tick * SMITHING_BASIN_HEATLOSS_COEFFICIENT + reagents.chem_temp -= temp_difference * seconds_per_tick * SMITHING_BASIN_HEATLOSS_COEFFICIENT + return -/obj/structure/reagent_water_basin/attack_robot(mob/living/user) - . = ..() - attempt_upgrade(user) - -/obj/structure/reagent_water_basin/proc/attempt_upgrade(mob/living/user) - var/smithing_skill = user.mind.get_skill_level(/datum/skill/smithing) - if(smithing_skill < SKILL_LEVEL_JOURNEYMAN || fishable) - return - - balloon_alert(user, "the water deepens!") - fishable = AddComponent(/datum/component/fishing_spot, /datum/fish_source/water_basin) - -/obj/structure/reagent_water_basin/attackby(obj/item/attacking_item, mob/living/user, params) - if(istype(attacking_item, /obj/item/stack/ore/glass)) - var/obj/item/stack/ore/glass/glass_obj = attacking_item - if(!glass_obj.use(1)) - return - - new /obj/item/stack/clay(get_turf(src)) - user.mind.adjust_experience(/datum/skill/production, 1) - return - - if(istype(attacking_item, /obj/item/stack/ore/bluespace_crystal)) - if(fishable) - return - var/obj/item/stack/ore/bluespace_crystal/bs_crystal = attacking_item - - if(!bs_crystal.use(1)) - return - - balloon_alert(user, "the water deepens!") - fishable = AddComponent(/datum/component/fishing_spot, /datum/fish_source/water_basin) - return +/obj/structure/reagent_dispensers/attackby(obj/item/attacking_item, mob/living/user, params) + START_PROCESSING(SSdcs, src) + var/datum/component/forge_smithable/smith_component = attacking_item.GetComponent(/datum/component/forge_smithable/) + if(!isnull(smith_component)) + smith_component.try_quench(reagents, src, user) + return ITEM_INTERACT_SUCCESS return ..() -/obj/structure/reagent_water_basin/wrench_act(mob/living/user, obj/item/tool) +/obj/structure/reagent_dispensers/reagent_smithing_basin/wrench_act(mob/living/user, obj/item/tool) tool.play_tool_sound(src) - - for(var/i in 1 to 5) - new /obj/item/stack/sheet/mineral/wood(get_turf(src)) - - qdel(src) + set_anchored(!anchored) + balloon_alert_to_viewers(anchored ? "secured" : "unsecured") return TRUE -/obj/structure/reagent_water_basin/tong_act(mob/living/user, obj/item/tool) - var/obj/item/forging/incomplete/search_incomplete = locate(/obj/item/forging/incomplete) in tool.contents - if(!search_incomplete) - return ITEM_INTERACT_SUCCESS +/obj/structure/reagent_dispensers/reagent_smithing_basin/crowbar_act(mob/living/user, obj/item/tool) + if(DOING_INTERACTION(user, DOAFTER_SMITHING_WATER_BASIN)) + return - playsound(src, 'modular_skyrat/modules/reagent_forging/sound/hot_hiss.ogg', 50, TRUE) + tool.play_tool_sound(src) - if(search_incomplete?.times_hit < search_incomplete.average_hits) - to_chat(user, span_warning("You cool down [search_incomplete], but it wasn't ready yet.")) - COOLDOWN_RESET(search_incomplete, heating_remainder) - return ITEM_INTERACT_SUCCESS + if (reagents.total_volume < 75) + to_chat(user, span_notice("You begin to pry apart \the [src]...")) + else + to_chat(user, span_warning("As you begin prying apart \the [src] you notice that it's full of fluid... maybe you should reconsider?")) - if(search_incomplete?.times_hit >= search_incomplete.average_hits) - to_chat(user, span_notice("You cool down [search_incomplete] and it's ready.")) - user.mind.adjust_experience(/datum/skill/smithing, 10) //using the water basin on a ready item gives decent experience. + if(!do_after(user, 5 SECONDS, src, interaction_key = DOAFTER_SMITHING_WATER_BASIN)) + return FALSE - var/obj/spawned_obj = new search_incomplete.spawn_item(get_turf(src)) - if(search_incomplete.custom_materials) - spawned_obj.set_custom_materials(search_incomplete.custom_materials, 1) //lets set its material + //spill contents, then deconstruct + if(reagents.total_volume > 0) + knock_down() + deconstruct(TRUE) + return TRUE - if(istype(spawned_obj, /obj/item/forging/complete)) - var/obj/item/forging/complete/complete_spawned = spawned_obj - complete_spawned.current_perfects = search_incomplete.current_perfects - - qdel(search_incomplete) - tool.icon_state = "tong_empty" - return ITEM_INTERACT_SUCCESS +/obj/structure/reagent_dispensers/tong_act(mob/living/user, obj/item/tool) + var/obj/item/tongs_contents = locate(/obj/item) in tool.contents + if(!tongs_contents) + to_chat(user, span_notice("No item to dip!")) + return ITEM_INTERACT_BLOCKING + else + . = attackby(tongs_contents, user) + if(tool.contents.len == 0) + tool.icon_state = "tong_empty" /// Fishing source for fishing out of basins that have been upgraded, contains saltwater fish (lizard fish fall under this too!) /datum/fish_source/water_basin - catalog_description = "Bottomless Water Basins" + catalog_description = "Filled Blacksmithing Quenching Troughs" fish_table = list( /obj/item/fish/clownfish = 15, /obj/item/fish/pufferfish = 10, @@ -115,6 +121,7 @@ /obj/item/fish/gunner_jellyfish = 15, /obj/item/fish/needlefish = 10, /obj/item/fish/armorfish = 10, + /obj/item/fish/swordfish = 10, /obj/effect/spawner/random/maintenance = 10, /obj/effect/spawner/random/trash/garbage = 15, ) diff --git a/modular_skyrat/modules/reagent_forging/icons/obj/forge_clothing.dmi b/modular_skyrat/modules/reagent_forging/icons/obj/forge_clothing.dmi index ee31a1c28d9c816cf1865eb0dac3358abe471976..f42db09c58d37550fec820c4cea05702a3195941 100644 GIT binary patch literal 10407 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%0AYrKvpN!f;*eE3z~QRsGsR3`I5Swf?2Z z4(wPGAU+zlB(>d6DY?LNXrO=SU)n!M)McSIx<3wss+u1CHdxa1Q!;|8J(O^H_-)c# zIjBWvY|myOaHX=ffz_4zHH4=#grPqRe>dm-G!{mI^vENYX`8*QdDAprUNa>h*6CgJ z@uRwgl!Vil2}&MgD}sIz{dQG05Z5YTkW6@DTQeVXHOz9R!aHTbE>tx39_$EU{tD&3 z7*9=7TjNv8Pp_@Mi4Z0O24zSwzIuEv=8j+iDzH`#5inX&6OR^?2c7wty+-Y#K7SUh z-Wl^}-E8=1K2o$IJPN9Mc}5au)f(mTM1a_k5t^?^Y{Z%gU!cZ3VQVz=y`9;-05%Tu z&%IeEZ}SRYv~uDAv{c&I-+ExmK%0dveXyg-flsp~juQif7f3eF##ref+VgIE$n6#? zOM=}Vvv>r2ft>N#fQ&_VQEA-u^12|CCV) zGt`hHW=?EkVaH^2reTxBqpWXD5%OEmd`rCfpznrEJOHJ0li1)PyvPCV#T*6hx)6&& z$#06lx~Bj_?7&TTVFkJmjN|>dXqmVc68onN6*=boD&Ra##Hboqm?A$W_Ov(ZOHB7T zpiPgRZ4Pz3oA})L6#SYc8|8UzGRUud$9q(gD3fll2uk-`ACtdOG#e=BPb3(3;rDZW z1>MNAaDXo(PxkU{ete?~zzr{r!dZtm7@A4|m5K?%zOdFo5Y!=>f zT}JcC`4b^@J>xTo2JP7%X)Ru;HWS09UQ(3jUBue(x871q5wnCg;pM+Ai;b^-;bPH4 z8Lk8_*@Su95~%0Cn}`**p5Ac3Tdp$LUrA~-V<#jbbE_g>b~_~<(`S}o(YUNiu_@zEv3i3U@_L;&#jOmm0%kvUWrpCoI{#VGKdF}MJ#yhP~Pe*Px z2)JY|7V$^7!YMgOk+(?__i?!NB;(VOM8ao`>udCTMuaqxMwbDJ`PO>u8O{qLQxp#? zcd5G{#I{%zy4-44YK@Tl*-J6Jdolo78e}evhrM2-W5!(a>Sl^42aMJeiS~+C*`DGo zdQLvJzs8n>665o14Kz&&o~jx}EmyLY>&tc0uS^e0Xp%@GUcg@ZjHTZdQ<6nQsTi`d z&%8$V7@pisH`*PsXONcpzT{Z>b8gGDDvmU7C$8ejqxc4c;;}x=emM@nTUk)`OCh#N`)bg=)k#q^j4< z;@9XPE5AH+atO&n?ZIc=LN!d>B^(M5n3_hD$7-3$pk$HVu{gtNODdwlm%B}=w=9{pcV->l@ z4sm4Isq1USOrQfMmq_AGqHRC3H~%j0G#772yq0E*kGVR2lF0l-mjju6w|3d@D*iOG zlUO$t0?rM^3;G^l;Xm+N$h3mk(%wL3j?m@J)~l-0p2dW<8DZ$& z(7MsH(ZkXtBViMo^e;?UjKjyJXF_Lt5C6h`Ck~# BDMA1M literal 1863 zcmZuycQo6J7yoJzd$mSm#NMM?o;@3@vGs{krH|ICNYEgZ7$rs=>#2H*M_a8lc=e2G zNO0_mwni2CnW+&qQX|&$%b&mV`~Cj7_jB&Kvht%QzO^P)N#&zf>yk=LA6X3}r7D~(aKN7# z>j5FpF8TogH_{1eb1S~$#~rIsX}Hw6zlI#uBq>Wl)dDIi*5lC;MvAEl#Z$sa#w6PSL*BObXe1R(G zV~5+Tof9WAh39lN9Z^vZpg8SCUyUfuJ4)t{4PvDEzIIxKFjC1%0`E+Xx1i#osZN1@3hiRL{KL~))_wSl#iWSl^G2+XB zd0y%i_+-AbYJ4QSeQtb12p!!nz_~sn!zDkT9E504>(OtGwJE~d*REnZ8i@7r?^@^) z0`g3a{yJ9WDN-A(|E)Y+nq`^GZbE9?>AfCrEQrCFD<v<4Ah9SN6WG`5x#5B+r{PXYSv2B zTr-zxBe@L=>L8vvKkDc0;%w3_ffc=|qfbf?yq+qdh~48wBveh7FO}68Z|sx%dGn8;7&C zB;22hR%(Hd{tED&c;-5F?z6Xfyi0u#i@B2^Sp)X)SRw$ z$_Y(%*l&MAsCjRGb8D~}$fD=G`Q6JPSo^E=048rs(wj-kFb+eXr999X@Q^hPfK!jf z+~^)@1mN=5d1q>EyT5HG>TL>8mY+MT@)&J8m{bipy49c+vX-L(3*Ly$tF$W!SP`-Y8 z)M*c@tgU{zcL6@98@Bfo`=}Vak7bL8nAJXtWh>+ex{2QxBOOm*Z!n?3L%Xa*>t-LPi{bfih~b zp!Jx2SVw<;{8TQpt0;yx*r|SG&+gOc&1->fd(~1}99Z2UtchSnG&5cC{93m!Fn@g! mrJPWrf1vf-^8df<=RkSrw}0+gIDTP&M!?C=7204MnD%c{WqK$8 diff --git a/modular_skyrat/modules/reagent_forging/icons/obj/forge_items.dmi b/modular_skyrat/modules/reagent_forging/icons/obj/forge_items.dmi index 4d80230251947dc11a4d6d9d353b920db99f646c..76c3adbad53c4142cd27e799f2c30983f42550cd 100644 GIT binary patch literal 8770 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 diff --git a/modular_skyrat/modules/reagent_forging/icons/obj/forge_structures.dmi b/modular_skyrat/modules/reagent_forging/icons/obj/forge_structures.dmi index c5d8e84977983fd9f9b1011f4e8ddf934a14e4d2..be2fa4d4399d9b12f2bdca7530697d972041373b 100644 GIT binary patch literal 4395 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 literal 3464 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 C!A}YR literal 15116 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 diff --git a/tgstation.dme b/tgstation.dme index 24105fbacda..57b0b011e26 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -7231,7 +7231,6 @@ #include "modular_skyrat\master_files\code\game\machinery\limbgrower.dm" #include "modular_skyrat\master_files\code\game\machinery\suit_storage.dm" #include "modular_skyrat\master_files\code\game\objects\items.dm" -#include "modular_skyrat\master_files\code\game\objects\objs.dm" #include "modular_skyrat\master_files\code\game\objects\effects\decals\remains.dm" #include "modular_skyrat\master_files\code\game\objects\effects\decals\cleanable\humans.dm" #include "modular_skyrat\master_files\code\game\objects\effects\decals\cleanable\misc.dm" @@ -8850,17 +8849,27 @@ #include "modular_skyrat\modules\quirks\neutral.dm" #include "modular_skyrat\modules\quirks\echolocation\echolocation.dm" #include "modular_skyrat\modules\radiosound\code\headset.dm" +#include "modular_skyrat\modules\reagent_forging\code\_DEFINES.dm" #include "modular_skyrat\modules\reagent_forging\code\anvil.dm" +#include "modular_skyrat\modules\reagent_forging\code\cargo_orders.dm" +#include "modular_skyrat\modules\reagent_forging\code\container_boxes.dm" #include "modular_skyrat\modules\reagent_forging\code\crafting_bench.dm" #include "modular_skyrat\modules\reagent_forging\code\crafting_bench_recipes.dm" #include "modular_skyrat\modules\reagent_forging\code\forge.dm" +#include "modular_skyrat\modules\reagent_forging\code\forge_belts.dm" #include "modular_skyrat\modules\reagent_forging\code\forge_clothing.dm" +#include "modular_skyrat\modules\reagent_forging\code\forge_equipment.dm" #include "modular_skyrat\modules\reagent_forging\code\forge_items.dm" #include "modular_skyrat\modules\reagent_forging\code\forge_recipes.dm" +#include "modular_skyrat\modules\reagent_forging\code\forge_revolver.dm" +#include "modular_skyrat\modules\reagent_forging\code\forge_smithable_component.dm" #include "modular_skyrat\modules\reagent_forging\code\forge_weapons.dm" +#include "modular_skyrat\modules\reagent_forging\code\memories.dm" #include "modular_skyrat\modules\reagent_forging\code\mindless_killer.dm" #include "modular_skyrat\modules\reagent_forging\code\reagent_component.dm" +#include "modular_skyrat\modules\reagent_forging\code\reagent_smithing_oil.dm" #include "modular_skyrat\modules\reagent_forging\code\smith_skill.dm" +#include "modular_skyrat\modules\reagent_forging\code\smithing_trait_and_chip.dm" #include "modular_skyrat\modules\reagent_forging\code\tool_override.dm" #include "modular_skyrat\modules\reagent_forging\code\two_hand_range.dm" #include "modular_skyrat\modules\reagent_forging\code\water_basin.dm" diff --git a/tgui/packages/tgui/interfaces/Orbit/JobIcon.tsx b/tgui/packages/tgui/interfaces/Orbit/JobIcon.tsx index 9f8fb56aa92..14ba803ad27 100644 --- a/tgui/packages/tgui/interfaces/Orbit/JobIcon.tsx +++ b/tgui/packages/tgui/interfaces/Orbit/JobIcon.tsx @@ -7,6 +7,7 @@ import type { Antagonist, Observable } from './types'; const customJobs = [ 'Telecomms Specialist', 'Barber', + 'Blacksmith', 'Blueshield', 'Bouncer', 'Corrections Officer', diff --git a/tools/UpdatePaths/Scripts_Bubber/5360_smithing_repath.txt b/tools/UpdatePaths/Scripts_Bubber/5360_smithing_repath.txt new file mode 100644 index 00000000000..b1d57fdd99f --- /dev/null +++ b/tools/UpdatePaths/Scripts_Bubber/5360_smithing_repath.txt @@ -0,0 +1,2 @@ +/obj/structure/reagent_water_basin : /obj/structure/reagent_dispensers/reagent_smithing_basin{@OLD} +/obj/item/forging/reagent_weapon : /obj/item/melee/forged_reagent_weapon From a5b7bee6884a035d9b8f8e8c44f5c6570f2a1ed0 Mon Sep 17 00:00:00 2001 From: Bubberbot <151680451+Bubberbot@users.noreply.github.com> Date: Fri, 3 Jul 2026 21:05:38 +0200 Subject: [PATCH 33/41] Automatic changelog for PR #5360 [ci skip] --- .../changelogs/AutoChangeLog-bubber-pr-5360.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5360.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5360.yml b/html/changelogs/AutoChangeLog-bubber-pr-5360.yml new file mode 100644 index 00000000000..3cfaeadfb6b --- /dev/null +++ b/html/changelogs/AutoChangeLog-bubber-pr-5360.yml @@ -0,0 +1,17 @@ +author: "ArrisFairburne" +delete-after: True +changes: + - rscadd: "Way, way too many blacksmith job features & smithing system changes to list. But here's the highlights:" + - balance: "Forged blacksmith weapons can now be used nonlethally via striking with pommels, spear shafts, etc. which knocks down victims and stamina damages them like a weaker baton." + - qol: "Blacksmith tongs now only pull one item at a time, if used on a stackable item." + - qol: "Blacksmiths can now auto-smith at an anvil by right clicking with a hammer." + - qol: "Blacksmithing tools now have more tooltips to tutorialize their usage." + - qol: "Blacksmithing crafting bench can now store item stacks, forging plates, and forging chains. Right-click to view what's in it." + - balance: "Removed multi-anvil smithing. Individual smithing pieces can now be made faster with the smithing chip and other means to compensate." + - rscadd: "Blacksmiths can now build a single action revolver if they are fully levelled." + - rscadd: "Blacksmiths can build a variety of new equipment at the crafting bench -- gun-charging holsters, knife belts, multiple types of scabbards, and even a new expanded-storage botany bag." + - rscadd: "Replaced the water barrel for smithing with a barrel of smithing oil; smithing oil is now used to grant the bonuses that was previously given by leaving the item unimbued. The new barrel can have its contents changed for reagent imbuing." + - rscadd: "A new reagent \"smithing oil\" which gives innate bonuses to any blacksmith equipment imbued using it." + - balance: "Material types now affect the quality of resulting items and how quickly they can be forged." + - balance: "The reagent smithing hammer now has increased toolspeed if forged well." + - balance: "Reagent imbuing's durability penalty has been altered; it reduces durability for each time an imbue effect procs, and then stops functioning for such when below a certain durability percentage." \ No newline at end of file From dc095dddb6d7cb32e45ce86c4aedbc733fd8ccf5 Mon Sep 17 00:00:00 2001 From: Bubberbot <151680451+Bubberbot@users.noreply.github.com> Date: Fri, 3 Jul 2026 19:07:33 +0000 Subject: [PATCH 34/41] Bubberstation automatic changelog compile [ci skip] --- .../AutoChangeLog-bubber-pr-5360.yml | 17 --------- .../AutoChangeLog-bubber-pr-5719.yml | 6 ---- html/changelogs/bubber_archive/2026-07.yml | 36 +++++++++++++++++++ 3 files changed, 36 insertions(+), 23 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5360.yml delete mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5719.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5360.yml b/html/changelogs/AutoChangeLog-bubber-pr-5360.yml deleted file mode 100644 index 3cfaeadfb6b..00000000000 --- a/html/changelogs/AutoChangeLog-bubber-pr-5360.yml +++ /dev/null @@ -1,17 +0,0 @@ -author: "ArrisFairburne" -delete-after: True -changes: - - rscadd: "Way, way too many blacksmith job features & smithing system changes to list. But here's the highlights:" - - balance: "Forged blacksmith weapons can now be used nonlethally via striking with pommels, spear shafts, etc. which knocks down victims and stamina damages them like a weaker baton." - - qol: "Blacksmith tongs now only pull one item at a time, if used on a stackable item." - - qol: "Blacksmiths can now auto-smith at an anvil by right clicking with a hammer." - - qol: "Blacksmithing tools now have more tooltips to tutorialize their usage." - - qol: "Blacksmithing crafting bench can now store item stacks, forging plates, and forging chains. Right-click to view what's in it." - - balance: "Removed multi-anvil smithing. Individual smithing pieces can now be made faster with the smithing chip and other means to compensate." - - rscadd: "Blacksmiths can now build a single action revolver if they are fully levelled." - - rscadd: "Blacksmiths can build a variety of new equipment at the crafting bench -- gun-charging holsters, knife belts, multiple types of scabbards, and even a new expanded-storage botany bag." - - rscadd: "Replaced the water barrel for smithing with a barrel of smithing oil; smithing oil is now used to grant the bonuses that was previously given by leaving the item unimbued. The new barrel can have its contents changed for reagent imbuing." - - rscadd: "A new reagent \"smithing oil\" which gives innate bonuses to any blacksmith equipment imbued using it." - - balance: "Material types now affect the quality of resulting items and how quickly they can be forged." - - balance: "The reagent smithing hammer now has increased toolspeed if forged well." - - balance: "Reagent imbuing's durability penalty has been altered; it reduces durability for each time an imbue effect procs, and then stops functioning for such when below a certain durability percentage." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5719.yml b/html/changelogs/AutoChangeLog-bubber-pr-5719.yml deleted file mode 100644 index 613352920c5..00000000000 --- a/html/changelogs/AutoChangeLog-bubber-pr-5719.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "UvvU" -delete-after: True -changes: - - rscadd: "Added a HoS service weapon case, allowing them to select their weapon. Revolver sprite by Niim" - - rscdel: "Removed the wardens compact shotgun from their locker" - - balance: "made the wardens martial arts gloves make them unable to be shoved down or staggered" \ No newline at end of file diff --git a/html/changelogs/bubber_archive/2026-07.yml b/html/changelogs/bubber_archive/2026-07.yml index 1d5d1c3712e..f7820b9032d 100644 --- a/html/changelogs/bubber_archive/2026-07.yml +++ b/html/changelogs/bubber_archive/2026-07.yml @@ -19,6 +19,36 @@ nikothedude: - code_imp: Lycan transformation sfx is now a variable on the brain 2026-07-03: + ArrisFairburne: + - rscadd: 'Way, way too many blacksmith job features & smithing system changes to + list. But here''s the highlights:' + - balance: Forged blacksmith weapons can now be used nonlethally via striking with + pommels, spear shafts, etc. which knocks down victims and stamina damages them + like a weaker baton. + - qol: Blacksmith tongs now only pull one item at a time, if used on a stackable + item. + - qol: Blacksmiths can now auto-smith at an anvil by right clicking with a hammer. + - qol: Blacksmithing tools now have more tooltips to tutorialize their usage. + - qol: Blacksmithing crafting bench can now store item stacks, forging plates, and + forging chains. Right-click to view what's in it. + - balance: Removed multi-anvil smithing. Individual smithing pieces can now be made + faster with the smithing chip and other means to compensate. + - rscadd: Blacksmiths can now build a single action revolver if they are fully levelled. + - rscadd: Blacksmiths can build a variety of new equipment at the crafting bench + -- gun-charging holsters, knife belts, multiple types of scabbards, and even + a new expanded-storage botany bag. + - rscadd: Replaced the water barrel for smithing with a barrel of smithing oil; + smithing oil is now used to grant the bonuses that was previously given by leaving + the item unimbued. The new barrel can have its contents changed for reagent + imbuing. + - rscadd: A new reagent "smithing oil" which gives innate bonuses to any blacksmith + equipment imbued using it. + - balance: Material types now affect the quality of resulting items and how quickly + they can be forged. + - balance: The reagent smithing hammer now has increased toolspeed if forged well. + - balance: Reagent imbuing's durability penalty has been altered; it reduces durability + for each time an imbue effect procs, and then stops functioning for such when + below a certain durability percentage. LT3: - map: Added a crate return to Void Raptor cargo - map: QoL improvements to PubbyStation cargo area @@ -26,3 +56,9 @@ - balance: reverts bluelens to TG base TealSeer: - bugfix: fixed modsuits hiding horns + UvvU: + - rscadd: Added a HoS service weapon case, allowing them to select their weapon. + Revolver sprite by Niim + - rscdel: Removed the wardens compact shotgun from their locker + - balance: made the wardens martial arts gloves make them unable to be shoved down + or staggered From 35ce72549b12ffda9d91de8db9708b2ced0ca8c2 Mon Sep 17 00:00:00 2001 From: BitSynergy Date: Fri, 3 Jul 2026 17:43:02 -0400 Subject: [PATCH 35/41] Skiff borgs from Troutstation (#5806) ## About The Pull Request Reference and species by Giik. 1686261871
giik_08b93f0c-d2f3-45fd-b746-fccb955c3cad pool_screenshot I got permission to port the skiff sprites from Troutstaion. Original sprite credit: Giik image Cargo, Science, Standard, Syndie, Lustwish, Ninja, resting states and wrecked sprited by me. image ## Why It's Good For The Game Adds a new borg model to play as. ## Proof Of Testing

Screenshots/Videos https://github.com/user-attachments/assets/70ef071e-bf75-4c50-820c-ae7797e02abc https://github.com/user-attachments/assets/0aeb6038-de1e-48a0-8946-7a316a079206 skiffs1 skiffs2 skiffs3 skiffs4 skiffs5 skiffs6 ## Changelog :cl: BitSynergy, Giik add: Ported Skiff cyborgs from Troutstation image: Added Skiff sprites image: Added extra resting states for Skiff image: Added wrecked state for Skiff image: Added new department sprites for Skiff /:cl: --- .../~~bubber_defines/robot_defines.dm | 21 ++++ .../silicons/borgs/code/robot_model.dm | 108 ++++++++++++++++++ .../silicons/borgs/sprites/skiff/CREDIT.MD | 7 ++ .../borgs/sprites/skiff/skiff_cargo.dmi | Bin 0 -> 14154 bytes .../borgs/sprites/skiff/skiff_clown.dmi | Bin 0 -> 15361 bytes .../borgs/sprites/skiff/skiff_eng.dmi | Bin 0 -> 14493 bytes .../borgs/sprites/skiff/skiff_jani.dmi | Bin 0 -> 14024 bytes .../borgs/sprites/skiff/skiff_lustwish.dmi | Bin 0 -> 18760 bytes .../borgs/sprites/skiff/skiff_med.dmi | Bin 0 -> 14393 bytes .../borgs/sprites/skiff/skiff_mine.dmi | Bin 0 -> 14458 bytes .../borgs/sprites/skiff/skiff_ninja.dmi | Bin 0 -> 14166 bytes .../silicons/borgs/sprites/skiff/skiff_pk.dmi | Bin 0 -> 13870 bytes .../borgs/sprites/skiff/skiff_sci.dmi | Bin 0 -> 14360 bytes .../borgs/sprites/skiff/skiff_sec.dmi | Bin 0 -> 14467 bytes .../borgs/sprites/skiff/skiff_serv.dmi | Bin 0 -> 14357 bytes .../borgs/sprites/skiff/skiff_standard.dmi | Bin 0 -> 14706 bytes .../borgs/sprites/skiff/skiff_syndie.dmi | Bin 0 -> 14614 bytes 17 files changed, 136 insertions(+) create mode 100644 modular_zubbers/code/modules/silicons/borgs/sprites/skiff/CREDIT.MD create mode 100644 modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_cargo.dmi create mode 100644 modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_clown.dmi create mode 100644 modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_eng.dmi create mode 100644 modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_jani.dmi create mode 100644 modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_lustwish.dmi create mode 100644 modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_med.dmi create mode 100644 modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_mine.dmi create mode 100644 modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_ninja.dmi create mode 100644 modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_pk.dmi create mode 100644 modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_sci.dmi create mode 100644 modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_sec.dmi create mode 100644 modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_serv.dmi create mode 100644 modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_standard.dmi create mode 100644 modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_syndie.dmi diff --git a/code/__DEFINES/~~bubber_defines/robot_defines.dm b/code/__DEFINES/~~bubber_defines/robot_defines.dm index 84691c1d528..8a086f942e9 100644 --- a/code/__DEFINES/~~bubber_defines/robot_defines.dm +++ b/code/__DEFINES/~~bubber_defines/robot_defines.dm @@ -206,6 +206,24 @@ #define CYBORG_ICON_CC_XENOBORG 'modular_zubbers/code/modules/silicons/borgs/sprites/xenomorphborgs/xenoborg_CC.dmi' #define CYBORG_ICON_SEC_XENOBORG 'modular_zubbers/code/modules/silicons/borgs/sprites/xenomorphborgs/xenoborg_sec.dmi' #define CYBORG_ICON_CLOWN_XENOBORG 'modular_zubbers/code/modules/silicons/borgs/sprites/xenomorphborgs/xenoborg_clown.dmi' + +// SKIFF ICON DEFINES - Sprites by Giik and BitSynergy +// #define CYBORG_ICON_TYPE_SKIFF "skiff" +#define CYBORG_ICON_CARGO_SKIFF 'modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_cargo.dmi' +#define CYBORG_ICON_CLOWN_SKIFF 'modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_clown.dmi' +#define CYBORG_ICON_ENG_SKIFF 'modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_eng.dmi' +#define CYBORG_ICON_JANI_SKIFF 'modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_jani.dmi' +#define CYBORG_ICON_MED_SKIFF 'modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_med.dmi' +#define CYBORG_ICON_MINE_SKIFF 'modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_mine.dmi' +#define CYBORG_ICON_NINJA_SKIFF 'modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_ninja.dmi' +#define CYBORG_ICON_PK_SKIFF 'modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_pk.dmi' +#define CYBORG_ICON_SCI_SKIFF 'modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_sci.dmi' +#define CYBORG_ICON_SEC_SKIFF 'modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_sec.dmi' +#define CYBORG_ICON_SERV_SKIFF 'modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_serv.dmi' +#define CYBORG_ICON_GEN_SKIFF 'modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_standard.dmi' +#define CYBORG_ICON_SYNDIE_SKIFF 'modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_syndie.dmi' +#define CYBORG_ICON_LUST_SKIFF 'modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_lustwish.dmi' + /************************************************************ CYBORG HAT OFFSETS GO BELOW *************************************************************/ @@ -262,3 +280,6 @@ #define XENOBORG_HAT_OFFSET \ SKIN_HAT_OFFSET = list("north" = list(16, 10), "south" = list(16, 5), "east" = list(32, 7), "west" = list(0, 7)), \ SKIN_HAT_REST_OFFSET = list("north" = list(16, 6), "south" = list(16, 6), "east" = list(31, 6), "west" = list(1, 6)) +#define SKIFF_HAT_OFFSET \ + SKIN_HAT_OFFSET = list("north" = list(0, -6), "south" = list(0, -5), "east" = list(-1, -5), "west" = list(1, -5)), \ + SKIN_HAT_REST_OFFSET = list("north" = list(0, -12), "south" = list(0, -18), "east" = list(6, -18), "west" = list(-6, -18)) diff --git a/modular_zubbers/code/modules/silicons/borgs/code/robot_model.dm b/modular_zubbers/code/modules/silicons/borgs/code/robot_model.dm index 516461841ee..d5b6841e26b 100644 --- a/modular_zubbers/code/modules/silicons/borgs/code/robot_model.dm +++ b/modular_zubbers/code/modules/silicons/borgs/code/robot_model.dm @@ -249,6 +249,12 @@ SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUEPANEL, TRAIT_R_WIDE), XENOBORG_HAT_OFFSET ), + "Skiff" = list( + SKIN_ICON_STATE = "skiff_science", + SKIN_ICON = CYBORG_ICON_SCI_SKIFF, + SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SQUADRUPED, TRAIT_R_SMALL), // Even if they aren't quadruped, it needs to be here for resting states to work + SKIFF_HAT_OFFSET + ), ) /* BUBBER SPRITE ADDITIONS BELOW */ @@ -285,6 +291,12 @@ SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUEPANEL, TRAIT_R_WIDE), XENOBORG_HAT_OFFSET ), + "Skiff" = list( + SKIN_ICON_STATE = "skiff_clown", + SKIN_ICON = CYBORG_ICON_CLOWN_SKIFF, + SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SQUADRUPED, TRAIT_R_SMALL), + SKIFF_HAT_OFFSET + ), ) // Standard borgs @@ -302,6 +314,12 @@ SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SMALL, TRAIT_R_WIDE), SMOL_RAPTOR_HAT_OFFSET ), + "Skiff" = list( + SKIN_ICON_STATE = "skiff_standard", + SKIN_ICON = CYBORG_ICON_GEN_SKIFF, + SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SQUADRUPED, TRAIT_R_SMALL), + SKIFF_HAT_OFFSET + ), ) // Medical borgs @@ -380,6 +398,12 @@ SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUEPANEL, TRAIT_R_WIDE), XENOBORG_HAT_OFFSET ), + "Skiff" = list( + SKIN_ICON_STATE = "skiff_medical", + SKIN_ICON = CYBORG_ICON_MED_SKIFF, + SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SQUADRUPED, TRAIT_R_SMALL), + SKIFF_HAT_OFFSET + ), ) // Engineering borgs @@ -458,6 +482,12 @@ SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUEPANEL, TRAIT_R_WIDE), XENOBORG_HAT_OFFSET ), + "Skiff" = list( + SKIN_ICON_STATE = "skiff_engineer", + SKIN_ICON = CYBORG_ICON_ENG_SKIFF, + SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SQUADRUPED, TRAIT_R_SMALL), + SKIFF_HAT_OFFSET + ), ) // Jani borgs @@ -520,6 +550,12 @@ SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUEPANEL, TRAIT_R_BIG), XENOBORG_HAT_OFFSET ), + "Skiff" = list( + SKIN_ICON_STATE = "skiff_janitor", + SKIN_ICON = CYBORG_ICON_JANI_SKIFF, + SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SQUADRUPED, TRAIT_R_SMALL), + SKIFF_HAT_OFFSET + ), ) // Mining borgs @@ -606,6 +642,12 @@ SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUEPANEL, TRAIT_R_BIG), XENOBORG_HAT_OFFSET ), + "Skiff" = list( + SKIN_ICON_STATE = "skiff_miner", + SKIN_ICON = CYBORG_ICON_MINE_SKIFF, + SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SQUADRUPED, TRAIT_R_SMALL), + SKIFF_HAT_OFFSET + ), ) // Security borgs @@ -678,6 +720,12 @@ SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUEPANEL, TRAIT_R_WIDE), XENOBORG_HAT_OFFSET ), + "Skiff" = list( + SKIN_ICON_STATE = "skiff_security", + SKIN_ICON = CYBORG_ICON_SEC_SKIFF, + SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SQUADRUPED, TRAIT_R_SMALL), + SKIFF_HAT_OFFSET + ), ) // Peacekeeper borgs @@ -762,6 +810,12 @@ SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUEPANEL, TRAIT_R_BIG), XENOBORG_HAT_OFFSET ), + "Skiff" = list( + SKIN_ICON_STATE = "skiff_peacekeeper", + SKIN_ICON = CYBORG_ICON_PK_SKIFF, + SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SQUADRUPED, TRAIT_R_SMALL), + SKIFF_HAT_OFFSET + ), ) // Service borgs @@ -851,6 +905,18 @@ SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUEPANEL, TRAIT_R_BIG), XENOBORG_HAT_OFFSET ), + "Skiff" = list( + SKIN_ICON_STATE = "skiff_service", + SKIN_ICON = CYBORG_ICON_SERV_SKIFF, + SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SQUADRUPED, TRAIT_R_SMALL), + SKIFF_HAT_OFFSET + ), + "Skiff (LustWish)" = list( + SKIN_ICON_STATE = "skiff_lustwish", + SKIN_ICON = CYBORG_ICON_LUST_SKIFF, + SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SQUADRUPED, TRAIT_R_SMALL), + SKIFF_HAT_OFFSET + ), ) // Cargo borgs @@ -908,6 +974,12 @@ SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUEPANEL, TRAIT_R_BIG), XENOBORG_HAT_OFFSET ), + "Skiff" = list( + SKIN_ICON_STATE = "skiff_cargo", + SKIN_ICON = CYBORG_ICON_CARGO_SKIFF, + SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SQUADRUPED, TRAIT_R_SMALL), + SKIFF_HAT_OFFSET + ), ) // Syndicate jack borgs @@ -991,6 +1063,12 @@ SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUEPANEL, TRAIT_R_BIG), XENOBORG_HAT_OFFSET ), + "Skiff" = list( + SKIN_ICON_STATE = "skiff_syndie", + SKIN_ICON = CYBORG_ICON_SYNDIE_SKIFF, + SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SQUADRUPED, TRAIT_R_SMALL), + SKIFF_HAT_OFFSET + ), ) // Syndicate borgs @@ -1056,6 +1134,12 @@ SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUEPANEL, TRAIT_R_BIG), XENOBORG_HAT_OFFSET ), + "Skiff" = list( + SKIN_ICON_STATE = "skiff_syndie", + SKIN_ICON = CYBORG_ICON_SYNDIE_SKIFF, + SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SQUADRUPED, TRAIT_R_SMALL), + SKIFF_HAT_OFFSET + ), ) // Syndicate medical borgs @@ -1123,6 +1207,12 @@ SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUEPANEL, TRAIT_R_BIG), XENOBORG_HAT_OFFSET ), + "Skiff" = list( + SKIN_ICON_STATE = "skiff_syndie", + SKIN_ICON = CYBORG_ICON_SYNDIE_SKIFF, + SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SQUADRUPED, TRAIT_R_SMALL), + SKIFF_HAT_OFFSET + ), ) // Syndicate Saboteur borgs @@ -1185,6 +1275,12 @@ SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUEPANEL, TRAIT_R_BIG), XENOBORG_HAT_OFFSET ), + "Skiff" = list( + SKIN_ICON_STATE = "skiff_syndie", + SKIN_ICON = CYBORG_ICON_SYNDIE_SKIFF, + SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SQUADRUPED, TRAIT_R_SMALL), + SKIFF_HAT_OFFSET + ), ) // Ninja borgs @@ -1245,6 +1341,12 @@ SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUEPANEL, TRAIT_R_BIG), XENOBORG_HAT_OFFSET ), + "Skiff" = list( + SKIN_ICON_STATE = "skiff_ninja", + SKIN_ICON = CYBORG_ICON_NINJA_SKIFF, + SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SQUADRUPED, TRAIT_R_SMALL), + SKIFF_HAT_OFFSET + ), ) // Ninja Saboteur borgs @@ -1280,4 +1382,10 @@ SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUEPANEL, TRAIT_R_BIG), XENOBORG_HAT_OFFSET ), + "Skiff" = list( + SKIN_ICON_STATE = "skiff_ninja", + SKIN_ICON = CYBORG_ICON_NINJA_SKIFF, + SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SQUADRUPED, TRAIT_R_SMALL), + SKIFF_HAT_OFFSET + ), ) diff --git a/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/CREDIT.MD b/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/CREDIT.MD new file mode 100644 index 00000000000..6c8b05266fc --- /dev/null +++ b/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/CREDIT.MD @@ -0,0 +1,7 @@ +**File:** `modular_zubbers\code\modules\silicons\borgs\sprites\skiff`
+**Creator:** Giik
+**License:** [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.en)
+**Notes:** Species and original sprites by Giik, ported with their permission.
+ +**Co-Creator:** BitSynergy
+**Notes:** Additional Lustwish, Science, Ninja, Syndicate, Cargo, Standard borgs, wiring panel edit and rest poses by BitSynergy, Original concept and design by Giik.
diff --git a/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_cargo.dmi b/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_cargo.dmi new file mode 100644 index 0000000000000000000000000000000000000000..1beb4b1e217978727fd13c0915202363d5538b1e GIT binary patch literal 14154 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 literal 0 HcmV?d00001 diff --git a/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_clown.dmi b/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_clown.dmi new file mode 100644 index 0000000000000000000000000000000000000000..3a59ac67f849da8b1a5c99e8f2c895c6e72f6477 GIT binary patch literal 15361 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 literal 0 HcmV?d00001 diff --git a/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_eng.dmi b/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_eng.dmi new file mode 100644 index 0000000000000000000000000000000000000000..624422ecc404340463c1949cfefca694d9e44dfb GIT binary patch literal 14493 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 literal 0 HcmV?d00001 diff --git a/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_jani.dmi b/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_jani.dmi new file mode 100644 index 0000000000000000000000000000000000000000..fbdad0b1ea70b2be8bdc9c346d6ede6ea51dfc98 GIT binary patch literal 14024 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 X4_Wk$BF=a*00000NkvXXu0mjf^0nZ@ literal 0 HcmV?d00001 diff --git a/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_med.dmi b/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_med.dmi new file mode 100644 index 0000000000000000000000000000000000000000..28f13ce9ef505cca482ba8095c96a3f0f42da9d5 GIT binary patch literal 14393 zcmch;XH-+s_bs{;S^$Aa5k!F?C`b`d5Tzv)1r(%66KPVU3L+p<6Pk)BpmY!ts&oV? z0#c+12nf=9laAET0wj6y_kZtwxMhqx#=YZy$UYg#IcM*)_FikxIoCSjy7$zX7`Pb# z08E-1YWe^`5dS_fS^xlhNHK<(uzBYA)YH+;6@V9zq7S9a!IJQoOZ%6( zc{l`q&dgaOUMgDz8QjQ9*X=Wcxw-vLk9H^zUwM{5B2Rj+i+5a>Yon)^klH|rT;hHv z`2BH&Ue7c0WZQ=3Tl}c(j^nIGo4{Sxloit+<)4n|5L5gDU53aaerjKBc@Xe z9dCH8Ww_x+oD{~46Z4AKSNP>RkN1S$<2jGQzb(Vql7@F{*nj^4f42goqLz5^hbj&7 zF+HE3^`PrX{zPp{av_*612eVPh`(HvQVJOIlKF0#9vcuNWk#g63RSL7;-86O#}%&hecTh@{IN~#SM zjITfN@2Mq){21i0|MeuPf3N2(YP|A^yszXLHgVHRv1;hZS9hCIzXMnMFv*|N%fk&` zYeN~2nqTe^rxg8K9&Z-64L5iellRxraV5wz_HTwHhB!aH%X8yId6sEVvwpV2Kh|4I zw3#m*c`uNWZM>%fwc6OpQ1jXD?CiAj@>n0Mcs6}sN0FoB=JeBMrk `T)Nm5jR7_ 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 SmniQ70?k|Z)QVNCg8v`RMVa>i literal 0 HcmV?d00001 diff --git a/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_mine.dmi b/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_mine.dmi new file mode 100644 index 0000000000000000000000000000000000000000..5d97cd60a6e1ed9c61e164b130930fc9d3b6dad7 GIT binary patch literal 14458 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 Fe*jWrkY4}* literal 0 HcmV?d00001 diff --git a/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_ninja.dmi b/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_ninja.dmi new file mode 100644 index 0000000000000000000000000000000000000000..4549543e49e97225320f68f5cab37087bf192d06 GIT binary patch literal 14166 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≫3!3V0>Gz0}0WH5{DX7Q5$KjC(8d_jLjzSz9B1e(I8Ey;; z>!hW}BKTGI=R`nA;p_9dK!Nx@@}v<+&b9EL0ldIhMXVf9;0N?*0$~Z_>f%6{9(g>w z^sNf>TGcK0=?^;DsJtr)>f}&t65>?8y%R8<@@#BxZ7bH*%aG{Vwhi1Lk_`e>O!q0l z5$p!ekxxYdjhto4V?d|PB0aL5zxm` znp=wiOf}LUfd!rmVJ8lXb_!e*hRqokqdLo#%L>6!oodJ5R}Ym&kN@l@o?O~IG%B?d z=EFaxg||}7of6Ks&jGk|2qU(t@i+UWJ7+U;(hD_mNvDeYw&-{&q^7kxkz(uKAjKUF z)tg?iF-Xvj{$ni4IsBl82a&Nu5r{ZOEV2Owfmm+}?8H7azW^xGR}GnHjkh#j1v6!V z1Q-ktH4HvYpN4BkCeb4|s0R;5`(jR{^L8UR1k=jA?cQu(>u_HmJD{^oyrLvD@i9MO zvr_LEvYeUC!i-j79Cjw}BRkX2%|80x+ZZiyz4IYufP_d+4 z`M7Q2*4RVGRSzw*2W7vg&J)|sA+Zjg?C`M1$iu@!Ri$nGdkC&nlKVC!$}IwIUrp8p_*@E&5nM8x}q`v*M%ipO{aH;QzHy4M^E7ks5oRVA#gt84OqeA!O$gxBRE zZKQO#9TdG8HVk|Fi~e?3ibIfR)-jmw)W^VAP9|q-0Nua#pw~CZg5SXL;Ry-VdTjl? zc~2aME)`VqaPCy`z}_cge$rG;DuS;<4OiQD&4+#k`f*u7Xv`QjM1kuh0s*D9py4_M z#Ts5I<;&Ulc*~7`3NfbMS+s61Z#mnQrP)cU%6#W7vfM|*GvZ8P*s&Wb&y#1FXpqTD zak1JZK`kSN#Qv3_7!C*WpkPyyodbrglumCW+50vgQ9lHy$X^f9Oep{a1n>(6cy!Y! z6b84*Ur#(iD?_lQZDhyAs@k)uV6Gy@!)OP2huF+mHK0KCHeMf!ltP6p{$qmLMk?3* zyf6(l0rbhDc>f5? z^%zjMXBnvueK$60Pg5$^ozK)p|KWv(B^gV9znzdY8wqoXGW*%7wrg16#L97HF60kc zx`iK^VQauDx`p#THNNh9xxYR^raFfCseqJfqZ|eI+`u_WYuzl$l3k6BC!`Hl|9Qa_ zS%JnjOjWK#bhf053d#&Y`rPJ&iSwY;Pm<)n~RL%VWUCiiSKW{}`^h0!weaG41pB_?*Y9@s}C{Cb63rt+@ zOB{SqJPHlXv=I(AN>!LJtNp= zSxUC9|5Ym>vJ!O>f%?i5+0GY^0e9p`us1yhf^5sA160gYm z)PWs+LWhu`!A)~$yj`t3kZ>QDNHV$mThZ4o&ob-EpHA7jVfyVnlqfe8q)t;Z?jo5( zm;v1&J81J7g%Ln)i>Ss&Uap;)$~3#8)@PCOq9q9jc~pk zI5H|z8jihX&lCqRFwok-@W|rHk#^xqT|CWt5P>@_YJ0MA5yu5R7H@SFE@$52r zL-wn3DKJ_(biHSPPwCLh4~%BJmpZs06rKsF>#79sJiW)`w&4u~y+xsaF0ddU#=(EQB$at$xtSjEUpy7^G$eAzi)wTq%E{lH-=$l2htXIBtZ z?2ZG!+2`M%Og|<(cf%YTvXF3Jg|VSE08)lPAf9D+9jrxkVz1ePkfx{S|ApKiwn1{# z?ArHgG6*p-AAzg$Wd$oZZf5k*&`>br&g5Mi<_%Mj6#b!e#S$2Xw>}B>iRrj4`-}H@ z7r(i=c@MbyH4wRZMW{fg1Ewl{H=fzds<2x}Y^$WTQTqw;RM4oc_0|`b?Wo-MsmpZ_ z(q7&yTe1$PE8Cs+BlL4tvJM0Gji&l?6&4L!F?LTKW*G|uG*gnl+hq*;V5M01FI9^1p2VE86k~-u&&u#Q2fizHyjrX zH*gjmZ2q4C>j0c{e~BbscEi}XQHW7Tm7hE70sS_yoZ;E6v6@(CMcC%SQGTyq`jk%f z#@o;LWiRh!h_8AM0Vuk4w?FYvT+=Idq7(m~^3f5@hnC6N26EU!aFU9~kzEP&S31G< zmOf*1dIRrwG_PVu$mbp|waf@t?~q41`UNSDel663ECnw2c%K|`DsK@h<#kd(-9ls< zV1#6Xx+rNYp^AllYcv4Pslx4R%oRhkr#P_9g=xp{Yqdj=d6!UG@B)}i~TP6OI zq-L<@{-0MCZppUlTy#?I!<>{zW|&2T+u?Sx=MUfA!D_`zYi%3Vciv>ak+Jr;=x@tO zsms&Tst+>=`u!=NKp>!jd={za8{HM#Z*$VBm`O}mae+1f4lG412#Rx7YQSeIt933L= z(EqrXM}=mkh2QY>KiZAme0eXALy|7c!)K1ksfmkWRm^f{q-?Y#Six#S?*UMIOXVij zGU@Eh`%I`*3J(<)%Z|M+4npvb6DG+QF;f<&DF(B5^KC zGB_EHS5k9pUNcVe26f(G)+}rkv%Gg$dOE5U4id<7AARDOxgK|NCqK{3g63;)JO^n{ z@2XHEYszPKZF09qvnr1kqp_#T0BBR|1)YQQ6+`Iu#Kp|3{>vNukfPX=>*l4V^QjY& j8dbiwK&|Bl5pu3Fc=^*B7a!@M9H672uU@5U8}i=(J0?;r literal 0 HcmV?d00001 diff --git a/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_pk.dmi b/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_pk.dmi new file mode 100644 index 0000000000000000000000000000000000000000..83f4af4c0c1dba2e2679f07ba6721d64f848ed17 GIT binary patch literal 13870 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 literal 0 HcmV?d00001 diff --git a/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_sci.dmi b/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_sci.dmi new file mode 100644 index 0000000000000000000000000000000000000000..3b8e5bdc8fcf28ff8c9f63c5bff1a42f100a4c72 GIT binary patch literal 14360 zcmch;XH-++_a=H$=mJ4R5CnoCO$4Ng)KCh+Im`hIKJ?5bbAf}zM%5ND!Ncn*sGNz0oH3w++Y99 zTftu`nTNoykLd9`-U_d;U)58Wm~8iI(7d?VYC5{^5i{Vf{8jUH04#Cu?RAY0)0PrL z%7!w#$1H{jw-o=Ik8G*EKFzoE$vSve#I=7nW??c=4`Q@1h6(4j`5%`PbO0YsH{m#A+@QY zs$}3hxtT?icBSK2opZ<_Is|uv<^f1)u?9^U`t^oYe`T&dbazLz{&z`la)csr7sE&|w}XgY zvwq^O5=hu6QigPUgHD!2Q0brdiWCWs(a{Sg!|mhP%C@)-PF6$(4bWO|*7P#Bu~BBH z>D%>hz48~QXZweDg9zN9Zd=f2pGd+0f7f!Ua_Mqc!qrw{Ai>r2LLCqk5lP*sY&|PY zn+RzAw7hGrsu4y$U*Im=@m=K7<&`X-?B7Uzef{li#HUr0M&WSxg0MBI|QKpI5=2ERM z;WnceST<vLJ-6_ND*tlimi_op_#{;B1*gWBdcT zvVmxjL6_>EYcgKRC*y6cu&H{KP==(lu%MuM;`suY0TOSkdL<*VCyvcO}OP=*emRE1SBIB@=C;my86rAfmh;U=GrW!LkQB;9uT`qsTY8e5DwNtC(+MaCWLI-Io@g(cT1g%WJ1YDw48VaTHG(_Zhb zrSR}lQKdggx(WhxoX<@q0116aENPZ9VltG%mTxSVjCKN!uJhAfpWrj93?76aD$QFK ziMD-j{eabx0?gmUiua}#La>-=>@2lR zCpmg&+Iif_=6#6wx&cQ|n+~M7rpCZ!wsm^#_iy)n5Gd;N8PBhwK+})A*OXTI2rNke z|4Y<3FgDd<0F-X#5LI$39dRXj)jf0Sv4#K|g$l zmmolEayd$X)@x=_8-8iStOz9GGVx(?-!8&;H?ypxhaSaG#IMv_frip&Pjzw$;@bC* zWp&jRJX2%uc`ln&M(Bg!r}E%pF?o){Gy)A7IzEHku=K7C4Z>exbp~3H3&1!~#pE6& z#IPzM)8AY<>B2A>Kw=l}#Iu5q|NgqoCauq86cD0!cweQY{O-5d={6W}9jcW7?J9l@ z-*x#^XH5^J+IoMVlDy%0)SEu6aO)(axX0p)%Aqo|A=r_c0Mv36);artUXSbSv8eJD zuR20CE%@dyme(40(M-3@`+QB0w^pvIiI`NWx9zJ;H`b(ZW7pz*n}L{w;akQ<928pP z&@o|)%b`k##sO#-FS7GP)itG}-k;Lfdy)8q$kLaaI>!~5+iv4P&DUXJnZD9$V)&1VDr-%be5DlHZJb2BB0+-E zLW@|~LI{O{(FQ1h@*@MjRPn7kB=7}ysL{{GIBj5Z&mLg<0Q2>oX(b#rHM`!O_ELH3 z_ANDn`-klAkP60kYOCc~=hQS?1brYeq;4Y#%wgR5d0WCp;=j-4`{=>WK%!1NOY_=5 z{!7uQ$u@^3Z6N*VUz_|pZ-vbS+3*9>3zvo)Jnb9kL51YNVdDEI)eo8pM^hgyKlp6V zbONf5a4a0fXtvCpagSG5rt@le zJe|-FJlt(k!FR{P88+fZzNkBdS^u}X`d^G_nvg?en|%lMg(DX0ZdyTDM>j$MSKIbL z-7E>x_&B2iL7?Vb%Z8XlF_5|U+svsK1qq+8^rDEjGKOL|1zfoFHT-qm$mh7k05UYO2m%KXuUh*=xc~OkSN}w zXEm!&+?P^}dj%2N6mNl>;GYs{ULa_R|)-0`f z!I!$b=i^9HeEP^9J;qm>*AVT{sm=y?tW_GfB=jtF#wBf}(P+%tmjbJC17j0^jRE`{ z@q{-xiQEMS4EC$8><4BfF|M~u~z$(ytMV(M&=ZLDpL^b%W#;#-5OdzW&P-C;h?#``0$~pl59u z;@!@mt!ldjz6E$}R!S+Wth1}9tUYjG3jQ=?aH7AjS>XDb8G7JrM*=Lzq3zFg%``ud zS(q$>=RQUb#-ND?lxE5`pEU$6t$&}9>Rv{u8WSr(#cda4-6ces>#j$k388>X6Z5Nl za^QSi`=T3AhAC5uNdjY=QlQ02&UnY++*Ku8_eak21AhmJhaHMy=)@nlelga1tv#x|bzNSsCE)n2yk7Ae zS`N7hR;cOOw*c=wcZ`8y3M-?5(a}=C6SG82L{Dj{KI)7LI^8#jty9uhD|n@$VuDJV z`HMu6D2Y0K@cPz+V`(KIE~l<>&g?Ad?!n0drf-P^T#FvfW^hx+F-TS2NNNCE1>GXl-^oSl}T&63huEa6#2mgQc#JcJ5*4-!0+q8 zZKy*@{O%ToKG1m$59LHes$$LZ!;&$Ikf@GcCBaMc)WM3Y9a(hj3i+l45+WJVd4O=r z>XGaAxmVkPUi~w-y!JaHvSlwtE!IkD!@)zgvRc0#EdVAofE~7WV=BT9BZGriHt$
DFvqnGk;mRjQG1vB-eWn7zDJv1F5&2C(H|>Nt;xG z=Sl@Us4U*y4fgCyM%e%iAV(|z%e=*rE=bB$q97p*zwl7y&N7PYL?uEGaxlfght@h> zfxhU%w#LB+GGh|Z)2(?tFhxvwY! zd{4Wh@|=x?eT={w(cLzf7xgUSb0t7(+7O7H#<~G-0M$)-C(w&w@+*9R83j7~l{BcI z7(sZ`X&VmJ97rM?Om!jZ@JT!!)2>?nxmZMYy7NTNdr-w7RB>lSnYk4F6pIF=KrB zd(#^t9|hY8h18()>NZUj<*35uuWCL6K+5@N|H+u%;URfEGbv`&{T^29FkG!e4L`3& zT_+i!9%<+~pnO&((bcgM(~3&7X9;y#He!$oEWzxI`37*XUl~hGm_#Fd<2md^5r$Wk zeX~D)+bJhCLX`84m1_BBwcYo`K3q_tSP0?QYzivgN9sa)M2~Y%Q38#xOH!&M z@QR^HzeJ#hd?I)2vtFIWU*Pi&{=d=1Jur+G5ffnUay8aaFb0F>O7)sNpyA$7xU0i-#Pdtb;7aw(8r6>yMP+YZ>FR$kOc1yr z)G;%nf3*dltXzUKUqk=VeHcY{Gj~yIPFC{yJ8_jxQcUpqqX|hj5Bn608s^Mw&=lDG z#yUqc8lVRA=StV_3HJfoilQ%Mz^{uwF_TA+=ARKiWbMy>9qX?UM;w|T*1Og^Ar9FQ zr2Rb{Rvd9tZW=(hKPx$`xR@^e`TO@ozTO3uQ{yB1u9tUup3)SavS6)6fnvBe6DVq%qW@lxN{6;`Eif}+r3s1cUgQAH9 zkrXV6U;U&)o1T~b^DnW)9Ke9`8tx1c4B$5N&lU#(5_+#-3plV&teGbNr>d?ek>v46@X%Fg&SsY#`AGrf5y9}+^Kj3(Z3=|^ z#R9n~$r4-tnV6{^aL}cwfc@umOWPX0V?Idf7gH_ zRQ_{cdC=-+Xt7WKOL80^ozhJ1edp7L-1(agLLzN?!akdmf^!xhDc%rBBiTGv1H*0t z$~VTKpRdPo|1d2ln&Hu@Mc*Vbn&?*t# zeY^aK|MvgK|FEAzF|L?4*KO&+f33Ej?YD>jSH|OQQc<*QTeZgoDSp#?*q@e6E@YiX z&FjE?*m`o7DL7Summ~#V0$$lGcTOFWzd=S*dq|PAnxWQX2nAHx>SSlm!}jR!FGn&3 ztuJ@ykVZzl#-*jD?@w;Ej+A+>jExyP|9nq%aPasN(3_?}9^dl$#U7=Bi{~f>$l@~^ z}ZM{o{o`7_ffdDy73@w41EewG-SfmK!5AA9ZRMuQNa@khSB2xwCr zxf=xKA|*!X5oR4ycUw3p$92vg&-Z%z$8tgZ`vyIkg_(3)TMgtCcAIYUf<-bfFog

Z$5!ARvsf6ElV^|LbD<@HMOXK9+sO?A_+7+ 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 literal 0 HcmV?d00001 diff --git a/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_sec.dmi b/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_sec.dmi new file mode 100644 index 0000000000000000000000000000000000000000..58eeec0a387261d7f011573154287c56d4ef6728 GIT binary patch literal 14467 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 WIXN-Hk^HYh;La@r%~Ex{u>S%;e}CTq literal 0 HcmV?d00001 diff --git a/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_serv.dmi b/modular_zubbers/code/modules/silicons/borgs/sprites/skiff/skiff_serv.dmi new file mode 100644 index 0000000000000000000000000000000000000000..319140c40b995e2fc600e4a9b203de657bbda416 GIT binary patch literal 14357 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 TZr`E&(Gk#8(^IWfwh#Xw9XYGj literal 0 HcmV?d00001 From 5b402dd93c88af9414248894db477655f3e4fe04 Mon Sep 17 00:00:00 2001 From: Bubberbot <151680451+Bubberbot@users.noreply.github.com> Date: Fri, 3 Jul 2026 23:43:27 +0200 Subject: [PATCH 36/41] Automatic changelog for PR #5806 [ci skip] --- html/changelogs/AutoChangeLog-bubber-pr-5806.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5806.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5806.yml b/html/changelogs/AutoChangeLog-bubber-pr-5806.yml new file mode 100644 index 00000000000..926d2d607b5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-bubber-pr-5806.yml @@ -0,0 +1,8 @@ +author: "BitSynergy, Giik" +delete-after: True +changes: + - rscadd: "Ported Skiff cyborgs from Troutstation" + - image: "Added Skiff sprites" + - image: "Added extra resting states for Skiff" + - image: "Added wrecked state for Skiff" + - image: "Added new department sprites for Skiff" \ No newline at end of file From f37bfabe53a14ad7bb91fd9738f90f4b0d86c5b1 Mon Sep 17 00:00:00 2001 From: Bubberbot <151680451+Bubberbot@users.noreply.github.com> Date: Sat, 4 Jul 2026 02:56:46 +0000 Subject: [PATCH 37/41] Bubberstation automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-bubber-pr-5806.yml | 8 -------- html/changelogs/bubber_archive/2026-07.yml | 7 +++++++ 2 files changed, 7 insertions(+), 8 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5806.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5806.yml b/html/changelogs/AutoChangeLog-bubber-pr-5806.yml deleted file mode 100644 index 926d2d607b5..00000000000 --- a/html/changelogs/AutoChangeLog-bubber-pr-5806.yml +++ /dev/null @@ -1,8 +0,0 @@ -author: "BitSynergy, Giik" -delete-after: True -changes: - - rscadd: "Ported Skiff cyborgs from Troutstation" - - image: "Added Skiff sprites" - - image: "Added extra resting states for Skiff" - - image: "Added wrecked state for Skiff" - - image: "Added new department sprites for Skiff" \ No newline at end of file diff --git a/html/changelogs/bubber_archive/2026-07.yml b/html/changelogs/bubber_archive/2026-07.yml index f7820b9032d..f80cf3fe509 100644 --- a/html/changelogs/bubber_archive/2026-07.yml +++ b/html/changelogs/bubber_archive/2026-07.yml @@ -62,3 +62,10 @@ - rscdel: Removed the wardens compact shotgun from their locker - balance: made the wardens martial arts gloves make them unable to be shoved down or staggered +2026-07-04: + BitSynergy, Giik: + - rscadd: Ported Skiff cyborgs from Troutstation + - image: Added Skiff sprites + - image: Added extra resting states for Skiff + - image: Added wrecked state for Skiff + - image: Added new department sprites for Skiff From 38b510437e504404af07f5e2073d93b22b6edb11 Mon Sep 17 00:00:00 2001 From: Robwo <31576505+R0bro@users.noreply.github.com> Date: Sat, 4 Jul 2026 13:15:07 -0400 Subject: [PATCH 38/41] Cell, Stock Part, Apc and Intercom Resprites (#5895) ## About The Pull Request **Skyrat killer! I kill the skyrat sprites!** In all seriousness, the main part of this pr was to replace the skyrat sprites for cells because it was bothering me that they were in a different perspective from most things. This grew into changing stock parts to fit in with the cells, then grew into respriting telecoms parts, then grew into respriting the intercom, THEN grew into respriting the apc! - For cells, extra states were added for the emp-proof cell, the miniature cell and the AA megacell. - For intercoms, extra states were added for the syndicate variant and all departmental encryption key variants. ## Why It's Good For The Game More uniformity and consistency for our sprite replacements! Fixes for edge cases like command/prison intercoms not having a state despite tg having it and the broken apc sticker not being accounted for, yay! ## Proof Of Testing

Screenshots/Videos image
## Changelog :cl: Robwo image: Cells, stock parts, apcs and intercoms have been resprited. /:cl: --- code/modules/power/apc/apc_appearance.dm | 4 ++ code/modules/power/power_store.dm | 2 + .../modules/aesthetics/apc/code/apc.dm | 7 ++++ .../modules/aesthetics/apc/icons/apc.dmi | Bin 5231 -> 5848 bytes .../modules/aesthetics/cells/cell.dm | 30 ++++++++++---- .../modules/aesthetics/cells/cell.dmi | Bin 6940 -> 11241 bytes .../modules/aesthetics/device/device.dmi | Bin 1136 -> 1091 bytes .../aesthetics/intercom/code/intercom.dm | 38 ++++++++++++++++++ .../aesthetics/intercom/icons/intercom.dmi | Bin 1136 -> 2033 bytes .../aesthetics/morgue/icons/morgue.dmi | Bin 4736 -> 4408 bytes .../modules/new_cells/code/power_cell.dm | 2 - .../modules/new_cells/icons/power.dmi | Bin 492 -> 503 bytes .../research/stock_parts.dm | 2 + .../icons/obj/devices/stock_parts.dmi | Bin 0 -> 19290 bytes tgstation.dme | 1 + 15 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 modular_zubbers/code/modules/general_sprite_overrides/research/stock_parts.dm create mode 100644 modular_zubbers/icons/obj/devices/stock_parts.dmi diff --git a/code/modules/power/apc/apc_appearance.dm b/code/modules/power/apc/apc_appearance.dm index 9959c209be8..466be8967a2 100644 --- a/code/modules/power/apc/apc_appearance.dm +++ b/code/modules/power/apc/apc_appearance.dm @@ -111,7 +111,11 @@ /obj/machinery/power/apc/proc/flicker_hacked_icon() if(opened != APC_COVER_CLOSED) return + /* BUBBER EDIT BEGIN - Fix for override not showing on apc var/image/hacker_image = image(icon = 'icons/obj/machines/wallmounts.dmi', loc = src, icon_state = "apcemag", layer = FLOAT_LAYER) + */ + var/image/hacker_image = image(icon = 'modular_skyrat/modules/aesthetics/apc/icons/apc.dmi', loc = src, icon_state = "apcemag", layer = FLOAT_LAYER) + //BUBBER EDIT END var/list/mobs_to_show = list() // Collecting mobs the APC can see for this animation, rather than mobs that can see the APC. Important distinction, intended such that mobs on camera / with XRAY cannot see the flicker. for(var/mob/viewer in view(src)) diff --git a/code/modules/power/power_store.dm b/code/modules/power/power_store.dm index 63b7a9ec8e1..d3c6388adc8 100644 --- a/code/modules/power/power_store.dm +++ b/code/modules/power/power_store.dm @@ -105,6 +105,7 @@ return . +/* OVERWRITTEN IN modular_skyrat\modules\aesthetics\cells\cell.dm /obj/item/stock_parts/power_store/update_overlays() . = ..() if(grown_battery) @@ -112,6 +113,7 @@ if((charge < 0.01) || !charge_light_type) return . += mutable_appearance('icons/obj/machines/cell_charger.dmi', "[cell_size_prefix]-[charge_light_type]-o[(percent() >= 99.5) ? 2 : 1]") +*/ /obj/item/stock_parts/power_store/vv_edit_var(vname, vval) if(vname == NAMEOF(src, charge)) diff --git a/modular_skyrat/modules/aesthetics/apc/code/apc.dm b/modular_skyrat/modules/aesthetics/apc/code/apc.dm index 0bddd02c7b4..c5a573391a4 100644 --- a/modular_skyrat/modules/aesthetics/apc/code/apc.dm +++ b/modular_skyrat/modules/aesthetics/apc/code/apc.dm @@ -23,3 +23,10 @@ return TRUE set_light(0) + +/datum/hallucination/malf_apc + apc_icon = 'modular_skyrat/modules/aesthetics/apc/icons/apc.dmi' + +/obj/item/sticker/syndicate/apc + icon = 'modular_skyrat/modules/aesthetics/apc/icons/apc.dmi' + //Why is the state called milf for this sticker? Who did this... diff --git a/modular_skyrat/modules/aesthetics/apc/icons/apc.dmi b/modular_skyrat/modules/aesthetics/apc/icons/apc.dmi index 41db02c539ba425ece7ae8b1512c505a36eb63f6..73819119d925d4d6e2a816519916d92ef1a3ff9c 100644 GIT binary patch literal 5848 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%0Apz0U219SH;P*0phPZW^U(kN^`pD`;Y z;!luasf?L#&Q9hqo`yE03A@e??|{6a|LpyxdELqYj*D1!r38v(d@^xvYYi@s>qSbP zIguf`sx5^8;4>%cWxnLsHGoP7S6_1ZTz_II9P3-jZy=NbN*X)2Zm~YigR{D*U!_ML zgFVtB`;*;d$klxG4_OO=65;nPswPuW>f_V+OIfZA~1 zfs{5dsi7TWog^`I>&wozdXf6&UvfqJNe_0aUE{H~2kIH4*Y~E?=OYZg{+P~69A>JX z$CM|#odr@gwJ|5ZG4147^8Hs6S#&4-Ffe(AKnZ>7amKrn&L9Lw|6kO1tKHS;qSmQ6 zsI>i*z=z9mjeir@}+9>Wo3X z{c-z-r-vcBRD-_ud$vKBV{6B6XWnj)y+n>h{gbq$Z|jO5X?DsR*rIE66WDd0ua2C( zfZFY%`9O@=1CYLbE#1UR$Bcn6O>K?&=~+rfj5Ofr$t|vm+9k7<0RJ;`(1q-$ZY`k* z{3CAjf2R1ZHPC2&@ay~`;<4Q;PQD@$pw2Qa5`=(1-1`@llt|4@S1>NYG8;YH$PZp5 zqjCGa5dcb9Z08YCNV;IFp6o3Z8DV7ZDL{MN#hJ^IIVYz60z^qbht*RsXD{&SnzXFq zchH=HmZIe1VUKqNA}(9`EBEB!*4!&0#b*0hm{-$I%kHM~7*)+gwzVow>M6?CP)P^skJLhDM56yjfPP=eJsg=)MZW zgawXsQ+!al=LVs_1CidK3qo_zmb=Z&@>f>e!FKYK~`t#{t2X9GF_z^;t9!YCY)BaU?;hyr@YDtLuXIs;bJDh)+& z2{rSi>(_Ra8DlY9@*y%&(-lr1>iQ9f0KST=W_pgfev)DfuKF9_ zz{e@3JAd|D#ekN+uWNH%Aw<1uJ7cM1s`MonZ;kc|8vz0F;32(M^!gFUod-wB4mR-Z zCjAV~PfqXoxJvhvB)o!D4@bV$-z|y-0D6UXm|O?uwwo*^cxl$g*pi=6n=E+%EOjPR zo*KlR{aBCIyp4(QEVQ<@NTN$<%q3>rK%RMMsJ2*<3+LKy%>DL`_}|8BW?_N&fo@%jn zlWmN;CVKNT>T--NR+Cv?S~$|+)ArPKK^Z4^%lt~7U}ECpfC+h0AQZIARzSG`A|!PX z>ad4uAd&uS)BN{;7{9U29yctgXuY&2ixExhQ#>CORa(=T=F{quUb7tH%B(5++Kz%gGt!v0g(%De~M;uT+j zIEgX@ODi+V^}y0R8(b`N8-@TL`HNRlb3Ac+E`{DdOw3r7a8>Lflkl=gdEa|lrS z{r$w8V!-GilVO9p9PnxRATXIqyl20;&YE;Vb$p(E8|;SR0e+L8+1Nj9bE=w=a^Ere z$~Fvbm3tq~$rHG9yftrO@%UTte$PM;;$U%ou`229wJ0IBRY5<9z8Q#1WO+pCC4BS_ z0>rMtcliYc(G$3xreu+z#}0?M0p~l_bK%9^!l;nYY(Ah-jwZ!2CmtX0W_}tP0(92JcX;>a>E=V*RqvBTdPQZDUj?UO}MG!GU|% z<7ip+78ZT$&qavQ&Bq#PYTFM)XGBCfBn?-Uva7)>#(%1O7Ek@FD>}Nh=hVR)Yv9H; LxNgZ6+pzxv_=GOk literal 5231 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 diff --git a/modular_skyrat/modules/aesthetics/cells/cell.dm b/modular_skyrat/modules/aesthetics/cells/cell.dm index ce9ce3b4e36..f2bdba3a034 100644 --- a/modular_skyrat/modules/aesthetics/cells/cell.dm +++ b/modular_skyrat/modules/aesthetics/cells/cell.dm @@ -36,18 +36,32 @@ /obj/item/stock_parts/power_store/cell/lead charging_icon = "lead_in" -/obj/item/stock_parts/power_store/cell/update_overlays() +/obj/item/stock_parts/power_store/cell/crystal_cell + charging_icon = "crystal_in" + +/obj/item/stock_parts/power_store/cell/emergency_light + icon_state = "minicell" + +/obj/item/stock_parts/power_store/cell/emproof + icon_state = "empcell" + charging_icon = "empcell_in" + +/obj/item/stock_parts/power_store/battery + icon = 'modular_skyrat/modules/aesthetics/cells/cell.dmi' + +/obj/item/stock_parts/power_store/battery/upgraded + icon_state = "upcellbig" + +/obj/item/stock_parts/power_store/battery/crap + icon_state = "aacellbig" + +/obj/item/stock_parts/power_store/update_overlays() . = ..() if(grown_battery) - . += mutable_appearance('icons/obj/machines/cell_charger.dmi', "grown_wires") + . += mutable_appearance('modular_skyrat/modules/aesthetics/cells/cell.dmi', "grown_wires") if((charge < 0.01) || !charge_light_type) return - var/icon_link - if(!grown_battery) - icon_link = 'modular_skyrat/modules/aesthetics/cells/cell.dmi' - else - icon_link = 'icons/obj/machines/cell_charger.dmi' - . += mutable_appearance(icon_link, "cell-[charge_light_type]-o[(percent() >= 99.5) ? 2 : 1]") + . += mutable_appearance('modular_skyrat/modules/aesthetics/cells/cell.dmi', "[cell_size_prefix]-[charge_light_type]-o[(percent() >= 99.5) ? 2 : 1]") /obj/machinery/cell_charger icon = 'modular_skyrat/modules/aesthetics/cells/cell.dmi' diff --git a/modular_skyrat/modules/aesthetics/cells/cell.dmi b/modular_skyrat/modules/aesthetics/cells/cell.dmi index 8e815adf7122ae60507da753926f271d887a4b34..ddf9c02e85e67acf9ebf6130763fbb98697f84e9 100644 GIT binary patch literal 11241 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 literal 6940 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 diff --git a/modular_skyrat/modules/aesthetics/device/device.dmi b/modular_skyrat/modules/aesthetics/device/device.dmi index aef6ad7d396026a2f49b04890edab2880a4965ea..8d87b98ff975a937250f12b51e412d6cd34fed24 100644 GIT binary patch delta 915 zcmV;E18n^82*U`FBsFhPOjJd{z`$f=XkA@ohlhtXH$K3?z_^4kI66Vzwmou1Dgc20 z9v&rT0RKM$4eHy20RR7ydN3qr|7QQ>06VEt|Fi(Wz`%v`+K&JL00DGTPE!Ct=GbNc z005uq zT>V_Y!3Y2`Mqa?Z9}J=Z00PlTL_t(|ob8(1a^f%$L~R4UNd}B?FkxBt^8f$1V_~ZH zAwA<=F(ePuRe3sC)7C9+m9oraGX0bCJWt|9YW;uJYQ9VdzRA>Kpsw$fngZ> zx>$dM2I4Fx6HbGNY%(w&xgN;#IE`_E6dnznX$qX{^*d-FE+eKu5}yrR#xq<6-c8-- zVF8J|$Q|IPFd3LsH^@L-=Zpb?ySNV^1N)8)OxsY+7?{>MXMpD}?gPj`wr|R27BEo7 z0?ZgoJQ{%fLr0By+FZ)-+FZ)-+FZ=<+FZ)->Rf-w z@7ny4-$#^Q?|i%rEWf;sEWh1uC>=}r{W*Lx0L};I{5~Af8_fA0_CVwV?tx6|0U^IX zhhMK(bUtwZ!4c;7nU8%Ej|M(o1yX+3=3;)==5l`5=3;)==5l`5=3;)==3;)=<|dQL zWHOmDJ0Gy~0XrXf#A`0!cOkGmgie2W9`P5Q4>0!!=6sKPAmiWQ!C?<&d=I_oe1N$> z@YfHRd{1w{^DeNQddSWP?0mq^2kd;nWHOmdrZ273>-VWjzW<-71^54z4T$&ubtT{b zSFSJL|JT)=?>m%k^$p1P|CJ47pWOrU{r^`O2p!7*>RNFBUsnt6|7$xC@Bb?+OV01w p67##h0U^Ju8?gLtGMPR>e*g-0W%pJ;Na6qh002ovPDHLkV1nGW!0iA4 delta 960 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 delta 1128 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
vZRo|4$)fyxe43MN5aRQAlbH_5)q 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 delta 410 zcmV;L0cHO81MCBTiBL{Q4GJ0x0000DNk~Le0000$0000$2m=5B0G+pi>;M1&Fi=cX zMZmzol$Wc;$J9qkTO=kfGXVep05d;%!8Ja6GXTuY05jj<=rFbBaC3+M005Z)0Ot&U z?f?J)0d!JMQvg8b*k%9#0E>E5Sad{Xb7OL8aCB*JZU6w0d|iJG6iv-ZtON<`pg}Iq zqSW%tycDn&Wd&D17qDXioG3A7h+Tco0002fNkleOKWQmJiF(+9cmk8T)-VLSoN|CWB{Ka1~nKREKA4Yd0~ zBmevR0m=XVeo)EAzJ5T`x4$2df&P9_*}(dNVLZkM6@3y4QOEjGqW}N^07*qoM6N<$ Eg7hV?f&c&j diff --git a/modular_zubbers/code/modules/general_sprite_overrides/research/stock_parts.dm b/modular_zubbers/code/modules/general_sprite_overrides/research/stock_parts.dm new file mode 100644 index 00000000000..991669aa437 --- /dev/null +++ b/modular_zubbers/code/modules/general_sprite_overrides/research/stock_parts.dm @@ -0,0 +1,2 @@ +/obj/item/stock_parts + icon = 'modular_zubbers/icons/obj/devices/stock_parts.dmi' diff --git a/modular_zubbers/icons/obj/devices/stock_parts.dmi b/modular_zubbers/icons/obj/devices/stock_parts.dmi new file mode 100644 index 0000000000000000000000000000000000000000..42b87b8c4822ba84ba6d37704d75349a94aee775 GIT binary patch literal 19290 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 Date: Sat, 4 Jul 2026 19:15:32 +0200 Subject: [PATCH 39/41] Automatic changelog for PR #5895 [ci skip] --- html/changelogs/AutoChangeLog-bubber-pr-5895.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5895.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5895.yml b/html/changelogs/AutoChangeLog-bubber-pr-5895.yml new file mode 100644 index 00000000000..0a562a87d63 --- /dev/null +++ b/html/changelogs/AutoChangeLog-bubber-pr-5895.yml @@ -0,0 +1,4 @@ +author: "Robwo" +delete-after: True +changes: + - image: "Cells, stock parts, apcs and intercoms have been resprited." \ No newline at end of file From b808bef63f29d2afc02357c1c71ecbd6f8a8f0ed Mon Sep 17 00:00:00 2001 From: Cabbage <130223709+SomeCabbage@users.noreply.github.com> Date: Sat, 4 Jul 2026 13:38:16 -0400 Subject: [PATCH 40/41] adds digi sprites for cheerleader shoes (#5885) ## About The Pull Request Title ## Why It's Good For The Game Lack of digitigrade sprites sucks for people who play characters with digitigrade legs. ## Proof Of Testing Screenshot 2026-07-02 104053 Screenshot 2026-07-02 104048 Screenshot 2026-07-02 104044 behold ## Changelog :cl: add: adds digitigrade sprites for the cheerleading shoes /:cl: Co-authored-by: Cabbage --- .../code/modules/GAGS/greyscale_configs.dm | 3 +++ .../modules/clothing/under/ba_cheerleader.dm | 2 ++ .../mob/clothing/under/ba_cheerleader_digi.dmi | Bin 0 -> 1169 bytes 3 files changed, 5 insertions(+) create mode 100644 modular_zubbers/icons/mob/clothing/under/ba_cheerleader_digi.dmi diff --git a/modular_zubbers/code/modules/GAGS/greyscale_configs.dm b/modular_zubbers/code/modules/GAGS/greyscale_configs.dm index 83c796f3e79..a32596a85b0 100644 --- a/modular_zubbers/code/modules/GAGS/greyscale_configs.dm +++ b/modular_zubbers/code/modules/GAGS/greyscale_configs.dm @@ -498,3 +498,6 @@ name = "BA Cheerleader Sneakers (Worn)" icon_file = 'modular_zubbers/icons/mob/clothing/under/ba_cheerleader.dmi' json_config = 'modular_zubbers/code/datums/greyscale/json_configs/under/ba_cheerleader/shoes_worn.json' + +/datum/greyscale_config/ba_cheerleader_shoes/worn/digi + icon_file = 'modular_zubbers/icons/mob/clothing/under/ba_cheerleader_digi.dmi' diff --git a/modular_zubbers/code/modules/clothing/under/ba_cheerleader.dm b/modular_zubbers/code/modules/clothing/under/ba_cheerleader.dm index 245155cabc1..2b2341f3987 100644 --- a/modular_zubbers/code/modules/clothing/under/ba_cheerleader.dm +++ b/modular_zubbers/code/modules/clothing/under/ba_cheerleader.dm @@ -223,9 +223,11 @@ icon_state = "ba_cheerleader_shoes_icon" post_init_icon_state = "ba_cheerleader_shoes" worn_icon = 'modular_zubbers/icons/mob/clothing/under/ba_cheerleader.dmi' + worn_icon_digi = 'modular_zubbers/icons/mob/clothing/under/ba_cheerleader_digi.dmi' worn_icon_state = "ba_cheerleader_shoes" greyscale_config = /datum/greyscale_config/ba_cheerleader_shoes greyscale_config_worn = /datum/greyscale_config/ba_cheerleader_shoes/worn + greyscale_config_worn_digi = /datum/greyscale_config/ba_cheerleader_shoes/worn/digi greyscale_colors = "#FFFFFF#2980b9" flags_1 = IS_PLAYER_COLORABLE_1 diff --git a/modular_zubbers/icons/mob/clothing/under/ba_cheerleader_digi.dmi b/modular_zubbers/icons/mob/clothing/under/ba_cheerleader_digi.dmi new file mode 100644 index 0000000000000000000000000000000000000000..cc289dc434092d450756b4d866a9fb397a2b7f54 GIT binary patch literal 1169 zcmeAS@N?(olHy`uVBq!ia0vp^4M3d0!3HF+R#kZdsotuPh!U67;^d;tf|AVqJO+je z#-;sx`3@QIv^@Wzxu(qhPf4od+5q-nToW^WWL65C?0fK))8O!-viW}V{jNVswCEH5 zwp{StnrWYSzu#DU?SY)8$jS}3n}q!WPqD8Fcqld7_-Evd(nPK`_f$5UK5z**fqB2Di(^Q|t+#XReS`xg z4#c~+KVo7QSk>DpATi6KBh#tLu*I>NPmNDP?NLg}rQSgG?W-myDkT;NTw&~-*0O}T zaY?6u!Nn|2g9A#kGUsci*PQ*l<;l9e?3~|!>z3E%{`y)Z1r z-`R^-&k1`~9$J0lp2=nLvW6C6&xRVi_oka-bakeB`Gqyq)X%so`mK2F6UA`rwm#P5 zvB&bKIA8g(kafrJFWuk&-nIQ7r&95+=-i!shEuBk)}8&mqyFfW^!C5s<<9Q;aQv}e z%%l3c(&PKDFLp=~)-+Xj{M==|FX!v_b^J4D8^^!i>Q!UQBzOMmKPhv*3sJ?FS3kQM zvTNVn+mG|-$C%~Yt!cGmbK+E({O7^HDfRpJ?tRa`F3jvTQ_7~lZnG}jzWp*qNafg% z8#Cm?C){W{Hof|!;{+SA>C@(TBwW|ZkdYO4Tw<^HD4T!DaifD}|5IZ&JXgIY>!4F_ zQTulORe2GY@U+Bl!E5+4cKu@6{o}!r8}kdlHe~p>+-0|B7vDYMn?=O_K67n3{zguA zMu7!0eyAxhkOEag8x}8CUcY*zX+fI->&2szi^umMlrbm=BY^+I2I>ZuQA0QArlbf4+quqj+uYz|syWSEOC}rJZ zBv>Z@MkeNs)2+t|f35DVsjy*DlL037q(`$GfQ136u)vMg!ouQ%m6g@M-={Cnn Date: Sat, 4 Jul 2026 19:38:41 +0200 Subject: [PATCH 41/41] Automatic changelog for PR #5885 [ci skip] --- html/changelogs/AutoChangeLog-bubber-pr-5885.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-bubber-pr-5885.yml diff --git a/html/changelogs/AutoChangeLog-bubber-pr-5885.yml b/html/changelogs/AutoChangeLog-bubber-pr-5885.yml new file mode 100644 index 00000000000..c7c74654c39 --- /dev/null +++ b/html/changelogs/AutoChangeLog-bubber-pr-5885.yml @@ -0,0 +1,4 @@ +author: "SomeCabbage" +delete-after: True +changes: + - rscadd: "adds digitigrade sprites for the cheerleading shoes" \ No newline at end of file