From 2d03695cd8d55e8b9aa9448b2bfb75ce889f788c Mon Sep 17 00:00:00 2001
From: shammysham <139022155+shammysham@users.noreply.github.com>
Date: Sat, 31 Jan 2026 17:29:16 -0500
Subject: [PATCH 1/2] Add: Recycling recipes for IV-UIV parallel control and
absolute parallel mastery hatches
---
.../tiered_machines/parallel_hatches.js | 100 +++++++++++++++++-
1 file changed, 98 insertions(+), 2 deletions(-)
diff --git a/kubejs/server_scripts/default/additions/machines_and_parts/tiered_machines/parallel_hatches.js b/kubejs/server_scripts/default/additions/machines_and_parts/tiered_machines/parallel_hatches.js
index 742e8c34b..f0f4681a3 100644
--- a/kubejs/server_scripts/default/additions/machines_and_parts/tiered_machines/parallel_hatches.js
+++ b/kubejs/server_scripts/default/additions/machines_and_parts/tiered_machines/parallel_hatches.js
@@ -3,6 +3,48 @@ ServerEvents.recipes(event => {
global.not_hardmode(() => {
const components = global.componentMaterials;
+ const calculateDuration = global.calculateRecyclingDuration;
+ const calculateVoltageMultiplier = global.calculateRecyclingVoltageMultiplier;
+
+ function postIVHatchRecycling(tierKey, postUV) {
+ const tierData = components[tierKey];
+
+ if (!tierData) return;
+
+ const {
+ materials: {
+ primMaterial,
+ cable,
+ tierMaterial
+ }
+ } = tierData;
+
+ const parallelHatchMaceratorOutputs = [
+ `18x gtceu:${primMaterial}_dust`,
+ '16x gtceu:rubber_dust',
+ `9x gtceu:${cable}_dust`,
+ `8x gtceu:${tierMaterial}_dust`
+ ]
+ event.recipes.gtceu.macerator(id(`macerate_${tierKey}_parallel_hatch`))
+ .itemInputs(`${postUV ? 'start_core' : 'gtceu'}:${tierKey}_parallel_hatch`)
+ .itemOutputs(parallelHatchMaceratorOutputs)
+ .duration(calculateDuration(parallelHatchMaceratorOutputs))
+ .EUt(2 * calculateVoltageMultiplier(parallelHatchMaceratorOutputs))
+ .category(GTRecipeCategories.MACERATOR_RECYCLING);
+
+ const parallelArcFurnaceOutputs = [
+ `18x gtceu:${primMaterial}_ingot`,
+ `9x gtceu:${cable}_ingot`,
+ `8x gtceu:${tierMaterial}_ingot`,
+ '16x gtceu:tiny_ash_dust'
+ ];
+ event.recipes.gtceu.arc_furnace(id(`arc_${tierKey}_parallel_hatch`))
+ .itemInputs(`${postUV ? 'start_core' : 'gtceu'}:${tierKey}_parallel_hatch`)
+ .itemOutputs(parallelArcFurnaceOutputs)
+ .duration(calculateDuration(parallelArcFurnaceOutputs))
+ .EUt(GTValues.VA[GTValues.LV])
+ .category(GTRecipeCategories.ARC_FURNACE_RECYCLING);
+ }
function postUVMachines(tierKey,chip) {
const tierData = components[tierKey];
@@ -11,7 +53,9 @@ ServerEvents.recipes(event => {
const {
tiers: { tier, tier0 },
- materials: {
+ materials: {
+ primMaterial,
+ tierMaterial,
tierFluid,
cable
}
@@ -41,11 +85,63 @@ ServerEvents.recipes(event => {
.itemOutputs(`start_core:${tier}_absolute_parallel_hatch`)
.duration(320)
.EUt(GTValues.VA[GTValues[tier.toUpperCase()]]);
+
+ postIVHatchRecycling(tierKey, true);
+
+ // absolute hatch recycling
+ const parallelHatchMaceratorOutputs = [
+ `64x gtceu:${primMaterial}_dust`,
+ `26x gtceu:${primMaterial}_dust`,
+ '64x gtceu:rubber_dust',
+ `33x gtceu:${cable}_dust`,
+ `8x gtceu:${tierMaterial}_dust`
+ ]
+ event.recipes.gtceu.macerator(id(`macerate_${tier}_absolute_parallel_hatch`))
+ .itemInputs(`start_core:${tier}_absolute_parallel_hatch`)
+ .itemOutputs(parallelHatchMaceratorOutputs)
+ .duration(calculateDuration(parallelHatchMaceratorOutputs))
+ .EUt(2 * calculateVoltageMultiplier(parallelHatchMaceratorOutputs))
+ .category(GTRecipeCategories.MACERATOR_RECYCLING);
+
+ const parallelArcFurnaceOutputs = [
+ `64x gtceu:${primMaterial}_ingot`,
+ `26x gtceu:${primMaterial}_ingot`,
+ `33x gtceu:${cable}_ingot`,
+ `8x gtceu:${tierMaterial}_ingot`,
+ '64x gtceu:tiny_ash_dust'
+ ];
+ event.recipes.gtceu.arc_furnace(id(`arc_${tier}_absolute_parallel_hatch`))
+ .itemInputs(`start_core:${tier}_absolute_parallel_hatch`)
+ .itemOutputs(parallelArcFurnaceOutputs)
+ .duration(calculateDuration(parallelArcFurnaceOutputs))
+ .EUt(GTValues.VA[GTValues.LV])
+ .category(GTRecipeCategories.ARC_FURNACE_RECYCLING);
}
+ // add recycling recipes to all hatches
+ // iv hatches are slightly cheaper than the rest because they are not made using assline components
+ const ivHatchMaceratorOutputs = ['12x gtceu:tungsten_steel_dust', '6x gtceu:rubber_dust', '3x gtceu:platinum_dust', '10x gtceu:small_iridium_dust'];
+ event.recipes.gtceu.macerator(id(`macerate_iv_parallel_hatch`))
+ .itemInputs(`gtceu:iv_parallel_hatch`)
+ .itemOutputs(ivHatchMaceratorOutputs)
+ .duration(calculateDuration(ivHatchMaceratorOutputs))
+ .EUt(2 * calculateVoltageMultiplier(ivHatchMaceratorOutputs))
+ .category(GTRecipeCategories.MACERATOR_RECYCLING);
+
+ const ivHatchArcFurnaceOutputs = ['12x gtceu:tungsten_steel_ingot', '3x gtceu:platinum_ingot', '22x gtceu:iridium_nugget', '6x gtceu:tiny_ash_dust'];
+ event.recipes.gtceu.arc_furnace(id(`arc_iv_parallel_hatch`))
+ .itemInputs(`gtceu:iv_parallel_hatch`)
+ .itemOutputs(ivHatchArcFurnaceOutputs)
+ .duration(calculateDuration(ivHatchArcFurnaceOutputs))
+ .EUt(GTValues.VA[GTValues.LV])
+ .category(GTRecipeCategories.ARC_FURNACE_RECYCLING);
+
+ postIVHatchRecycling('luv', false);
+ postIVHatchRecycling('zpm', false);
+ postIVHatchRecycling('uv', false);
+
postUVMachines('uhv','kubejs:uepic_chip');
postUVMachines('uev','kubejs:uepic_chip');
postUVMachines('uiv','kubejs:uipic_chip');
-
});
});
\ No newline at end of file
From a98db89b2ecbc42ec11afe5aef796e6d85ba1d33 Mon Sep 17 00:00:00 2001
From: shammysham <139022155+shammysham@users.noreply.github.com>
Date: Sat, 31 Jan 2026 19:33:09 -0500
Subject: [PATCH 2/2] Cleanup: Deduplicate recycling code with a couple helpers
---
.../machines_and_parts/converters.js | 26 ++---
.../tiered_machines/parallel_hatches.js | 103 +++++-------------
.../utils/helpers/recipe_helpers.js | 39 ++++++-
3 files changed, 71 insertions(+), 97 deletions(-)
diff --git a/kubejs/server_scripts/default/additions/machines_and_parts/converters.js b/kubejs/server_scripts/default/additions/machines_and_parts/converters.js
index d165e0a80..be1edcb03 100644
--- a/kubejs/server_scripts/default/additions/machines_and_parts/converters.js
+++ b/kubejs/server_scripts/default/additions/machines_and_parts/converters.js
@@ -1,9 +1,8 @@
global.not_hardmode(() => {
ServerEvents.recipes(event => {
- const id = global.id;
- const calculateDuration = global.calculateRecyclingDuration;
- const calculateVoltageMultiplier = global.calculateRecyclingVoltageMultiplier;
+ const registerScrapRecyclingRecipe = global.registerScrapRecyclingRecipe;
+ const registerPlasmaRecyclingRecipe = global.registerPlasmaRecyclingRecipe;
event.remove({ output: /gtceu:.*_energy_converter/ });
// remove recyling recipes
@@ -84,8 +83,8 @@ global.not_hardmode(() => {
C: `#gtceu:circuits/${tier}`,
S: `gtceu:${tier}_machine_hull`
}).id(`start:shaped/${tier}_${amps}a_energy_converter`);
- };
- };
+ }
+ }
converterCraftingRecipe(1, 'single');
converterCraftingRecipe(4, 'quadruple');
@@ -118,19 +117,8 @@ global.not_hardmode(() => {
let appendMacerator = amps === 64 ? [`64x ${info.superconductor}_dust`, `64x ${info.superconductor}_dust`] : [`${amps * 2}x ${info.superconductor}_dust`];
outputsMacerator.splice.apply(outputsMacerator, [amps < 8 ? 1 : 0, 0].concat(appendMacerator));
- event.recipes.gtceu.arc_furnace(id(`arc_${tier}_${amps}a_energy_converter`))
- .itemInputs(`${converterPrefix}:${tier}_${amps}a_energy_converter`)
- .itemOutputs(outputsArc)
- .duration(calculateDuration(outputsArc))
- .EUt(GTValues.VA[GTValues.LV])
- .category(GTRecipeCategories.ARC_FURNACE_RECYCLING);
-
- event.recipes.gtceu.macerator(id(`macerate_${tier}_${amps}a_energy_converter`))
- .itemInputs(`${converterPrefix}:${tier}_${amps}a_energy_converter`)
- .itemOutputs(outputsMacerator)
- .duration(calculateDuration(outputsMacerator))
- .EUt(2 * calculateVoltageMultiplier(outputsMacerator))
- .category(GTRecipeCategories.MACERATOR_RECYCLING);
+ registerScrapRecyclingRecipe(event, `${converterPrefix}:${tier}_${amps}a_energy_converter`, outputsMacerator);
+ registerPlasmaRecyclingRecipe(event, `${converterPrefix}:${tier}_${amps}a_energy_converter`, outputsArc);
}
}
});
@@ -140,5 +128,5 @@ BlockEvents.placed(event => {
let block = event.getBlock();
if (/^(?:gtceu|start_core):.*energy_converter$/.test(block.getId())) {
block.mergeEntityData({ energyContainer: { feToEu: true } });
- };
+ }
});
\ No newline at end of file
diff --git a/kubejs/server_scripts/default/additions/machines_and_parts/tiered_machines/parallel_hatches.js b/kubejs/server_scripts/default/additions/machines_and_parts/tiered_machines/parallel_hatches.js
index f0f4681a3..190bd4b0c 100644
--- a/kubejs/server_scripts/default/additions/machines_and_parts/tiered_machines/parallel_hatches.js
+++ b/kubejs/server_scripts/default/additions/machines_and_parts/tiered_machines/parallel_hatches.js
@@ -3,10 +3,11 @@ ServerEvents.recipes(event => {
global.not_hardmode(() => {
const components = global.componentMaterials;
- const calculateDuration = global.calculateRecyclingDuration;
- const calculateVoltageMultiplier = global.calculateRecyclingVoltageMultiplier;
+ const registerScrapRecyclingRecipe = global.registerScrapRecyclingRecipe;
+ const registerPlasmaRecyclingRecipe = global.registerPlasmaRecyclingRecipe;
+ const getPrefixByTier = global.getPrefixByTier;
- function postIVHatchRecycling(tierKey, postUV) {
+ function postIVHatchRecycling(tierKey) {
const tierData = components[tierKey];
if (!tierData) return;
@@ -19,31 +20,11 @@ ServerEvents.recipes(event => {
}
} = tierData;
- const parallelHatchMaceratorOutputs = [
- `18x gtceu:${primMaterial}_dust`,
- '16x gtceu:rubber_dust',
- `9x gtceu:${cable}_dust`,
- `8x gtceu:${tierMaterial}_dust`
- ]
- event.recipes.gtceu.macerator(id(`macerate_${tierKey}_parallel_hatch`))
- .itemInputs(`${postUV ? 'start_core' : 'gtceu'}:${tierKey}_parallel_hatch`)
- .itemOutputs(parallelHatchMaceratorOutputs)
- .duration(calculateDuration(parallelHatchMaceratorOutputs))
- .EUt(2 * calculateVoltageMultiplier(parallelHatchMaceratorOutputs))
- .category(GTRecipeCategories.MACERATOR_RECYCLING);
-
- const parallelArcFurnaceOutputs = [
- `18x gtceu:${primMaterial}_ingot`,
- `9x gtceu:${cable}_ingot`,
- `8x gtceu:${tierMaterial}_ingot`,
- '16x gtceu:tiny_ash_dust'
- ];
- event.recipes.gtceu.arc_furnace(id(`arc_${tierKey}_parallel_hatch`))
- .itemInputs(`${postUV ? 'start_core' : 'gtceu'}:${tierKey}_parallel_hatch`)
- .itemOutputs(parallelArcFurnaceOutputs)
- .duration(calculateDuration(parallelArcFurnaceOutputs))
- .EUt(GTValues.VA[GTValues.LV])
- .category(GTRecipeCategories.ARC_FURNACE_RECYCLING);
+ registerScrapRecyclingRecipe(event, `${getPrefixByTier(tierKey, true)}:${tierKey}_parallel_hatch`,
+ [`18x gtceu:${primMaterial}_dust`, '16x gtceu:rubber_dust', `9x gtceu:${cable}_dust`, `8x gtceu:${tierMaterial}_dust`]);
+
+ registerPlasmaRecyclingRecipe(event, `${getPrefixByTier(tierKey, true)}:${tierKey}_parallel_hatch`,
+ [`18x gtceu:${primMaterial}_ingot`, `9x gtceu:${cable}_ingot`, `8x gtceu:${tierMaterial}_ingot`, '16x gtceu:tiny_ash_dust']);
}
function postUVMachines(tierKey,chip) {
@@ -86,60 +67,32 @@ ServerEvents.recipes(event => {
.duration(320)
.EUt(GTValues.VA[GTValues[tier.toUpperCase()]]);
- postIVHatchRecycling(tierKey, true);
+ // normal hatch recycling
+ postIVHatchRecycling(tierKey);
// absolute hatch recycling
- const parallelHatchMaceratorOutputs = [
- `64x gtceu:${primMaterial}_dust`,
- `26x gtceu:${primMaterial}_dust`,
- '64x gtceu:rubber_dust',
- `33x gtceu:${cable}_dust`,
- `8x gtceu:${tierMaterial}_dust`
- ]
- event.recipes.gtceu.macerator(id(`macerate_${tier}_absolute_parallel_hatch`))
- .itemInputs(`start_core:${tier}_absolute_parallel_hatch`)
- .itemOutputs(parallelHatchMaceratorOutputs)
- .duration(calculateDuration(parallelHatchMaceratorOutputs))
- .EUt(2 * calculateVoltageMultiplier(parallelHatchMaceratorOutputs))
- .category(GTRecipeCategories.MACERATOR_RECYCLING);
-
- const parallelArcFurnaceOutputs = [
- `64x gtceu:${primMaterial}_ingot`,
- `26x gtceu:${primMaterial}_ingot`,
- `33x gtceu:${cable}_ingot`,
- `8x gtceu:${tierMaterial}_ingot`,
- '64x gtceu:tiny_ash_dust'
- ];
- event.recipes.gtceu.arc_furnace(id(`arc_${tier}_absolute_parallel_hatch`))
- .itemInputs(`start_core:${tier}_absolute_parallel_hatch`)
- .itemOutputs(parallelArcFurnaceOutputs)
- .duration(calculateDuration(parallelArcFurnaceOutputs))
- .EUt(GTValues.VA[GTValues.LV])
- .category(GTRecipeCategories.ARC_FURNACE_RECYCLING);
+ registerScrapRecyclingRecipe(event, `start_core:${tier}_absolute_parallel_hatch`,
+ [`64x gtceu:${primMaterial}_dust`, `26x gtceu:${primMaterial}_dust`, '64x gtceu:rubber_dust',
+ `33x gtceu:${cable}_dust`, `8x gtceu:${tierMaterial}_dust`]);
+
+ registerPlasmaRecyclingRecipe(event, `start_core:${tier}_absolute_parallel_hatch`,
+ [`64x gtceu:${primMaterial}_ingot`, `26x gtceu:${primMaterial}_ingot`, `33x gtceu:${cable}_ingot`,
+ `8x gtceu:${tierMaterial}_ingot`, '64x gtceu:tiny_ash_dust']);
}
// add recycling recipes to all hatches
// iv hatches are slightly cheaper than the rest because they are not made using assline components
- const ivHatchMaceratorOutputs = ['12x gtceu:tungsten_steel_dust', '6x gtceu:rubber_dust', '3x gtceu:platinum_dust', '10x gtceu:small_iridium_dust'];
- event.recipes.gtceu.macerator(id(`macerate_iv_parallel_hatch`))
- .itemInputs(`gtceu:iv_parallel_hatch`)
- .itemOutputs(ivHatchMaceratorOutputs)
- .duration(calculateDuration(ivHatchMaceratorOutputs))
- .EUt(2 * calculateVoltageMultiplier(ivHatchMaceratorOutputs))
- .category(GTRecipeCategories.MACERATOR_RECYCLING);
-
- const ivHatchArcFurnaceOutputs = ['12x gtceu:tungsten_steel_ingot', '3x gtceu:platinum_ingot', '22x gtceu:iridium_nugget', '6x gtceu:tiny_ash_dust'];
- event.recipes.gtceu.arc_furnace(id(`arc_iv_parallel_hatch`))
- .itemInputs(`gtceu:iv_parallel_hatch`)
- .itemOutputs(ivHatchArcFurnaceOutputs)
- .duration(calculateDuration(ivHatchArcFurnaceOutputs))
- .EUt(GTValues.VA[GTValues.LV])
- .category(GTRecipeCategories.ARC_FURNACE_RECYCLING);
-
- postIVHatchRecycling('luv', false);
- postIVHatchRecycling('zpm', false);
- postIVHatchRecycling('uv', false);
+ registerScrapRecyclingRecipe(event, `gtceu:iv_parallel_hatch`,
+ ['12x gtceu:tungsten_steel_dust', '6x gtceu:rubber_dust', '3x gtceu:platinum_dust', '10x gtceu:small_iridium_dust']);
+
+ registerPlasmaRecyclingRecipe(event, `gtceu:iv_parallel_hatch`,
+ ['12x gtceu:tungsten_steel_ingot', '3x gtceu:platinum_ingot', '22x gtceu:iridium_nugget','6x gtceu:tiny_ash_dust']);
+
+ postIVHatchRecycling('luv');
+ postIVHatchRecycling('zpm');
+ postIVHatchRecycling('uv');
+ // add additional custom hatches
postUVMachines('uhv','kubejs:uepic_chip');
postUVMachines('uev','kubejs:uepic_chip');
postUVMachines('uiv','kubejs:uipic_chip');
diff --git a/kubejs/startup_scripts/utils/helpers/recipe_helpers.js b/kubejs/startup_scripts/utils/helpers/recipe_helpers.js
index 347505b28..299ebdec1 100644
--- a/kubejs/startup_scripts/utils/helpers/recipe_helpers.js
+++ b/kubejs/startup_scripts/utils/helpers/recipe_helpers.js
@@ -1,11 +1,26 @@
// priority: 1000
+/**
+ * Get the recipe/mod namespace prefix for a given tier.
+ * @param tier{string} - voltage tier
+ * @param forCoreMod{boolean} - appends _core to the result (used for referencing core mod items)
+ * @returns {string} - gtceu for voltages at or below uv, start[[_core]] otherwise
+ */
+global.getPrefixByTier = (tier, forCoreMod) => {
+ switch (tier.toLowerCase()) {
+ case 'ulv': case 'lv': case 'mv': case 'hv': case 'ev': case 'iv': case 'luv': case 'zpm': case 'uv':
+ return 'gtceu';
+ default:
+ return `start${forCoreMod ? '_core' : ''}`;
+ }
+};
+
/**
* https://github.com/GregTechCEu/GregTech-Modern/blob/v1.6.4-1.20.1/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/RecyclingRecipes.java#L424
* @param {string[]} itemOutputs
* @returns {number}
*/
-global.calculateRecyclingDuration = (itemOutputs) => {
+function calculateRecyclingDuration(itemOutputs) {
return (
itemOutputs.reduce((duration, item) => {
const is = Item.of(item);
@@ -15,14 +30,14 @@ global.calculateRecyclingDuration = (itemOutputs) => {
return duration + matDuration;
}, 0) / GTValues.M
);
-};
+}
/**
* https://github.com/GregTechCEu/GregTech-Modern/blob/v1.6.4-1.20.1/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/RecyclingRecipes.java#L389
* @param {string[]} itemOutputs
* @returns {number}
*/
-global.calculateRecyclingVoltageMultiplier = (itemOutputs) => {
+function calculateRecyclingVoltageMultiplier(itemOutputs) {
const highestTemp = itemOutputs.reduce((temp, item) => {
const ms = global.getGtMaterial(item);
if (!ms) return temp;
@@ -47,4 +62,22 @@ global.calculateRecyclingVoltageMultiplier = (itemOutputs) => {
if (highestTemp == 0) return 1;
if (highestTemp < 2000) return 4;
return 16;
+}
+
+global.registerScrapRecyclingRecipe = (event, itemInput, itemOutputs) => {
+ event.recipes.gtceu.macerator(global.id(`macerate_${itemInput.split(":")[1]}`))
+ .itemInputs(`${itemInput}`)
+ .itemOutputs(itemOutputs)
+ .duration(calculateRecyclingDuration(itemOutputs))
+ .EUt(2 * calculateRecyclingVoltageMultiplier(itemOutputs))
+ .category(GTRecipeCategories.MACERATOR_RECYCLING);
+};
+
+global.registerPlasmaRecyclingRecipe = (event, itemInput, itemOutputs) => {
+ event.recipes.gtceu.arc_furnace(global.id(`arc_${itemInput.split(":")[1]}`))
+ .itemInputs(`${itemInput}`)
+ .itemOutputs(itemOutputs)
+ .duration(calculateRecyclingDuration(itemOutputs))
+ .EUt(GTValues.VA[GTValues.LV])
+ .category(GTRecipeCategories.ARC_FURNACE_RECYCLING);
};