Compare commits

...

10 Commits

Author SHA1 Message Date
Integer Limit
cb7e8115cb
Update Nomi Labs to 0.11.3 (#1151)
[EXPAND]
messageTitle = "Fix DME Machine and JEI Gui Overlap"
messageBody = "[BUG]"
[EXPAND]
2024-12-11 11:05:47 +11:00
Integer Limit
86cb1fbf85
Allow Usage of Fluid Containers in Crafting (#1142)
This PR allows the usage of any fluid container, such as GT cells and drums, or EIO portable tanks, or Thermal portable tanks, in crafting recipes involving buckets.

This is done through mass recipe replacing, replacing ingredients with a custom 'fluid bucket ingredient'. This ingredient also displays some options for containers in JEI, allowing for crafting auto-fill.

Some recipes have been changed:
- Cake + Cake Base + Chocolate Cake now supports dough or rice dough
- Cake + Cake Base no longer allow using unfilled buckets
- Concrete Bucket (for Firebricks Recipe) change:
	- Now makes Concrete Cell (Iron)
	- Takes a cell as input, and any fluid container (for water) as input
- New Recipe: Water + Lava = Obsidian

Reviewers:
- Anything else we should add to the display list? Should we remove something?
- Any recipes that are not replaced?
- Check for bugs involving crafting, e.g. crash, dupe, unexpected behaviours.

[EXPAND]
[[messages]]
messageBody = '''
[FEATURE]
[DETAILS]
details = [
"Allows using ANY Fluid Container (GT Drums/Cells, EIO Tanks, Thermal Tanks, etc.) in Crafting Recipes, Substituting Filled Buckets",
"Also adds Crafting Recipe for Obsidian (Water + Lava)"
]
[DETAILS]
'''

[[messages]]
messageTitle = "Revamp Concrete Bucket Crafting Recipe"
messageBody = '''
[BALANCING]
[HM]
[DETAILS]
detail = "Now takes an Empty Cell as Input, and outputs a Filled Cell"
[DETAILS]
'''
[EXPAND]
2024-12-11 09:11:28 +11:00
Integer Limit
4166fd3454
Hide EIO Lava Generator JEI Category (#1145)
[SKIP]
2024-12-09 22:36:27 +11:00
Integer Limit
5bb91be679
Update Labs to 0.11.2 + Use New GrS API (#1144)
[SKIP]
2024-12-09 21:42:47 +11:00
Integer Limit
8b5bcf15b7
Small Earlygame Tweaks (#1139)
[BALANCING]
[HM]

[DETAILS]
details = [
"Adds a Log -> Stick Shortcut Recipe",
"Removes Paper Recipes Directly from Sugar Cane and Rice",
"Makes Wood Pulp Crafting Output 2 Instead of 4",
]
[DETAILS]
2024-12-09 19:56:53 +11:00
Integer Limit
e6a39127a7
Simplify CraftPresence Window Title Handling (#1143)
[BUG]

[DETAILS]
detail = "May fix issues with CraftPresence on Cleanroom"
[DETAILS]
2024-12-09 18:55:28 +11:00
Integer Limit
7a8e7619ae
Add Creosote & Concrete Buckets to JEI (#1140)
[FEATURE]

[DETAILS]
detail = "They are used in some Crafting Recipes."
[DETAILS]
2024-12-08 21:33:16 +11:00
Integer Limit
4961b40747
Update Config Override Thermal Configs (#1141)
[SKIP]
2024-12-08 21:32:34 +11:00
Integer Limit
24abb5896c
Check for Unused Locals/Parameters in Scripts (#1138)
[SKIP]
2024-12-08 08:59:50 +11:00
Integer Limit
a19ca884f0
Further Standardize Formatting in Quest Books (#1134)
[INTERNAL]
2024-12-08 00:51:05 +11:00
31 changed files with 2989 additions and 2211 deletions

View File

@ -725,7 +725,7 @@
}, },
{ {
"projectID": 932060, "projectID": 932060,
"fileID": 5949579, "fileID": 5981309,
"required": true "required": true
}, },
{ {

View File

@ -60,14 +60,14 @@ Device {
} }
XpCollector { XpCollector {
B:Enable=true B:Enable=false
# Adjust this value to change the capture radius for the Insightful Condenser. [range: 2 ~ 16, default: 5] # Adjust this value to change the capture radius for the Insightful Condenser. [range: 2 ~ 16, default: 5]
I:Radius=5 I:Radius=5
} }
Diffuser { Diffuser {
B:Enable=true B:Enable=false
# Adjust this value to change the area effect radius when Lingering Potion fluid is used in a Decoctive Diffuser. [range: 2 ~ 16, default: 8] # Adjust this value to change the area effect radius when Lingering Potion fluid is used in a Decoctive Diffuser. [range: 2 ~ 16, default: 8]
I:LingeringPotionRadius=8 I:LingeringPotionRadius=8
@ -120,7 +120,7 @@ Dynamo {
B:Upgradable=true B:Upgradable=true
# If TRUE, Dynamos can be upgraded in a Crafting Grid using Kits. If Classic Crafting is enabled, only the Creative Conversion Kit may be used in this fashion. # If TRUE, Dynamos can be upgraded in a Crafting Grid using Kits. If Classic Crafting is enabled, only the Creative Conversion Kit may be used in this fashion.
B:UpgradeKitCrafting=true B:UpgradeKitCrafting=false
########################################################################################################## ##########################################################################################################
# AugmentSlots # AugmentSlots
@ -292,7 +292,7 @@ Machine {
B:Upgradable=true B:Upgradable=true
# If TRUE, Machines can be upgraded in a Crafting Grid using Kits. If Classic Crafting is enabled, only the Creative Conversion Kit may be used in this fashion. # If TRUE, Machines can be upgraded in a Crafting Grid using Kits. If Classic Crafting is enabled, only the Creative Conversion Kit may be used in this fashion.
B:UpgradeKitCrafting=true B:UpgradeKitCrafting=false
########################################################################################################## ##########################################################################################################
# AugmentSlots # AugmentSlots
@ -407,7 +407,7 @@ Machine {
Crucible { Crucible {
# Adjust this value to change the Energy consumption (in RF/t) for a Magma Crucible. This base value will scale with block level and Augments. [range: 10 ~ 5000, default: 40] # Adjust this value to change the Energy consumption (in RF/t) for a Magma Crucible. This base value will scale with block level and Augments. [range: 10 ~ 5000, default: 40]
I:BasePower=40 I:BasePower=40
B:Enable=true B:Enable=false
} }
Refinery { Refinery {
@ -419,7 +419,7 @@ Machine {
Transposer { Transposer {
# Adjust this value to change the Energy consumption (in RF/t) for a Fluid Transposer. This base value will scale with block level and Augments. [range: 10 ~ 5000, default: 20] # Adjust this value to change the Energy consumption (in RF/t) for a Fluid Transposer. This base value will scale with block level and Augments. [range: 10 ~ 5000, default: 20]
I:BasePower=20 I:BasePower=20
B:Enable=true B:Enable=false
} }
Charger { Charger {
@ -458,7 +458,7 @@ Machine {
Enchanter { Enchanter {
# Adjust this value to change the Energy consumption (in RF/t) for an Arcane Ensorcellator. This base value will scale with block level and Augments. [range: 10 ~ 5000, default: 20] # Adjust this value to change the Energy consumption (in RF/t) for an Arcane Ensorcellator. This base value will scale with block level and Augments. [range: 10 ~ 5000, default: 20]
I:BasePower=50 I:BasePower=50
B:Enable=true B:Enable=false
} }
Precipitator { Precipitator {
@ -642,7 +642,7 @@ Storage {
B:Securable=true B:Securable=true
# If TRUE, Energy Cells can be upgraded in a Crafting Grid using Kits. If Classic Crafting is enabled, only the Creative Conversion Kit may be used in this fashion. # If TRUE, Energy Cells can be upgraded in a Crafting Grid using Kits. If Classic Crafting is enabled, only the Creative Conversion Kit may be used in this fashion.
B:UpgradeKitCrafting=true B:UpgradeKitCrafting=false
} }
Tank { Tank {
@ -717,5 +717,3 @@ Upgrades {
Version { Version {
S:Identifier=5.5.7 S:Identifier=5.5.7
} }

View File

@ -60,14 +60,14 @@ Device {
} }
XpCollector { XpCollector {
B:Enable=true B:Enable=false
# Adjust this value to change the capture radius for the Insightful Condenser. [range: 2 ~ 16, default: 5] # Adjust this value to change the capture radius for the Insightful Condenser. [range: 2 ~ 16, default: 5]
I:Radius=5 I:Radius=5
} }
Diffuser { Diffuser {
B:Enable=true B:Enable=false
# Adjust this value to change the area effect radius when Lingering Potion fluid is used in a Decoctive Diffuser. [range: 2 ~ 16, default: 8] # Adjust this value to change the area effect radius when Lingering Potion fluid is used in a Decoctive Diffuser. [range: 2 ~ 16, default: 8]
I:LingeringPotionRadius=8 I:LingeringPotionRadius=8
@ -120,7 +120,7 @@ Dynamo {
B:Upgradable=true B:Upgradable=true
# If TRUE, Dynamos can be upgraded in a Crafting Grid using Kits. If Classic Crafting is enabled, only the Creative Conversion Kit may be used in this fashion. # If TRUE, Dynamos can be upgraded in a Crafting Grid using Kits. If Classic Crafting is enabled, only the Creative Conversion Kit may be used in this fashion.
B:UpgradeKitCrafting=true B:UpgradeKitCrafting=false
########################################################################################################## ##########################################################################################################
# AugmentSlots # AugmentSlots
@ -292,7 +292,7 @@ Machine {
B:Upgradable=true B:Upgradable=true
# If TRUE, Machines can be upgraded in a Crafting Grid using Kits. If Classic Crafting is enabled, only the Creative Conversion Kit may be used in this fashion. # If TRUE, Machines can be upgraded in a Crafting Grid using Kits. If Classic Crafting is enabled, only the Creative Conversion Kit may be used in this fashion.
B:UpgradeKitCrafting=true B:UpgradeKitCrafting=false
########################################################################################################## ##########################################################################################################
# AugmentSlots # AugmentSlots
@ -407,7 +407,7 @@ Machine {
Crucible { Crucible {
# Adjust this value to change the Energy consumption (in RF/t) for a Magma Crucible. This base value will scale with block level and Augments. [range: 10 ~ 5000, default: 40] # Adjust this value to change the Energy consumption (in RF/t) for a Magma Crucible. This base value will scale with block level and Augments. [range: 10 ~ 5000, default: 40]
I:BasePower=40 I:BasePower=40
B:Enable=true B:Enable=false
} }
Refinery { Refinery {
@ -419,7 +419,7 @@ Machine {
Transposer { Transposer {
# Adjust this value to change the Energy consumption (in RF/t) for a Fluid Transposer. This base value will scale with block level and Augments. [range: 10 ~ 5000, default: 20] # Adjust this value to change the Energy consumption (in RF/t) for a Fluid Transposer. This base value will scale with block level and Augments. [range: 10 ~ 5000, default: 20]
I:BasePower=20 I:BasePower=20
B:Enable=true B:Enable=false
} }
Charger { Charger {
@ -458,7 +458,7 @@ Machine {
Enchanter { Enchanter {
# Adjust this value to change the Energy consumption (in RF/t) for an Arcane Ensorcellator. This base value will scale with block level and Augments. [range: 10 ~ 5000, default: 20] # Adjust this value to change the Energy consumption (in RF/t) for an Arcane Ensorcellator. This base value will scale with block level and Augments. [range: 10 ~ 5000, default: 20]
I:BasePower=50 I:BasePower=50
B:Enable=true B:Enable=false
} }
Precipitator { Precipitator {
@ -642,7 +642,7 @@ Storage {
B:Securable=true B:Securable=true
# If TRUE, Energy Cells can be upgraded in a Crafting Grid using Kits. If Classic Crafting is enabled, only the Creative Conversion Kit may be used in this fashion. # If TRUE, Energy Cells can be upgraded in a Crafting Grid using Kits. If Classic Crafting is enabled, only the Creative Conversion Kit may be used in this fashion.
B:UpgradeKitCrafting=true B:UpgradeKitCrafting=false
} }
Tank { Tank {
@ -717,5 +717,3 @@ Upgrades {
Version { Version {
S:Identifier=5.5.7 S:Identifier=5.5.7
} }

File diff suppressed because it is too large Load Diff

View File

@ -365,14 +365,14 @@
} }
}, },
"dynamicIcons": { "dynamicIcons": {
"default": "https://via.placeholder.com/256.png" "default": "https://via.placeholder.com/256.png",
"IntegerLimit_": "https://mc-heads.net/avatar/ba3d12a4b7f347309db3b9f71531e8d6"
}, },
"dynamicVariables": { "dynamicVariables": {
"windowCreated": "{executeMethod('org.lwjgl.opengl.Display', null, 'isCreated')}",
"mods": "{general.mods} Mod(s)", "mods": "{general.mods} Mod(s)",
"players": "{server.players.current} / {server.players.max} Players", "players": "{server.players.current} / {server.players.max} Players",
"player_info_items": "Items: {item.main_hand.message}", "player_info_items": "Items: {item.main_hand.message}",
"windowTitle": "{custom.windowCreated ? executeMethod('org.lwjgl.opengl.Display', null, 'getTitle') : ''}", "windowTitle": "{executeMethod('com.nomiceu.nomilabs.util.LabsDisplayHelper', null, 'getWindowTitle')}",
"player_info_health": "Health: {player.health.current}/{player.health.max}", "player_info_health": "Health: {player.health.current}/{player.health.max}",
"pack": "{pack.name}", "pack": "{pack.name}",
"mode": "{executeMethod('com.nomiceu.nomilabs.util.LabsModeHelper', null, 'getFormattedMode')}", "mode": "{executeMethod('com.nomiceu.nomilabs.util.LabsModeHelper', null, 'getFormattedMode')}",
@ -385,4 +385,4 @@
"world_info": "On {world.name}" "world_info": "On {world.name}"
} }
} }
} }

View File

@ -56,7 +56,8 @@ advanced {
> >
# Whether to disable the Narrator. # Whether to disable the Narrator.
# Fixes Crashes in Arm Macs, in some very specific environments. # Fixes crashes in Arm Macs, in some development environments.
# This config does nothing outside of deobfuscated environments!
# If your game is crashing, try enabling this! # If your game is crashing, try enabling this!
# [default: false] # [default: false]
B:disableNarrator=false B:disableNarrator=false
@ -461,6 +462,10 @@ content {
# [default: false] # [default: false]
B:enableBlocks=false B:enableBlocks=false
# Enable Custom GT Items.
# [default: true]
B:enableItems=true
# Enable Custom Materials. # Enable Custom Materials.
# [default: true] # [default: true]
B:enableMaterials=true B:enableMaterials=true
@ -526,10 +531,10 @@ content {
########################################################################################################## ##########################################################################################################
"mod integration" { "mod integration" {
# Whether to add a Empty Line between any Crafting Recipe Output Tooltips in JEI. # Whether to add a Empty Line between any Ingredient Tooltips in JEI.
# Examples of Crafting Recipe Output Tooltips are `Recipe By <MOD_ID>` and `Recipe ID: <RECIPE_ID>`. # Examples of Ingredient Tooltips are `Recipe By <MOD_ID>`, `Recipe ID: <RECIPE_ID>`, and `Accepts any: <ORE_DICT>`.
# [default: true] # [default: true]
B:addJEICraftingOutputEmptyLine=true B:addJEIIngEmptyLine=true
# Whether to enable Advanced Rocketry Integration, which fixes Advanced Rocketry registering items for Fluid Blocks. # Whether to enable Advanced Rocketry Integration, which fixes Advanced Rocketry registering items for Fluid Blocks.
# [default: true] # [default: true]

View File

@ -9,6 +9,39 @@ import net.minecraftforge.fluids.FluidStack
import static com.nomiceu.nomilabs.groovy.GroovyHelpers.RecyclingHelpers.* import static com.nomiceu.nomilabs.groovy.GroovyHelpers.RecyclingHelpers.*
import static gregtech.api.GTValues.* import static gregtech.api.GTValues.*
if (LabsModeHelper.expert) {
// Log -> Stick Shortcut (Expert Mode)
crafting.shapedBuilder()
.output(item('minecraft:stick') * 4)
.matrix('B', 'B')
.key('B', ore('logWood'))
.register()
// Remove endercore paper recipe
crafting.remove('endercore:shapeless_paper')
// Remove aa paper recipe (with rice)
crafting.remove('actuallyadditions:recipes23')
// Allow rice -> paper through chad
crafting.shapedBuilder()
.output(metaitem('dustPaper') * 2)
.matrix('RRR', ' M ')
.key('R', item('actuallyadditions:item_food', 16))
.key('M', ore('toolMortar'))
.register()
} else {
// Remove mc paper recipe, is useless with endercore's shapeless one
crafting.remove('minecraft:paper')
}
// Wood Pulp
// Output 4 for Normal, 2 for Expert
crafting.addShapeless(metaitem('dustWood') * (LabsModeHelper.expert ? 2 : 4), [ore('logWood'), ore('toolMortar')])
// Remove Thermal Foundation's clay recipe, slag is unobtainable
crafting.remove('thermalfoundation:clay_ball')
// Furnaces // Furnaces
// Iron Furnace // Iron Furnace
mods.gregtech.assembler.recipeBuilder() mods.gregtech.assembler.recipeBuilder()

View File

@ -0,0 +1,528 @@
import com.google.common.base.CaseFormat
import com.nomiceu.nomilabs.util.LabsModeHelper
import com.nomiceu.nomilabs.groovy.SimpleIIngredient
import net.minecraft.item.ItemStack
import net.minecraftforge.fluids.Fluid
import net.minecraftforge.fluids.FluidStack
import net.minecraftforge.fluids.FluidUtil
import net.minecraftforge.fluids.capability.CapabilityFluidHandler
import net.minecraftforge.fluids.capability.IFluidHandlerItem
import static com.nomiceu.nomilabs.util.LabsTranslate.Translatable
import static com.nomiceu.nomilabs.groovy.GroovyHelpers.TranslationHelpers.translate
import static com.nomiceu.nomilabs.groovy.GroovyHelpers.TranslationHelpers.translatable
/*
* Allows recipes with buckets to accept all fluid containers.
* Also adds other misc. fluid crafting recipes.
*/
/* Starter OreDicts */
ore('dough').add(item('actuallyadditions:item_misc', 4))
ore('dough').add(item('actuallyadditions:item_misc', 9))
/* Existing Replacements (Recipe itself not changed) */
/* Water Bucket */
// AE2 Cable Cleaning
var caseConverter = CaseFormat.LOWER_UNDERSCORE.converterTo(CaseFormat.UPPER_CAMEL)
for (var entry : [0: 'glass', 20: 'covered', 40: 'smart', 60: 'dense_smart', 500: 'dense_covered']) {
var cables = ore("ae2Colored${caseConverter.convert(entry.value)}Cable")
var output = item('appliedenergistics2:part', entry.key + 16)
for (var meta : entry.key..entry.key + 15) {
cables.add(item('appliedenergistics2:part', meta))
}
crafting.remove("appliedenergistics2:network/cables/${entry.value}_fluix_clean")
crafting.shapelessBuilder()
.output(output)
.input(cables, fluidIng(fluid('water')))
.setInputTooltip(1, IngredientFluidBucket.getInputTooltip(fluid('water')))
.replace().register()
}
// Paper
crafting.remove('thermalfoundation:paper')
crafting.shapelessBuilder()
.output(item('minecraft:paper') * 2)
.input(ore('dustWood'), ore('dustWood'), ore('dustWood'), ore('dustWood'), fluidIng(fluid('water')))
.setInputTooltip(4, IngredientFluidBucket.getInputTooltip(fluid('water')))
.register()
// Podzol
crafting.remove('thermalfoundation:block_podzol')
crafting.shapelessBuilder()
.output(item('minecraft:dirt', 2))
.input(ore('treeLeaves'), ore('treeLeaves'), item('minecraft:dirt', 1),
item('thermalfoundation:fertilizer', 1), fluidIng(fluid('water')))
.setInputTooltip(4, IngredientFluidBucket.getInputTooltip(fluid('water')))
.register()
// Mycelium
crafting.remove('thermalfoundation:block_mycelium')
crafting.shapelessBuilder()
.output(item('minecraft:mycelium'))
.input(item('minecraft:brown_mushroom'), item('minecraft:red_mushroom'), item('minecraft:dirt', 1),
item('thermalfoundation:fertilizer', 1), fluidIng(fluid('water')))
.setInputTooltip(4, IngredientFluidBucket.getInputTooltip(fluid('water')))
.register()
// Little Tiles Water
crafting.shapelessBuilder()
.output(item('littletiles:lttransparentcoloredblock', 5) * 2)
.input(fluidIng(fluid('water')), fluidIng(fluid('water')))
.setInputTooltip(0, IngredientFluidBucket.getInputTooltip(fluid('water')))
.setInputTooltip(1, IngredientFluidBucket.getInputTooltip(fluid('water')))
.replace().register()
// Waterstone
crafting.shapedBuilder()
.output(item('chisel:waterstone') * 8)
.matrix('AAA', 'ABA', 'AAA')
.key('A', item('minecraft:stone'))
.key('B', fluidIng(fluid('water')))
.setInputTooltip(4, IngredientFluidBucket.getInputTooltip(fluid('water')))
.replace().register()
// Water Mob Filter
crafting.remove('darkutils:filter_water')
crafting.shapedBuilder()
.output(item('darkutils:filter', 5) * 4)
.matrix('ABA', 'BCB', 'ABA')
.key('A', ore('fenceGateWood'))
.key('B', ore('stone'))
.key('C', fluidIng(fluid('water')))
.setInputTooltip(4, IngredientFluidBucket.getInputTooltip(fluid('water')))
.register()
// Rice Slimeball
crafting.remove('actuallyadditions:recipes24')
crafting.shapedBuilder()
.output(item('actuallyadditions:item_misc', 12) * 4)
.matrix(' A ', 'ABA', ' A ')
.key('A', item('actuallyadditions:item_misc', 9))
.key('B', fluidIng(fluid('water')))
.setInputTooltip(4, IngredientFluidBucket.getInputTooltip(fluid('water')))
.register()
// Ring of Liquid Banning
crafting.shapedBuilder()
.output(item('actuallyadditions:item_water_removal_ring'))
.matrix('ABA', 'BCB', 'ABA')
.key('A', fluidIng(fluid('water')))
.key('B', item('actuallyadditions:item_crystal_empowered', 2))
.key('C', item('actuallyadditions:item_misc', 6))
.setInputTooltip(0, IngredientFluidBucket.getInputTooltip(fluid('water')))
.setInputTooltip(2, IngredientFluidBucket.getInputTooltip(fluid('water')))
.setInputTooltip(6, IngredientFluidBucket.getInputTooltip(fluid('water')))
.setInputTooltip(8, IngredientFluidBucket.getInputTooltip(fluid('water')))
.replace().register()
// Red Machine -> Blank Machine
crafting.remove('enderio:deco_block_1_1_f')
crafting.shapelessBuilder()
.output(item('enderio:block_decoration1', 1))
.input(item('enderio:block_decoration1', 13), fluidIng(fluid('water')))
.setInputTooltip(1, IngredientFluidBucket.getInputTooltip(fluid('water')))
.register()
// Hard Mode Recipes
if (LabsModeHelper.expert) {
// Paper
crafting.remove('gregtech:paper')
crafting.shapedBuilder()
.output(item('minecraft:paper') * 2)
.matrix(' M ', 'DDD', ' W ')
.key('M', ore('toolMallet'))
.key('D', ore('dustPaper'))
.key('W', fluidIng(fluid('water')))
.setInputTooltip(7, IngredientFluidBucket.getInputTooltip(fluid('water')))
.register()
// Bricks
crafting.remove('gregtech:brick_from_water')
crafting.shapedBuilder()
.output(item('minecraft:brick_block') * 2)
.matrix('BBB', 'BWB', 'BBB')
.key('B', item('minecraft:brick'))
.key('W', fluidIng(fluid('water')))
.setInputTooltip(4, IngredientFluidBucket.getInputTooltip(fluid('water')))
.register()
// Concrete Bucket recipe is changed, see below
}
/* Lava Bucket */
// Little Tiles Lava
crafting.shapelessBuilder()
.output(item('littletiles:ltcoloredblock', 12))
.input(fluidIng(fluid('lava')))
.setInputTooltip(4, IngredientFluidBucket.getInputTooltip(fluid('lava')))
.replace().register()
// Lavastone
crafting.shapedBuilder()
.output(item('chisel:lavastone') * 8)
.matrix('AAA', 'ABA', 'AAA')
.key('A', item('minecraft:stone'))
.key('B', fluidIng(fluid('lava')))
.setInputTooltip(4, IngredientFluidBucket.getInputTooltip(fluid('lava')))
.replace().register()
// Nullifier
crafting.removeByOutput(item('thermalexpansion:device', 1))
crafting.shapedBuilder()
.output(item('thermalexpansion:device', 1)
.withNbt(['Facing': (byte) 3, 'SideCache': [(byte) 0, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1],
'RSControl': (byte) 0, 'Energy': 0]))
.matrix(' A ', 'BCB', 'DED')
.key('A', fluidIng(fluid('lava')))
.key('B', item('minecraft:brick_block'))
.key('C', item('thermalexpansion:frame', 64))
.key('D', ore('gearIron'))
.key('E', item('thermalfoundation:material', 512))
.setInputTooltip(1, IngredientFluidBucket.getInputTooltip(fluid('lava')))
.register()
// Void Satchel
crafting.shapedBuilder()
.output(item('thermalexpansion:satchel', 100))
.matrix(' A ', 'BCB', 'A A')
.key('A', item('minecraft:leather'))
.key('B', ore('stone'))
.key('C', fluidIng(fluid('lava')))
.setInputTooltip(4, IngredientFluidBucket.getInputTooltip(fluid('lava')))
.replace().register()
/* Milk Bucket */
// White Water
crafting.shapelessBuilder()
.output(item('littletiles:lttransparentcoloredblock', 6))
.input(fluidIng(fluid('milk')), item('littletiles:lttransparentcoloredblock', 5))
.setInputTooltip(0, IngredientFluidBucket.getInputTooltip(fluid('milk')))
.replace().register()
// White Lava
crafting.shapelessBuilder()
.output(item('littletiles:ltcoloredblock', 14))
.input(fluidIng(fluid('milk')), item('littletiles:ltcoloredblock', 12))
.setInputTooltip(0, IngredientFluidBucket.getInputTooltip(fluid('milk')))
.replace().register()
// Pet Mob Filter
crafting.remove('darkutils:filter_pet')
crafting.shapedBuilder()
.output(item('darkutils:filter', 7) * 4)
.matrix('ABA', 'BCB', 'ABA')
.key('A', ore('fenceGateWood'))
.key('B', ore('stone'))
.key('C', fluidIng(fluid('milk')))
.setInputTooltip(4, IngredientFluidBucket.getInputTooltip(fluid('milk')))
.register()
// Chocolate Coin
crafting.shapelessBuilder()
.output(metaitem('coin.chocolate'))
.input(ore('dustCocoa'), ore('foilGold'), fluidIng(fluid('milk')), ore('dustSugar'))
.setInputTooltip(3, IngredientFluidBucket.getInputTooltip(fluid('milk')))
.replace().register()
// Cheese
crafting.shapelessBuilder()
.output(item('actuallyadditions:item_food'))
.input(fluidIng(fluid('milk')), ore('egg'))
.setInputTooltip(0, IngredientFluidBucket.getInputTooltip(fluid('milk')))
.replace().register()
// Chocolate
crafting.shapedBuilder()
.output(item('actuallyadditions:item_food', 9) * 3)
.matrix('C C', 'CMC', 'C C')
.key('C', item('minecraft:dye', 3))
.key('M', fluidIng(fluid('milk')))
.setInputTooltip(4, IngredientFluidBucket.getInputTooltip(fluid('milk')))
.replace().register()
// Chocolate Cake
crafting.shapedBuilder()
.output(item('actuallyadditions:item_food', 8))
.matrix('MMM', 'CCC', 'EDS')
.key('M', fluidIng(fluid('milk')))
.key('C', item('minecraft:dye', 3))
.key('E', ore('egg'))
.key('D', ore('dough'))
.key('S', ore('dustSugar'))
.setInputTooltip(0, IngredientFluidBucket.getInputTooltip(fluid('milk')))
.setInputTooltip(1, IngredientFluidBucket.getInputTooltip(fluid('milk')))
.setInputTooltip(2, IngredientFluidBucket.getInputTooltip(fluid('milk')))
.replace().register()
/* Misc */
// Treated Wood
crafting.shapedBuilder()
.output(item('gregtech:planks', 1) * 8)
.matrix('AAA', 'ABA', 'AAA')
.key('A', ore('plankWood'))
.key('B', fluidIng(fluid('creosote')))
.setInputTooltip(4, IngredientFluidBucket.getInputTooltip(fluid('creosote')))
.replace().register()
// Torch
crafting.shapedBuilder()
.output(item('minecraft:torch') * 16)
.matrix('AB', 'C ')
.key('A', ore('wool'))
.key('B', fluidIng(fluid('creosote')))
.key('C', ore('stick'))
.setInputTooltip(1, IngredientFluidBucket.getInputTooltip(fluid('creosote')))
.replace().register()
// Concrete Cell + Firebricks
if (LabsModeHelper.expert) {
crafting.shapedBuilder()
.output(IngredientFluidBucket.fillStack(metaitem('fluid_cell'), fluid('concrete') * 1000))
.matrix('ABC', 'ADE', ' F ')
.key('A', ore('dustCalcite'))
.key('B', metaitem('fluid_cell'))
.key('C', ore('dustStone'))
.key('D', fluidIng(fluid('water')))
.key('E', ore('dustQuartzSand'))
.key('F', ore('dustClay'))
.setInputTooltip(4, IngredientFluidBucket.getInputTooltip(fluid('water')))
.replace().register()
crafting.shapedBuilder()
.output(item('gregtech:metal_casing', 1))
.matrix('BGB', 'BCB', 'BGB')
.key('B', metaitem('brick.fireclay'))
.key('G', ore('dustGypsum'))
.key('C', fluidIng(fluid('concrete')))
.setInputTooltip(4, IngredientFluidBucket.getInputTooltip(fluid('concrete')))
.replace().register()
}
/* New Recipes */
if (LabsModeHelper.normal) {
// Dust -> Clay
crafting.shapelessBuilder()
.output(item('minecraft:clay'))
.input(item('nomilabs:block_dust'), fluidIng(fluid('water')))
.setInputTooltip(1, IngredientFluidBucket.getInputTooltip(fluid('water')))
.register()
}
// NC Water Source
crafting.shapedBuilder()
.output(item('nuclearcraft:water_source'))
.matrix('AAA', 'B B', 'AAA')
.key('A', LabsModeHelper.expert ? ore('plateDoubleSteel') : ore('plateWroughtIron'))
.key('B', fluidIng(fluid('water')))
.setInputTooltip(3, IngredientFluidBucket.getInputTooltip(fluid('water')))
.setInputTooltip(5, IngredientFluidBucket.getInputTooltip(fluid('water')))
.replace().register()
// NC Cobblestone Generator
crafting.shapedBuilder()
.output(item('nuclearcraft:cobblestone_generator'))
.matrix('AAA', 'B C', 'AAA')
.key('A', LabsModeHelper.expert ? ore('plateBlackSteel') : ore('plateWroughtIron'))
.key('B', fluidIng(fluid('water')))
.key('C', fluidIng(fluid('lava')))
.setInputTooltip(3, IngredientFluidBucket.getInputTooltip(fluid('water')))
.setInputTooltip(5, IngredientFluidBucket.getInputTooltip(fluid('lava')))
.setOutputTooltip(translatable('nomiceu.tooltip.mixed.mirrorable'))
.replace().mirrored().register()
// Lava Factory
crafting.shapedBuilder()
.output(item('actuallyadditions:block_lava_factory_controller'))
.matrix('ABA', 'CDC')
.key('A', item('actuallyadditions:item_misc', 8)) // Advanced Coil
.key('B', item('actuallyadditions:block_misc', 7)) // Lava Factory Casing
.key('C', fluidIng(fluid('lava')))
.key('D', item('morefurnaces:furnaceblock', 3)) // Obsidian Furnace
.setInputTooltip(6, IngredientFluidBucket.getInputTooltip(fluid('lava')))
.setInputTooltip(8, IngredientFluidBucket.getInputTooltip(fluid('lava')))
.replace().register()
// Pyroclastic Injection
crafting.shapedBuilder()
.output(item('thermalexpansion:augment', 496))
.matrix('ABA', 'BCB', 'ABA')
.key('A', ore('ingotMithril'))
.key('B', ore('plateMithril'))
.key('C', fluidIng(fluid('water')))
.setInputTooltip(4, IngredientFluidBucket.getInputTooltip(fluid('water')))
.replace().register()
// Obsidian Quick Craft
crafting.shapelessBuilder()
.output(item('minecraft:obsidian'))
.input(fluidIng(fluid('water')), fluidIng(fluid('lava')))
.setInputTooltip(0, IngredientFluidBucket.getInputTooltip(fluid('water')))
.setInputTooltip(1, IngredientFluidBucket.getInputTooltip(fluid('lava')))
.register()
// Cake Base
crafting.shapedBuilder()
.output(item('enderio:item_material', 70))
.matrix('SMS', 'DDD')
.key('S', ore('dustSugar'))
.key('M', fluidIng(fluid('milk')))
.key('D', ore('dough'))
.setInputTooltip(4, IngredientFluidBucket.getInputTooltip(fluid('milk')))
.replace().register()
// Cake
crafting.shapedBuilder()
.output(item('minecraft:cake'))
.matrix('BBB', 'SES', 'DDD')
.key('B', fluidIng(fluid('milk')))
.key('S', ore('dustSugar'))
.key('E', ore('egg'))
.key('D', ore('dough'))
.setInputTooltip(0, IngredientFluidBucket.getInputTooltip(fluid('milk')))
.setInputTooltip(1, IngredientFluidBucket.getInputTooltip(fluid('milk')))
.setInputTooltip(2, IngredientFluidBucket.getInputTooltip(fluid('milk')))
.replace().register()
/* Classes and Helpers */
// IIngredient Class that Matches Based on FluidStack in Containers
class IngredientFluidBucket extends SimpleIIngredient {
public static final AMOUNT = 1000
// Example Fills (excludes bucket)
private static final List<ItemStack> fillables = [
metaitem('fluid_cell'),
metaitem('fluid_cell.universal'),
metaitem('nomilabs:bronze_cell'),
metaitem('large_fluid_cell.steel'),
metaitem('large_fluid_cell.aluminium'),
metaitem('large_fluid_cell.stainless_steel'),
metaitem('large_fluid_cell.titanium'),
metaitem('large_fluid_cell.tungstensteel'),
metaitem('fluid_cell.glass_vial'),
metaitem('drum.bronze'),
metaitem('drum.gold'),
metaitem('drum.steel'),
metaitem('drum.aluminium'),
metaitem('drum.stainless_steel'),
metaitem('drum.titanium'),
metaitem('drum.tungstensteel'),
item('enderio:block_tank'),
item('enderio:block_tank', 1),
item('thermalexpansion:tank').withNbt(['RSControl': (byte) 0, 'Creative': (byte) 0, 'Level': (byte) 0]),
item('thermalexpansion:tank').withNbt(['RSControl': (byte) 0, 'Creative': (byte) 0, 'Level': (byte) 1]),
item('thermalexpansion:tank').withNbt(['RSControl': (byte) 0, 'Creative': (byte) 0, 'Level': (byte) 2]),
item('thermalexpansion:tank').withNbt(['RSControl': (byte) 0, 'Creative': (byte) 0, 'Level': (byte) 3]),
item('thermalexpansion:tank').withNbt(['RSControl': (byte) 0, 'Creative': (byte) 0, 'Level': (byte) 4]),
]
private final FluidStack stack
private final ItemStack[] matchingStacks
IngredientFluidBucket(FluidStack stack) {
this.stack = stack * AMOUNT
List<ItemStack> matchingStacks = [FluidUtil.getFilledBucket(this.stack)]
for (ItemStack fill : fillables) {
var toFill = fill.copy()
var handler = getHandler(toFill)
if (handler == null) continue
int capacity = handler.tankProperties[0].capacity
if (capacity <= 0) capacity = AMOUNT
int filled = handler.fill(stack * capacity, true)
if (filled == capacity)
matchingStacks.add(toFill)
}
this.matchingStacks = matchingStacks.toArray()
}
@Override
ItemStack[] getMatchingStacks() { return matchingStacks }
@Override
boolean test(ItemStack itemStack) {
var handler = getHandler(itemStack)
if (handler == null) return false
FluidStack drained = handler.drain(stack, false)
return drained != null && drained.amount >= AMOUNT && drained.isFluidEqual(stack)
}
@Override
ItemStack applyTransform(ItemStack matchedInput) {
matchedInput = matchedInput.copy()
if (matchedInput.getItem().hasContainerItem(matchedInput))
return super.applyTransform(matchedInput)
var handler = getHandler(matchedInput)
if (handler == null) return super.applyTransform(matchedInput)
handler.drain(stack, true)
return handler.getContainer() * 1
}
static ItemStack fillStack(ItemStack itemStack, FluidStack fluidStack) {
var toFill = itemStack.copy()
getHandler(toFill)?.fill(fluidStack, true)
return toFill
}
static IFluidHandlerItem getHandler(ItemStack itemStack) {
if (itemStack.isEmpty()) return null
IFluidHandlerItem handler = null
if (itemStack.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null)) {
if (itemStack.getCount() > 1) {
itemStack = itemStack.copy()
itemStack.setCount(1)
}
handler = itemStack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null)
}
return handler
}
static Translatable[] getInputTooltip(FluidStack fluidStack) {
return new Translatable[] {
new TranslatableFluidTooltip(fluidStack.fluid),
translatable('nomiceu.tooltip.mixed.accepts_fluid_container')
}
}
}
/**
* Simple wrapper class so we can use translated name of fluid in tooltip
*/
class TranslatableFluidTooltip extends Translatable {
Fluid fluid
TranslatableFluidTooltip(Fluid fluid) {
super('nomiceu.tooltip.mixed.accepts_fluid')
this.fluid = fluid
}
@Override
protected String translateThis() {
String fluidName = translate(fluid.unlocalizedName)
return translate(key, fluidName)
}
}
static IngredientFluidBucket fluidIng(FluidStack stack) {
return new IngredientFluidBucket(stack)
}

View File

@ -4,7 +4,6 @@ import com.nomiceu.nomilabs.groovy.ShapedDummyRecipe
import com.nomiceu.nomilabs.util.ItemMeta import com.nomiceu.nomilabs.util.ItemMeta
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import static com.nomiceu.nomilabs.groovy.GroovyHelpers.JEIHelpers.addRecipeOutputTooltip
import static com.nomiceu.nomilabs.groovy.GroovyHelpers.TranslationHelpers.translatable import static com.nomiceu.nomilabs.groovy.GroovyHelpers.TranslationHelpers.translatable
// Hand Framing Tool // Hand Framing Tool
@ -35,47 +34,28 @@ items.add(tool)
for (ItemStack stack : items) { for (ItemStack stack : items) {
for (boolean trim : [true, false]) { for (boolean trim : [true, false]) {
for (boolean front : [true, false]) { for (boolean front : [true, false]) {
def recipeName = getRecipeName(stack, trim, front)
def recipeStack = addNBT(stack, trim, front) def recipeStack = addNBT(stack, trim, front)
crafting.shapedBuilder() crafting.shapedBuilder()
.name(recipeName)
.output(recipeStack) .output(recipeStack)
.matrix( .matrix('ST ', 'FI ', ' ')
'ST ',
'FI ',
' ')
.key('S', item("xtones:zane")) .key('S', item("xtones:zane"))
.key('T', trim ? item("extendedcrafting:storage", 4) : IIngredient.EMPTY) .key('T', trim ? item("extendedcrafting:storage", 4) : IIngredient.EMPTY)
.key('F', front ? item("xtones:zane", 15) : IIngredient.EMPTY) .key('F', front ? item("xtones:zane", 15) : IIngredient.EMPTY)
.key('I', stack) .key('I', stack)
.recipeClassFunction((output, width, height, ingredients) -> new ShapedDummyRecipe(output, ingredients, width, height, false)) .recipeClassFunction((output, width, height, ingredients) -> new ShapedDummyRecipe(output, ingredients, width, height, false))
.register() .setOutputTooltip(
ItemMeta.compare(tool, recipeStack) ?
addRecipeOutputTooltip(recipeStack, resource(recipeName), translatable("nomiceu.tooltip.labs.hand_framing.tool") :
ItemMeta.compare(tool, recipeStack) ? translatable("nomiceu.tooltip.labs.hand_framing.drawer"),
translatable("nomiceu.tooltip.labs.hand_framing.tool") : translatable("nomiceu.tooltip.labs.hand_framing.top_left"),
translatable("nomiceu.tooltip.labs.hand_framing.drawer"), translatable("nomiceu.tooltip.labs.hand_framing.top_right"),
translatable("nomiceu.tooltip.labs.hand_framing.top_left"), translatable("nomiceu.tooltip.labs.hand_framing.bottom_left")
translatable("nomiceu.tooltip.labs.hand_framing.top_right"), ).register()
translatable("nomiceu.tooltip.labs.hand_framing.bottom_left"))
} }
} }
} }
static String getRecipeName(ItemStack stack, boolean trim, boolean front) {
String baseName = "nomiceu:hand_framing_"
def rl = stack.getItem().getRegistryName()
if (rl != null)
baseName = baseName + rl.getNamespace() + "_" + rl.getPath()
baseName = baseName + "." + stack.getMetadata() + "_side"
if (trim) baseName = baseName + "_trim"
if (front) baseName = baseName + "_front"
return baseName
}
static ItemStack addNBT(ItemStack stack, boolean trim, boolean front) { static ItemStack addNBT(ItemStack stack, boolean trim, boolean front) {
def sideStack = item("xtones:zane") def sideStack = item("xtones:zane")
def trimStack = trim ? item("extendedcrafting:storage", 4) : ItemStack.EMPTY def trimStack = trim ? item("extendedcrafting:storage", 4) : ItemStack.EMPTY

View File

@ -105,6 +105,19 @@ for (def material : ["wood", "bronze", "steel", "aluminium", "stainless_steel",
clearableContainers.add(metaitem("drum.${material}")) clearableContainers.add(metaitem("drum.${material}"))
} }
// Cells
// Bronze Cell does not need tooltip added, its recipe is added above
// Special Cells
clearableContainers.add(metaitem('fluid_cell'))
clearableContainers.add(metaitem('fluid_cell.universal'))
// Material Cells
for (def material : ["steel", "aluminium", "stainless_steel", "titanium", "tungstensteel"]) {
clearableContainers.add(metaitem("large_fluid_cell.${material}"))
}
// EIO Tanks // EIO Tanks
// Technically Machines Too... but Not As Useful // Technically Machines Too... but Not As Useful
clearableContainers.add(item('enderio:block_tank')) clearableContainers.add(item('enderio:block_tank'))

View File

@ -24,6 +24,7 @@ List<ItemStack> fillable = [
metaitem('large_fluid_cell.titanium'), metaitem('large_fluid_cell.titanium'),
metaitem('large_fluid_cell.tungstensteel'), metaitem('large_fluid_cell.tungstensteel'),
metaitem('fluid_cell.glass_vial'), metaitem('fluid_cell.glass_vial'),
metaitem('nomilabs:bronze_cell'),
item('minecraft:bucket'), item('minecraft:bucket'),
item('minecraft:water_bucket'), item('minecraft:water_bucket'),
item('minecraft:lava_bucket'), item('minecraft:lava_bucket'),

View File

@ -154,7 +154,7 @@ mods.gregtech.wiremill.recipeBuilder()
.buildAndRegister() .buildAndRegister()
// Glass Cable // Glass Cable
crafting.removeByOutput(item('appliedenergistics2:part', 16)) crafting.remove('appliedenergistics2:network/cables/glass_fluix')
mods.gregtech.alloy_smelter.recipeBuilder() mods.gregtech.alloy_smelter.recipeBuilder()
.inputs(ore('dustFluix'), item('appliedenergistics2:part', 140)) .inputs(ore('dustFluix'), item('appliedenergistics2:part', 140))
.outputs(item('appliedenergistics2:part', 16) * 2) .outputs(item('appliedenergistics2:part', 16) * 2)
@ -162,6 +162,7 @@ mods.gregtech.alloy_smelter.recipeBuilder()
.buildAndRegister() .buildAndRegister()
// Covered Cable // Covered Cable
crafting.remove('appliedenergistics2:network/cables/covered_fluix')
for (var rubber in [fluid('rubber') * 144, fluid('styrene_butadiene_rubber') * 36, fluid('silicone_rubber') * 76]) { for (var rubber in [fluid('rubber') * 144, fluid('styrene_butadiene_rubber') * 36, fluid('silicone_rubber') * 76]) {
mods.gregtech.assembler.recipeBuilder() mods.gregtech.assembler.recipeBuilder()
.inputs(item('appliedenergistics2:part', 16)) .inputs(item('appliedenergistics2:part', 16))
@ -169,7 +170,6 @@ for (var rubber in [fluid('rubber') * 144, fluid('styrene_butadiene_rubber') * 3
.outputs(item('appliedenergistics2:part', 36)) .outputs(item('appliedenergistics2:part', 36))
.duration(100).EUt(VA[ULV]) .duration(100).EUt(VA[ULV])
.buildAndRegister() .buildAndRegister()
} }
// ME Conduit // ME Conduit

View File

@ -1,6 +1,7 @@
import com.nomiceu.nomilabs.util.LabsModeHelper import com.nomiceu.nomilabs.util.LabsModeHelper
import gregtech.common.metatileentities.MetaTileEntities import gregtech.common.metatileentities.MetaTileEntities
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraftforge.fluids.FluidUtil
import static com.nomiceu.nomilabs.groovy.GroovyHelpers.JEIHelpers.* import static com.nomiceu.nomilabs.groovy.GroovyHelpers.JEIHelpers.*
import static gregtech.api.GTValues.* import static gregtech.api.GTValues.*
@ -10,20 +11,20 @@ import static gregtech.api.GTValues.*
/* Item Removals */ /* Item Removals */
// AR // AR
mods.jei.ingredient.removeAndHide(item('advancedrocketry:crystal:*')) // Random Crystal Blocks mods.jei.ingredient.hide(item('advancedrocketry:crystal:*')) // Random Crystal Blocks
removeAndHideItemIgnoreNBT(item('advancedrocketry:bucketrocketfuel')) hideItemIgnoreNBT(item('advancedrocketry:bucketrocketfuel'))
removeAndHideItemIgnoreNBT(item('advancedrocketry:bucketnitrogen')) hideItemIgnoreNBT(item('advancedrocketry:bucketnitrogen'))
removeAndHideItemIgnoreNBT(item('advancedrocketry:buckethydrogen')) hideItemIgnoreNBT(item('advancedrocketry:buckethydrogen'))
removeAndHideItemIgnoreNBT(item('advancedrocketry:bucketoxygen')) hideItemIgnoreNBT(item('advancedrocketry:bucketoxygen'))
removeAndHideItemIgnoreNBT(item('advancedrocketry:bucketenrichedlava')) hideItemIgnoreNBT(item('advancedrocketry:bucketenrichedlava'))
// Armor Plus // Armor Plus
mods.jei.ingredient.removeAndHide(item('armorplus:block_melting_obsidian')) // Null Texture Item mods.jei.ingredient.hide(item('armorplus:block_melting_obsidian')) // Null Texture Item
// Nomi Labs // Nomi Labs
if (LabsModeHelper.expert) { if (LabsModeHelper.expert) {
mods.jei.ingredient.removeAndHide(item('nomilabs:impossiblerealmdata')) mods.jei.ingredient.hide(item('nomilabs:impossiblerealmdata'))
} }
// GregTech // GregTech
@ -44,14 +45,20 @@ List<ItemStack> lootBoxes = [
item('bq_standard:loot_chest', 103), item('bq_standard:loot_chest', 103),
item('bq_standard:loot_chest', 104), item('bq_standard:loot_chest', 104),
] ]
lootBoxes.forEach { removeAndHideItemIgnoreNBT(it) } lootBoxes.forEach { hideItemIgnoreNBT(it) }
mods.jei.ingredient.removeAndHide(item('betterquesting:placeholder')) mods.jei.ingredient.hide(item('betterquesting:placeholder'))
mods.jei.ingredient.removeAndHide(fluid('betterquesting.placeholder')) mods.jei.ingredient.hide(fluid('betterquesting.placeholder'))
// Modded Buckets // Modded Buckets
hideItemIgnoreNBT(item('forge:bucketfilled')) hideItemIgnoreNBT(item('forge:bucketfilled'))
// Add back Creosote Bucket, has usages in recipes and furnace
mods.jei.ingredient.add(FluidUtil.getFilledBucket(fluid('creosote') * 1000))
// Add Concrete Cell to JEI
mods.jei.ingredient.add(metaitem('fluid_cell').withNbt(['Fluid': ['FluidName': 'concrete', 'Amount': 1000]]))
/* Remove Categories (Appear Randomly after /gs reload) */ /* Remove Categories (Appear Randomly after /gs reload) */
// Avatitia // Avatitia
mods.jei.category.hideCategory('Avatitia.Extreme') mods.jei.category.hideCategory('Avatitia.Extreme')
@ -69,6 +76,7 @@ mods.jei.category.hideCategory('GrindingBall')
mods.jei.category.hideCategory('SagMill') mods.jei.category.hideCategory('SagMill')
mods.jei.category.hideCategory('SolarPanel') mods.jei.category.hideCategory('SolarPanel')
mods.jei.category.hideCategory('StirlingGenerator') mods.jei.category.hideCategory('StirlingGenerator')
mods.jei.category.hideCategory('LavaGenerator')
// AR // AR
mods.jei.category.hideCategory('zmaster587.AR.rollingMachine') mods.jei.category.hideCategory('zmaster587.AR.rollingMachine')

View File

@ -5,6 +5,9 @@ nomifactory.nonetherportals=Nether portals are disabled in §5Nomi-CEu§r. Follo
# Mixed # Mixed
nomiceu.tooltip.mixed.fillable=Can be filled with the §bCanning Machine§r. nomiceu.tooltip.mixed.fillable=Can be filled with the §bCanning Machine§r.
nomiceu.tooltip.mixed.mirrorable=§7Recipe can be mirrored.§r
nomiceu.tooltip.mixed.accepts_fluid=§7Fluid: §b%s§r
nomiceu.tooltip.mixed.accepts_fluid_container=§7Accepts §aBuckets§7, §aCells§7, §aDrums§7, and other §aFluid Containers§7!
# MC # MC
nomiceu.tooltip.mc.xp_bottle=§eGives 25 XP, or one XP Level!§r nomiceu.tooltip.mc.xp_bottle=§eGives 25 XP, or one XP Level!§r

View File

@ -7,15 +7,15 @@ import scripts.common.makeShaped as makeShaped;
//Wooden Gear //Wooden Gear
recipes.remove(<enderio:item_material:9>); recipes.remove(<enderio:item_material:9>);
recipes.addShaped(<enderio:item_material:9>, [[null,<minecraft:stick>,null], recipes.addShaped(<enderio:item_material:9>, [[null,<ore:stickWood>,null],
[<minecraft:stick>,null,<minecraft:stick>], [<ore:stickWood>,null,<ore:stickWood>],
[null,<minecraft:stick>,null]]); [null,<ore:stickWood>,null]]);
//Wooden Shears //Wooden Shears
recipes.remove(<thermalfoundation:tool.shears_wood>); recipes.remove(<thermalfoundation:tool.shears_wood>);
recipes.addShaped(<thermalfoundation:tool.shears_wood>, [[null,<minecraft:stick>,null], recipes.addShaped(<thermalfoundation:tool.shears_wood>, [[null,<ore:stickWood>,null],
[<minecraft:stick>,null,<minecraft:stick>], [<ore:stickWood>,null,<ore:stickWood>],
[<enderio:item_material:9>,<minecraft:stick>,null]]); [<enderio:item_material:9>,<ore:stickWood>,null]]);
//Fertilizer //Fertilizer
recipes.addShaped("actuallyadditions_fertilizer", <actuallyadditions:item_fertilizer> * 8, [[<minecraft:sand>,<metaitem:gemApatite>,<minecraft:sand>]]); recipes.addShaped("actuallyadditions_fertilizer", <actuallyadditions:item_fertilizer> * 8, [[<minecraft:sand>,<metaitem:gemApatite>,<minecraft:sand>]]);
@ -25,14 +25,6 @@ recipes.remove(<dimensionaledibles:nether_cake>);
recipes.remove(<dimensionaledibles:end_cake>); recipes.remove(<dimensionaledibles:end_cake>);
recipes.remove(<dimensionaledibles:island_cake>); recipes.remove(<dimensionaledibles:island_cake>);
recipes.remove(<dimensionaledibles:custom_cake>); recipes.remove(<dimensionaledibles:custom_cake>);
recipes.remove(<minecraft:cake>);
recipes.remove(<enderio:item_material:70>);
//Cake Base
recipes.addShaped(<enderio:item_material:70>, [[<minecraft:sugar>, <minecraft:milk_bucket> | <minecraft:bucket>, <minecraft:sugar>], [<actuallyadditions:item_misc:4> | <actuallyadditions:item_misc:9>, <actuallyadditions:item_misc:4> | <actuallyadditions:item_misc:9>, <actuallyadditions:item_misc:4> | <actuallyadditions:item_misc:9>]]);
//Cake
recipes.addShaped(<minecraft:cake>, [[<minecraft:milk_bucket> | <minecraft:bucket>, <minecraft:milk_bucket> | <minecraft:bucket>, <minecraft:milk_bucket> | <minecraft:bucket>], [<minecraft:sugar>, <ore:egg>, <minecraft:sugar>], [<actuallyadditions:item_misc:4>,<actuallyadditions:item_misc:4>,<actuallyadditions:item_misc:4>]]);
//Overworld Cake //Overworld Cake
recipes.addShaped(<dimensionaledibles:overworld_cake>, [[<minecraft:redstone>, <metaitem:dustGold>, <minecraft:redstone>], [<ore:treeSapling>, <enderio:item_material:70>, <ore:treeSapling>],[<metaitem:plant_ball>,<minecraft:diamond>,<metaitem:plant_ball>]]); recipes.addShaped(<dimensionaledibles:overworld_cake>, [[<minecraft:redstone>, <metaitem:dustGold>, <minecraft:redstone>], [<ore:treeSapling>, <enderio:item_material:70>, <ore:treeSapling>],[<metaitem:plant_ball>,<minecraft:diamond>,<metaitem:plant_ball>]]);

View File

@ -46,7 +46,7 @@ recipes.addShaped(<minecraft:diamond_boots>, [
// recipes.addShaped(<minecraft:diamond_sword>, [ // recipes.addShaped(<minecraft:diamond_sword>, [
// [null, <metaitem:plateDiamond>, null], // [null, <metaitem:plateDiamond>, null],
// [null, <metaitem:plateDiamond>, null], // [null, <metaitem:plateDiamond>, null],
// [null, <minecraft:stick>, null]]); // [null, <ore:stickWood>, null]]);
furnace.addRecipe(<thermalfoundation:material:833>, <metaitem:rubber_drop>, 0.0); furnace.addRecipe(<thermalfoundation:material:833>, <metaitem:rubber_drop>, 0.0);
@ -72,7 +72,7 @@ recipes.addShaped(<armorplus:redstone_boots>, [
recipes.addShaped(<armorplus:redstone_sword>, [ recipes.addShaped(<armorplus:redstone_sword>, [
[null, <nomilabs:redstonearmorplate>, null], [null, <nomilabs:redstonearmorplate>, null],
[null, <nomilabs:redstonearmorplate>, null], [null, <nomilabs:redstonearmorplate>, null],
[null, <minecraft:stick>, null]]); [null, <ore:stickWood>, null]]);
//Lapis Armor //Lapis Armor
recipes.addShaped(<nomilabs:lapisarmorplate>, [ recipes.addShaped(<nomilabs:lapisarmorplate>, [
@ -96,7 +96,7 @@ recipes.addShaped(<armorplus:lapis_boots>, [
recipes.addShaped(<armorplus:lapis_sword>, [ recipes.addShaped(<armorplus:lapis_sword>, [
[null, <nomilabs:lapisarmorplate>, null], [null, <nomilabs:lapisarmorplate>, null],
[null, <nomilabs:lapisarmorplate>, null], [null, <nomilabs:lapisarmorplate>, null],
[null, <minecraft:stick>, null]]); [null, <ore:stickWood>, null]]);
//Carbon Armor //Carbon Armor
recipes.addShaped(<nomilabs:carbonarmorplate>, [ recipes.addShaped(<nomilabs:carbonarmorplate>, [
@ -205,7 +205,7 @@ recipes.addShaped(<armorplus:knight_slime_boots>, [
//Infused Lava //Infused Lava
var obs = <armorplus:lava_infused_obsidian>; var obs = <armorplus:lava_infused_obsidian>;
var cry = <armorplus:lava_crystal:1>; var cry = <armorplus:lava_crystal:1>;
var stick = <minecraft:stick>; var stick = <ore:stickWood>;
mods.extendedcrafting.TableCrafting.addShaped(<armorplus:infused_lava_helmet>, [ mods.extendedcrafting.TableCrafting.addShaped(<armorplus:infused_lava_helmet>, [
[obs,obs,cry,obs,obs], [obs,obs,cry,obs,obs],
[cry,null,null,null,cry], [cry,null,null,null,cry],
@ -258,7 +258,7 @@ mods.extendedcrafting.TableCrafting.addShaped(<armorplus:obsidian_boots>, [
recipes.addShaped(<armorplus:obsidian_sword>, [ recipes.addShaped(<armorplus:obsidian_sword>, [
[null, <armorplus:compressed_obsidian>, null], [null, <armorplus:compressed_obsidian>, null],
[null, <armorplus:compressed_obsidian>, null], [null, <armorplus:compressed_obsidian>, null],
[null, <minecraft:stick>, null]]); [null, <ore:stickWood>, null]]);
//Emerald //Emerald

View File

@ -163,7 +163,6 @@ macerator.recipeBuilder().inputs([<enderio:item_material:19>]).outputs([<enderio
macerator.recipeBuilder().inputs([<enderio:item_material:15>]).outputs([<enderio:item_material:35>]).duration(300).EUt(16).buildAndRegister(); macerator.recipeBuilder().inputs([<enderio:item_material:15>]).outputs([<enderio:item_material:35>]).duration(300).EUt(16).buildAndRegister();
macerator.recipeBuilder().inputs([<enderio:item_material:14>]).outputs([<enderio:item_material:36>]).duration(200).EUt(16).buildAndRegister(); macerator.recipeBuilder().inputs([<enderio:item_material:14>]).outputs([<enderio:item_material:36>]).duration(200).EUt(16).buildAndRegister();
macerator.recipeBuilder().inputs([<enderio:item_material:17>]).outputs([<nomilabs:grainsofinnocence>]).duration(200).EUt(16).buildAndRegister(); macerator.recipeBuilder().inputs([<enderio:item_material:17>]).outputs([<nomilabs:grainsofinnocence>]).duration(200).EUt(16).buildAndRegister();
recipes.remove(<appliedenergistics2:part:36>);
//Yeta Wrench //Yeta Wrench
recipes.remove(<enderio:item_yeta_wrench>); recipes.remove(<enderio:item_yeta_wrench>);
@ -225,15 +224,10 @@ chemical_reactor.recipeBuilder()
//Remove other recipe for Dimethylhydrazine //Remove other recipe for Dimethylhydrazine
chemical_reactor.findRecipe(480, [null], [<liquid:methanol> * 2000, <liquid:ammonia> * 2000, <liquid:hypochlorous_acid> * 1000]).remove(); chemical_reactor.findRecipe(480, [null], [<liquid:methanol> * 2000, <liquid:ammonia> * 2000, <liquid:hypochlorous_acid> * 1000]).remove();
//Lava Factory //Lava Factory Casing
recipes.remove(<actuallyadditions:block_misc:7>); recipes.remove(<actuallyadditions:block_misc:7>);
recipes.addShaped(<actuallyadditions:block_misc:7> * 2, [[<metaitem:plateAluminium>, <metaitem:plateSteel>, <metaitem:plateAluminium>],[<metaitem:plateSteel>, null, <metaitem:plateSteel>], [<metaitem:plateAluminium>, <metaitem:plateSteel>, <metaitem:plateAluminium>]]); recipes.addShaped(<actuallyadditions:block_misc:7> * 2, [[<metaitem:plateAluminium>, <metaitem:plateSteel>, <metaitem:plateAluminium>],[<metaitem:plateSteel>, null, <metaitem:plateSteel>], [<metaitem:plateAluminium>, <metaitem:plateSteel>, <metaitem:plateAluminium>]]);
recipes.remove(<actuallyadditions:block_lava_factory_controller>);
recipes.addShaped(<actuallyadditions:block_lava_factory_controller>, [
[<actuallyadditions:item_misc:8>, <actuallyadditions:block_misc:7>, <actuallyadditions:item_misc:8>],
[<minecraft:lava_bucket:*>, <morefurnaces:furnaceblock:3>, <minecraft:lava_bucket:*>]]);
recipes.remove(<actuallyadditions:block_fluid_collector>); recipes.remove(<actuallyadditions:block_fluid_collector>);
recipes.remove(<actuallyadditions:block_placer>); recipes.remove(<actuallyadditions:block_placer>);
recipes.remove(<actuallyadditions:block_fluid_placer>); recipes.remove(<actuallyadditions:block_fluid_placer>);

View File

@ -169,14 +169,6 @@ recipes.addShaped(<thermalexpansion:augment:337>, [
[<thermalfoundation:material:328>, <metaitem:gearDiamond>, <thermalfoundation:material:328>], [<thermalfoundation:material:328>, <metaitem:gearDiamond>, <thermalfoundation:material:328>],
[<thermalfoundation:material:136>, <thermalfoundation:material:328>, <thermalfoundation:material:136>]]); [<thermalfoundation:material:136>, <thermalfoundation:material:328>, <thermalfoundation:material:136>]]);
//Pyroconductive Loop
recipes.remove(<thermalexpansion:augment:352>);
recipes.addShaped(<thermalexpansion:augment:352>, [
[<thermalfoundation:material:136>, <thermalfoundation:material:328>, <thermalfoundation:material:136>],
[<thermalfoundation:material:328>, <minecraft:lava_bucket>, <thermalfoundation:material:328>],
[<thermalfoundation:material:136>, <thermalfoundation:material:328>, <thermalfoundation:material:136>]]);
//charger thing //charger thing
recipes.remove(<thermalexpansion:augment:400>); recipes.remove(<thermalexpansion:augment:400>);
recipes.addShaped(<thermalexpansion:augment:400>, [ recipes.addShaped(<thermalexpansion:augment:400>, [
@ -212,13 +204,6 @@ recipes.addShaped(<thermalexpansion:augment:656>, [
[<metaitem:nomilabs:plateDarkSteel>, <thermalfoundation:material:1024>, <metaitem:nomilabs:plateDarkSteel>], [<metaitem:nomilabs:plateDarkSteel>, <thermalfoundation:material:1024>, <metaitem:nomilabs:plateDarkSteel>],
[<ore:ingotDarkSteel>, <metaitem:nomilabs:plateDarkSteel>, <ore:ingotDarkSteel>]]); [<ore:ingotDarkSteel>, <metaitem:nomilabs:plateDarkSteel>, <ore:ingotDarkSteel>]]);
//i give up
recipes.remove(<thermalexpansion:augment:496>);
recipes.addShaped(<thermalexpansion:augment:496>, [
[<thermalfoundation:material:136>, <thermalfoundation:material:328>, <thermalfoundation:material:136>],
[<thermalfoundation:material:328>, <minecraft:water_bucket>, <thermalfoundation:material:328>],
[<thermalfoundation:material:136>, <thermalfoundation:material:328>, <thermalfoundation:material:136>]]);
//i give up //i give up
recipes.remove(<thermalexpansion:augment:688>); recipes.remove(<thermalexpansion:augment:688>);
recipes.addShaped(<thermalexpansion:augment:688>, [ recipes.addShaped(<thermalexpansion:augment:688>, [

View File

@ -136,9 +136,6 @@ assembler.recipeBuilder()
// [<ore:plateWroughtIron>, <ore:plateWroughtIron>, <ore:plateWroughtIron>], // [<ore:plateWroughtIron>, <ore:plateWroughtIron>, <ore:plateWroughtIron>],
// [<ore:cableGtSingleTin>, <gregtech:machine_casing:1>, <ore:cableGtSingleTin>]]); // [<ore:cableGtSingleTin>, <gregtech:machine_casing:1>, <ore:cableGtSingleTin>]]);
//Wood Pulp
recipes.addShapeless(<metaitem:dustWood> * 4,[<ore:logWood>,<ore:toolMortar>]);
//Pyrolyse Oven (moved to groovy) //Pyrolyse Oven (moved to groovy)
//// LV Casing //// LV Casing

View File

@ -135,15 +135,6 @@ makeShaped("exchangertool", <buildinggadgets:exchangertool>.withTag({blockstate:
R : <ore:dustRedstone>, R : <ore:dustRedstone>,
I : <ore:ingotIron>}); I : <ore:ingotIron>});
recipes.remove(<nuclearcraft:water_source>);
makeShaped("of_nc_water_source", <nuclearcraft:water_source>,
["AAA",
"B B",
"AAA"],
{ A : <ore:plateDoubleSteel>,
B : <minecraft:water_bucket:*> });
// XP Juice // XP Juice
mixer.recipeBuilder() mixer.recipeBuilder()
.inputs(<ore:itemPulsatingPowder>) .inputs(<ore:itemPulsatingPowder>)
@ -314,26 +305,6 @@ recipes.addShaped(<storagedrawers:upgrade_template> * 4, [
recipes.addShaped(<storagedrawers:upgrade_storage:3>, [[<ore:stickWood>, <ore:stickWood>, <ore:stickWood>], [<ore:ingotAluminium>, <storagedrawers:upgrade_template>, <ore:ingotAluminium>], [<ore:stickWood>, <ore:stickWood>, <ore:stickWood>]]); recipes.addShaped(<storagedrawers:upgrade_storage:3>, [[<ore:stickWood>, <ore:stickWood>, <ore:stickWood>], [<ore:ingotAluminium>, <storagedrawers:upgrade_template>, <ore:ingotAluminium>], [<ore:stickWood>, <ore:stickWood>, <ore:stickWood>]]);
recipes.addShaped(<storagedrawers:upgrade_storage:4>, [[<ore:stickWood>, <ore:stickWood>, <ore:stickWood>], [<ore:ingotVibrantAlloy>, <storagedrawers:upgrade_template>, <ore:ingotVibrantAlloy>], [<ore:stickWood>, <ore:stickWood>, <ore:stickWood>]]); recipes.addShaped(<storagedrawers:upgrade_storage:4>, [[<ore:stickWood>, <ore:stickWood>, <ore:stickWood>], [<ore:ingotVibrantAlloy>, <storagedrawers:upgrade_template>, <ore:ingotVibrantAlloy>], [<ore:stickWood>, <ore:stickWood>, <ore:stickWood>]]);
// NC Cobble gen
recipes.remove(<nuclearcraft:cobblestone_generator>);
makeShaped("of_nc_cobblestone_generator",
<nuclearcraft:cobblestone_generator>,
["AAA",
"B C",
"AAA"],
{ A : <ore:plateBlackSteel>,
B : <minecraft:water_bucket:*>,
C : <minecraft:lava_bucket:*> });
makeShaped("of_nc_cobblestone_generator_mirrored",
<nuclearcraft:cobblestone_generator>,
["AAA",
"C B",
"AAA"],
{ A : <ore:plateBlackSteel>,
B : <minecraft:water_bucket:*>,
C : <minecraft:lava_bucket:*> });
//Crystal Growth Chamber //Crystal Growth Chamber
recipes.addShaped(<ae2stuff:grower>, [ recipes.addShaped(<ae2stuff:grower>, [
[<ore:frameGtBlueSteel>, <appliedenergistics2:material:1>, <ore:frameGtBlueSteel>], [<ore:frameGtBlueSteel>, <appliedenergistics2:material:1>, <ore:frameGtBlueSteel>],
@ -494,7 +465,7 @@ recipes.addShaped(<metaitem:gcym:parallel_hatch.uv>, [
// Stabilized Miners (Moved to Groovy) // Stabilized Miners (Moved to Groovy)
// Remove shortcut recipes // Remove shortcut recipes
recipes.remove(<minecraft:stick> * 16); recipes.remove(<ore:stickWood> * 16);
recipes.removeByRecipeName("appliedenergistics2:misc/vanilla_comparator"); recipes.removeByRecipeName("appliedenergistics2:misc/vanilla_comparator");
recipes.remove(<minecraft:chest> * 4); recipes.remove(<minecraft:chest> * 4);

View File

@ -31,8 +31,6 @@ furnace.addRecipe(<metaitem:ingotWroughtIron>, <minecraft:iron_ingot>, 0.0);
//Red Alloy Dust //Red Alloy Dust
recipes.addShapeless(<metaitem:dustRedAlloy>, [<metaitem:dustCopper>, <minecraft:redstone>, <minecraft:redstone>, <minecraft:redstone>, <minecraft:redstone>]); recipes.addShapeless(<metaitem:dustRedAlloy>, [<metaitem:dustCopper>, <minecraft:redstone>, <minecraft:redstone>, <minecraft:redstone>, <minecraft:redstone>]);
recipes.addShapeless(<minecraft:clay>, [<nomilabs:block_dust>,<minecraft:water_bucket>]);
//Clay Electrolyzing //Clay Electrolyzing
electrolyzer.findRecipe(60, [<metaitem:dustClay> * 13], [null]).remove(); electrolyzer.findRecipe(60, [<metaitem:dustClay> * 13], [null]).remove();
electrolyzer.recipeBuilder().inputs([<metaitem:dustClay> * 13]).outputs([<metaitem:dustSodium> * 2, <metaitem:dustSilicon> * 2, <metaitem:dustLithium>, <metaitem:dustAluminium> * 2]).fluidOutputs([<liquid:water>*6000]).duration(364).EUt(15).buildAndRegister(); electrolyzer.recipeBuilder().inputs([<metaitem:dustClay> * 13]).outputs([<metaitem:dustSodium> * 2, <metaitem:dustSilicon> * 2, <metaitem:dustLithium>, <metaitem:dustAluminium> * 2]).fluidOutputs([<liquid:water>*6000]).duration(364).EUt(15).buildAndRegister();
@ -331,14 +329,6 @@ makeShaped("of_dml_living_matter_extraterrestrial",
E : <minecraft:ender_pearl> } E : <minecraft:ender_pearl> }
); );
recipes.remove(<nuclearcraft:water_source>);
makeShaped("of_nc_water_source", <nuclearcraft:water_source>,
["AAA",
"B B",
"AAA"],
{ A : <ore:plateWroughtIron>,
B : <minecraft:water_bucket:*> });
//Rubber by hand //Rubber by hand
recipes.addShaped(<metaitem:plateRubber>,[[<ore:toolHammer>],[<metaitem:rubber_drop>],[<metaitem:rubber_drop>]]); recipes.addShaped(<metaitem:plateRubber>,[[<ore:toolHammer>],[<metaitem:rubber_drop>],[<metaitem:rubber_drop>]]);
@ -561,26 +551,6 @@ recipes.addShaped(<storagedrawers:upgrade_template> * 2, [
[<ore:stickWood>, <storagedrawers:customdrawers>, <ore:stickWood>], [<ore:stickWood>, <storagedrawers:customdrawers>, <ore:stickWood>],
[<ore:stickWood>, <ore:stickWood>, <ore:stickWood>]]); [<ore:stickWood>, <ore:stickWood>, <ore:stickWood>]]);
// NC Cobble gen
recipes.remove(<nuclearcraft:cobblestone_generator>);
makeShaped("of_nc_cobblestone_generator",
<nuclearcraft:cobblestone_generator>,
["AAA",
"B C",
"AAA"],
{ A : <ore:plateSteel>,
B : <minecraft:water_bucket:*>,
C : <minecraft:lava_bucket:*> });
makeShaped("of_nc_cobblestone_generator_mirrored",
<nuclearcraft:cobblestone_generator>,
["AAA",
"C B",
"AAA"],
{ A : <ore:plateSteel>,
B : <minecraft:water_bucket:*>,
C : <minecraft:lava_bucket:*> });
//Crystal Growth Chamber //Crystal Growth Chamber
recipes.addShaped(<ae2stuff:grower>, [ recipes.addShaped(<ae2stuff:grower>, [
[<ore:frameGtDarkSteel>, <appliedenergistics2:material:1>, <ore:frameGtDarkSteel>], [<ore:frameGtDarkSteel>, <appliedenergistics2:material:1>, <ore:frameGtDarkSteel>],

View File

@ -9,7 +9,7 @@
"private": true, "private": true,
"scripts": { "scripts": {
"gulp": "node --import ./tsNodeESMRegister.mjs node_modules/gulp/bin/gulp.js", "gulp": "node --import ./tsNodeESMRegister.mjs node_modules/gulp/bin/gulp.js",
"check": "tsc --pretty" "check": "tsc --pretty --noUnusedLocals --noUnusedParameters"
}, },
"imports": { "imports": {
"#types/*": "./types/*", "#types/*": "./types/*",

View File

@ -0,0 +1,161 @@
import {
formattingChar,
invalidFormatting,
isSpaceOrNewLine,
} from "./checksData.ts";
export type Character = {
char: string;
formatBefore: string;
formatAfter: string;
};
export type Characters = Character[];
const emptyChar: Character = { char: "", formatBefore: "r", formatAfter: "r" };
export default class ChecksCharProcessor {
// Filled up initially with all characters from value.
public source: Characters;
// Resultant list
public result: Characters;
private currIndex;
constructor(value: string) {
this.source = [];
// Init source with characters
for (let i = 0; i < value.length; i++) {
let char = value.charAt(i);
if (char !== formattingChar) {
this.add(char, this.source);
continue;
}
let next = value.charAt(++i) ?? "";
// Don't add if next character is also formatting, just leave it as lone signal and have formatter deal with it
// Newlines and spaces BQu ignores after a formatting char, so keep them
if (next === formattingChar) {
next = "";
// Decrement i again, so the next character is added separately
i--;
}
this.addFormat(next, this.source);
}
this.result = [];
// Start index at -1, as we always use index to get the 'next' char, not the current char
this.currIndex = -1;
}
/**
* Adds a normal character to the specified list. Defaults to result list.
*/
public add(char: string, list: Characters = this.result): void {
if (!char) return;
const fmt = this.getCurrentFormat(list);
list.push({ char, formatBefore: fmt, formatAfter: fmt });
}
/**
* Adds a formatting signal to the specified list. Defaults to result list.
*/
public addFormat(signal: string, list: Characters = this.result): void {
const result = formattingChar + signal;
let formatAfter = signal;
if (invalidFormatting.test(result)) {
// Use previous
formatAfter = this.getCurrentFormat(list);
}
list.push({
char: result,
formatBefore: this.getCurrentFormat(list),
formatAfter,
});
}
/**
* Gets the current format, in the specified list. Defaults to result list.
*/
public getCurrentFormat(list: Characters = this.result): string {
return this.getLast(list).formatAfter;
}
/**
* Returns whether there are more characters to process in the source list.
*/
public hasNext(): boolean {
return this.currIndex < this.source.length;
}
/**
* Gets the next character in the source list, and increments the current index.
* @return character Character in the source list. Returns empty character if out of bounds.
*/
public toNext(): Character {
return this.at(++this.currIndex, this.source);
}
/**
* Gets the next character in the source list.
* @param amount The amount to get after currentIndex. This should never be less than 1. Defaults to 1
* (the next character to process)
* @return character Character in the source list. Returns empty character if out of bounds.
*/
public getNext(amount: number = 1): Character {
return this.at(this.currIndex + amount, this.source);
}
/**
* Gets the character at the index of the specified list safely. Defaults to result list.
* Returns empty character if out of bounds.
*/
public at(index: number, list = this.result): Character {
return list.at(index) ?? emptyChar;
}
/**
* Gets the last character in the specified list. Defaults to result list.
*/
public getLast(list = this.result) {
return this.at(-1, list);
}
/**
* Removes the last amt characters added to the results. Defaults to 1.
*/
public removeLast(amt: number = 1) {
this.result = this.result.slice(0, -amt);
}
/**
* Finds the last non-space/newline character in the specified list. Defaults to results list.
* If none found, returns an empty character.
*/
public getLastNonSpaceLike(list = this.result): {
char: Character;
index: number;
} {
const index = list.findLastIndex(
(char) => !isSpaceOrNewLine.test(char.char),
);
return index === -1
? { char: emptyChar, index }
: { char: this.at(index, list), index };
}
/**
* Gets the string this builder condenses into.
*/
public getResult(): string {
return this.result.map((char) => char.char).join("");
}
}

View File

@ -0,0 +1,39 @@
import ChecksCharProcessor from "#tasks/helpers/questChecks/checksCharProcessor.ts";
/* Patterns */
export const doubleSpace = / {2,}/g;
export const invalidFormatting = /§$|§[^0-9a-ek-or]/;
export const isSpaceOrNewLine = /[ \n]/;
export const isFormattingSignal = /§([0-9a-ek-or])/;
/* Constants */
export const formattingChar = "§";
export const resettingSignal = "r";
export default class ChecksData {
public shouldCheck: boolean;
public value: string;
public id: number;
public name: string;
public key: string;
public processor: ChecksCharProcessor;
constructor(
shouldCheck: boolean,
value: string,
id: number,
name: string,
key: string,
) {
this.shouldCheck = shouldCheck;
this.value = value;
this.id = id;
this.name = name;
this.key = key;
this.processor = new ChecksCharProcessor(value);
}
public saveValue() {
this.value = this.processor.getResult();
}
}

View File

@ -0,0 +1,217 @@
/* Storage for Per Char Checks */
// Builder for per character
import ChecksData, {
doubleSpace,
formattingChar,
invalidFormatting,
isSpaceOrNewLine,
isFormattingSignal,
resettingSignal,
} from "./checksData.ts";
import {
isResettingSignal,
logOrThrowProblem,
setupUtil,
} from "./checksUtil.ts";
/**
* Makes various space and newline related checks, and checks formatting.
*/
export default function checkSpacesAndFormatting(
shouldCheck: boolean,
value: string,
id: number,
name: string,
key: string,
): string {
const data = new ChecksData(shouldCheck, value, id, name, key);
setupUtil(data);
checkFormatting(data);
if (doubleSpace.test(data.value)) {
logOrThrowProblem("Double Space(s)");
data.value = data.value.replace(doubleSpace, " ");
}
const trimmedResult = data.value.trim();
if (trimmedResult !== data.value) {
logOrThrowProblem("Extra Spaces or New Lines at Beginning or End");
data.value = trimmedResult;
}
if (!data.value.includes("\n")) return data.value;
const lineBuilder: string[] = [];
for (const bit of data.value.split("\n")) {
const trimmedBit = bit.trim();
if (trimmedBit !== bit)
logOrThrowProblem("Extra Spaces at Beginning or End of a Line");
lineBuilder.push(trimmedBit);
}
return lineBuilder.join("\n");
}
/**
* Whole string formatting checks.
*/
function checkFormatting(data: ChecksData) {
if (!data.value.includes(formattingChar)) return;
checkFormattingChar(data);
/* End of String Checks */
let prevChar = data.processor.getLast();
// Check for redundant formatting at end
if (isFormattingSignal.test(prevChar.char)) {
// If not resetting change, or we have no need to reset
// Note the second case should be caught by redundant formatting check, so no need to check
if (!isResettingSignal(prevChar.char)) {
logOrThrowProblem("Redundant Formatting At End");
data.processor.removeLast();
}
// For continued processing, refresh prevChar
prevChar = data.processor.getLast();
}
data.saveValue();
// Check for missing resetting signal at end
if (
!isResettingSignal(prevChar.char) &&
prevChar.formatBefore !== resettingSignal
) {
logOrThrowProblem("Resetting Formatting At End", "Missing", "Adding");
// Trim value, then add §r to it
data.value = data.value.trim() + formattingChar + resettingSignal;
}
}
/**
* Per character formatting checks.
*/
function checkFormattingChar(data: ChecksData) {
while (data.processor.hasNext()) {
const char = data.processor.toNext();
// If not formatting signal, ignore
if (!char.char.includes(formattingChar)) {
data.processor.add(char.char);
continue;
}
let signal = "";
// Check for invalid formatting, including legacy 'f' signal
if (invalidFormatting.test(char.char)) {
logOrThrowProblem(
`Invalid Formatting Signal '${char.char}'`,
"",
"Replacing",
"",
"with '§r'",
);
// BQu treats signals like §z as a resetting signal, so make them reset
// Yes, even ones followed after by `'`, a space, or a newline
signal = "r";
} else signal = char.char.replace(isFormattingSignal, "$1");
// Note: Do not use char.char past this point, use signal instead!
// Check if formatting is right after another (ignoring spaces, newlines, etc.)
let prevIgnoreSpaces = data.processor.getLastNonSpaceLike();
if (isFormattingSignal.test(prevIgnoreSpaces.char.char)) {
logOrThrowProblem("Redundant Formatting");
// Remove previous formatting
// Note: this won't be called if not found, as empty string is not a formatting signal
// Instead of splicing, remove all, then add back, so we ensure correct formatting of spaces
const empties = data.processor.result.slice(prevIgnoreSpaces.index + 1);
data.processor.removeLast(
data.processor.result.length - prevIgnoreSpaces.index,
);
empties.forEach((char) => data.processor.add(char.char));
}
/* Redundant Formatting Checks */
// Check if formatting does nothing
if (data.processor.getCurrentFormat() === signal) {
logOrThrowProblem("Redundant Formatting");
// No need to do anything, just continue
continue;
}
/* End Redundant Formatting Checks */
/* Formatting Order Checks */
// Make sure resetting formatting is BEFORE spaces
if (signal === "r") {
if (isSpaceOrNewLine.test(data.processor.getLast().char)) {
logOrThrowProblem(
"Resetting Formatting",
"",
"Moving",
"After Space(s)",
"Before Space(s)",
);
// Refetch ignore spaces, it may have changed
prevIgnoreSpaces = data.processor.getLastNonSpaceLike();
if (prevIgnoreSpaces.index === -1) {
// We don't need to add resetting formatting at start of processor
// Also, this condition should have already been caught through redundant checks
// Ignore
continue;
}
// Move in before spaces (Add after existing character, so use index + 1)
// Instead of splicing, remove all, then add back, so we ensure correct formatting of spaces
const empties = data.processor.result.slice(prevIgnoreSpaces.index + 1);
data.processor.removeLast(
data.processor.result.length - prevIgnoreSpaces.index - 1, // -1, we don't want to remove last-non-space char itself
);
data.processor.addFormat(signal);
empties.forEach((char) => data.processor.add(char.char));
continue;
}
data.processor.addFormat(signal);
continue;
}
// Make sure non-resetting formatting is AFTER spaces
// Note: we don't have to check if have next, as empty string is not space or newline
if (!isSpaceOrNewLine.test(data.processor.getNext().char)) {
data.processor.addFormat(signal);
continue;
}
logOrThrowProblem(
"Non-Resetting Formatting",
"",
"Moving",
"Before Space(s)",
"After Space(s)",
);
// Add all upcoming space/newline characters
while (
data.processor.hasNext() &&
isSpaceOrNewLine.test(data.processor.getNext().char)
) {
data.processor.add(data.processor.toNext().char);
}
// Add formatting
data.processor.addFormat(signal);
}
}

View File

@ -0,0 +1,36 @@
import ChecksData, { formattingChar, resettingSignal } from "./checksData.ts";
import { logWarn } from "#utils/log.ts";
let data: ChecksData;
export function setupUtil(dataIn: ChecksData) {
data = dataIn;
}
/**
* Either throws, if checking, or logs a fixing notice.
* <br><br>
* Error Msg formatted as: `${name} with ID ${id} at ${key} has ${describer} ${problem} ${conditionBefore}!`,<br>
* Fixing Msg formatted as: `${verb} ${problem} ${conditionAfter} in ${name} with ID ${id} at ${key}...`,
*/
export function logOrThrowProblem(
problem: string,
describer = "",
verb: string = "Removing",
conditionBefore = "",
conditionAfter = "",
) {
if (data.shouldCheck)
throw new Error(
`${data.name} with ID ${data.id} at ${data.key} has ${describer}${describer ? ` ${describer}` : ""}
${problem}${conditionBefore ? ` ${conditionBefore}` : ""}!`,
);
logWarn(
`${verb} ${problem}${conditionAfter ? ` ${conditionAfter}` : ""} in ${data.name} with ID ${data.id} at ${data.key}...`,
);
}
export function isResettingSignal(char: string): boolean {
return char === formattingChar + resettingSignal;
}

View File

@ -21,8 +21,7 @@ import colors from "colors";
import { isEnvVariableSet } from "#utils/util.ts"; import { isEnvVariableSet } from "#utils/util.ts";
import * as core from "@actions/core"; import * as core from "@actions/core";
import lodash from "lodash"; import lodash from "lodash";
import checkSpacesAndFormatting from "./checksFormatting.ts";
const isAvailableForFormatting = /[0-9a-ek-or]/;
export const check = async () => { export const check = async () => {
try { try {
@ -183,7 +182,7 @@ async function checkAndFixQB(
// Check Name Formatting // Check Name Formatting
quest["properties:10"]["betterquesting:10"]["name:8"] = quest["properties:10"]["betterquesting:10"]["name:8"] =
stripOrThrowExcessSpacesOrFormatting( checkSpacesAndFormatting(
shouldCheck, shouldCheck,
name(quest), name(quest),
foundID, foundID,
@ -204,7 +203,7 @@ async function checkAndFixQB(
} }
// Check Desc Formatting (Still check if after, as user may have entered dupe formatting) // Check Desc Formatting (Still check if after, as user may have entered dupe formatting)
quest["properties:10"]["betterquesting:10"]["desc:8"] = quest["properties:10"]["betterquesting:10"]["desc:8"] =
stripOrThrowExcessSpacesOrFormatting( checkSpacesAndFormatting(
shouldCheck, shouldCheck,
quest["properties:10"]["betterquesting:10"]["desc:8"], quest["properties:10"]["betterquesting:10"]["desc:8"],
foundID, foundID,
@ -318,7 +317,7 @@ async function checkAndFixQB(
for (const lineKey of Object.keys(qb["questLines:9"])) { for (const lineKey of Object.keys(qb["questLines:9"])) {
const line = qb["questLines:9"][lineKey]; const line = qb["questLines:9"][lineKey];
line["properties:10"]["betterquesting:10"]["name:8"] = line["properties:10"]["betterquesting:10"]["name:8"] =
stripOrThrowExcessSpacesOrFormatting( checkSpacesAndFormatting(
shouldCheck, shouldCheck,
line["properties:10"]["betterquesting:10"]["name:8"], line["properties:10"]["betterquesting:10"]["name:8"],
line["lineID:3"], line["lineID:3"],
@ -326,7 +325,7 @@ async function checkAndFixQB(
"Name", "Name",
); );
line["properties:10"]["betterquesting:10"]["desc:8"] = line["properties:10"]["betterquesting:10"]["desc:8"] =
stripOrThrowExcessSpacesOrFormatting( checkSpacesAndFormatting(
shouldCheck, shouldCheck,
line["properties:10"]["betterquesting:10"]["desc:8"], line["properties:10"]["betterquesting:10"]["desc:8"],
line["lineID:3"], line["lineID:3"],
@ -374,155 +373,3 @@ async function checkAndFixQB(
qb["questSettings:10"]["betterquesting:10"]["editmode:1"] = 0; qb["questSettings:10"]["betterquesting:10"]["editmode:1"] = 0;
} }
} }
function stripOrThrowExcessSpacesOrFormatting(
shouldCheck: boolean,
value: string,
id: number,
name: string,
key: string,
): string {
let formattingResult = stripOrThrowExcessFormatting(
shouldCheck,
value,
id,
name,
key,
);
const trimmedResult = formattingResult.trim();
if (trimmedResult !== formattingResult) {
if (shouldCheck)
throw new Error(
`${name} with ID ${id} at ${key} has Extra Spaces or New Lines at Beginning or End!`,
);
logWarn(
`Removing Extra Spaces or New Lines in ${name} with ID ${id} at ${key}...`,
);
formattingResult = trimmedResult;
}
if (!value.includes("\n")) return formattingResult;
const builder: string[] = [];
for (const bit of formattingResult.split("\n")) {
const trimmedBit = bit.trim();
if (trimmedBit !== bit) {
if (shouldCheck)
throw new Error(
`${name} with ID ${id} at ${key} has Extra Spaces at Beginning or End of a Line!`,
);
logWarn(
`Removing Extra Spaces in a Line of ${name} with ID ${id} at ${key}...`,
);
}
builder.push(trimmedBit);
}
return builder.join("\n");
}
function stripOrThrowExcessFormatting(
shouldCheck: boolean,
value: string,
id: number,
name: string,
key: string,
): string {
if (!value.includes("§")) return value;
let builder: string[] = [];
let emptyAmt: number = 0;
for (let i = 0; i < value.length; i++) {
const char = value.charAt(i);
// If Space, ignore, add one to Empty Amt
if (char === " ") {
emptyAmt++;
builder.push(char);
continue;
}
// Else, reset Empty Amt
const oldEmptyAmt = emptyAmt;
emptyAmt = 0;
if (builder.at(-1) === "§") {
if (char === "f") {
if (shouldCheck)
throw new Error(
`${name} with ID ${id} at ${key} has Formatting Code 'f'!`,
);
logWarn(
`Replacing Formatting Code 'f' with 'r' in ${name} with ID ${id} at ${key}...`,
);
builder.push("r");
continue;
}
if (!isAvailableForFormatting.test(char)) {
if (shouldCheck)
throw new Error(
`${name} with ID ${id} at ${key} has Lone Formatting Signal!`,
);
logWarn(
`Removing Lone Formatting Signal in ${name} with ID ${id} at ${key}...`,
);
// Remove Last Element
builder = builder.slice(0, -1);
continue;
}
// Start of String, Remove Formatting is NOT Needed
if (builder.length === 1 && char === "r") {
if (shouldCheck)
throw new Error(
`${name} with ID ${id} at ${key} has Redundant Formatting!`,
);
logWarn(
`Removing Redundant Formatting from ${name} with ID ${id} at ${key}...`,
);
// Remove Previous
builder = [];
continue;
}
builder.push(char);
continue;
}
if (char === "§") {
// If two characters before was not § (if builder length < 2, `.at` returns undefined)
// (Ignoring Spaces)
if (builder.at(-2 - oldEmptyAmt) !== "§") {
builder.push(char);
continue;
}
if (shouldCheck)
throw new Error(
`${name} with ID ${id} at ${key} has Redundant Formatting!`,
);
logWarn(
`Removing Redundant Formatting from ${name} with ID ${id} at ${key}...`,
);
// Remove Previous
builder = builder.slice(0, -2 - oldEmptyAmt);
// Add Empty Amount Spaces
for (let i = 0; i < oldEmptyAmt; i++) {
builder.push(" ");
}
}
builder.push(char);
}
return builder.join("");
}

View File

@ -93,7 +93,9 @@ export default async function portQBChanges(): Promise<void> {
const obj = {} as { [key: string]: Quest }; const obj = {} as { [key: string]: Quest };
const iter = data.toChangeIDsToQuests.values(); const iter = data.toChangeIDsToQuests.values();
for (let i = 0; i < data.toChangeIDsToQuests.size; i++) { for (let i = 0; i < data.toChangeIDsToQuests.size; i++) {
obj[`${i}:10`] = iter.next().value; const quest = iter.next().value;
if (!quest) continue;
obj[`${i}:10`] = quest;
} }
toChange["questDatabase:9"] = obj; toChange["questDatabase:9"] = obj;